# You can't handle the Buddhabrot!

### Exploring the little-known sibling of the world's most famous fractal.

In today’s episode, let’s talk about fractals, floating point numbers, and why that one guy on Wikipedia is wrong.

First things first: if you’re unfamiliar with the term, fractals are a loosely-defined class of geometric shapes with a complex, endlessly-repeating structure that’s visible no matter how much you zoom in. A rudimentary example is the Koch curve, which can be constructed by repeatedly dividing every straight line into three equal parts, and then adding a fourth segment to form a “spike”. Keep doing this forever and presto — a fractal:

In addition to being constructed on purpose, fractal patterns keep showing up in the solutions to a number of useful functions, usually near where the function is exhibiting high rates of separation — that is, rapid divergence of results in response to infinitesimal differences in input values. The study of such systems is of considerable scientific interest: they are deterministic yet hard to predict if you don’t have a perfect knowledge of the system’s state. They are a boon to cryptographers and the bane of weather forecasts.

As for the fractals themselves, they come with some interesting theoretical underpinnings too — but for the most part, they function as visual curiosities. The most famous example is the Mandelbrot set, named after Benoit Mandelbrot and first portrayed on this printout from 1978:

The core construct of the Mandelbrot set is the following iterated formula:

Both variables — *z *and *c *— are complex numbers. The value of *c *corresponds to pixel coordinates; for the purpose of the computation, they’re usually scaled to -2 … 1.5 in the horizontal direction and* *-1.5 … 1.5 vertically. The value of *z _{0 }*is initialized to zero.

Complex numbers are a bit icky, but we can get rid of them before moving forward. First, let’s replace z* _{n }*and

*c*with a sum of normal Cartesian coordinates —

*z*and

_{n}= (x_{n}, y_{n})*c = (u, v) —*that are separated by the magic value of

*i = √-1:*

The right-hand side of the equation can be expanded by following the normal rules for the square of a sum; just keep in mind that squaring *√-1 *yields* *a real number (-1):

The final step is to separate the real and imaginary (*i*-coupled) parts into two real-number-only coordinates:

Now that we have a less scary formula, we can compute the Mandelbrot set by calculating about 1,000 steps of the (*x _{n}*,

*y*) sequence for every screen coordinate

_{n}*(u, v)*; and then marking the

*(u, v)*pixel as a part of the fractal if

*the (*

*x*,

_{n}*y*) coordinates never escaped some modest radius (

_{n}*r*≥

*2*) around the center of the coordinate system.

To add some flair, we can also color the pixels outside the perimeter based on their “escape velocity” — that is, how quickly they bailed out:

The resulting Mandelbrot set is pretty but also fairly bland: all the fractal features are clustered along the perimeter and there is a huge void in the middle. Luckily, there is another remarkable way to visualize this set — or rather, the fate of the pixels that don’t get sucked into the black hole.

### Follow it… if you can

As it turns out, it’s not just the boundary of the Mandelbrot set that’s mind-bogglingly complex: the same goes for the (*x _{n}*,

*y*) escape trajectories associated with the

_{n}*(u, v)*pixels near the set’s edge. The iterated coordinates follow elaborate, long-winded paths through space; their ethereal trails form a density plot reminiscent of the Mandelbrot fractal itself. At low iteration counts, this similarity is quite pronounced:

That said, when iterated over longer timescales, the new set develops a character of its own:

Compared to the famed Mandelbrot set, this visualization — known as the Buddhabrot — is quite obscure. It is also notoriously difficult to compute; for example, two prominent renderings on Wikipedia are quite a bit off.

The main issue is the trajectories’ extreme sensitivity to starting conditions, exacerbated by the need to iterate the system for longer than necessary for most other plots. To illustrate the pitfalls, let’s consider the seemingly trivial task of translating integer screen coordinates to normalized floating-point *(u, v)* values, with the zero axis running through the middle of the plot. The most intuitive solution is the following formula:

Alas, that division is a trap: we all know that the results can be inexact, but it’s less obvious that this loss of precision might not be symmetrical in respect to our newly-chosen zero point. Here’s a real example of the unexpected bias for *x _{max}*

*= 3,000*:

This small error, compounded across hundreds of thousands of iterations, is enough to break the plot’s symmetry. I’d wager this is the most likely explanation of the issues with the following Wikipedia image:

Another problem present in that Wikipedia rendering and many other online examples are sharply-delineated curved lines, halos, and circles in the plot. They’re not an intrinsic feature of the set: instead, they’re density discontinuities caused by the discrete stepover of *(u, v)* values, probably worsened by floating-point math. The patterns are pretty, but they’re just a computational artifact that changes in response to variations in sample rate:

Indeed, with sufficient oversampling, these artifacts fade into the background:

If you’d like to experiment with this or similar fractals, I have a very concise implementation here. I used this code to generate all the images in this article, except for the Koch curve and the printout from the 1978 book.

Peace out,

*I also have a second article about the nature of the Mandelbrot set itself. For a thematic overview of articles on this blog, click here.*

edited Apr 26Bonus clip: ghost rabbit - the disintegration of Buddhabrot:

https://vimeo.com/936851633/f42a67b851

High-res versions of the last Buddhabrot:

https://lcamtuf.coredump.cx/fractals/buddhabrot_shadow.jpg (with Mandelbrot overlay)

https://lcamtuf.coredump.cx/fractals/buddhabrot_no_shadow.jpg (w/o overlay)

There are 112 major points. If you can spot and highlight ...