Turn every body in the system view by its IAU pole and prime meridian, so the lit face is the real one

Until now each body's axis was its orbit normal, tipped by the obliquity about the orbit's node,
an azimuth the data never gave. Its phase started at an arbitrary point at the elements' epoch.
The rate and the sense were real; the face towards the Sun was not. Now each of the 33 bodies with
IAU elements is set, every tick, from its pole and its W at the clock's date. Eris, Haumea and
Makemake keep the old fallback: their published period, about their orbit normal. None of them
has an obliquity, so the tilt code that only served bodies now turned by the IAU is gone.
Exoplanets have no rotation published and stay still, as before.

The texture convention is settled once, in src/app/shared/rendering/body-orientation.ts (MAP_TO_BODY):
- SphereGeometry runs u eastward about +Y from a seam on -X, so u = 0.5 faces +X.
- Every photograph in the catalogue is centred on longitude 0 with east to the right. Checked on
  the maps: Greenwich; Olympus Mons 134 degrees left of centre; Mare Crisium right and Mare
  Orientale left; Kuiper just left.
- A map labelled in west longitude is still drawn east-right, so where longitude 0 sits is the
  only question, and for all of them it is the centre.
- So a quarter turn about X puts the map on the IAU body frame: pole +Z, prime meridian +X.

The scene is already ICRF equatorial (the ecliptic is turned into it by the J2000 obliquity), so
the pole goes in as it is. The equator frame is built through laplacePlaneToEquatorial, the same
conversion the moons' Laplace planes use; moonFrame now calls it too. The clock is UTC and the
elements TDB, so TT - UTC (69.184 s) is added: Earth turns 0.29 degrees in that time, Jupiter 0.70
and Phobos 0.90.

Measured on the live app (port 4311), clock pinned to 2025-06-01 12:00 UTC:
- The Sun stands over 0.433 W, 22.125 N on Earth's drawn sphere. The equation of time puts it at
  0.53 W.
- Each body was drawn one light-time earlier and compared with Horizons' observer quantities 14
  and 15:
  - Earth (from the Sun): longitude 0.095 off.
  - Mars: sub-Earth 0.001, sub-solar 0.004.
  - Jupiter: sub-Earth 0.005, sub-solar 0.002.
  - The Moon: sub-solar 0.004; sub-Earth 0.699, which is the error of its mean orbit.
- Horizons' latitudes are planetodetic. Raw, they differ by the flattening: Earth 0.14, Mars
  0.23-0.27, Jupiter 0.33, the Moon (a sphere) 0.000.

The unit tests put the same comparison through real raycasts on the drawn spheres' texture
coordinates, with the latitudes put on each body's flattened figure. Every residual is within
0.09 degrees, but for the Moon's sub-Earth point (0.70 and 0.09).

The retrograde tests of #33 are rewritten for the IAU's convention: a planet's named pole is
the one on the north side, so W runs backwards for Venus and Uranus, while Pluto follows the
right-hand rule. The spin read off the drawn sphere, against the drawn orbit's normal, is 177.36
for Venus, 97.77 for Uranus and 119.61 for Pluto, all past 90, and 23.44 for Earth. Each is
within 0.5 of Horizons.

Six mutants, each failing its named test: the map upside down; UTC taken for TDB (Jupiter's
test); W turned the wrong way (the retrograde test, and again Earth's noon test); moons, or
planets, not turned by the IAU; and the fallback ignoring a negative period.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-24 22:48:05 +02:00
co-authored by Claude Opus 5.5
parent 1c86584642
commit cdf474bcd5
4 changed files with 211 additions and 64 deletions
+8
View File
@@ -19,6 +19,14 @@ export const DEFAULT_EPOCH_JD = 2451545.0;
*/
export const GM_SUN_AU3_PER_DAY2 = 0.01720209895 * 0.01720209895;
/**
* TT - UTC, in days: 32.184 s plus the 37 leap seconds UTC has taken since 1972, the last at the
* end of 2016. TDB, which ephemerides run on, stays within 2 ms of TT. Held constant, as Horizons
* holds it for dates past the last announced leap second; before 2017 it was smaller, about 29 s
* in 1950.
*/
export const TT_MINUS_UTC_DAYS = 69.184 / 86400;
/** Converts a JS `Date` into a Julian date (days), for driving the Kepler propagator "now". */
export function dateToJulianDate(date: Date = new Date()): number {
return date.getTime() / 86400000 + 2440587.5;