Advertisement
ptrelford

Random Art Functional

Jan 18th, 2015
371
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 4.33 KB | None | 0 0
  1. type expr =
  2.    | VariableX
  3.    | VariableY
  4.    | Constant
  5.    | Sum of expr * expr
  6.    | Product of expr * expr
  7.    | Mod of expr * expr
  8.    | Well of expr
  9.    | Tent of expr
  10.    | Sin of expr
  11.    | Level of expr * expr * expr
  12.    | Mix of expr * expr * expr
  13.  
  14. let random = System.Random()
  15. let next () = random.NextDouble()
  16.  
  17. let average (c1,c2,w) =
  18.    let r1,g1,b1 = c1
  19.    let r2,g2,b2 = c2
  20.    let r = w * r1 + (1.0 - w) * r2
  21.    let g = w * g1 + (1.0 - w) * g2
  22.    let b = w * b1 + (1.0 - w) * b2
  23.    r,g,b
  24.  
  25. let well x = 1.0 - 2.0 / (1.0 + x * x) ** 8.0
  26.  
  27. let tent x = 1.0 - 2.0 * abs x
  28.  
  29. let rec eval = function
  30.    | VariableX -> fun (x,y) -> (x,x,x)
  31.    | VariableY -> fun (x,y) -> (y,y,y)
  32.    | Constant ->
  33.       let r,g,b = next(),next(),next()
  34.       fun (x,y) -> (r,g,b)
  35.    | Sum(e1,e2) ->
  36.       let f1,f2 = eval e1, eval e2
  37.       fun (x,y) ->
  38.          average(f1(x,y),f2(x,y),0.5)
  39.    | Product(e1,e2) ->
  40.       let f1,f2 = eval e1, eval e2
  41.       fun (x,y) ->
  42.          let r1,g1,b1 = f1(x,y)
  43.          let r2,g2,b2 = f2(x,y)
  44.          r1*r2, g1*g2, b1*b2
  45.    | Mod(e1,e2) ->
  46.       let f1,f2 = eval e1, eval e2
  47.       fun (x,y) ->
  48.          let r1,g1,b1 = f1(x,y)
  49.          let r2,g2,b2 = f2(x,y)
  50.          r1 % r2, g1 % g2, b1 % b2
  51.    | Well(e) ->
  52.       let f = eval e
  53.       fun (x,y) ->        
  54.          let r,g,b = f(x,y)
  55.          well r, well g, well b
  56.    | Tent(e) ->
  57.       let f = eval e
  58.       fun (x,y) ->        
  59.          let r,g,b = f(x,y)
  60.          tent r, tent g, tent b
  61.    | Sin(e) ->
  62.       let f = eval e
  63.       let phase = next() * System.Math.PI
  64.       let freq = (next()*5.0)+1.0      
  65.       fun (x,y) ->
  66.          let r,g,b = f(x,y)
  67.          sin(phase + r*freq),sin(phase+g*freq),sin (phase+b*freq)        
  68.    | Level(e1,e2,e3) ->
  69.       let f1,f2,f3 = eval e1, eval e2, eval e3
  70.       let threshold = (next()*2.0) - 1.0
  71.       fun (x,y) ->
  72.          let r1,g1,b1 = f1(x,y)
  73.          let r2,g2,b2 = f2(x,y)
  74.          let r3,g3,b3 = f3(x,y)
  75.          let r = if r1 < threshold then r2 else r3
  76.          let g = if g1 < threshold then g2 else g3
  77.          let b = if b1 < threshold then b2 else b3
  78.          r,g,b
  79.    | Mix(e1,e2,e3) ->
  80.       let f1,f2,f3 = eval e1, eval e2, eval e3
  81.       let threshold = (next()*2.0) - 1.0
  82.       fun (x,y) ->
  83.          let n, _, _ = f1(x,y)
  84.          let w = 0.5 * (n + 1.0)
  85.          let c1 = f2(x,y)
  86.          let c2 = f3(x,y)
  87.          average(c1,c2,w)
  88.  
  89. let rec gen k =
  90.    if k <= 0 || next() < 0.01 then
  91.       let terminals = [VariableX; VariableY;Constant]
  92.       terminals.[random.Next(terminals.Length)]
  93.    else
  94.       let n() = random.Next(k)
  95.       let operators = [
  96.          fun () -> Sum(gen (n()), gen(n()))
  97.          fun () -> Product(gen (n()), gen(n()))
  98.          fun () -> Mod(gen (n()), gen(n()))
  99.          fun () -> Well(gen (n()))
  100.          fun () -> Tent(gen (n()))
  101.          fun () -> Sin(gen (n()))
  102.          fun () -> Level(gen (n()), gen (n()), gen(n()))
  103.          fun () -> Mix(gen (n()), gen (n()), gen(n()))
  104.       ]
  105.       operators.[random.Next(operators.Length)]()
  106.  
  107. let e = gen 256
  108. let f = eval e
  109.  
  110. #r "System.Drawing.dll"
  111. #r "System.Windows.Forms.dll"
  112.  
  113. let rgb (r,g,b) =
  114.    let r = max 0 (min 255 (int (128.0 * (r + 1.0))))
  115.    let g = max 0 (min 255 (int (128.0 * (g + 1.0))))
  116.    let b = max 0 (min 255 (int (128.0 * (b + 1.0))))
  117.    r,g,b
  118.  
  119. let width, height = 512, 384
  120.  
  121. open System
  122. open System.Drawing
  123. open System.Windows.Forms
  124.  
  125. let draw n =    
  126.    let image = new Bitmap(width, height)
  127.    use graphics = Graphics.FromImage(image)  
  128.    [|for y in 0..n..height-n do
  129.       for x in 0..n..width-n -> x,y
  130.    |]
  131.    |> Array.Parallel.map (fun (x,y) ->
  132.          let x' = -1.0 + (float ((x+(n/2))*2)/float width)
  133.         let y' = -1.0 + (float ((y+(n/2))*2)/float height)
  134.          let r,g,b = f(x',y')
  135.          let r,g,b = rgb(r,g,b)
  136.          x,y,r,g,b
  137.    )
  138.    |> Array.iter (fun (x,y,r,g,b) ->        
  139.       use pen = new SolidBrush(Color.FromArgb(r,g,b))
  140.       graphics.FillRectangle(pen, x, y, n, n)
  141.    )
  142.    image
  143.  
  144. let show () =
  145.    let image = draw 1
  146.    let form = new Form (Text="Random Art", Width=width+16, Height=height+36)  
  147.    let picture = new PictureBox(Dock=DockStyle.Fill, Image=image)
  148.    do  form.Controls.Add(picture)
  149.    picture.Image <- image
  150.    form.Show() |> ignore
  151.    image.Save(@"C:\app\Random.png", Imaging.ImageFormat.Png)
  152.        
  153. show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement