Leave a system outwards from wherever the camera stands, and test that the scene frames the furthest it draws

Leaving a system flew the camera to a fixed 400 AU. Since c45d916 frames the Sun's system on Eris's
97.7 AU aphelion, a phone held upright arrives 508 AU out, so leaving drew the system 21 per cent
nearer during the 0.9 s exit (review, 390x844: 507.9 -> 400.0 AU). The exit now flies to 400 AU or
half as far again as the camera already stands, whichever is further. Measured live on :4301, the
distance from the Sun through the exit, first and last frame:

  390x844    507.9 -> 761.8 AU   (was 507.9 -> 400.0)
  360x780    508.5 -> 762.7
  768x1024   312.9 -> 469.3      (was 312.9 -> 400)
  1600x1000  234.7 -> 400.0      (unchanged)

and never nearer in between. The swap puts the camera at GALAXY_APPROACH_DISTANCE_PC whatever the
exit distance, so only the animation changes.

No test checked that the scene hands outermostRadiusAu to the framing: framing on the 67.9 AU
semi-major axis instead, which on a square window puts Eris off screen on arrival, passed all 841
tests. The scene spec's fixture held Earth alone. A describe now adds Eris (a = 67.934, e = 0.4382):
- "frames the furthest the system draws" requires the settled camera to stand at
  systemFramingDistanceAu(outermostRadiusAu) from its target, 234.7 AU at aspect 1.
- "leaves the system outwards even from a phone's framing" enters at aspect 390/844, then samples the
  camera each frame of the exit until the swap: never nearer, and further at the end.

Controls, each run on the full suite:
- outermostRadiusAu -> maxTopLevelSemiMajorAxisAu in the scene fails both (2 failed, 842 passed);
  the second fails too because the arrival is then under 500 AU.
- Math.max -> Math.min in the exit (back to 400 AU) fails the exit test only (1 failed, 843 passed).

The framing spec's fit() said it was "what the scene actually composes"; it frames the ring only, so
its comment now says it is the grid's half and where the aphelion is tested.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-29 23:17:00 +02:00
co-authored by Claude Opus 5.5
parent f6bb2b9584
commit 936d1c01f8
3 changed files with 66 additions and 3 deletions
@@ -289,8 +289,13 @@ const SYSTEM_MIN_DISTANCE_AU = 0.05;
const SYSTEM_MAX_DISTANCE_AU = 5000;
/** Where the camera lands (AU) immediately after swapping into system space, pre-settle. */
const SYSTEM_ENTRY_DISTANCE_AU = 200;
/** How far out (AU) the camera flies before swapping back to galaxy/parsec space. */
/**
* How far out (AU) the camera flies, at least, before swapping back to galaxy/parsec space. A camera
* already beyond it flies half as far again: a phone held upright frames the Sun's system from 508 AU,
* and flying to 400 drew the system 21 per cent nearer while the reader was leaving it.
*/
const SYSTEM_EXIT_DISTANCE_AU = 400;
const SYSTEM_EXIT_PULL_BACK = 1.5;
const APPROACH_DURATION_SECONDS = 1.0;
const SETTLE_DURATION_SECONDS = 0.9;
@@ -2321,7 +2326,7 @@ export class GalaxySystemSceneComponent implements AfterViewInit, OnDestroy {
this.rig.flyTo(
{
position: direction.clone().multiplyScalar(SYSTEM_EXIT_DISTANCE_AU),
position: direction.clone().multiplyScalar(Math.max(SYSTEM_EXIT_DISTANCE_AU, SYSTEM_EXIT_PULL_BACK * camera.position.length())),
target: new THREE.Vector3(0, 0, 0),
},
EXIT_DURATION_SECONDS,