Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- open System
- let random = Random()
- let rand = fun () -> random.NextDouble()
- let average (c1,c2,w) =
- let r1,g1,b1 = c1
- let r2,g2,b2 = c2
- let r = w * r1 + (1.0 - w) * r2
- let g = w * g1 + (1.0 - w) * g2
- let b = w * b1 + (1.0 - w) * b2
- r,g,b
- let rgb (r,g,b) =
- let r = max 0 (min 255 (int (128.0 * (r + 1.0))))
- let g = max 0 (min 255 (int (128.0 * (g + 1.0))))
- let b = max 0 (min 255 (int (128.0 * (b + 1.0))))
- r,g,b
- let well x = 1.0 - 2.0 / (1.0 + x * x) ** 8.0
- let tent x = 1.0 - 2.0 * abs x
- type color = float * float * float
- [<AbstractClass>]
- type Expr () =
- abstract member Eval : float * float -> color
- type VariableX() =
- inherit Expr()
- override __.Eval(x,y) = (x,x,x)
- type VariableY() =
- inherit Expr()
- override __.Eval(x,y) = (y,y,y)
- type Constant() =
- inherit Expr()
- let r,g,b = rand(), rand(), rand()
- override __.Eval(x,y) = (r,g,b)
- type Sum(e1:Expr,e2:Expr) =
- inherit Expr()
- override __.Eval(x,y) = average(e1.Eval(x,y), e2.Eval(x,y), 0.5)
- type Product(e1:Expr,e2:Expr) =
- inherit Expr()
- override __.Eval(x,y) =
- let r1,g1,b1 = e1.Eval(x,y)
- let r2,g2,b2 = e2.Eval(x,y)
- r1 * r2, g1 * g2, b1 * b2
- type Max(e1:Expr,e2:Expr) =
- inherit Expr()
- override __.Eval(x,y) =
- let r1,g1,b1 = e1.Eval(x,y)
- let r2,g2,b2 = e2.Eval(x,y)
- max r1 r2, max g1 g2, max b1 b2
- type Mod(e1:Expr,e2:Expr) =
- inherit Expr()
- override __.Eval(x,y) =
- let r1,g1,b1 = e1.Eval(x,y)
- let r2,g2,b2 = e2.Eval(x,y)
- r1 % r2, g1 % g2, b1 % b2
- type Well(e:Expr) =
- inherit Expr()
- override __.Eval(x,y) =
- let r,g,b = e.Eval(x,y)
- well r, well g, well b
- type Neg(e:Expr) =
- inherit Expr()
- override __.Eval(x,y) =
- let r,g,b = e.Eval(x,y)
- -r, -g, -b
- type Square(e:Expr) =
- inherit Expr()
- override __.Eval(x,y) =
- let r,g,b = e.Eval(x,y)
- r*r, g*g, b*b
- type Tent(e:Expr) =
- inherit Expr()
- override __.Eval(x,y) =
- let r,g,b = e.Eval(x,y)
- tent r, tent g, tent b
- type Sin(e:Expr) =
- inherit Expr()
- let phase = rand() * Math.PI
- let freq = (rand()*5.0)+1.0
- override __.Eval(x,y) =
- let r,g,b = e.Eval(x,y)
- sin(phase + r*freq),sin(phase+g*freq),sin (phase+b*freq)
- type Level(e1:Expr,e2:Expr,e3:Expr) =
- inherit Expr()
- let threshold = (rand()*2.0) - 1.0
- override __.Eval(x,y) =
- let r1,g1,b1 = e1.Eval(x,y)
- let r2,g2,b2 = e2.Eval(x,y)
- let r3,g3,b3 = e3.Eval(x,y)
- let r = if r1 < threshold then r2 else r3
- let g = if g1 < threshold then g2 else g3
- let b = if b1 < threshold then b2 else b3
- r,g,b
- type Mix(e1:Expr,e2:Expr,e3:Expr) =
- inherit Expr()
- override __.Eval(x,y) =
- let n, _, _ = e1.Eval(x,y)
- let w = 0.5 * (n + 1.0)
- let c1 = e1.Eval(x,y)
- let c2 = e2.Eval(x,y)
- average(c1,c2,w)
- let types = [
- typeof<Constant>
- typeof<VariableX>
- typeof<VariableY>
- typeof<Sum>
- typeof<Product>
- //typeof<Max>
- //typeof<Neg>
- //typeof<Square>
- typeof<Mod>
- typeof<Well>
- typeof<Tent>
- typeof<Sin>
- typeof<Level>
- typeof<Mix>
- ]
- let exprs =
- types |> List.map (fun ty ->
- let ci = ty.GetConstructors().[0]
- let ps = ci.GetParameters()
- ps.Length, fun args -> ci.Invoke(args) :?> Expr
- )
- let expr0, exprN = exprs |> List.partition (fun (arity,_) -> arity = 0)
- let rec generate k =
- if k <= 0 then
- let _, c = expr0.[random.Next(expr0.Length)]
- c [||]
- else
- let arity, cons = exprN.[random.Next(exprN.Length)]
- let args = [|for i in 1..arity -> box <| generate(k-i)|]
- cons args
- let expr = generate 12
- #r "System.Drawing.dll"
- #r "System.Windows.Forms.dll"
- let width, height = 512, 384
- open System
- open System.Drawing
- open System.Windows.Forms
- let draw () =
- let image = new Bitmap(width, height)
- use graphics = Graphics.FromImage(image)
- [|for y = 0 to height - 1 do
- for x in 0 .. width - 1 -> x,y|]
- |> Array.Parallel.map (fun (x,y) ->
- let x' = -1.0 + (float (x*2)/float width)
- let y' = -1.0 + (float (y*2)/float height)
- let r,g,b = expr.Eval(x',y')
- let r,g,b = rgb(r,g,b)
- x,y,r,g,b
- )
- |> Array.iter (fun (x,y,r,g,b) ->
- use pen = new Pen(Color.FromArgb(r,g,b))
- graphics.DrawRectangle(pen, x, y, 1, 1)
- )
- image
- let show () =
- let image = draw ()
- image.Save(@"C:\app\Random.png", Imaging.ImageFormat.Png)
- let form = new Form (Text="Random Art", Width=width+16, Height=height+36)
- let picture = new PictureBox(Dock=DockStyle.Fill, Image=image)
- do form.Controls.Add(picture)
- form.ShowDialog() |> ignore
- show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement