Mandelbrot Zoom
The Mandelbrot set is what one line of arithmetic, z → z² + c, draws when you ask of every point whether it stays put or flies off. This piece starts on the whole set and zooms without a cut into Seahorse Valley, about 42 doublings deep, until a pixel is so narrow that the computer’s 64-bit numbers can barely tell one from the next. It says so in the corner, fades back, and dives again.
About this piece
Every point of this picture is a number c on the complex plane, and every one gets the same test: start at z = 0, replace z with z² + c, and repeat. If |z| never gets past 2, c is in the Mandelbrot set and is painted in the theme’s paper. If |z| does pass 2, c is outside, and its colour comes from how many steps that took. The loop opens on the whole set, then dives into Seahorse Valley, the crease between the big heart-shaped cardioid and the round bulb on its left. It goes down about 42 octaves (each octave doubles the magnification), to roughly 4 × 1012 times on a laptop-sized frame. At that depth JavaScript’s 64-bit numbers can no longer keep neighbouring pixels comfortably apart. So the piece stops, holds for 6 seconds with a note in the corner, fades back to the whole set and starts again. One dive takes a little over two minutes.
The rule, and why 2 is enough
The Wikipedia article on the Mandelbrot set defines it by the map z ↦ z² + c, starting from z = 0. It states the test this plate uses: c belongs to the set if and only if |zn| ≤ 2 for every n. Why 2 is enough takes two lines of algebra. If |c| > 2 the very first step, z1 = c, is already past 2. Otherwise, as soon as some |z| > 2, it is also at least |c|, and then
|z² + c| ≥ |z|² − |c| ≥ |z|² − |z| = |z|·(|z| − 1) > |z|
because |z| − 1 > 1. Every later step multiplies the size by more than the step before did, so the orbit cannot come back. Once any zn passes 2 the point is out for good, and the step n where that happens is what the colour is built from.
A worked example. c = 1 gives 0, 1, 2, 5, 26… |2| is not more than 2 but |5| is, so c = 1 escapes at iteration 3. c = −1 gives 0, −1, 0, −1… for ever, so it is in the set. So are c = 0 (stuck at 0), c = −2 (0, −2, 2, 2, 2…, sitting exactly on the radius and never past it) and c = i (0, i, −1 + i, −i, −1 + i…). The test suite checks all five against the plate’s own code. It also plants an escape radius of 1.5 and requires the check to fail: that radius throws out c = −2 at once and gets c = 1 one step early.
Where it is going: Seahorse Valley
The Wikipedia article’s zoom gallery names the region “seahorse valley” and says it is centred on the point −0.75 + 0.1i. For an exact target this plate takes the centre of step 14 of that same zoom sequence, made by Wolfgang Beyer with Ultra Fractal 3. Its Wikimedia Commons file page gives the centre and the frame width:
Re(c) = −0.743643887037151 Im(c) = 0.131825904205330 frame width 5.1299 × 10⁻¹¹
This dive ends with a frame about 50 times narrower than that one on a laptop, and about 100 times narrower on a phone. On the way down the target slides from left of centre into the middle of the frame, because the camera’s distance from it shrinks twice as fast as the frame does. The curled “seahorse” tails appear within the first ten octaves. At 9 octaves in, a 512× zoom, the spirals fill the frame, and that is the still a visitor with reduced motion switched on sees.
Where the numbers run out
The browser does every sum here in 64-bit floating point. MDN defines Number.EPSILON (ε) as the difference between 1 and the smallest floating-point number greater than 1, which is 2−52, about 2.22 × 10−16. Near the target, |c| ≈ 0.755, and in that range the numbers a double can hold are 2−53 ≈ 1.1 × 10−16 apart. The plate stops where a pixel is 8 × ε × |c| ≈ 1.34 × 10−15 wide, so neighbouring pixels are only about a dozen representable numbers apart. Every one of the thousands of iterations each pixel needs rounds again, so going deeper in plain doubles stops being trustworthy, and the 8 is a safety margin. The corner note at the bottom reads “64-bit floats run out here”. Programs that zoom further switch to arbitrary-precision arithmetic, or to perturbation methods built on it; Wikipedia’s plotting-algorithms article describes both. This plate deliberately does not, so the bottom of the dive is a real limit you can see.
Two shortcuts: the cardioid and the bulb
Points inside the set are the expensive ones: they never escape, so a plain loop runs all the way to its cap. Two regions can be recognised without iterating at all. The plotting-algorithms article gives both tests. Write c = x + iy and q = (x − ¼)² + y²:
main cardioid: q·(q + (x − ¼)) ≤ ¼·y² period-2 bulb: (x + 1)² + y² ≤ 1/16
The bulb is the disc of radius ¼ around −1. On the opening frame these two tests settle 11 % of the points without a single iteration, and the whole frame averages under 10 iterations a point. Any other orbit that comes back to within a thousandth of a pixel of a value it held earlier has settled into a cycle, and it is stopped as inside too. The test suite runs 10,000 seeded points, half of them hugging the edges of the cardioid and the bulb, and requires the shortcut and brute iteration to agree on every one.
Smooth colour in two inks
Colouring by the whole-number count gives hard steps between bands. Instead each escaping orbit is iterated on until |z| > 256, at step m, and the plate uses the normalised iteration count from the plotting-algorithms article’s continuous-colouring section:
ν = m − log₂( ln|zₘ| / ln 256 )
ν is a real number that changes smoothly where the whole-number count jumps. The test suite finds 40 places where the count steps by one and measures ν on both sides, 10−13 apart. The largest jump it finds is about 10−11. The colour goes once round a band every time ν + 1 grows by a factor of about 1.54: from a faint tint of paper up to the cobalt ink, through a thin coral crest, and back. The paper, the cobalt and the coral all come from the site’s shared palette. In the dark theme that means pale cobalt and coral on near-black, with the set itself near-black. In the light theme it means deep cobalt and rust on warm paper.
How it is computed
Recomputing every pixel on every frame is out of the question: near the bottom an average pixel takes more than 2,000 iterations. So the picture is computed at whole octaves only. Keyframe k is the frame at depth k, computed on one point per CSS pixel, capped at 360,000 points. A phone gets every pixel; a laptop-sized stage gets about 800 × 450. Between depths k and k + 1 you see keyframe k enlarged, with keyframe k + 1 laid over its middle, half the size and twice as sharp. Each keyframe is computed coarse to fine, in passes of 16-, 8-, 4-, 2- and 1-pixel blocks, and only as fast as a budget of 360 iterations per point per second allows. The camera may never run more than one octave past the deepest finished keyframe. That lets it move at up to 0.8 octaves a second through the cheap shallow part, and it slows to several seconds an octave further down, where the sums get long. The iteration cap rises with depth: 300 on the whole set, 120 more for every octave, 5,220 at the bottom of a laptop-sized dive. Measured in Node on an 800 × 450 grid, one dive spends about 39,000 iterations per point and reaches the bottom 127 seconds in.
The plate keeps its own clock in fixed ticks of 1/120 of a second and spends its budget per tick, not per frame. So a 30-frames-per-second phone and a 144 Hz monitor hold the identical state at the same moment, down to the last byte of every keyframe, and the test suite checks exactly that. A device too slow to keep up falls behind the wall clock rather than drawing a different picture.
Who drew it first
According to the Wikipedia article, the set was first defined and drawn by Robert W. Brooks and Peter Matelski in 1978, as part of a study of Kleinian groups. On 1 March 1980, Benoit Mandelbrot obtained high-quality visualisations of it at IBM’s Thomas J. Watson Research Center in Yorktown Heights, New York. Its mathematical study really began with Adrien Douady and John H. Hubbard (1985), who established many of its fundamental properties and named the set in honour of Mandelbrot.
The two plates it sits nearest
- Strange Attractor also iterates a simple formula over and over, but it follows one orbit and plots where it lands. Here every pixel runs an orbit of its own and is coloured by whether, and how fast, that orbit leaves.
- Fractal Dreams grows a fractal tree from a rewriting rule, and its self-similarity is built in by hand. The Mandelbrot set is not built to look like anything: the seahorses, spirals and tiny copies of the whole set fall out of one line of arithmetic.
Honest limits
The edge is approximate. A point still inside radius 2 when the iteration cap runs out is painted as inside, and some of those would escape if given longer. While building this plate, at 24 octaves deep, about one in seven of the points painted as inside still escaped when re-run to 30,000 iterations. A point that escapes that slowly lies very close to the set by nature, so the effect is an edge drawn slightly too thick, not a shape that is not there.
One sample per pixel. There is no anti-aliasing, so the finest filaments break up into a speckle of cobalt and coral rather than drawing as clean threads.
Large screens are enlarged. To keep the sums affordable the grid is capped at 360,000 points, so a big monitor, and a 4K wallpaper saved from this page, is drawn from that grid and enlarged: softer than the other plates’ wallpapers, which are redrawn at full size.
One fixed path. The dive always goes to the same point along the same route, and it is not a fractal explorer: you cannot steer it. This gallery ships finished compositions.
Curious how the loop and canvas fit together? Read how it works →
More from the gallery
- Plate 34 Lorenz Attractor A hundred weather models started a millionth apart, unzipping across the butterfly.
- Plate 01 Quantum Fibonacci Golden-angle phyllotaxis blooming from the seed outward.
- Plate 02 Bitcoin Matrix A quiet rain of ₿ and hex sliding down the glass.
- Plate 03 Cosmic Circles Soft orbs drifting through slow orbital rounds.
- Plate 04 Spiral Waves Archimedean arms turning, so the bands seem to stream inward.
- Plate 05 Particle Burst A continuous bloom of particles from the core.