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
This commit is contained in:
@@ -88,6 +88,54 @@ describe('SystemOrbitsRenderer exoplanet propagation', () => {
|
||||
renderer.dispose();
|
||||
});
|
||||
|
||||
describe('orbits with no published eccentricity', () => {
|
||||
// The archive publishes a semi-major axis far more often than an eccentricity. Requiring
|
||||
// both dropped 1509 otherwise drawable planets.
|
||||
it('draws a planet that has an axis but no eccentricity', () => {
|
||||
const renderer = new SystemOrbitsRenderer([], [exoplanet({ orbit: { semiMajorAxisAu: 0.4 } })]);
|
||||
|
||||
expect(renderer.members).toHaveLength(1);
|
||||
renderer.dispose();
|
||||
});
|
||||
|
||||
it('places it on a circle of the right radius', () => {
|
||||
const renderer = new SystemOrbitsRenderer([], [exoplanet({ orbit: { semiMajorAxisAu: 0.4 } })]);
|
||||
|
||||
for (const offset of [0, 5, 20, 60]) {
|
||||
expect(positionAt(renderer, DEFAULT_EPOCH_JD + offset).length()).toBeCloseTo(0.4, 6);
|
||||
}
|
||||
renderer.dispose();
|
||||
});
|
||||
|
||||
it('still honours the measured period', () => {
|
||||
const renderer = new SystemOrbitsRenderer(
|
||||
[],
|
||||
[exoplanet({ orbit: { semiMajorAxisAu: TRAPPIST_1B_SEMI_MAJOR_AXIS_AU }, periodDays: TRAPPIST_1B_PERIOD_DAYS })]
|
||||
);
|
||||
|
||||
const start = positionAt(renderer, DEFAULT_EPOCH_JD);
|
||||
const afterOnePeriod = positionAt(renderer, DEFAULT_EPOCH_JD + TRAPPIST_1B_PERIOD_DAYS);
|
||||
expect(afterOnePeriod.distanceTo(start)).toBeLessThan(1e-6);
|
||||
renderer.dispose();
|
||||
});
|
||||
});
|
||||
|
||||
it('skips an escape trajectory rather than emitting NaN positions', () => {
|
||||
// e >= 1 is not an ellipse; propagating it anyway yields NaN, which poisons the geometry's
|
||||
// bounding sphere and disables culling for the whole object.
|
||||
const renderer = new SystemOrbitsRenderer([], [exoplanet({ orbit: { semiMajorAxisAu: 1, eccentricity: 1.4 } })]);
|
||||
|
||||
expect(renderer.members).toHaveLength(0);
|
||||
renderer.dispose();
|
||||
});
|
||||
|
||||
it('skips a non-positive semi-major axis', () => {
|
||||
const renderer = new SystemOrbitsRenderer([], [exoplanet({ orbit: { semiMajorAxisAu: 0, eccentricity: 0.1 } })]);
|
||||
|
||||
expect(renderer.members).toHaveLength(0);
|
||||
renderer.dispose();
|
||||
});
|
||||
|
||||
it('keeps every propagated position finite', () => {
|
||||
const renderer = new SystemOrbitsRenderer([], [exoplanet({ periodDays: TRAPPIST_1B_PERIOD_DAYS, orbit: { semiMajorAxisAu: TRAPPIST_1B_SEMI_MAJOR_AXIS_AU, eccentricity: 0.62 } })]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user