I was reminded last week by Adam about a project I had worked on with him in calculus, creating fractal images using Newton’s method in C++, and picked that as my weekend haskell project. Although this time starting with the Mandelbrot set for variety. My real motivation was to possibly start work on an image library, but GD bindings had already been created, so that was unnecessary. I had to expose a function to set individual pixels to the bindings, so if you actually want to run the code below, you’ll need to either pull haskell-gd from my copy, or just apply these patches to the official release from hackage. (GD now includes my patches)
It’s fortunate I enjoy mundane programming tasks, because the “real” work of calculating the Mandelbrot set took only a few minutes. Adding the necessary setPixel function to GD, and even transforming coordinates from an image to the complex plane took far more time. It was much easier to translate the actual mathematical definition of the set, rather than to try and convert from optimized code that used mutable variables.
-- recursive mandelbrot
mandelbrot :: Complex Double -- Coordinate to test
-> Complex Double -- Iterating Z value
-> Int -- Current iteration count
-> Int -- Iterations before diverging
mandelbrot c z iter
| iter > maxIter = 0
| otherwise = let z' = z^2 + c in
if magnitude(z') > 2
then iter
else mandelbrot c z' (iter+1)
It needs to be reworked with a high-precision floating point library to make more interesting images, but Doubles are good enough for the following (Mandelbrot, Julia Set, Newton’s Method, Burning Ship):