Advertisement
ptrelford

Random x1000

Jan 18th, 2015
382
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 4.14 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. #if INTERACTIVE
  108. #r "System.Drawing.dll"
  109. #endif
  110.  
  111. let rgb (r,g,b) =
  112.    let r = max 0 (min 255 (int (128.0 * (r + 1.0))))
  113.    let g = max 0 (min 255 (int (128.0 * (g + 1.0))))
  114.    let b = max 0 (min 255 (int (128.0 * (b + 1.0))))
  115.    r,g,b
  116.  
  117. let width, height = 512, 384
  118.  
  119. open System
  120. open System.Drawing
  121.  
  122. let draw f n =
  123.    let image = new Bitmap(width, height)
  124.    use graphics = Graphics.FromImage(image)  
  125.    [|for y in 0..n..height-n do
  126.       for x in 0..n..width-n -> x,y
  127.    |]
  128.    |> Array.Parallel.map (fun (x,y) ->
  129.          let x' = -1.0 + (((float x+(float n/2.0))*2.0)/float width)
  130.         let y' = -1.0 + (((float y+(float n/2.0))*2.0)/float height)
  131.          let r,g,b = f(x',y')
  132.          let r,g,b = rgb(r,g,b)
  133.          x,y,r,g,b
  134.    )
  135.    |> Array.iter (fun (x,y,r,g,b) ->        
  136.       use pen = new SolidBrush(Color.FromArgb(r,g,b))
  137.       graphics.FillRectangle(pen, x, y, n, n)
  138.    )
  139.    image
  140.  
  141. let show n =
  142.    let e = gen 50
  143.    let f = eval e
  144.    let image = draw f 1
  145.    image.Save(sprintf @"C:\temp\Random%04d.png" n, Imaging.ImageFormat.Png)
  146.        
  147. for i = 1 to 1000 do show i
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement