106 lines
No EOL
2.8 KiB
FSharp
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) * 360.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 |