Three Bodies — how it works
One law, and why it is not enough
Every body pulls on every other along the line between them, with a force proportional to both masses and inversely proportional to the square of the distance. Newton, 1687:
F = G·m₁·m₂ / r²
Two bodies under that law have a closed-form solution — Kepler's ellipse, an exact formula for where each body is at any time. Three do not. Poincaré proved in 1890 that no such formula can exist: the three-body problem is not unsolved, it is unsolvable in that sense.
So the only way to know what three bodies do is to step them forward and watch. That is what this plugin does: the orbits are integrated from the numbers on every render.
Integration: velocity Verlet, deliberately not RK4
The pendulum in the sibling plugin uses Runge–Kutta 4, which is more accurate per step. Here the integrator is velocity Verlet — half-kick, drift, recompute, half-kick — because it is symplectic: its energy error oscillates around the truth instead of accumulating. For orbital mechanics that matters far more than per-step accuracy. An RK4 orbit slowly spirals; a Verlet orbit stays closed for as long as you care to watch, which is the difference between a demo that survives thirty seconds and one that does not.
Gravity is softened — r² + ε² with ε = 0.02 — so a direct hit cannot divide by zero. A pass
closer than ε is therefore drawn gentler than it truly is; the explanation under each system reports
its closest approach so you can see when that matters.
Every run reports its energy drift as a fraction of the initial energy. For a bound gravitational system that is safely non-zero (it is negative), unlike the pendulum's, which is why the relative measure is the meaningful one here.
Motion without scripts
The trajectory is integrated once, sampled to ~260 frames, and handed to the browser as SVG SMIL keyframes over a faint full-orbit trail. No script, no timer, no hub involvement — the motion is data, so every viewer sees the same run.
The view is framed on the centre of mass of the first frame and scaled to the widest excursion, so a system whose barycentre drifts stays on screen and a wide orbit is not clipped.
The eight systems
Three are exact solutions, one is the solar-system limit, one is what three bodies normally do, and three are the notebook's zone demonstration.
| System | What it shows |
|---|---|
| Figure eight | Three equal masses chasing each other along ONE closed curve. Moore found it numerically in 1993; Chenciner and Montgomery proved it in 2000. The published initial conditions, to eight decimals. The run is exactly two periods (2 × 6.332) so the animation closes on itself. |
| Lagrange triangle | Lagrange's 1772 solution: an equilateral triangle rotating rigidly, forever. One of only two families of exact solutions the problem has (Euler's collinear one is the other). In the solar system these corners are L4/L5 — Jupiter's Trojans. |
| Binary and a moon | A circular binary with a light body orbiting the pair four separations out. The hierarchical case: the only reliably stable arrangement three bodies have, and why triple star systems exist. |
| Sun and planets | One dominant mass, three light ones on nested near-circular orbits. Kepler holds to under 2%. The control: what the n-body problem looks like when it is not a problem. |
| Chaotic trio | Three equal masses with no symmetry to protect them. This is the generic case; the choreographies above are the freaks. |
| Light body, close orbit | The notebook's first zone: a test particle deep in the primary's grip. 18 clean turns in 5.5 time units. |
| Light body, chaotic | Second zone: neither heavy body dominates, and every pass rewrites the next. |
| Light body, wide orbit | Third zone: far enough out that the pair averages into one mass, so the orbit is nearly Keplerian again. |
Stable inside, chaotic between, stable outside. Those last three are one experiment in three frames, and they are why planets can survive around binary stars.
⚠️ Two of these were wrong before 2026-08-11 and are worth knowing about. Lagrange triangle shipped with unit speed; the solution only exists at
√(G·m/(√3·r)) ≈ 0.7598, and at speed 1 the triangle expanded from side 1.73 to 8.9 within fourteen time units — it flew apart while claiming to be the exact solution that never changes shape. Binary and a moon shipped with the pair launched well above circular speed, which stretched the binary to four times its separation and ejected the moon. Both now carry regression tests that pin the SHAPE (the triangle's side length, the binary's separation) rather than the initial numbers, so a future nudge fails loudly.
Languages
Every explanation on the Orbits and Play pages exists in English and German, in NBodyTexts —
one pure table per language. ?lang=de first, then the viewer's profile locale, then English; a 🌐
line at the foot switches. System NAMES stay English: they are also the ?system= URL parameter.
That includes the playground's computed guidance — the zone it puts you in and how your launch speed compares with the circular one — so a German-reading child gets the same number and the same advice, not a translated approximation of it.
One control
There used to be four routes — a gallery, a playground, a walkthrough and its chrome-free twin — and moving between them meant leaving the system you were watching. There is now one screen:
┌──────────────────────────────────────────────┐
│ the orbits running, trails growing │ ← behind each body, not ahead of it
├──────────────────────────────────────────────┤
│ masses 10/1 sep 2 third 1 @ 3.162 12 units│
│ [ Run ] [ 🎲 Surprise ] │
├──────────────────────────────────────────────┤
│ ‹The law› ‹Examples› ‹Try yourself› │
└──────────────────────────────────────────────┘
| Area | What it is |
|---|---|
| Orbits (default) | The whole control. ?system=Figure%20eight opens on a named choreography; ?size=900 enlarges; ?lang=de picks the language. |
| Play | The same control. The old playground route, kept alive so no link, bookmark or embed 404s. |
| Tests | The physics suite, executed on the mesh. |
- You land on a RANDOM system. No
?system=, and the page rolls one — a different choreography every time you open it, already running. A roll is not a free-for-all: a custom launch draws its speed as a FRACTION of the circular speed for the distance it picked (75–115%), because most of that parameter space is a body that either falls straight in or leaves the frame and never returns. The top of that band is lower than it looks like it should be for a reason: escape is at √2 ≈ 141%, so 130% is a perfectly bound orbit — whose apoapsis is five and a half times the starting distance, rendering the binary at the middle as two touching dots. Being bound is not the bar; being watchable is. - 🚨 The trails ACCUMULATE. Each body's whole orbit used to be painted before anything moved, so
a figure-eight was handed to you finished and then traced over. Each trail now draws itself behind
its body, via an animated
stroke-dashoffsetkeyed to cumulative arc length (NBodyMath.TrailReveal). The arc-length keying is load-bearing: a body races through periapsis and crawls at apoapsis, so a constant-rate reveal would run ahead on the fast arc and lag on the slow one. Trails and bodies are sampled from the same frames over the same duration, so they are in lockstep by construction — and a test pins it. - It re-runs on the BUTTON, not the keystroke.
Examples and Try-yourself are different parameter spaces — deliberately
Most of the eight are one-off solutions that exist at exactly one arrangement of masses and velocities; the figure-eight is not a point in some family you can wander around in, it is a single choreography someone found. The playground is the two-heavy-plus-one-light family that three of the eight belong to and that a person can actually reason about.
So the control carries the two as separate cases (NBodyAreas.Choice) rather than pretending a
preset click can fill in the toolbar. Clicking one of the eight runs that choreography; pressing
Run switches to your numbers and leaves it. The Examples tab says this in as many words, because
a viewer who clicks Figure eight and sees the bar unchanged deserves to know why rather than to
conclude the page is broken.
What the playground gives you
A form cannot edit a flat array of fifteen numbers in any way a person can reason about. So the playground offers the family the whole lesson lives in: two heavy bodies placed on the exact circular orbit for the separation you choose — so the pair itself is always stable — and a test particle at a distance and speed you choose.
All three "Light body" examples are members of that family, so you can reproduce them, walk between them, and find the boundary yourself. The page computes the circular speed for the distance you picked (about the primary alone when you are inside, about the pair when you are outside) and tells you what fraction of it you launched at, so an experiment is one number away rather than a hunt.
The experiment worth running: start close in at circular speed, then move out in steps, re-launching at circular each time. Somewhere the regular orbit stops being regular — that boundary is the three-body problem. Keep going and it becomes regular again.
Authoring a node
Content is the bodies as flat quintuples [x, y, vx, vy, mass], plus G and the integration
settings:
{ "nodeType": "ThreeBody/Bodies",
"content": { "$type": "NBodyContent", "preset": "Figure eight" } }
Naming a preset fills in the bodies; writing the quintuples yourself is the other way to say it.
Either way the node pins that system and the page opens on it — and a node that authors nothing
rolls one instead, which is what ThreeBody/Orbits does. A malformed list (not a multiple of five,
or empty) falls back to the figure-eight rather than throwing, so a mistyped node still shows
something true.
There is no body field any more: the note under a system is the Examples tab's, keyed off the
preset, so a per-node one would describe whichever system the page happened to roll.
Original notebooks: Generalization of the TwoBody Solution to N Bodies (Peter Kunszt, on work by Andres Ruiz Vargas and Roland Bürgi), Two-dimensional Many-body problem (Andrea Muolo) and Scopes: Simplified three body problem, Systemorph Cloud. Rebuilt for MeshWeaver in 2026.