81 lines
2.1 KiB
FSharp
81 lines
2.1 KiB
FSharp
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 = ((float i) / 100.0) * 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
|