Wednesday, June 2, 2010

Gorgeous Haskell Mandelbrot (and Burning Ship) in Haskell for your Enjoyment

As usual it's slow. It could be made much faster by using a parallel map. That's an exercise for the reader. Also PPM is terrible for anything but writing to, it must be converted immediately.
import Complex
main = writeFile "mandelthing.ppm" $ imageMB 1000 3
type Colour = [Int]
type Image = [Colour]
createPPM :: Int -> Int -> Image -> String
createPPM w h i =
concat ["P3 ", show w, " ", show h, " 255\n",
unlines.map (unwords.map show) $ i]
--Calculates a fractal pixel from an initial condition 0+0i
mandelbrotPixel x y = mb (x:+y) (0:+0) 0
mb c x iter
| magnitude x > 2 = iter
| iter >= 255 = 255
| otherwise = mb c (c+q^2) (iter+1)
where
q = x -- Mandelbrot
-- q = (abs.realPart $ x) :+ (abs.imagPart $ x) --Burning Ship
argandPlane x0 x1 y0 y1 width height =
[(x,y)| y<-[y1,(y1-dy)..y0], --traverse from
x<-[x0,(x0+dx)..x1]] --top-left to bottom-right
where
dx = (x1 - x0)/(width-1)
dy = (y1 - y0)/(height-1)
drawPlane :: (a->b->c)->(c->Colour)->[(a,b)]->Image
drawPlane function = -- takes a function ,a colour function and a plane
map . (.uncurry function)
--'s' is size, 'a' is aspect as in a:1
imageMB s a = createPPM (a*s) s $
drawPlane mandelbrotPixel (\x->[x,x,x]) $
argandPlane (-2) 1 0 1 (fromIntegral a *s') s'
where s' = fromIntegral s
view raw Mandelthing.hs hosted with ❤ by GitHub

No comments:

Post a Comment