Advertisement
ptrelford

Random Art

Jan 15th, 2015
533
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 4.76 KB | None | 0 0
  1. open System
  2.  
  3. let random = Random()
  4.  
  5. let rand = fun () -> random.NextDouble()
  6.  
  7. let average (c1,c2,w) =
  8.    let r1,g1,b1 = c1
  9.    let r2,g2,b2 = c2
  10.    let r = w * r1 + (1.0 - w) * r2
  11.    let g = w * g1 + (1.0 - w) * g2
  12.    let b = w * b1 + (1.0 - w) * b2
  13.    r,g,b
  14.  
  15. let rgb (r,g,b) =
  16.    let r = max 0 (min 255 (int (128.0 * (r + 1.0))))
  17.    let g = max 0 (min 255 (int (128.0 * (g + 1.0))))
  18.    let b = max 0 (min 255 (int (128.0 * (b + 1.0))))
  19.    r,g,b
  20.  
  21. let well x = 1.0 - 2.0 / (1.0 + x * x) ** 8.0
  22.  
  23. let tent x = 1.0 - 2.0 * abs x
  24.  
  25. type color = float * float * float
  26.  
  27. [<AbstractClass>]
  28. type Expr () =    
  29.    abstract member Eval : float * float -> color
  30.  
  31. type VariableX() =
  32.    inherit Expr()
  33.    override __.Eval(x,y) = (x,x,x)
  34.  
  35. type VariableY() =
  36.    inherit Expr()  
  37.    override __.Eval(x,y) = (y,y,y)
  38.  
  39. type Constant() =
  40.    inherit Expr()
  41.    let r,g,b = rand(), rand(), rand()  
  42.    override __.Eval(x,y) = (r,g,b)
  43.  
  44. type Sum(e1:Expr,e2:Expr) =
  45.    inherit Expr()
  46.    override __.Eval(x,y) = average(e1.Eval(x,y), e2.Eval(x,y), 0.5)
  47.  
  48. type Product(e1:Expr,e2:Expr) =
  49.    inherit Expr()
  50.    override __.Eval(x,y) =
  51.       let r1,g1,b1 = e1.Eval(x,y)
  52.       let r2,g2,b2 = e2.Eval(x,y)
  53.       r1 * r2, g1 * g2, b1 * b2
  54.  
  55. type Max(e1:Expr,e2:Expr) =
  56.    inherit Expr()
  57.    override __.Eval(x,y) =
  58.       let r1,g1,b1 = e1.Eval(x,y)
  59.       let r2,g2,b2 = e2.Eval(x,y)
  60.       max r1 r2, max g1 g2, max b1 b2
  61.  
  62. type Mod(e1:Expr,e2:Expr) =
  63.    inherit Expr()
  64.    override __.Eval(x,y) =
  65.       let r1,g1,b1 = e1.Eval(x,y)
  66.       let r2,g2,b2 = e2.Eval(x,y)
  67.       r1 % r2, g1 % g2, b1 % b2
  68.  
  69. type Well(e:Expr) =
  70.    inherit Expr()
  71.    override __.Eval(x,y) =
  72.       let r,g,b = e.Eval(x,y)
  73.       well r, well g, well b
  74.  
  75. type Neg(e:Expr) =
  76.    inherit Expr()
  77.    override __.Eval(x,y) =
  78.       let r,g,b = e.Eval(x,y)
  79.       -r, -g, -b
  80.  
  81. type Square(e:Expr) =
  82.    inherit Expr()
  83.    override __.Eval(x,y) =
  84.       let r,g,b = e.Eval(x,y)
  85.       r*r, g*g, b*b
  86.  
  87. type Tent(e:Expr) =
  88.    inherit Expr()
  89.    override __.Eval(x,y) =
  90.       let r,g,b = e.Eval(x,y)    
  91.       tent r, tent g, tent b
  92.  
  93. type Sin(e:Expr) =
  94.    inherit Expr()
  95.    let phase = rand() * Math.PI
  96.    let freq = (rand()*5.0)+1.0      
  97.    override __.Eval(x,y) =
  98.       let r,g,b = e.Eval(x,y)
  99.       sin(phase + r*freq),sin(phase+g*freq),sin (phase+b*freq)
  100.  
  101. type Level(e1:Expr,e2:Expr,e3:Expr) =
  102.    inherit Expr()
  103.    let threshold = (rand()*2.0) - 1.0
  104.    override __.Eval(x,y) =
  105.       let r1,g1,b1 = e1.Eval(x,y)
  106.       let r2,g2,b2 = e2.Eval(x,y)
  107.       let r3,g3,b3 = e3.Eval(x,y)
  108.       let r = if r1 < threshold then r2 else r3
  109.       let g = if g1 < threshold then g2 else g3
  110.       let b = if b1 < threshold then b2 else b3
  111.       r,g,b
  112.  
  113. type Mix(e1:Expr,e2:Expr,e3:Expr) =
  114.    inherit Expr()
  115.    override __.Eval(x,y) =
  116.       let n, _, _ = e1.Eval(x,y)
  117.       let w = 0.5 * (n + 1.0)
  118.       let c1 = e1.Eval(x,y)
  119.       let c2 = e2.Eval(x,y)
  120.       average(c1,c2,w)
  121.  
  122. let types = [
  123.    typeof<Constant>
  124.    typeof<VariableX>
  125.    typeof<VariableY>
  126.    typeof<Sum>
  127.    typeof<Product>
  128.    //typeof<Max>
  129.    //typeof<Neg>
  130.    //typeof<Square>
  131.    typeof<Mod>
  132.    typeof<Well>
  133.    typeof<Tent>
  134.    typeof<Sin>
  135.    typeof<Level>
  136.    typeof<Mix>
  137.    ]
  138.  
  139. let exprs =
  140.    types |> List.map (fun ty ->
  141.       let ci = ty.GetConstructors().[0]
  142.       let ps = ci.GetParameters()
  143.       ps.Length, fun args -> ci.Invoke(args) :?> Expr
  144.    )
  145.  
  146. let expr0, exprN = exprs |> List.partition (fun (arity,_) -> arity = 0)
  147.  
  148. let rec generate k =
  149.    if k <= 0 then
  150.       let _, c = expr0.[random.Next(expr0.Length)]
  151.       c [||]
  152.    else
  153.       let arity, cons = exprN.[random.Next(exprN.Length)]
  154.       let args = [|for i in 1..arity -> box <| generate(k-i)|]
  155.       cons args
  156.  
  157. let expr = generate 12
  158.  
  159. #r "System.Drawing.dll"
  160. #r "System.Windows.Forms.dll"
  161.  
  162. let width, height = 512, 384
  163.  
  164. open System
  165. open System.Drawing
  166. open System.Windows.Forms
  167.  
  168. let draw () =  
  169.    let image = new Bitmap(width, height)
  170.    use graphics = Graphics.FromImage(image)  
  171.    [|for y = 0 to height - 1 do
  172.       for x in 0 .. width - 1 -> x,y|]
  173.    |> Array.Parallel.map (fun (x,y) ->
  174.       let x' = -1.0 + (float (x*2)/float width)
  175.      let y' = -1.0 + (float (y*2)/float height)
  176.       let r,g,b = expr.Eval(x',y')
  177.       let r,g,b = rgb(r,g,b)
  178.       x,y,r,g,b
  179.    )
  180.    |> Array.iter (fun (x,y,r,g,b) ->
  181.       use pen = new Pen(Color.FromArgb(r,g,b))
  182.       graphics.DrawRectangle(pen, x, y, 1, 1)        
  183.    )
  184.    image
  185.  
  186. let show () =
  187.    let image = draw ()
  188.    image.Save(@"C:\app\Random.png", Imaging.ImageFormat.Png)
  189.    let form = new Form (Text="Random Art", Width=width+16, Height=height+36)  
  190.    let picture = new PictureBox(Dock=DockStyle.Fill, Image=image)
  191.    do  form.Controls.Add(picture)
  192.    form.ShowDialog() |> ignore
  193.  
  194. show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement