cosinekitty / astronomy

Astronomy Engine: multi-language calculation of Sun, Moon, and planet positions. Predicts lunar phases, eclipses, transits, oppositions, conjunctions, equinoxes, solstices, rise/set times, and other events. Provides vector and angular coordinate transforms among equatorial, ecliptic, horizontal, and galactic orientations.
MIT License
420 stars 59 forks source link

Why is the accuracy error of my calculation results so large? Especially the moon. #335

Open ichingsoft opened 4 months ago

ichingsoft commented 4 months ago

Astronomy Engine is designed to be small, fast, and accurate to within ±1 arcminute. It is based on the authoritative and well-tested models VSOP87 and NOVAS C 3.1.

Is there something wrong with my code? The running environment is node.js .

const Astronomy = require('astronomy-engine');
const observer = new Astronomy.Observer(0, 0, 0);
const date = new Date('2023-01-01T00:00:00Z')
for (let body of ['Sun', 'Moon', 'Mercury', 'Venus', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune', 'Pluto']) {
    let equ_2000 = Astronomy.Equator(body, date, observer, false, true);
    console.log(body, equ_2000.ra * 15);
}

The calculated degree of the planet is:

Sun 280.84142445266076 Moon 30.45792396696944
Mercury 295.07476976548236 Venus 299.4006183356455
Mars 66.54558868798762
Jupiter 1.3125988767227075 Saturn 324.8817602609786
Uranus 42.47582030780864
Neptune 353.6326779482502 Pluto 299.8780779863024

But the calculation result of Swiss Ephemeris is:

planet longitude
Sun 280.2838870 Moon 33.6479912 Mercury 293.7019368 Venus 297.3826285 Mars 69.0657735 Jupiter 1.1929697 Saturn 322.4188522 Uranus 45.1476005 Neptune 352.8706151 Pluto 297.6578268

cosinekitty commented 4 months ago

Hello @ichingsoft and welcome to the project!

The first thing I would do is to get clear about whether you want equatorial coordinates (right ascension) or ecliptic coordinates (ecliptic longitude). The code you wrote above correctly uses Astronomy Engine to find right ascension in degrees, including multiplying by 360/24 = 15 to convert sidereal hours to degrees.

But it sounds like you are using Swiss Ephemeris to calculate ecliptic longitude, which is not the same thing as right ascension, because it is in a different orientation system. The equatorial system uses the plane of the Earth's equator as a reference, but the ecliptic system uses the plane of the Earth's orbit around the Sun. These planes are tilted by 23.5° with respect to each other. Both angles are referenced to the equinox point, which is the intersection of the two planes in the direction of the March equinox. That is why your numbers are similar but not the same.

Here is how I would find its ecliptic longitude in the JavaScript version of Astronomy Engine:

    // ... same as your code above ...
    let equ_2000 = Astronomy.Equator(body, date, observer, false, true);
    // but convert equatorial to ecliptic ...
    let ecl = Astronomy.Ecliptic(equ_2000.vec);
    console.log(`{body} ecliptic longitude = {ecl.elon}`);

For Mercury, this results in

Mercury ecliptic longitude = 293.700464566546

which is very close to the answer from Swiss Ephemeris.

I hope this helps!

cosinekitty commented 4 months ago

One more thing... the Moon is so close to the Earth that your position on the Earth will significantly affect where it appears in the sky. You used the location (0°N, 0°E) as your location. You will either need to use the same geographic location in your Swiss Ephemeris calculation, or if the SE calculation is geocentric, you will need to write different code to get the geocentric position of the Moon from Astronomy Engine. Feel free to post more here if you could use help with that part.

ichingsoft commented 4 months ago

Thank you very much for your answer. Yes, the problem is that I didn't figure out the coordinate system of the ecliptic and the equator. Your work is very valuable and your library can run in more environments than Swiss Ephemeris.

As you said, I did also think about the factor of the moon's distance from the earth. So if I want to get more accurate lunar degrees, is there any separate calculation method using Astronomy Engine?

cosinekitty commented 4 months ago

So if I want to get more accurate lunar degrees

It depends on what you are trying to do. Many calendars use geocentric coordinates for the Moon so that it is the best compromise for observers around the world. For example, the time of full moon is usually determined geocentrically.

If you are trying to describe the Moon as a particular observer would see it on or near the Earth's surface, then you should use a topocentric calculation as you did in the code example above. Only you would pass in their actual geographic latitude, longitude, and elevation, not (0, 0, 0).

ichingsoft commented 4 months ago

I found the EclipticGeoMoon function. It does not have latitude and longitude parameters. Is it the geocentric coordinate you said? Look at my code below. Is it correct about geocentric coordinates and the earth's surface?

const Astronomy = require("astronomy-engine");
const date = new Date('2023-01-01T00:00:00Z')

// use geocentric coordinates for the Moon
const moon = Astronomy.EclipticGeoMoon(date);
console.log(moon.lon)
// 33.64854136541663

// observer on earth's surface
const observer = new Astronomy.Observer(38.913611, 77.013222, 0);
const equ_2000 = Astronomy.Equator('Moon', date, observer, false, true);
let ecl = Astronomy.Ecliptic(equ_2000.vec);
console.log(ecl.elon);
// 33.029537778784714