Most readers of this blog are probably familiar with the idea of celestial bodies orbiting each other due to mutual gravitational attraction. The most familiar examples involve two bodies, such as the moon and the earth, the earth and the sun, or a pair of stars (binary stars). The general n-body problem is the mathematical problem of finding a way to predict the locations of several bodies acting on each other by gravity, given initial positions and velocities. It is famously difficult, even when restricted to as few as three bodies.

This past year, James Montaldi of the University of Manchester contacted me to see if I could assist in creating some animations of some intriguing special solutions to the n-body problem that he and his former doctoral student Katrina Steckles wrote about in a research article (based in part on the doctoral thesis of Steckles).

The source code is somewhat complicated, but here it is in case you would like to download and examine it. The application is broken up into one html page with the main JavaScript application embedded, plus a separate JavaScript file containing the data which describes the orbits in JSON format (the online demo uses a minified version of this data file, but a beautified version is included in the download). Also included are some open source JavaScript libraries (see acknowledgments below).

## The mathematics and the code

The solutions to the n-body problem illustrated in this application fall under a special category called choreographies: periodic motions where the particles have equal mass and follow each other around a closed path at regular intervals. In part of their paper, Montaldi and Steckles completely classify the symmetries that such choreographies can have. The paper is available for download here.

Part of a figure from the paper by Montaldi and Steckles

The animations in this web application are not created by computing physics in real time. Instead, the analytic solutions discovered by various mathematicians provide precise equations to describe the positions of the particles at any given time.

Since these parametric curves describe periodic motion, they can be described by
Fourier series, a way of writing periodic functions as an infinite sum of sines and cosines of increasing frequency. The orbits are animated by using these Fourier series (but by truncating the infinite sums down to finite approximations).

If you have a look at the code, you’ll find within the setParticlePositions function which computes the trajectories a call to a separate fourierSum function which computes a Fourier sum from given coefficients.

### The orbit data

The application animates quite a number of different choreographies. They are described by several pieces of data for each orbit, and all this data has been collected together in one large JSON object. The data includes orbit names, the number of particles, how to color them, and the Fourier coefficients used to compute the motion.

For simplicity, I decided to place all of the data in a separate JavaScript file, rather than creating a JSON object and loading it using XMLHttpRequest. It was simpler, it works, and I don’t see any problems with this approach (but let me know if you think otherwise!).

### Drawing trajectories in the HTML5 canvas: more complicated than it looks!

This animation makes use of three separate canvas elements layered on top of each other to create the desired effect. On the top we see the particles. The next two canvases combine to create the trajectories with the effect of fading from color to blue-gray.

As the particles move around the canvas, they trace out trajectories behind them. To create these trails, I decided to exploit an artifact caused by the repeated painting of a low-alpha black over the whole display: because of integer rounding, the colors will not fade completely and instead will bottom out at a gray color. I wrote about this effect in a previous blog post here. In that blog post, the gray trails were treated as an unfortunate artifact preventing the complete slow fade-to-black seen in many particle animations. But here I wanted these gray trails left behind in order to illustrate the geometry of the choreographies.

But now I had the reverse problem: some browsers do pixel math differently, and the trails would fade to complete black. So what to do? The solution was simply to draw semi-transparent trajectories explicitly, in a separate canvas layer.

But there was another issue: when the speed of the animation was slowed down using the slider in the GUI, there was more build-up of color, creating more opaque trails. So I had to change the code so that the the trajectories would be drawn based on distance, rather than time. Have a look at the code to see how I measure how far the particles have traveled to see if it is time to draw a new segment. Also note that the drawing of the trails is turned off once a complete cycle is drawn.

Thus the trails are created like this: on the bottom layer, colorful trails fade to gray (in some browsers, black in others), while above that semi-transparent blue-gray trails are painted. You then see colors fade away to leave blue-gray behind. On top of everything, a separate layer animates the particles.