The span went to `distanceRings` as the target's straight-line distance from the
Sun, but a ring of radius r passes within |r - p| of the view's centre, where p
is how far out that centre is *along* the galactic plane. For a target above the
plane the two differ by its height, so the band was centred on a radius no ring
has — and `ringLabels` picks its bearing by comparing its own in-plane distance
against the innermost ring, a comparison the new first ring quietly broke.
Two comments and a constant, from the same review. A frame short of the survey
edge gets its callout only when its last ring overshoots it: 245 pc does, 235 pc
does not, which is now a test rather than a sentence. The ring count can reach
16, not 14, now that the span need not start at the Sun. And a ring label was
measured as 135 px of star name when "50 pc" is a third of that, which rejected
rungs a hand's breadth clear of the name: RING_LABEL_REACH_NDC, 0.23, is the
widest of them — "1.5 kpc" with "Survey edge" under it.
Three mutants, three caught. Measured again in the app: unchanged for a star in
the plane (4 labels at 20 pc above it, 7 at 2 pc), and the rings now follow the
plane for one 195 pc above it rather than ringing a place the grid does not
reach.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jxMkwA2rbicdGxHosecYi
The rings are centred on the Sun and the frame need not be. Sizing their step
from how far the frame reaches — 210 pc for a star at 190 with the camera 20 pc
back — gives 20 pc rings at 180 and 200, both outside a frame 19 pc deep, so a
view away from the Sun still had no ring on it and no ladder of labels either.
`distanceRings` now takes the span the frame covers rather than its far edge,
and the step is a fifth of that: 5 pc rings from 165 to 210 for the same view.
Measured in the app, centred on a star 187 pc out in the galactic plane: 4 ring
labels drawn 20 pc above the plane and 7 from 2 pc, against 1 and none before.
The clearance was a radius around the anchor, and a label is a line of text
hanging 135 px to one side of its anchor: at 0.065 NDC apart, past the radius,
"50 pc" printed inside "Alpha Centauri". It is now tested against the span the
name occupies, on the side it hangs, with the radius kept for the pair whose
text runs the other way.
Also from the review: the ladder in the clearance test was built at exactly the
constant it tests, so 1057 of 2000 camera poses would have decided it by float
round-trip error — the rungs now sit 0.02 either side of the rule. And two
comments that were wrong: a frame one step short of the survey edge does get its
callout, and CSS2DRenderer hides a label behind the camera rather than drawing
it at the page edge.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jxMkwA2rbicdGxHosecYi
From the review of #19. The rings are distances from the Sun, but their step was taken from
`effectiveDistance`, which under the plan view means the extent of the frame rather than how far
the camera is from the Sun. Centred on a star 200 pc out and flipped to 2D, the grid became rings
of 2 to 20 pc: not one of them on screen. The step now comes from where the view is centred plus
how far the camera is orbiting it, which is the same distance under either projection.
The set was also rebuilt while the grid was hidden, and every rebuild disposes the rings and
builds every vertex again; it now happens only while the grid is drawn.
The ring labels went straight to the overlay: never culled to the frame, and free to land on a
star's name. They now have to be on screen and clear of the names already placed, by half the
separation two names keep — they are a ladder up one ray a twentieth of the screen apart, and
holding them apart from each other would take "Survey edge" off the map.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jxMkwA2rbicdGxHosecYi
The map had one way to read a distance: the Range readout, a number for how
far back the camera is. The local grid's five rings sat at 50 to 250 pc,
fixed and unlabelled. They said nothing from inside a 2 pc hop, and nothing
past 250 pc now that the Hipparcos stars Gaia places there are drawn.
A scale bar now sits under the scale rail. It shows the longest round length
(1, 2 or 5 x 10^n) that fits in 120 px, in AU inside a system and in parsecs
or kiloparsecs outside. It is measured at the depth the view is centred on,
since under perspective every depth has its own scale; under the plan view
it is exact everywhere.
The local grid's rings are now distances from the Sun, at a round step of
about a fifth of the camera's distance and out past the camera: 50 to 350 pc
from the opening view, 2 to 20 pc from twenty parsecs out. Each ring is
labelled with its distance, on the side facing what the view is centred on,
or across the far side of the grid when that is the Sun (the near side is
under the camera and out of frame). The survey edge at 250 pc stays called
out, as "Survey edge", whatever the step.
The rounding lives in one place, scale-bar.ts, shared by the bar and the
rings and tested there. Its formatter keeps three significant digits: one
digit, enough for the bar's round lengths, printed the 250 pc ring as
"300 pc".
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jxMkwA2rbicdGxHosecYi