The Julia Set

The dragon Julia set (c = -0.8 + 0.156i) in the complex plane with smooth plum, amethyst, champagne, and rose-gold escape-time coloring
Theme

If we fix a complex constant c and plot the escape times for every starting point z0 in the complex plane, each choice of c unfolds its own self-similar fractal world known as a Julia set.

zn+1=zn2+c,z0=x0+iy0,i=−1z_{n+1} = z_n^2 + c, \quad z_0 = x_0 + iy_0, \quad{i = \sqrt{-1}}

World overview

Every Julia set has 180° rotational symmetry around the center. Because squaring a number erases its sign, any starting point z0 and its opposite −z0 land on the exact same value after the first step, giving every spiral arm a matching twin across the origin.

180-degree rotational symmetry of the three-branched rabbit rosette Julia set (c = -0.0876 + 0.6551i) across -1.6 to 1.6

While the Mandelbrot set is a single map, every complex number c produces its own Julia set. When c comes from inside the Mandelbrot set, the Julia set holds together as one connected shape; when c moves outside the boundary, the shape breaks apart into a scattered cloud of isolated points known as Fatou dust.

Disconnected filigree Julia set (c = -0.7269 + 0.1889i) where interior basins shatter into logarithmic spiral Fatou dust
Parameter Plane (Mandelbrot c → Julia Kc)c = -0.8000 + 0.1560i
Mandelbrot parameter plane (click or drag c)
Disconnected Fatou Cantor dust (escapes in 252 steps)

Julia set equation

The equation using complex numbers is:

zn+1=zn2+cz_{n+1} = z_n^2 + c

Each pixel supplies the initial complex coordinate z0:

z0=x0+iy0,i=−1z_0 = x_0 + iy_0, \quad{i = \sqrt{-1}}

While the complex parameter c stays fixed across the entire image:

c=cx+icyc = c_x + ic_y

If we expand the complex squaring, the iteration reduces to:

xn+1=xn2−yn2+cxx_{n+1} = x_n^2 - y_n^2 + c_x
yn+1=2xnyn+cyy_{n+1} = 2x_ny_n + c_y

A common way of exploring Julia sets is by putting each pixel's starting (x0, y0) coordinates into the recurrence for a fixed c = (cx, cy) and making note of whether the series:

  • diverges to infinity (the Fatou escaping basin) or stays within a bounded limit (the filled Julia set)
  • if the series diverges, we make note of:
    • the number of iterations until reaching the escape radius
    • the distance from zero (0, 0) during the escape
Orbit Trajectory (z0 → z1 → z2 → …)z0 = -0.4200 + 0.2400i
OutcomeEscapes |z| > 2 (step 24)
Last |zn|47.2399
Min |zk| (critical distance)0.2438

Drag z0 across the canvas to watch how points on the spiral filaments wind around the repelling fixed point before crossing the dashed |z| = 2 escape horizon.

Sub-structures

Across the complex plane, each parameter c shapes its Julia set into spirals, basilicas, Siegel disks, dendrites, and Cantor galaxies. Zooming toward repelling periodic points and their preimages uncovers the same global motif repeating at every scale.

Overview

At shallow magnifications, every pixel runs its own independent escape-time loop inside a WebGL fragment shader using native 32-bit GPU floats, seeding z0 directly from the pixel coordinate and iterating with the fixed complex constant c.

Seahorse Dragon Vortex

Twin logarithmic spiral arms wind into the repelling α fixed point of the dragon Julia set for c = −0.8 + 0.156i, centred near z = −0.5275 + 0.0759i.

Seahorse Dragon Vortex — Twin logarithmic spiral arms wind into the repelling α fixed point of the dragon Julia set for c = −0.8 + 0.156i, centred near z = −0.5275 + 0.0759i.
span 8.00e-31,024 iter max · Ready

Seahorse Valley Spiral Sanctuary

Counter-rotating seahorse tails in the Julia set for c = −0.747 + 0.108i, centred on its repelling fixed point at a 5.8 × 10⁻³ vertical span, separating deep nocturnal basins from luminous filigree curls.

Seahorse Valley Spiral Sanctuary — Counter-rotating seahorse tails in the Julia set for c = −0.747 + 0.108i, centred on its repelling fixed point at a 5.8 × 10⁻³ vertical span, separating deep nocturnal basins from luminous filigree curls.
span 7.73e-31,024 iter max · Ready

