Commit Graph
4 Commits
Author SHA1 Message Date
SenrokaiandClaude Opus 5.5 48319c3fe2 Move the solar system on JPL's mean elements, so it stays right as the clock runs
Every body carried one set of osculating elements from Horizons at 2025-01-01, run forward by
Kepler with a GM from a table of mass ratios. That set is exact at its instant and drifts from
then on, and the clock now runs a month a second: the Moon, with Earth's mass ratio lacking its
own and the osculating axis, went round in 27.70 days instead of 27.32, 66 degrees out after a
year, and its locked face was spun at the same wrong rate.

Planets and Pluto now take Standish's Table 2a/2b ("Keplerian Elements for Approximate
Positions of the Major Planets"): elements against the J2000 ecliptic, their rates per century,
and the b, c, s, f terms of Jupiter to Pluto, fit for 3000 BC to AD 3000. Table 1 is closer near
the present (Saturn 0.23 degrees at worst 1950-2100, against 0.32 here) but is only fit for
1800-2050, and by AD 3000 has Saturn 4.3 degrees out where Table 2 holds every planet within 0.3.
The moons take JPL SSD's satellite mean elements: sidereal mean motion n to ten figures, the
periods of their node and periapsis, and each one's local Laplace plane by its pole. They
propagate with n itself, never a GM: gmForParent and its mass table are gone. Horizons still
gives size, spin and obliquity.

Both tables are read from the Internet Archive's copy of JPL's pages, pinned to one capture: the
live approx_pos page has dropped Pluto, and the live sats/elem page has dropped n and rounds the
period to four or five figures (Phobos 0.3187 d, a revolution out within a decade).

What the tables leave implicit, measured against Horizons before it was accepted:
- The precession periods are magnitudes. A node regresses on a prograde orbit and advances on a
  retrograde one; a periapsis advances except where a resonance forces the eccentricity. Io's
  and Europa's follow their conjunction line backwards at 2 n(Europa) - n(Io) = 0.74 degrees a
  day, which is exactly the 1.625- and 1.394-year periods in the table. Read as advancing, Io
  was 0.9 degrees out and Europa 2.1.
- On a retrograde orbit the node's turning is added back to the mean anomaly. Taken off, Triton
  drifted a degree a year, 105 degrees by 2100.
- The Laplace frame's x axis is where the plane rises through the ICRF equator, RA of the pole
  plus 90. Read against the ecliptic, Io was 2.8 degrees out, Phobos 54 and Titan 127.

Orbit lines are now drawn in their own plane and turned by a quaternion each tick, so a turning
node carries the line with the body: fixed at one date, the Moon's line would be up to 69 000 km
off it nine years on. The Earth row is the Earth-Moon barycentre, 4 700 km from Earth, 0.002
degrees from the Sun. A tidally locked moon's day is now 360 / n, its sidereal period (the Moon
27.321662 d), so it stays locked to the orbit it is drawn on.

Angular error against Horizons VECTORS (ICRF, TDB; heliocentric for planets, planet-centred for
moons), degrees, read from the live renderer's markers in the running app:

body       1950-01-01 1975-01-01 1987-07-23 2000-01-01 2025-01-01 2037-03-06 2050-01-01 2075-01-01 2100-01-01   max
mercury         0.004      0.002      0.003      0.002      0.002      0.001      0.000      0.002      0.000  0.004
venus           0.003      0.007      0.003      0.004      0.004      0.004      0.003      0.004      0.004  0.007
earth           0.003      0.008      0.002      0.005      0.004      0.009      0.003      0.002      0.003  0.009
mars            0.009      0.010      0.008      0.024      0.009      0.012      0.009      0.011      0.028  0.028
jupiter         0.063      0.030      0.171      0.135      0.013      0.020      0.056      0.041      0.075  0.171
saturn          0.080      0.064      0.018      0.320      0.066      0.114      0.044      0.164      0.177  0.320
uranus          0.018      0.169      0.068      0.050      0.101      0.015      0.141      0.017      0.114  0.169
neptune         0.070      0.028      0.004      0.021      0.036      0.037      0.013      0.029      0.072  0.072
pluto           0.045      0.054      0.041      0.033      0.019      0.020      0.023      0.027      0.026  0.054
moon            0.486      1.928      0.127      0.631      1.407      1.086      0.720      0.339      1.180  1.928
phobos          2.068      0.294      0.881      1.113      0.313      0.636      2.089      5.862     11.099 11.099
deimos          0.077      0.043      0.310      0.066      0.164      0.068      0.034      0.468      0.044  0.468
io              0.021      0.015      0.010      0.019      0.009      0.035      0.006      0.011      0.022  0.035
europa          0.036      0.039      0.053      0.064      0.078      0.032      0.006      0.034      0.044  0.078
ganymede        0.132      0.103      0.018      0.007      0.023      0.054      0.091      0.118      0.044  0.132
callisto        0.040      0.019      0.023      0.019      0.038      0.008      0.060      0.119      0.056  0.119
titan           0.003      0.019      0.023      0.023      0.027      0.028      0.048      0.008      0.014  0.048
triton          0.051      0.029      0.009      0.021      0.052      0.048      0.063      0.089      0.137  0.137

Three miss what was hoped for, and why:
- Jupiter 0.17, Saturn 0.32, Uranus 0.17 against the 0.1 hoped for: short-period perturbations
  of the giants by one another, which no Keplerian fit carries. Standish states his own Table 2
  errors as 600, 1 000 and 2 000 arcseconds (0.17, 0.28, 0.56 degrees). Out to AD 3000, measured
  at 1800, 2200, 2400, 2600 and 3000, every planet stays within 0.3.
