← Back to Mandelscope

Understanding and Programming the Mandelbrot Set

Mathematical explanation and step-by-step implementation guide

What is the Mandelbrot Set?

The Mandelbrot set is a mathematical set of complex numbers that produces beautiful fractal patterns when visualised. It was discovered by Benoit Mandelbrot in 1980 and has become one of the most famous examples of mathematical beauty.

The set is defined by a surprisingly simple iterative formula applied to complex numbers, yet it produces infinitely complex patterns. What makes it special is that you can zoom into the boundary forever and keep finding new intricate structures at every scale.

The Mathematics

Complex Numbers Review

Complex numbers have the form a + bi, where:

To multiply complex numbers: (a + bi)(c + di) = (ac - bd) + (ad + bc)i

The Mandelbrot Formula

For each complex number c, we test whether it belongs to the Mandelbrot set by repeatedly applying this formula:

zn+1 = zn² + c

Starting with z₀ = 0, we calculate:

The Membership Test

Key Concept: A complex number c is in the Mandelbrot set if the sequence stays bounded (doesn't "escape to infinity") as we iterate forever.

In practice, we use two rules to decide if a number is in the set:

  1. Escape condition: If |z| > 2 at any point, the sequence will definitely escape to infinity. The number is NOT in the set.
  2. Iteration limit: If we've done many iterations (e.g., 100) and |z| is still ≤ 2, we assume the number IS in the set.
Note: The magnitude |z| of a complex number z = a + bi is calculated as √(a² + b²)

Worked Example

Let's test whether c = 0.3 + 0.5i is in the Mandelbrot set:

For this value, |z| remains less than 2 throughout many iterations, so c = 0.3 + 0.5i is in the Mandelbrot set.

Colouring and Visualisation

The beautiful colours you see in Mandelbrot images aren't part of the mathematical set itself — the Mandelbrot set is typically shown as dark! The colours represent how quickly points outside the set escape to infinity:

The main Mandelscope explorer uses "Smooth Periodic Wave Colouring" which creates fluid rainbow patterns by using the final iteration count and the magnitude of z to generate smooth, continuous colour transitions.

Why Complex Numbers?

Complex numbers are essential because they give us a 2D space to explore. The real part of c corresponds to the x-axis (horizontal position), and the imaginary part corresponds to the y-axis (vertical position). This allows us to visualise the set as an image where each pixel represents testing a different complex number.

Connection to Julia Sets

Julia sets are closely related to the Mandelbrot set: instead of fixing z₀ = 0 and varying c, we fix c to a specific value and vary z₀. Each point in the Mandelbrot set corresponds to a different Julia set. Points inside the Mandelbrot set produce connected Julia sets, while points outside produce disconnected "dust" Julia sets.

You can explore Julia sets in the main Mandelscope application by clicking on any point in the Mandelbrot view!

The Algorithm

Pseudocode

Here's the algorithm in language-independent pseudocode:

FUNCTION mandelbrot(c_real, c_imag, max_iterations) // c_real: real part of c // c_imag: imaginary part of c // max_iterations: how many times to iterate before giving up z_real = 0 z_imag = 0 FOR iteration FROM 0 TO max_iterations // Calculate magnitude squared: |z|² magnitude_squared = z_real * z_real + z_imag * z_imag // Check if escaped (using |z|² > 4 instead of |z| > 2 to avoid sqrt) IF magnitude_squared > 4 THEN RETURN iteration // Escaped after 'iteration' steps END IF // Calculate z² = (z_real + z_imag*i)² // Using: (a + bi)² = (a² - b²) + (2ab)i new_real = z_real * z_real - z_imag * z_imag new_imag = 2 * z_real * z_imag // Add c to get z² + c z_real = new_real + c_real z_imag = new_imag + c_imag END FOR RETURN max_iterations // Didn't escape - probably in the set END FUNCTION FUNCTION drawMandelbrot(width, height, max_iterations) // Define the region of the complex plane to view x_min = -2.5 x_max = 1.0 y_min = -1.25 y_max = 1.25 FOR each pixel row y FROM 0 TO height FOR each pixel column x FROM 0 TO width // Map pixel coordinates to complex plane c_real = x_min + (x / width) * (x_max - x_min) c_imag = y_min + (y / height) * (y_max - y_min) // Test if this point is in the Mandelbrot set iterations = mandelbrot(c_real, c_imag, max_iterations) // Color the pixel IF iterations == max_iterations THEN setPixel(x, y, DARK_COLOR) // In the set ELSE setPixel(x, y, LIGHT_COLOR) // Not in the set END IF END FOR END FOR END FUNCTION

Key Implementation Details

Working Implementation

Here's a complete, minimal implementation in JavaScript using a 2D canvas. This code draws a simple two-color Mandelbrot set with no additional features.

600×450 pixels, 100 iterations per point

JavaScript Implementation

✏️ Editable Code: Try modifying the code below and click "Run Code" to see your changes!

💡 Try These Experiments:
  • Change maxIterations to 50 or 200 to see how detail changes
  • Modify the viewing window (xMin, xMax, yMin, yMax) to zoom in
  • Change the colors: try '#ff5555', '#88ff88', or experiment with different hex codes
  • Add a third color for points that escape quickly: if (iterations < 10) ctx.fillStyle = '#999';
  • Make the canvas smaller (e.g., 300×225) to see it draw faster

Understanding the Output

In the image above, you should see:

Tip: The boundary between dark and light is where the interesting fractal patterns emerge. In the main Mandelscope explorer, we use colors to show HOW QUICKLY points escape, revealing beautiful detail.

Extending the Basic Implementation

Once you understand this basic implementation, you can add many enhancements:

Computational Complexity

For an image of W×H pixels with maximum M iterations per point:

For a 600×450 image with 100 iterations, that's up to 27 million operations! This is why the main Mandelscope explorer uses GPU acceleration - graphics cards can perform these calculations in parallel across thousands of cores.

Try It Yourself

Exercise: Try modifying the code above to:
  • Change the viewing window (xMin, xMax, yMin, yMax) to zoom into different regions
  • Increase maxIterations to 200 or 500 to see more detail (warning: will be slower!)
  • Add grayscale coloring: map the iteration count to different shades of gray
  • Draw only the boundary: color pixels differently only if they escape within a certain iteration range

Further Learning

Next steps in your Mandelbrot journey:

← Back to Mandelscope