The restricted three-body problem as a plaster relief, Trojans looping on its summits.
In the frame turning with two orbiting masses, gravity and centrifugal force add up to one effective potential, drawn here as a plaster relief model: funnels at the two masses, a ring-shaped ridge along their orbit with summits at L4 and L5 and mountain passes at L1, L2 and L3. The mesh is shaded and drawn back to front with the painter's algorithm, and its contour lines come from marching squares, bucketed by row so nearer hills hide them; the vermilion contours through L1, L2 and L3 are zero-velocity curves that no particle with that Jacobi constant can cross. Test particles are integrated with fourth-order Runge-Kutta, including the Coriolis force that turns a slide off a summit into a loop around it, so they trace tadpole orbits around L4 and L5 and, for a light secondary, horseshoes around L3. Above Routh's limit, a mass ratio of 0.0385, the summits stop holding anything and the Trojans spiral away.
Try it. Click anywhere on the landscape to release a particle moving at the local circular speed, or drag to aim it. Drag the mass-ratio slider (or use the arrow keys) past the Routh limit, press V to switch between the relief and the plan view, plus and minus to change the speed, R to reseed, C to clear and Space to pause. Left alone, it visits the Earth-Moon mass ratio, an unstable one past the Routh limit, and the Sun-Jupiter ratio in plan view.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a visualization of the five Lagrange points of the restricted three-body problem with JavaScript and the HTML canvas element. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.
Start simple:
- Make a canvas that fills the window, stays sharp on high-DPI screens (scale by devicePixelRatio), and resizes with the window.
- Work in the frame that rotates with two masses, 1 - mu and mu, at (-mu, 0) and (1 - mu, 0), with G = 1, their separation 1 and angular speed 1. Start with mu = 0.01.
- Compute the effective potential Omega = (x^2 + y^2) / 2 + (1 - mu) / r1 + mu / r2 on a grid, and draw it as a shaded image (into a small offscreen canvas scaled up with drawImage).
- Find L1, L2 and L3 on the x axis by bisection on dOmega/dx; L4 and L5 sit at (0.5 - mu, plus or minus sqrt(3) / 2). Mark all five.
- Integrate test particles with fourth-order Runge-Kutta, using x'' = 2y' + dOmega/dx and y'' = -2x' + dOmega/dy (the 2y' and -2x' terms are the Coriolis force). Release a few at rest on the unit circle a little past L4 and L5 and draw their trails: they trace tadpole orbits.
Once that works, make it beautiful:
- Draw contour lines of 2 Omega with marching squares, and highlight the levels through L1, L2 and L3: these are the zero-velocity curves.
- Add a slider for mu and watch L4 and L5 stop holding particles above Routh's limit, mu of about 0.0385.
- Let me click to release new particles moving at the local circular speed, 1 / sqrt(r) - r in this frame.
Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as drawing the potential as a 3D relief with the painter's algorithm, horseshoe orbits for very small mu, or a plot of each particle's Jacobi constant to check the integrator.