Introduction
After watching a very interesting video about the mandelbrot set I decided to explore the topic programatically.
The math
The Mandelbrot set is the set of values c in the complex plain for which the following iteration:
remains bounded when starting with . We know that once the equation 'escapes' past it will become unbounded. As such we can escape our iteration and mark the coordinates as outside the set when we surpass this limit. The rendered image is simply a color coding of this result. A maximum number of 255 iterations is made for each coordinate in the plane and the number of iterations required to reach is used to set the color of each pixel. Where 255 is black and 0 is white yielding the following image:
MandelJs
At first I wrote a simple web application to render the mandelbrot set. This is the result of a weekend of mathematical exploration. I made an attempt to port the computation-heavy code to WASM for performance gains. After several hours of trying to get emscripten to play nice with webpack I decided to defer playing with it to another time and leave the code as-is in JS. This is a bit slow since for every pixel it will do a maximum of 255 iterations to determine the stability of the mandelbrot function.
You can have a play with it here.
To navigate click the canvas and:
- W move up.
- A move left.
- S move down.
- D move right.
- Arrow up zoom in.
- Arrow down zoom out.
Resizing the window doesn't work without a reload.
MandelCpp
After the disappointing performance of the Javascript implementation I decided to port the code to C++. I built on my SDLWindow class created for Woud and quickly had a working application.
Again, I was disappointed by the speed of the application. Requiring a maximum of 255 million iterations per frame for my 1000x1000 window and no room for improvement in the iteration itself I was looking for another way to increase performance. Using multi-threading wasn't going to cut it. The speed increase of 4x for a fairly standard CPU with the added overhead of multi-threading just wouldn't give significant results.
OpenCL
Enter OpenCL.
"The open standard for parallel programming of heterogeneous systems."Since the problem at hand is the highly parallel processing of floating-point arithmetic it is perfectly suited to a solution in OpenCL. With a little help from the excellent book Heterogeneous Computing with OpenCL 2.0 I ported the algorithm to OpenCL C. Passing in an array with every pixel's coordinates in the rendered space and then iterating over the Mandelbrot function for many points in parallel, I finally had an application that was blazing fast even on my basic GPU.
Julia sets

An interesting variation of the Mandelbrot set is the Julia set (or rather, the Mandelbrot set is a specific Julia set.) Where the mandelbrot set starts with , a Julia set start with being any coordinate in the complex plane. As such there is an endless number of Julia sets.
This means that we can render a Julia set that corresponds to a coordinate in the complex plane that we have rendered the Mandelbrot set on. Doing this shows an interesting property of the Julia set: the shape of the set shows features similar to the corresponding area of the mandelbrot set.
I modified the software to capture coordinates on mouse-click and convert them to coordinates in the imaginary plane in the rendered space. The original code rendering the Mandelbrot set was easily converted to run Julia sets, the same OpenCL kernel now calculates the Mandelbrot set with being passed in. The Julia set is rendered to a second window enabling the exploration of these sets.
Transformation to 3 Dimensions
Looking at the beautiful motion of the transforming Julia sets when moving the cursor across the imaginary plane I wrote some code to capture these images for each frame. I then loaded this series of images into the open-source scientific imaging package Fiji mapping the changing coordinates to the Z-axis. After cleaning this model up in Blender I printed a Julia vase.

The path through the complex plane was captured by moving the cursor by hand leading to less than smooth transitions, and the tool-chain using Fiji was a bit cumbersome. There is interesting potential to design some beautiful looking vases or lamp shades in the future.