Douady’s Rabbit

For c ≈ −0.122561 + 0.744862i at the centre of the period-3 bulb, three dark interior basins meet at every preimage of the α fixed point to form the three-eared silhouette named by Adrien Douady.

Douady’s Rabbit — For c ≈ −0.122561 + 0.744862i at the centre of the period-3 bulb, three dark interior basins meet at every preimage of the α fixed point to form the three-eared silhouette named by Adrien Douady.
span 2.80e+01,024 iter max · Ready

San Marco Basilica

Near the period-2 basilica parameter c = −0.75 + 0.015i, pinched interior basins and mirrored spires stretch along the real axis like Saint Mark’s Basilica reflected across a flooded Venetian lagoon.

San Marco Basilica — Near the period-2 basilica parameter c = −0.75 + 0.015i, pinched interior basins and mirrored spires stretch along the real axis like Saint Mark’s Basilica reflected across a flooded Venetian lagoon.
span 3.20e+01,024 iter max · Ready

Golden Mean Siegel Disk

On the main cardioid boundary at c ≈ −0.390541 + 0.586788i, the fixed-point multiplier rotates by the golden mean. Instead of spiraling inward, bounded orbits trace invariant topological disks.

Golden Mean Siegel Disk — On the main cardioid boundary at c ≈ −0.390541 + 0.586788i, the fixed-point multiplier rotates by the golden mean. Instead of spiraling inward, bounded orbits trace invariant topological disks.
span 2.20e+01,024 iter max · Ready

Double Spiral Filigree

In the Seahorse filigree Julia set for c = −0.7269 + 0.1889i, two intertwined arms wind across the origin while smaller curls repeat at every preimage of the critical orbit.

Double Spiral Filigree — In the Seahorse filigree Julia set for c = −0.7269 + 0.1889i, two intertwined arms wind across the origin while smaller curls repeat at every preimage of the critical orbit.
span 4.67e-11,024 iter max · Ready

Double Spiral Nexus

Centred near z = −0.51498922 + 0.06722602i at a 1.2 × 10⁻³ vertical span in the Julia set for c = −0.77568377 + 0.13646737i, paired logarithmic spirals converge on the repelling α fixed point.

Double Spiral Nexus — Centred near z = −0.51498922 + 0.06722602i at a 1.2 × 10⁻³ vertical span in the Julia set for c = −0.77568377 + 0.13646737i, paired logarithmic spirals converge on the repelling α fixed point.
span 1.60e-31,024 iter max · Ready

Triple Spiral Junction

For c = −0.087593732 + 0.65509028i near the upper period-3 bulb, three spiral branches meet at the repelling fixed point z ≈ −0.232992 + 0.446860i and repeat along each tributary arm.

Triple Spiral Junction — For c = −0.087593732 + 0.65509028i near the upper period-3 bulb, three spiral branches meet at the repelling fixed point z ≈ −0.232992 + 0.446860i and repeat along each tributary arm.
span 5.87e-31,024 iter max · Ready

Quad Spiral Pinwheel

Near the upper period-4 bulb at c = 0.28245 + 0.4831i, four-armed spiral filaments wind into the repelling fixed point z ≈ 0.024743 + 0.508251i, adding a fourth turn to the three-armed rabbit junction.

Quad Spiral Pinwheel — Near the upper period-4 bulb at c = 0.28245 + 0.4831i, four-armed spiral filaments wind into the repelling fixed point z ≈ 0.024743 + 0.508251i, adding a fourth turn to the three-armed rabbit junction.
span 5.33e-31,024 iter max · Ready

Misiurewicz Lightning Dendrite

At the Misiurewicz parameter c = i, the critical orbit lands on a repelling cycle after two steps. With no attracting basin, the Julia set has empty interior and forms a pure, infinitely branched tree.

Misiurewicz Lightning Dendrite — At the Misiurewicz parameter c = i, the critical orbit lands on a repelling cycle after two steps. With no attracting basin, the Julia set has empty interior and forms a pure, infinitely branched tree.
span 2.60e+01,024 iter max · Ready

Scepter Horn Spiral

In the Scepter Valley Julia set for c = −1.25066 + 0.02012i, curled filaments around the repelling fixed point z ≈ −0.725042 + 0.008212i sprout ornate branching spikes.

