Lower the star halo floor so the inner orbits stay legible

The floor that stopped the Sun disappearing reached past Venus and up to
Earth, covering the two orbits it most needed to leave alone.

Halved, from 3.5% of the framed radius to 2%. The halo's visual radius is
half its extent, so that puts its edge at 1% of the framed radius, and the
orbits it has to clear sit at their own fraction of the same radius: in
the solar system, framed to hold Pluto, Venus is at 1.3% and Earth at
1.8%. Both are now outside it, and the star still reads at about nine
pixels across on a typical window.

Mercury, at 0.7%, is still inside — and would be at any halo large enough
to see, since its orbit is only three pixels wide at that range. That is
now a pinned test rather than an oversight.

The floor was only ever the lower bound; the tests now state the upper one
too, in the terms the trade is actually made in — pixels on screen for
visibility, AU against real orbits for clearance.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WaySiNst4HhDXBHnMy8p5G
This commit is contained in:
Claude
2026-08-05 08:01:19 +00:00
parent be19d9cbcc
commit 029162ff52
3 changed files with 48 additions and 9 deletions
+3 -1
View File
@@ -56,7 +56,9 @@ system those differ by a factor of a hundred. At the distance that fits Pluto in
that stays clear of Mercury is about a pixel across, and no radius satisfies both. So the disc that stays clear of Mercury is about a pixel across, and no radius satisfies both. So the disc
stays honest to the orbits and the star's halo carries its visibility, floored against the framed stays honest to the orbits and the star's halo carries its visibility, floored against the framed
radius: light is not a surface, and a glow reaching past the innermost orbit says the star is radius: light is not a surface, and a glow reaching past the innermost orbit says the star is
bright rather than that it is large. bright rather than that it is large. That floor is bounded from both sides — large enough that
the star reads at a glance, small enough that Venus's and Earth's orbits stay legible as rings
around it. Mercury's, three pixels wide at that range, does not survive either way.
**Body detail** — a dedicated close-up scene and info panel for one planet, moon or exoplanet, **Body detail** — a dedicated close-up scene and info panel for one planet, moon or exoplanet,
with real photography where NASA/ESA/USGS imagery exists, and a surface derived from the body's with real photography where NASA/ESA/USGS imagery exists, and a surface derived from the body's
@@ -114,13 +114,27 @@ describe('systemFramingDistanceAu', () => {
}); });
describe('starGlowExtentAu', () => { describe('starGlowExtentAu', () => {
/** A typical viewport, so a screen-space claim can be made in pixels rather than in ratios. */
const REFERENCE_VIEWPORT_HALF_HEIGHT_PX = 450;
/** The halo's visual radius, in AU, at the distance this system is framed from. */
function haloRadiusAu(innermostAu: number, outermostAu: number, glowScale = 1): number {
// The sprite's extent is its full width, so half of it is what reaches out from the star.
return starGlowExtentAu(starMarkerRadiusAu(innermostAu), frameRadiusFor(outermostAu), glowScale) / 2;
}
function frameRadiusFor(outermostAu: number): number {
const rings = systemGridRingsAu(outermostAu);
return systemFrameRadiusAu(systemFramingDistanceAu(rings[rings.length - 1]));
}
/** Apparent size on screen, as a fraction of the frame's half-height. */ /** Apparent size on screen, as a fraction of the frame's half-height. */
function apparentFraction(innermostAu: number, outermostAu: number, glowScale = 1): number { function apparentFraction(innermostAu: number, outermostAu: number, glowScale = 1): number {
const rings = systemGridRingsAu(outermostAu); return haloRadiusAu(innermostAu, outermostAu, glowScale) / frameRadiusFor(outermostAu);
const distance = systemFramingDistanceAu(rings[rings.length - 1]); }
const frame = systemFrameRadiusAu(distance);
// The sprite's extent is its full width, so half of it is what reaches out from the star. function apparentPixels(innermostAu: number, outermostAu: number): number {
return starGlowExtentAu(starMarkerRadiusAu(innermostAu), frame, glowScale) / 2 / frame; return apparentFraction(innermostAu, outermostAu) * REFERENCE_VIEWPORT_HALF_HEIGHT_PX;
} }
it('scales with the star for a compact system, where the star is already big enough', () => { it('scales with the star for a compact system, where the star is already big enough', () => {
@@ -142,7 +156,23 @@ describe('starGlowExtentAu', () => {
it('keeps the Sun visible at the distance that frames the solar system', () => { it('keeps the Sun visible at the distance that frames the solar system', () => {
// The case that prompted this: the solar system spans a factor of a hundred from Mercury to // The case that prompted this: the solar system spans a factor of a hundred from Mercury to
// Pluto, so a disc that stays clear of Mercury is about a pixel across once Pluto is in view. // Pluto, so a disc that stays clear of Mercury is about a pixel across once Pluto is in view.
expect(apparentFraction(0.387, 39.288)).toBeGreaterThan(0.015); expect(apparentPixels(0.387, 39.288)).toBeGreaterThan(4);
});
it('leaves the inner orbits clear of the halo', () => {
// The other half of the same trade. Venus and Earth have to stay legible as rings around the
// star, which bounds the halo from above just as visibility bounds it from below.
const halo = haloRadiusAu(0.387, 39.288);
const VENUS_AU = 0.723;
const EARTH_AU = 1;
expect(halo).toBeLessThan(VENUS_AU);
expect(halo).toBeLessThan(EARTH_AU);
});
it('cannot clear Mercury as well, and does not pretend to', () => {
// Mercury's orbit is 0.7% of the framed radius — about three pixels — so it is inside any
// halo big enough to see. Pinned so the trade is a decision rather than an oversight.
expect(haloRadiusAu(0.387, 39.288)).toBeGreaterThan(0.387);
}); });
it('holds the floor across every system scale the datasets contain', () => { it('holds the floor across every system scale the datasets contain', () => {
@@ -154,7 +184,7 @@ describe('starGlowExtentAu', () => {
[0.01154, 0.06189], [0.01154, 0.06189],
[1.2, 12.4] [1.2, 12.4]
]) { ]) {
expect(apparentFraction(innermost, outermost)).toBeGreaterThan(0.015); expect(apparentPixels(innermost, outermost)).toBeGreaterThan(4);
} }
}); });
@@ -41,9 +41,16 @@ const STAR_RADIUS_TO_INNERMOST_ORBIT = 0.45;
* The halo resolves it, because light is not a surface: a glow that reaches past the innermost * The halo resolves it, because light is not a surface: a glow that reaches past the innermost
* orbit does not claim the star is that large, it claims the star is bright. So the disc stays * orbit does not claim the star is that large, it claims the star is bright. So the disc stays
* honest to the orbits and the halo is floored against the frame. * honest to the orbits and the halo is floored against the frame.
*
* The floor is set by what it must not cover. Its visual radius is half the extent, so a floor
* of `f` puts the halo's edge at `f / 2` of the frame radius — and the orbits it has to leave
* legible sit at their own fraction of that same radius. In the solar system, framed to hold
* Pluto, Venus's orbit is at 1.3% of the frame radius and Earth's at 1.8%, so a floor of 2%
* leaves both of them outside the halo. Mercury's, at 0.7%, is inside it — and would be at any
* halo large enough to see, since the orbit itself is only a few pixels wide there.
*/ */
const STAR_GLOW_TO_MARKER = 3.2; const STAR_GLOW_TO_MARKER = 3.2;
const MIN_STAR_GLOW_TO_FRAME = 0.035; const MIN_STAR_GLOW_TO_FRAME = 0.02;
/** /**
* Clear space left around the framed radius, as a fraction of it. The camera backs off this * Clear space left around the framed radius, as a fraction of it. The camera backs off this