module MandelBrot open System.Drawing open System.Numerics open System 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 Color.FromArgb(255, clamp (int (R*255.0)), clamp (int (G*255.0)), clamp (int (B*255.0))) let getComplexValueForPixel x y height width zoom = Complex ((x-width/2.0)/zoom, (y-height/2.0)/zoom) let colorMap i nMax = let h = if ((float i) / 100.0) <= 1.0 then ((float i) / 100.0) * 360.0 else 360.0 let s = 1.0 let v = if i < nMax then 1.0 else 0.0 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) (c+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