- The Moon, 1.9: evection (1.27) and variation (0.66), which a mean ellipse leaves out.
- Phobos, 2.1 until 2050, then 5.9 in 2075 and 11.1 in 2100, growing as the square of the time:
  its tidal acceleration, which the table has no column for. Its elements are MAR080's, epoch
  1950. The map's dates are also UTC where the elements are TDB, 69 s today,
  which is 0.9 degrees of Phobos and nothing for anything else.

Held in place by:
- build.ts: each body's mean elements against Horizons' own osculating elements on the ETL's
  2025-01-01, at most 0.25 degrees for a planet and 2.5 for a moon (measured: Uranus 0.101, the
  Moon 1.407; a regressing Triton node reads 10.24 and fails), and every moon's day equal to its
  sidereal period (a 1% error fails).
- Unit tests freezing nine Horizons vectors (Earth 2100, Jupiter 1950, Saturn 2075, Pluto 1975,
  the Moon 2050, Io and Europa 1950, Titan and Triton 2100) through SystemOrbitsRenderer, the
  Moon kept on its own turning line, the retrograde rule, the Standish terms, the Laplace frame,
  and both table parsers. Nine mutants each fail the test named for them, and the two
  validators each refuse a mutated build of the real catalogue.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 20:18:57 +02:00
Claude f241b093eb Draw the 1509 exoplanets that were being silently dropped
The system renderer required both a semi-major axis and an eccentricity before
it would place an exoplanet, even though resolveOrbitalElements already defaults
every other missing element. The archive publishes an axis far more often than
an eccentricity: 3895 records have one and only 2386 have both, so 1509 planets
were dropped for want of a value that can simply be assumed.

A missing eccentricity now defaults to 0, a circle. That is the conventional
assumption for an orbit whose shape has not been constrained, and it is the only
honest option available, since the axis alone says nothing about elongation.

The effect is not subtle. 18 systems gain planets, and seven of them previously
rendered as a bare star with nothing around it at all: Gl 357 goes from zero
planets to three, HD 176986 likewise. Beyond the effect today, a user could
already reach one of these planets through search and its detail page, then jump
to its system and find it missing from the very system it belongs to.

isPropagatableOrbit replaces the old inline guard and also rejects what the old
one never checked: a non-positive axis, and an eccentricity of 1 or more. Those
are escape trajectories that no ellipse describes, and propagating them anyway
does not throw — it yields NaN, which reaches the vertex buffer and poisons the
geometry's bounding sphere, disabling culling for the whole object rather than
just the bad orbit. Being a type guard, it also lets the caller drop a seven-line
field-by-field copy of the orbit.

Fixes a label leak found while verifying this in the browser. Galaxy star labels
were being cleared on entering system space but immediately recomputed, because
the tick gated them on `currentStarId`, which is not assigned until the arrival
flight finishes a second later — so parsec-scale names sat pinned over the
system. Both label and orbit updates now gate on which group is actually visible,
which is true throughout the transition rather than only at the end of it.

Tests: 185 passing, up from 171. Verified in a real browser: GJ 1151 draws the
orbit and marker it gained, and no labels survive into the system view.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WaySiNst4HhDXBHnMy8p5G
2026-08-04 11:31:59 +00:00
Claude 8d8c65bdb2 Propagate exoplanets with their real orbital period
Every exoplanet was propagated with gmForParent(undefined) — the Sun's
gravitational parameter — so the whole catalogue orbited as though each host
were exactly one solar mass. Most hosts are red dwarfs far lighter than that,
and a heavier central mass pulls harder and shortens the period, so their
planets were whirling round much too fast: TRAPPIST-1 is 0.09 solar masses, and
its planets were completing an orbit in roughly a third of the true time.

pl_orbper was already in the TAP query and was being discarded on the way into
the record. It is now kept, along with st_mass. A period and a semi-major axis
together pin the host's gravitational parameter exactly, via GM = n^2 a^3 — no
stellar model, no assumption, just the inverse of the orbitalPeriodDays helper
that was already there.

resolveGravitationalParameter picks the best available source: the measured
period, else the published host mass, else one solar mass as before. A derived
value implying something outside 0.01-150 solar masses is rejected and falls
through, since a period and axis taken from disagreeing solutions would
otherwise send a planet spinning at a visibly absurd rate.

Note the direction of the error, which is the opposite of what it looks like:
assuming a *heavier* host than reality makes a planet orbit *faster*. A test
pins it, and caught me stating it backwards first.

The NASA Exoplanet Archive is unreachable from this environment (egress policy
returns 403 on CONNECT), so exoplanets.json cannot be regenerated here and still
carries no periods. Behaviour is therefore unchanged until `npm run etl` is run
somewhere with archive access, at which point every planet with a published
period starts moving correctly with no further code changes. build.ts reports
how many records gained a period, and rejects non-positive ones.

Tests: 171 passing, up from 151, including a new end-to-end check that
TRAPPIST-1 b with its real period completes exactly one orbit in 1.51088 days
and sits a full diameter away at half that.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WaySiNst4HhDXBHnMy8p5G
2026-08-04 11:19:45 +00:00
Senrokai d7e8ea1d4d @
Add star-map Angular app, ETL pipeline, and caveman plugin

Angular 3D star map (galaxy/system/body views, Three.js rendering,
navigation store) plus the NASA ETL tooling that builds the star,
exoplanet and solar-system datasets, Playwright e2e suite, and the
cs:caveman Claude Code plugin (command, agent, skill).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@
2026-08-03 16:50:10 +02:00