Scepter Horn Spiral — In the Scepter Valley Julia set for c = −1.25066 + 0.02012i, curled filaments around the repelling fixed point z ≈ −0.725042 + 0.008212i sprout ornate branching spikes.
span 1.20e-31,024 iter max · Ready

Deep zoom

Once the viewport narrows past 10-3, subpixel spacing approaches the 10-7 rounding step of single-precision float32 shaders. These views step up to compensated double-single (dsAdd / dsMul) Dekker-split shaders and 53-bit significand float64 workers to keep filaments razor-sharp down to the 10-15 IEEE 754 precision floor.

Double-spiral Julia Medallion

At a 9 × 10⁻⁶ vertical span inside the Julia set for c = −1.768620774 + 0.002428273i, curling filaments around the repelling fixed point form paired logarithmic spirals and nested medallions.

Double-spiral Julia Medallion — At a 9 × 10⁻⁶ vertical span inside the Julia set for c = −1.768620774 + 0.002428273i, curling filaments around the repelling fixed point form paired logarithmic spirals and nested medallions.
span 1.20e-51,024 iter max · Ready

Elephant’s Trunk Scroll

Inside the Elephant Valley Julia set for c ≈ 0.277732 + 0.007345i near the main cardioid cusp, long curved branches curl into tightly wound parabolic trunks around z ≈ 0.478136 + 0.167960i.

Elephant’s Trunk Scroll — Inside the Elephant Valley Julia set for c ≈ 0.277732 + 0.007345i near the main cardioid cusp, long curved branches curl into tightly wound parabolic trunks around z ≈ 0.478136 + 0.167960i.
span 2.97e-51,024 iter max · Ready

Snowflake Filigree Rosette

Fine, feathery branches in the Julia set for c = −0.658448 − 0.466852i form crystalline snowflake clusters around z ≈ −0.482302 − 0.237632i.

Snowflake Filigree Rosette — Fine, feathery branches in the Julia set for c = −0.658448 − 0.466852i form crystalline snowflake clusters around z ≈ −0.482302 − 0.237632i.
span 8.67e-41,024 iter max · Ready

Elephant’s Trunk Filaments

At 10⁻¹⁰ vertical span around the repelling fixed point of the Elephant Valley Julia set (c ≈ 0.277732 + 0.007345i), compensated double-single and perturbation passes resolve fine concentric rings around the spiral core.

Elephant’s Trunk Filaments — At 10⁻¹⁰ vertical span around the repelling fixed point of the Elephant Valley Julia set (c ≈ 0.277732 + 0.007345i), compensated double-single and perturbation passes resolve fine concentric rings around the spiral core.

Seahorse Labyrinthine Spiral

At 1.2 × 10⁻¹⁴ vertical span inside the Seahorse Valley Julia set (c = −0.77568377 + 0.13646737i), high-precision reference orbits and Bivariate Linear Approximation keep every spiral filament sharp near the IEEE 754 float64 precision floor.

Seahorse Labyrinthine Spiral — At 1.2 × 10⁻¹⁴ vertical span inside the Seahorse Valley Julia set (c = −0.77568377 + 0.13646737i), high-precision reference orbits and Bivariate Linear Approximation keep every spiral filament sharp near the IEEE 754 float64 precision floor.

Parameter morphs

Because a single Julia set fixes c across the entire complex plane, its richest topological transitions happen when c(t) travels along a path in the Mandelbrot parameter plane. Sweeping c(t) around the main cardioid, across period-doubling necks, onto Misiurewicz filaments, or past the connectedness boundary drives the filled Julia set through continuous bifurcations and Cantor dust transitions at interactive frame rates.

Cardioid Tour

Sweeping c(θ) = ½reiθ − ¼r²e2iθ around the main cardioid boundary rotates the fixed-point multiplier λ = reiθ through a full turn, morphing the filled Julia set from the cusped cauliflower through three-eared rabbit buds, pinched basilica lobes, and golden-mean Siegel spirals.

z · Cauliflower CuspConnected Julia set (period-1 attracting basin)
c = 0.2499 + 0.0000i

Bifurcation Pinch

