Viewing eclipses in a WebGL Solar System simulation

TL;DR: here is the link to the simulation:

A few years ago, I programmed jsOrrery, a Solar System simulation in the browser. It’s been a while since I added features to it, but with this summer’s eclipse date coming near, I wanted to see if I could view it in the simulation.

Computing the Moon’s exact position over time is not a simple problem, so much so that it has eluded scientists for centuries. The orbits of celestial bodies can normally be determined quite accurately using a simple geometric formula involving a few numbers called orbital elements. Since most orbits don’t evolve much over time, this technique is fairly accurate to find the positions of planets in the Solar System at any given time.

Sometimes though, a body’s orbit is heavily influenced by more than one other body, and the computations required to determine its position are much more complex. Such is the case of the Moon, as it is influenced heavily by the Earth’s as well as the Sun’s gravity.

Furthermore, when looking at the Moon from the Earth, we see it as as a tiny disk in the sky, so a very slight inaccuracy in its position amounts to a very visible one. The Moon’s angular size is about half a degree as seen from the Earth, and so is the Sun’s. As a matter of fact, in order to simulate an eclipse, both the Earth’s and the Moon’s position must be ultraprecise as both bodies position must overlap exactly. A difference of a single arcsecond in precision for either body would make it impossible to observe a total eclipse when it’s supposed to happen.

In my original simulation, I had used a computation for the Moon’s position whose precision I knew was imperfect. For my needs then, that computation was more than sufficient though. I had tried to view eclipses in the simulation and was not exactly on point but close, and I did not then pursue further to get better precision.

The view from the Earth at August 2017’s eclipse date in the original jsOrrery

In the right place at the right time

The first thing you have to do in order to view an eclipse is to go somewhere on the Earth where you will expect to see the eclipse. Only by being at a very precise latitude and longitude would it be possible for you to see the total eclipse, as they are very localized events. If you were anywhere else on Earth, you would not see it.

In jsOrrery, I originally could not position the camera on the surface of the Earth. When choosing the Earth as the viewpoint, the camera was positionned at the Earth’s position, so at the center of it. The first step was to be able to place the camera on the surface, at a given latitude and longitude.

Latitude is the easy part, as it is an angle from -90 to +90, that can be used directly without any other transformation than to add the Earth’s tilt of ~23.5 degrees. Longitude is harder, since it is constantly changing in respect to the universe because the Earth is rotating. Therefore, in order to get the correct longitude, time has to be taken into account. To find the position of a given longitude at a given moment, the Earth’s rotation at that moment has to be added to the longitude coordinate.

So I programmed in jsOrrery a way to input a geolocation for the camera, and through a rather simple algorithm I was able to transform these radial coordinates to cartesian coordinates by rotating a position on the surface of the Earth’s model according the parameters described above.

When that was done, I tried to view August 2017’s eclipse from the time and position on the Earth when it will be total, data that I got from Nasa’s Eclipse website, that is August 21 at 18:26:40 UT and 36.9664N -87.6709W. I was quite disappointed that I was not seeing a total eclipse. The Moon was not that far from the center of the Sun, but “not far” was not good enough.

August 2017 eclipse as seen from the correct geolocation, but without enough precision in the Moon’s position

Moar precision

I decided to read more about the computation I was using to find the Moon’s position, as I knew it might not be precise enough for my needs. That computation is based on a theory called Ephemeride Lunaire Parisienne, or ELP, that I got from Mathworks back in 2013. Now even if this algorithm has a lot of terms, I found out that my computation did not have all of the theory’s term, and was therefore a simplification of it. The computation I used had about a thousand terms, whereas complete ELP has a few hundred thousands.

It turns out that if one wants to predict the Moon’s position precisely enough to observe eclipses, taking into account only the Earth’s and the Sun’s gravity is not enough. The Moon’s orbit is disturbed by all of the Solar System’s planet’s gravities and this has to be considered in the computation, which is what ELP does in its complete form.

I eventually found out the complete theory in Fortran, which I quickly rewrote in Javascript. Not that I know Fortran, but the program was simple enough that I was able to read it and translate it.

I was quite excited to try it out, as I was sure now that I had the position of the Moon with utmost precision. But once again, I was disappointed to see that I could not observe the eclipse. I was closer, but still not enough to see the total eclipse.

I figured then that the Earth’s position could be the culprit. I was computing the Earth’s position from classical elements, but its orbit is also disturbed by other bodies in the Solar System, which I had to take into account. It was not long before I found out about another theory, also developped at Bureau des longitudes, called Variations Séculaires des Orbites Planétaires (or VSOP), which is an integration akin to ELP, but to compute planets’ positions.

Fortunately, I was able to plug the Earth’s VSOP quite easily in jsOrrery, and once again was very excited to test it out. I was sure that with the Earth’s and the Moon’s precise positions, I would be able to see the total eclipse. Well, you guessed it, it did not happen.

Searching for an answer

