← DEVLOG
Interactive2025.11.107 min read

Three-Body Problem — Simulating Chaos

Building a real-time three-body problem simulator in the browser after watching the Netflix Three-Body series — numerical integration, energy conservation, and visualizing the butterfly effect

canvasvelocity-verletn-bodychaosweb-audiointeractive

The Beginning — Inspired by a Show

Watching the Netflix Three-Body series, I was fascinated by the premise of "three suns creating unpredictable orbits." Could a 300-year-old unsolvable mathematical problem actually run as a real-time simulation in a web browser? Driven by pure curiosity, I started gathering resources.


What Is the Three-Body Problem

Newton's law of universal gravitation perfectly predicts the orbits of two celestial bodies. But add a third, and no closed-form general solution exists. Since Poincaré proved the existence of chaos in this system in 1890, the three-body problem has become the quintessential example of a "deterministic yet unpredictable" system.

After some research, I found it was more feasible to implement than I'd expected. The core boiled down to just two things: gravitational acceleration calculation and numerical integration.


Velocity Verlet — An Integrator That Doesn't Leak Energy

The first challenge was choosing a numerical integration method. The simple Euler method (x += v*dt) is easy to implement, but energy gradually increases over time, causing orbits to diverge from reality. For precise patterns like the figure-eight orbit, the trajectory breaks down quickly.

Velocity Verlet has a "symplectic" property that preserves energy over long periods.

// 1. Position update: x(t+dt) = x(t) + v(t)·dt + ½·a(t)·dt²
newX = x + vx * dt + 0.5 * ax * dt * dt;

// 2. Recalculate acceleration at new position
newAx = computeAccel(newX, ...);

// 3. Velocity update: v(t+dt) = v(t) + ½·(a(t) + a(t+dt))·dt
newVx = vx + 0.5 * (ax + newAx) * dt;

By running 12–16 substeps per frame to subdivide dt finely, I was able to maintain less than 0.1% energy drift over thousands of frames in the figure-eight orbit.


Preset Orbits — Mathematical Gems

The most fascinating part of building the simulator was finding preset initial conditions.

  • Figure-Eight Orbit: Discovered computationally by Chris Moore in 1993. The initial positions and velocities must be matched to several decimal places to remain stable.
  • Lagrange Triangle: Requires precisely calculating circular orbital velocities for an equilateral triangle configuration.
  • Chaos: Asymmetric masses in close proximity. Beautiful chaos unfolds.

Converting initial conditions from academic papers to normalized coordinates (-1 to 1) turned out to be surprisingly tricky.


Butterfly Effect Visualization

The "butterfly effect" mode clones the current simulation state, then shifts the first body's x-coordinate by just 0.1% to show two simulations side by side. At first they appear nearly identical, but over time you can watch the trajectories diverge completely.

The split screen is implemented using Canvas's clip() API. On desktop it splits left/right, on mobile it splits top/bottom.


Soundscape — Turning Gravity into Sound

I added a Web Audio soundscape that maps inter-body distances to frequency and volume. Close pairs produce low, strong tones, while distant pairs emit high, faint ones. Beating drones at 36Hz and 38.5Hz create an ambient cosmic atmosphere.

Changing frequencies directly each frame causes audible glitches, so I applied smooth transitions using linearRampToValueAtTime at 80ms intervals.


What Was Challenging

Honestly, the physics of the three-body problem isn't my area of expertise. I spent time debugging coordinate system transformation errors when porting initial conditions from papers, and figuring out why energy drift was unexpectedly large.

But through that process, I gained a visceral understanding of why this problem remained unsolved for 300 years. The greatest reward of this project was being able to see with my own eyes how tiny differences create vastly different outcomes — the essence of chaos.


Tech Stack

ItemDetails
RenderingCanvas 2D + DPR/4K scaling
Physics EngineVelocity Verlet integrator (12 substeps)
AudioWeb Audio API — distance-based frequency mapping
Presets6 types (Figure-8, Lagrange, Butterfly, Chaos, Sun-Earth-Moon, Today)
Butterfly EffectCanvas clip split view + 0.1% perturbation

Content related to this post

Try it yourself