A macOS app that turns the Mandelbrot set into a 3D surface by exploiting the relationship between a point's position in the Mandelbrot set and the structure of its corresponding Julia set.
Every point c in the complex plane has a corresponding Julia set. When c is inside the Mandelbrot set, that Julia set is connected and solid — orbits starting nearby tend to stay bounded. When c is just outside the Mandelbrot set, the Julia set shatters into Cantor dust — only a thin, scattered set of starting points have bounded orbits.
BrotTerrain makes this transition visible in 3D:
- Lay out a grid of c values across a small rectangle near the Mandelbrot boundary (the X–Y plane).
- For each c, probe the corresponding Julia set along a chosen axis of the complex plane — by default the imaginary axis, sampling starting points z₀ = i·t for t ∈ [−2, 2].
- At each (c, t) pair, run the Julia orbit. Non-escaping → filled voxel. Escaping → empty.
- Extract a surface from the resulting voxel field and render it.
The Z axis therefore shows, for each c, which starting points on the probe axis have bounded orbits. Near the Mandelbrot boundary this varies dramatically: thick connected regions for c inside M, thin fractal wisps for c just outside.
Two regions are rendered differently:
- Gold (c inside the Mandelbrot set): rendered as face-culled voxel boxes. Interior faces shared between adjacent filled voxels are suppressed, giving crisp block-like boundaries that somewhat clearly delineate the Mandelbrot region.
- Cyan (c outside the Mandelbrot set, Julia orbit still bounded): rendered using marching cubes, producing a smooth isosurface through the thin, scattered bounded regions of the Cantor-dust Julia sets.
| Control | Description |
|---|---|
| Presets | Jump to interesting locations near the Mandelbrot boundary; each preset also restores an appropriate Z probe range |
| Probe Axis | Switch between Im(z₀) and Re(z₀) as the Z-axis probe |
| Z Probe Range | Set center and radius of the t sampling range — zoom into thin sheet structures |
| Axis Scale | Independently stretch X, Y, Z for better visibility |
| Resolution | Target grid density; rendering proceeds through progressive passes (9→17→33→…) so a coarse preview appears immediately |
Starting points with |t| > 2 escape on the first iteration regardless of c, so the mathematically interesting region is entirely within t ∈ (−2, 2). Near t = 0 the Mandelbrot interior fills solidly (the orbit of z₀ ≈ 0 is essentially the Mandelbrot orbit itself). The thin cyan sheet structures appear at moderate |t| values, where the probe axis intersects the sparse Cantor-dust structure of Julia sets for c just outside M. Narrowing the Z probe radius and panning with the center control lets you zoom into these thin features at higher effective resolution.
Worth pointing out that this algorithm introduces some 3D-ness to the inside of the Mandelbrot Set.
This is a proof of concept. The voxel grid is coarse enough that thin mathematical features can appear as flat slabs rather than curved surfaces — increasing resolution helps, at the cost of significant compute time (the finest setting samples on the order of 100–500 million orbit evaluations). Whether this particular 3D construction of the Mandelbrot/Julia relationship has been explored before isn't clear to the author; if you know of prior work or want to take this further, contributions and pointers are welcome.
Caveat, excuse, whining, etc.: Although the idea and mathematics are mine, the code is pretty much AI generated. And this README was a heavily AI-edited version of my original. It's better, but it's kind of AI-ish.