Crossing the parabolic neck at c = −0.75 from the main cardioid (c = −0.52) into the period-2 basilica bulb (c = −1.0) and period-4 cascade (c = −1.31) pinches the single central basin at every preimage of the α fixed point, splitting one chamber into an infinite chain of paired lobes.

z · Single BasinConnected Julia set (period-1 attracting basin)
c = -0.5200 + 0.0080i

Dendrite Lightning

Tracing along the upper period-3 wake from Douady’s Rabbit (c ≈ −0.123 + 0.745i) out along the external ray filament to the Misiurewicz tip c = i collapses the interior basins to zero area, leaving a pure, infinitely branched lightning dendrite.

z · Douady’s RabbitConnected Julia set (period-3 attracting basin)
c = -0.1226 + 0.7449i

Fatou Dust Transition

Crossing the Seahorse Valley boundary from a connected basin web (c = −0.745 + 0.105i) through the dragon filament (c = −0.7757 + 0.1365i) into the escaping basin (c = −0.805 + 0.225i) shatters the connected Julia continuum into an uncountable Fatou Cantor dust of isolated points.

z · Connected WebDisconnected Fatou Cantor dust (escapes in 58 steps)
c = -0.7450 + 0.1050i

Self-similar zoom

By Koenigs' Linearization Theorem, iterating z² + c near a repelling fixed point αc with multiplier λ = 2αc (|λ| > 1) is conformally conjugate to multiplying by λ. Scaling the viewport by |λ|−mt, counter-rotating by −t·arg(λm), and shifting smooth escape counts by −mt loops a single shallow octave seamlessly without needing arbitrary-precision arithmetic.

Koenigs Self-Similar Spiral Loop

Near any repelling fixed point αc = (1 − √(1 − 4c))/2 with multiplier λ = 2αc (|λ| > 1), iterating fcˆm expands each spiral arm onto itself by λm. Applying the cubic inverse Koenigs chart ψ(w) = αc + w + a2w² + a3w³ while scaling by |λ|−mt, counter-rotating by −t·arg(λm), and shifting smooth escape counts by −mt loops a single shallow octave seamlessly forever.

αc = -0.5275 + 0.0759i · |λ|2 = 1.136×c = -0.8000 + 0.1560i · 2-step return (-16.4° twist) · span 2.80e-3

Fractal coloring

Given a starting point (x0, y0) and a fixed parameter (cx, cy), escape-time coloring records how many iterations the orbit takes to cross the escape circle |z| > 2 along with the complex coordinate where it escapes.

const ESCAPE_THRESHOLD = 4;
const MAX_ITERATIONS = 1024;

function iterateUntilEscape(x0, y0, cx, cy) {
  let x = x0, y = y0;
  let numIterations = 0;
  while ((x * x + y * y <= ESCAPE_THRESHOLD) &&
         (numIterations < MAX_ITERATIONS)) {
    const xNext = x * x - y * y + cx;
    const yNext = 2 * x * y + cy;
    x = xNext;
    y = yNext;
    numIterations++;
  }
  const escaped = x * x + y * y > ESCAPE_THRESHOLD;
  return { numIterations, x, y, cx, cy, escaped };
}

To keep high iteration counts near the Julia boundary from bunching into noisy stripes, palettePhase compresses the escape count with a square-root curve before sampling a 512-entry periodic cubic spline interpolated in Oklab color space.

const PALETTE_SIZE = 512;

function palettePhase(value, gScale = 7) {
  return (Math.sqrt(Math.max(0, value) + 1) - 1) *
    gScale / 55;
}

function samplePalette(value, paletteTable) {
  const phase = palettePhase(value);
  const position =
    (phase - Math.floor(phase)) * PALETTE_SIZE;
  const index = Math.floor(position);
  const fraction = position - index;
  const base0 = index * 4;
  const base1 = ((index + 1) % PALETTE_SIZE) * 4;
  const sampleChannel = c => {
    const c0 = paletteTable[base0 + c];
    const c1 = paletteTable[base1 + c];
    return Math.round(c0 + (c1 - c0) * fraction);
  };
  return [
    sampleChannel(0),
    sampleChannel(1),
    sampleChannel(2),
    255,
  ];
}

function getIterationColor(result, paletteTable) {
  const { numIterations } = result;
  return samplePalette(numIterations, paletteTable);
}

