Skip to content

Instantly share code, notes, and snippets.

@wolfiestyle
Last active October 3, 2015 23:36
Show Gist options
  • Select an option

  • Save wolfiestyle/20285d5bdfedf0d48e62 to your computer and use it in GitHub Desktop.

Select an option

Save wolfiestyle/20285d5bdfedf0d48e62 to your computer and use it in GitHub Desktop.
mandelbrot generator in haskell
import Data.Complex
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as C
viewport :: RealFloat a => Int -> Int -> a -> Complex a -> (Complex a, Complex a)
viewport width height size center = (p0, p1 - p0)
where s = size * 0.5
(w, h) = (fromIntegral width, fromIntegral height)
dist = if w > h then (s :+ s * h / w) else (s * w / h :+ s)
(p0, p1) = (center - dist, center + dist)
render :: RealFloat a => Int -> Int -> a -> Complex a -> (Complex a -> Int) -> [Int]
render w h size center f = [pixel x y | y <- [1..h], x <- [1..w]]
where (p0, (sx :+ sy)) = viewport w h size center
(dx, dy) = (sx / fromIntegral w, sy / fromIntegral h)
pixel x y = f $ (fromIntegral x * dx :+ fromIntegral y * dy) + p0
mandel_dist :: RealFloat a => Int -> Complex a -> Maybe a
mandel_dist max_it c = mandel_loop 0 1 0
where mandel_loop z dz it
| it >= max_it = Nothing
| zsq > 1024 = Just dist
| otherwise = mandel_loop z' dz' (it + 1)
where z' = z * z + c
dz' = z * dz * 2 + 1
zsq = sqr z'
dist = sqrt (zsq / sqr dz') * log zsq * 0.5
sqr (re :+ im) = re * re + im * im
to_ppm :: Int -> Int -> [Int] -> B.ByteString
to_ppm w h img = B.append header img_bin
where header = C.pack $ "P5\n" ++ show w ++ " " ++ show h ++ "\n255\n"
img_bin = B.pack $ map fromIntegral img
mandel_img :: RealFloat a => Int -> Int -> a -> Int -> Complex a -> B.ByteString
mandel_img w h size max_it c = to_ppm w h $ render w h size c mandel_soft
where max_col = 255
mandel_soft c = maybe max_col color $ mandel_dist max_it c
where color d = truncate $ (1 - clamp 0 1 val) * fromIntegral max_col
where val = (d * 8 / size) ** 0.125
clamp mn mx = max mn . min mx
main = B.writeFile "out.ppm" $ mandel_img 640 480 3.5 255 (-0.7)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment