From 029162ff52494efebe96eeb5a7c837dec2debe61 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 5 Aug 2026 08:01:19 +0000 Subject: [PATCH] Lower the star halo floor so the inner orbits stay legible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Claude-Session: https://claude.ai/code/session_01WaySiNst4HhDXBHnMy8p5G --- README.md | 4 +- .../galaxy-system/system-framing.spec.ts | 44 ++++++++++++++++--- .../features/galaxy-system/system-framing.ts | 9 +++- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 3bfab13..f31183a 100644 --- a/README.md +++ b/README.md @@ -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 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 -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, with real photography where NASA/ESA/USGS imagery exists, and a surface derived from the body's diff --git a/src/app/features/galaxy-system/system-framing.spec.ts b/src/app/features/galaxy-system/system-framing.spec.ts index e7e9d21..03e7e35 100644 --- a/src/app/features/galaxy-system/system-framing.spec.ts +++ b/src/app/features/galaxy-system/system-framing.spec.ts @@ -114,13 +114,27 @@ describe('systemFramingDistanceAu', () => { }); 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. */ function apparentFraction(innermostAu: number, outermostAu: number, glowScale = 1): number { - const rings = systemGridRingsAu(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. - return starGlowExtentAu(starMarkerRadiusAu(innermostAu), frame, glowScale) / 2 / frame; + return haloRadiusAu(innermostAu, outermostAu, glowScale) / frameRadiusFor(outermostAu); + } + + function apparentPixels(innermostAu: number, outermostAu: number): number { + 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', () => { @@ -142,7 +156,23 @@ describe('starGlowExtentAu', () => { 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 // 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', () => { @@ -154,7 +184,7 @@ describe('starGlowExtentAu', () => { [0.01154, 0.06189], [1.2, 12.4] ]) { - expect(apparentFraction(innermost, outermost)).toBeGreaterThan(0.015); + expect(apparentPixels(innermost, outermost)).toBeGreaterThan(4); } }); diff --git a/src/app/features/galaxy-system/system-framing.ts b/src/app/features/galaxy-system/system-framing.ts index 361a50b..ba85391 100644 --- a/src/app/features/galaxy-system/system-framing.ts +++ b/src/app/features/galaxy-system/system-framing.ts @@ -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 * 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. + * + * 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 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