fsharp-mandelbrot/MandelBrot.fs
2019-02-07 21:13:38 +01:00

106 lines
No EOL
2.8 KiB
FSharp

module MandelBrot
open System.Drawing
open System.Numerics
open System
open System.Drawing
open System.Drawing
open System.Numerics
let hsbToRgb (h:float) (s:float) (v:float) =
let clamp x =
if x < 0 then 0
else if x > 255 then 255
else x
let mutable H = h
while H < 0.0 do H <- H + 360.0
while H >= 360.0 do H <- H - 360.0
let mutable R = 0.0
let mutable G = 0.0
let mutable B = 0.0
if v <= 0.0 then
R <- 0.0
G <- 0.0
B <- 0.0
else if s <= 0.0 then
R <- v
G <- v
B <- v
else
let hf = H / 60.0
let i = int (Math.Floor(hf))
let f = hf - (float i)
let pv = v * (1.0 - s)
let qv = v * (1.0 - s * f)
let tv = v * (1.0 - s * (1.0 - f))
match i with
| 0 -> R <- v; G <- tv; B <- pv
| 1 -> R <- qv; G <- v; B <- pv
| 2 -> R <- pv; G <- v; B <- tv
| 3 -> R <- pv; G <- qv; B <- v
| 4 -> R <- tv; G <- pv; B <- v
| 5 -> R <- v; G <- pv; B <- qv
| 6 -> R <- v; G <- tv; B <- pv
| -1 -> R <- v; G <- pv; B <- qv
| _ -> R <- v; G <- v; B <- v
//printfn "%f %f %f" R G B
Color.FromArgb(255, clamp (int (R*255.0)),
clamp (int (G*255.0)),
clamp (int (B*255.0)))
(*
let hi = (int (Math.Floor(h / 60.0)))
let f = h / 60.0 - Math.Floor(h / 60.0)
let value = v * 255.0
let vv = (int value)
let p = (int (value * (1.0-s)))
let q = (int (value * (1.0-f*s)))
let t = (int (value * (1.0-(1.0-f) * s)))
match hi with
| 0 -> Color.FromArgb(255, vv, t, p)
| 1 -> Color.FromArgb(255, q, vv, p)
| 2 -> Color.FromArgb(255, p, vv, t)
| 3 -> Color.FromArgb(255, p, q, vv)
| 4 -> Color.FromArgb(255, t, p, vv)
| _ -> Color.FromArgb(255, vv, p, q)
*)
let getComplexValueForPixel x y height width zoom =
Complex ((x-width/2.0)/zoom, (y-height/2.0)/zoom)
let colorMap i nMax =
let h = (float i) / 100.0
let s = 1.0
let v = if i < nMax then 1.0 else 0.0
//printfn "%f %f %f" h s v
hsbToRgb h s v
let generatePixel x y height width zoom rMax maxIter =
let c = getComplexValueForPixel (float x) (float y) (float height) (float width) zoom
let rec findI i z =
if i >= maxIter then i
else if Complex.Abs(z) >= (float rMax) then i
//else findI (i+1) (z*z+c)
else findI (i+1) (Complex.Add(c, (Complex.Multiply(z, z))))
colorMap (findI 0 (Complex(0.0, 0.0))) maxIter
let generate (width:int) height zoom rMax maxIter =
let result = new Bitmap(width, height)
for y in 0 .. height-1 do
for x in 0 .. width-1 do
generatePixel x y height width zoom rMax maxIter
|> (fun color -> result.SetPixel(x, y, color))
result