Stumbling into the Mandelbrot

Basics

A coordinate c is said to be within the Mandelbrot set if the function zn=zn12+cz_n = z_{n-1}^2 + c does not diverge to infinity when iterated. c is a complex number, which means that it is represented by a real and imaginary component: a+bia + bi.

So, let's plug in the value 1+0i1 + 0i, starting at z=0z = 0.

z1=02+(1+0i)=1z2=12+(1+0i)=2z3=22+(1+0i)=5z4=52+(1+0i)=26 \begin{aligned} z_1 &= 0^2 + (1 + 0i) = 1 \\ z_2 &= 1^2 + (1 + 0i) = 2 \\ z_3 &= 2^2 + (1 + 0i) = 5 \\ z_4 &= 5^2 + (1 + 0i) = 26 \end{aligned}

The coordinate 1+0i1 + 0i grows unbounded and, as such, is outside the set. Let's look at the coordinate 1+0i-1 + 0i.

z1=02+(1+0i)=1z2=(1)2+(1+0i)=0z3=02+(1+0i)=1z4=(1)2+(1+0i)=0 \begin{aligned} z_1 &= 0^2 + (-1 + 0i) = -1 \\ z_2 &= (-1)^2 + (-1 + 0i) = 0 \\ z_3 &= 0^2 + (-1 + 0i) = -1 \\ z_4 &= (-1)^2 + (-1 + 0i) = 0 \\ \end{aligned}

The coordinate 1+0i-1 + 0i is clearly stuck in a pattern, oscillating between 1-1 and 11 forever. We can safely label 1+0i-1 + 0i as a point within the set.

Given this definition, we can plot the complex number plane where each point c is either within the set, black, or outside, white.

Escape Time

This binary classification is rather boring. It fails to express interesting emergent behaviors of the system. A good place to start is with the speed of divergence, that is, how fast does z approach infinity? Let's define an escape radius, r, that represents the maximum distance that z can stray from the origin and record the iteration i for which the magnitude of z surpasses r.

while i < max_iteration {
    let x2 = x * x;
    let y2 = y * y;

    if x2 + y2 > r {
        break;
    }

    y = 2.0 * x * y + y0;
    x = x2 - y2 + x0;
    i += + 1;
}

The escaped iteration i can be mapped to the range 0..max_iteration to create a grayscale image1.

let luminance = i as f32 / max_iteration as f32;
let color = Rgb::new(luminance, luminance, luminance);
r2=4
r2=10,000

Smooth Coloring

The escape time algorithm suffers from color banding where a group of coordinates trigger the break condition despite having different "escape velocities". In other words, two values can exceed the escape radius on the same iteration with different magnitudes.

I do not understand the mathmatics behind interpolating i but fortunately it is quite simple in practice.

let log_zn = (x * x + y * y).log() / 2.0;
let nu = (log_zn / 2f32.log()).log() / 2f32.log();
let si = iteration as f32 + 1.0 - nu;

Now, sustituting i with si results in a smooth color gradient.

let luminance = si / max_iteration as f32;
let color = Rgb::new(luminance, luminance, luminance);
r2=4
r2=10,000

Color Palettes

Given i, the the corresponding color is a simple index into the palette.

let index = (i as f32 / max_iteration as f32) as usize;
let color = palette[index * palette.len()];

Given si, the color should be interpolated by the fractional component of si.

let index = (si / max_iteration as f32) as usize;
let c1 = palette[index];
let c2 = palette[(index + 1) % palette.len()];
let color = mix(c1, c2, si.fract());

By parameterizing the scale of the color, different features are extracted and moved around the palette.

let index = (si / (max_iteration as f32 * color_scale)) as usize;
color_scale=1.0
color_scale=12.0

So What?

There is something ineffible in the zoom of a fractal. The way in which self similar patterns emerge, re-emerge, disintegrate, transform into unrecognizable yet familiar structures. A stream of change unrolls and you stumble into a melting reality but beating underneath is a thread of curiosity for what is just beyond the fold. A questioning answer, a meaning that is never understood. And that is a pure form of art. Abstract art. The kind of art that you work at. But beneath that still is the absolute horror of the immensity of the universe.

Awake. Falling... Still falling, still awake? Never awake. Always falling. Darkness shrouds my body. Where are my hands? Did I ever have hands? Ay, to fall is to be still.

How long have you been there, watching me? I move my hand over you but it does not block your bleeding glow. You must be imaginary. Ay, to imagine to to fall.

Do you hate me? Do you feel like I feel? Do you fall? Silence. Ay, to hear is to fall.

Do you feel me scraping at your walls? Yes, you are bigger now than you were. I am falling into you? Should I look away? Ay, to fall is to look away.

Inevitable. Time is inevitable and I did not ask it to be. Are you time? Ay, to fall is to be time.

zn=zn12+c z_n = z_{n-1}^2 + c

  1. Note that increasing r will increase the accuracy of the escape time algorithm, so large values are recommended.