Add the deep-sky backdrop, the last unbuilt piece of the plan
The design doc scopes deep-sky objects as a galaxy-view backdrop and lists fetchDeepSky.ts, deepsky.json and deepsky.model.ts, but none of it existed — it was the only part of the plan with no implementation behind it. ETL: fetchDeepSky.ts pulls the OpenNGC catalog, classifies each object as a galaxy/nebula/cluster, and keeps the ~460 worth drawing (everything Messier, everything with a common name, and anything brighter than magnitude 9) out of ~12,000 mostly-anonymous rows. build.ts runs it and validates the output. Distances are the hard part: OpenNGC has no distance column, and both fallbacks fail for the best-known objects. M31, M33 and M42 are Local Group members whose redshift is negative or absent, and a galaxy's catalog parallax comes from a cross-matched foreground star — 6 mas for M31 would put a 780 kpc galaxy at 167 pc. So records store a unit direction on the celestial sphere rather than a position (the line of sight is always known precisely, and the objects are drawn on a fixed backdrop shell where true distance is unusable anyway), and distance is optional metadata carrying its own provenance. Parallax is trusted only for galactic objects, redshift only above z=0.003 where expansion outweighs peculiar velocity. 330 of 463 get a distance; the rest honestly report none. Rendering: DeepSkyRenderer paints the objects as soft additive billboards on a 2500 pc shell — clear of the 50 pc star field, beyond the camera's 2000 pc orbit limit, and inside its 5000 pc far plane. Size comes from real angular extent, so Andromeda is six times wider than the full Moon, clamped at both ends. Sprites rather than points because the WebGPU backend caps point primitives at one pixel; materials are shared per kind and brightness band, so 460 objects cost nine of them. The brightest dozen get permanent labels, which needed the label overlay to accept string ids alongside numeric star ids. The backdrop is decorative, so a failure to load its dataset is logged and the star field comes up regardless. Also documents the app in the README, which until now covered only the plugin marketplace. Tests: 112 passing, up from 54. Build, both typechecks and the Playwright suite are green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WaySiNst4HhDXBHnMy8p5G
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
/** Broad visual category a deep-sky object is grouped under on the galaxy-view backdrop. */
|
||||
export type DeepSkyKind = 'galaxy' | 'nebula' | 'cluster';
|
||||
|
||||
/** How a record's distance estimate was derived, when one could be derived at all. */
|
||||
export type DeepSkyDistanceMethod = 'parallax' | 'redshift';
|
||||
|
||||
/**
|
||||
* A notable deep-sky object (nebula, star cluster or galaxy) from the OpenNGC catalog,
|
||||
* rendered as the galaxy view's backdrop.
|
||||
*
|
||||
* **Why a direction and not a position.** Every other record in this app carries a Cartesian
|
||||
* position in parsecs, but deep-sky objects deliberately do not. The star field spans 50 pc;
|
||||
* the nearest object here is several hundred parsecs away and the galaxies are millions. At
|
||||
* true scale they would all sit far outside the galaxy camera's far plane, so a position in
|
||||
* parsecs would be unusable for the backdrop it exists to draw.
|
||||
*
|
||||
* More importantly the distances mostly are not knowable from this catalog: OpenNGC publishes
|
||||
* no distance column, so it has to be inferred from redshift or parallax, and that inference
|
||||
* fails for exactly the best-known objects — M31, M33 and M42 are all Local Group members whose
|
||||
* redshift is negative (they are approaching us) or absent. What *is* always known, and known
|
||||
* precisely, is the line of sight. So the position here is a unit vector on the celestial
|
||||
* sphere and {@link distancePc} is optional metadata.
|
||||
*/
|
||||
export interface DeepSkyRecord {
|
||||
/** OpenNGC designation, e.g. `NGC0224`. Stable, and unique within the catalog. */
|
||||
id: string;
|
||||
/** Best available display name: common name, else Messier number, else the designation. */
|
||||
name: string;
|
||||
kind: DeepSkyKind;
|
||||
/**
|
||||
* Unit vector toward the object, in the same equatorial J2000 frame as `StarRecord`
|
||||
* (+X toward the vernal equinox, +Z toward the north celestial pole). Not a position —
|
||||
* see the note on this interface.
|
||||
*/
|
||||
x: number;
|
||||
y: number;
|
||||
z: number;
|
||||
/** Apparent major-axis size on the sky, in degrees. */
|
||||
angularSizeDeg: number;
|
||||
/** Apparent visual magnitude (falling back to blue), or `null` when unphotometered. */
|
||||
magnitude: number | null;
|
||||
/** Estimated distance in parsecs, or `null` when it could not be derived. */
|
||||
distancePc: number | null;
|
||||
/** Provenance for {@link distancePc}; `null` whenever the distance is `null`. */
|
||||
distanceMethod: DeepSkyDistanceMethod | null;
|
||||
/** IAU constellation abbreviation, e.g. `And`. */
|
||||
constellation: string;
|
||||
/** Messier designation, e.g. `M31`, when the object has one. */
|
||||
messier: string | null;
|
||||
}
|
||||
Reference in New Issue
Block a user