I thought perhaps I had some other source of imprecision in my system. I read a lot about the coordinate systems used to determine the bodies’ positions, as I figured that maybe the different sources and algorithms I was relying on might not use the same coordinate system. I confirmed that they indeed used the same coordinate system, so that was not the problem.

So what was the source of inacuracy? I was not far off being able to see the eclipse… I could play with the latitude and longitude of the camera on the Earth’s surface a bit to get to a point where I was seeing the total eclipse. The eclipse was visible from the Earth’s surface at the expected time, but just not from the right position.

I eventually realized that I did not even need to change the latitude in order to see the total eclipse. It was just the longitude that was off. That was good news, it meant that I had isolated the part of the problem that was causing the inacuracy. I was progressing! I tried the dates of different historical eclipses, and I realized that I was ALWAYS off by the same number of degrees of latitude to prevent me from seeing the eclipse. I then knew for a fact that the source of the innacuracy was not the positions of the bodies, therefore it could be resolved.

The difference in latitude was always about 8.5 degrees, or 1/42nd of a circle. As you recall, longitude computation depends on time, so instead of correcting the longitude itself, I could make the correction to time. If I subtracted about 34 minutes from the time I had, or about 1/42nd of a day, I was pinpoint on a location where I could see the total eclipse. I was therefore 1/42nd of a day late, in all scenarios, to be able to see the eclipse. Oh god I was near the solution!

Animation showing the difference in the Moon’s apparent position relative to the Sun when changing the viewpoint’s longitude on the surface of the Earth. Latitude stays the same.

An epiphany

Of course I could just put these 34 minutes in a const that I subtracted from time to get the accurate result and call it a day, but it would be crappy programming. I needed to understand the reason. I think it is sloppy to add constants in your code that fix problems you don’t understand (I’ve never done that, I promise…)

1/42nd… what was this number related to? What is 1/42nd of a circle, 1/42nd of a day… or 1/42nd of a year perhaps? Then it hit me like a ton of bricks. Of course!

The reference time, or zero time, in jsOrrery is J2000, January 1st 2000 at noon. That date is the reference time to compute most of the planet’s positions from their orbital elements as you can find them on JPL’s website, so that is what I used as my global reference time.

And guess what comes about 1/42nd of a year before january 1st? The winter solstice.

In the coordinate system, the x and y axes are (mostly) aligned with the equinoxes and solstices of the Earth. If I rotate an object in the scene, it will be in regards to that coordinate system. But at the zero time I use for initialization, the Earth does not lie directly on one of theses axes. My error was that I assumed that at initialization time, the Earth was directly somewhere on the Y axis. Then, I would rotate the Earth for the prime meridian (Greenwich) to align with the axis to face the Sun (because the J2000 is at noon, Greenwich facing the Sun). The difference between J2000 and the winter solstice was too small for me to visually notice an error of about 8 degrees, that is until I tried to see eclipses.

So all I had to do was factor in this difference between J2000 and the winter’s solstice in the computation of the Earth’s rotation in regards to the Y axis, and voilà!

The Moon completely obscuring the sun on August 21, 2017 at 18:26:40 UT.

The limits of the simulation

Now, I know that there is still a small error in this rotation, and I must admit that I am not sure of the exact reason. At the time of any equinox or solstice, even though I have a very precise position for the Earth (and I verified against the numbers produced by JPL’s Horizon), the positions are not exactly aligned with their respective axis.

What I know is that it is not due to the precession of the equinoxes, as I take that into account when setting the Earth’s tilt direction. The zero for the precession’s wobble is J2000, so that then the Earth’s tilt points toward the winter solstice, and I rotate the tilt on a 26,000 year period.

I tested 1919’s total eclipse without factoring in the precession and I was off a bit, but if I compute it I am dead on. Some other eclipses are still off a bit (for example 2024's). I suspect that it’s because of the Earth’s nutation, which I don’t take into account — but I could be wrong. Your guess is as good as mine.

EDIT: I have made further modifications to the simulation and can now get more precision. First, I changed the version of VSOP for a more complete one, but more importantly I now factor in a correction in the rotation of the Earth. The Earth has some variations in its rotation rate, called delta T, which can be computed with a simple algorithm. It has to be taken into account in order to see eclipses. I also know that the integration I use for computing the Moon’s position is not the exact same as what is used by Nasa (I use ELP2000–85 whereas Nasa computes its eclipse canon using ELP2000–82B) There is a slight difference between both, which prevents me from observing some eclipses far back in time. So it turns out nutations had nothing to do with the imprecision I get.


In any event, I managed to view eclipses in jsOrrery with a precision that is enough for this kind of simulation. It is at least enough to have a very good idea of what the eclipse will look like from your home, and I find that quite interesting. I am proud of it — not that I invented any of these computations, but I was able to make sense of them. I still have a lot to learn about all of those things, but I guess I am a little closer to understanding them than when I began working on this project. In the end, that’s the reason I built this project — to learn.

See it in your browser

Here is the link to 2017’s eclipse in jsOrrery:

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.