A pendulum over three magnets, and the fractal map of where every release point ends up.
Seen from above, an iron bob is pulled back to the center by gravity, slowed by air friction and attracted to three magnets by an inverse-square force softened by its height above them. It must come to rest over one of them, but which one depends so sensitively on where it starts that the basins of attraction form a fractal: between any two colors there is always the third. Each pixel of the map is a full simulation (semi-implicit Euler, run until the bob settles over a magnet), colored by the winner and darkened by how long it took. The map refines coarse to fine on 16, 8, 4, 2 and 1 pixel grids, and a sample is interpolated instead of simulated when the four coarser samples around it agree, which concentrates the work on the boundaries where the fractal lives; while magnets move, only the coarsest grid is swept over and over as a live preview. Live pendulums run on top with the same integrator in real time, their trails colored by the basin they were released in, so you can watch the map's prediction come true.
Try it. Click anywhere to release a pendulum from that point, and drag a magnet to reshape the whole map, which follows it as a soft live preview and sharpens when you let go. Keys 2 to 6 set the number of magnets, [ and ] change friction, - and + change the bob's height, S glides the magnets to a new arrangement, Space releases a random pendulum and C clears the trails.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a magnetic pendulum fractal with JavaScript and the HTML canvas element: a map that colors every starting point by which of three magnets a pendulum released there ends up on. 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.
- Put three magnets at radius 1 around the origin, 120 degrees apart, each with a color. The view should span about -2.2 to 2.2.
- Model the bob from above: acceleration = -0.5 * p - 0.2 * v + the sum over magnets of (m - p) / (|m - p|^2 + 0.06)^1.5, where 0.06 is the squared height of the bob above the magnets.
- Write simulate(x, y): start at rest, step with semi-implicit Euler (update velocity, then position) with dt = 0.025, and stop when the bob is within 0.17 of a magnet and moving slowly. Return the magnet and the number of steps it took.
- Render the map into a small offscreen canvas (about a quarter of the screen resolution), a few rows per frame so the page never freezes, and scale it up with drawImage. Darken each pixel by how many steps it took.
Once that works, make it come alive:
- Render progressively: first every 8th pixel painted as an 8x8 block, then every 4th, 2nd and finally every pixel, so a rough map appears instantly and sharpens.
- Click to release a live pendulum from that point, simulated with the same integrator in real time, and draw its glowing trail in the color its basin predicts.
- Let me drag the magnets around, restarting the map each time.
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 skipping pixels whose neighbors agree, adding more magnets, or sliders for friction and height.