Sweeping across the viewport grid maps each pixel to its starting coordinate (x0, y0), runs the recurrence for the fixed parameter (cx, cy), and writes the sampled RGBA color for every escaping orbit while leaving bounded interior points dark.

function drawJuliaSet(
  canvasEl, xRange, yRange, cx, cy,
  getColor, paletteTable
) {
  const canvasWidth = canvasEl.width;
  const canvasHeight = canvasEl.height;
  const context = canvasEl.getContext('2d');
  const canvasImageData =
    context.createImageData(canvasWidth, canvasHeight);
  const image = canvasImageData.data;
  for (let i = 0; i < canvasHeight; i++) {
    for (let j = 0; j < canvasWidth; j++) {
      const x0 = xRange[0] +
        j * (xRange[1] - xRange[0]) / canvasWidth;
      const y0 = yRange[0] +
        i * (yRange[1] - yRange[0]) / canvasHeight;
      const result = iterateUntilEscape(x0, y0, cx, cy);
      const pixelIndex = 4 * (i * canvasWidth + j);
      if (result.escaped) {
        const pixels = getColor(result, paletteTable);
        for (let p = 0; p < 4; p++) {
          image[pixelIndex + p] = pixels[p];
        }
      }
    }
  }
  context.putImageData(canvasImageData, 0, 0);
}

Here's the central spiral of the dragon Julia set (c = −0.8 + 0.156i) colored from integer iteration counts alone, where each discrete escape step forms a visible contour band.

Central spiral of the dragon Julia set colored using discrete integer iteration counts, showing contour bands
span 9.60e-11,024 iter max · Ready

Running three additional iterations after crossing |z| > 2 and subtracting the doubly logarithmic escape potential turns the integer step count into a continuous escape time mu.

const ESCAPE_RADIUS = 2;
const SMOOTHING_STEPS = 3;

function getMu({ numIterations, x, y, cx, cy }) {
  for (let i = 0; i < SMOOTHING_STEPS; i++) {
    const xNext = x * x - y * y + cx;
    const yNext = 2 * x * y + cy;
    x = xNext;
    y = yNext;
  }
  const distanceSquared = x * x + y * y;
  return numIterations + SMOOTHING_STEPS + 1 -
    Math.log(0.5 * Math.log(distanceSquared)) /
    Math.log(ESCAPE_RADIUS);
}

function getSmoothColor(result, paletteTable) {
  const mu = getMu(result);
  return samplePalette(mu, paletteTable);
}

Feeding mu into the same repeating plum, amethyst, champagne, and rose-gold Oklab spline removes the stepped contour seams across the spiral arms.

Central spiral of the dragon Julia set colored with continuous logarithmic escape-time smoothing
span 9.60e-11,024 iter max · Ready

Inverse iteration and orbit-density methods render Julia sets by plotting either the backward preimages of repelling periodic points or the visit frequency of escaping trajectories across the viewport.

Inverse Iteration & Orbit Density16,384 backward square-root preimages
MethodBackward Preimages
Parameter c-0.8000 + 0.1560i

Because the Julia boundary Jc is backward-invariant, repeatedly taking both complex square roots zn−1 = ±√(zn − c) from a repelling fixed point lands directly on Jc.

About

All fractals on the page are interactive and rendered when they're in view. Every image can be expanded into full-screen mode using the button in its bottom-right corner. Full-screen views also display live complex-plane coordinates and let you undo camera steps or reset to the starting view.

As you zoom deeper, each canvas automatically switches to more sophisticated rendering pipelines to stay fast and avoid pixelation. Shallow views run per-pixel escape loops in 32-bit WebGL fragment shaders.

Zooming past 10-3 switches to compensated double-single shaders and 64-bit workers. Beyond 10-14, the renderer switches to perturbation theory and arbitrary-precision decimal math so you can keep zooming without losing detail.

Fractal image controls when hovering

  • shift + scroll mouse wheel — zoom in/out
  • shift + click and drag — draw a selection box to zoom in
  • double-click (or shift + double-click) — zoom in/out at cursor
  • + / − keys — zoom in/out
  • pinch — zoom in/out
  • click and drag — pan the view
  • arrow keys (when focused or hovering) — pan the view in 10% steps
  • two-finger swipe — pan the view on touchscreens
  • one-finger swipe — scroll the page
  • cmd-z / cmd-shift-z — undo or redo camera actions
  • 0 — reset view to its initial position