Files
suaveplan/packages/geospatial/geo/universe/src/frames/frames.md
2026-05-27 23:47:53 +01:00

3.9 KiB

Coordinate Frames

(no submodules)

Purpose

Defines the CoordinateFrame discriminator ("heliocentric" | "galactic" | "custom") and the conversion entry points used across the universe-family packages. The module is the single seam through which any astronomical coordinate transformation is requested, so consumers do not need to know which rotation matrix or epoch correction is in play — they hand off a SphericalCoord, name the source and target frames, and receive a SphericalCoord in the new frame.

The current implementation is a placeholder identity transform: convertFrame, toHeliocentric, and toGalactic return the input unchanged. The public surface and discriminator are stable; consumers can wire to it now and pick up real conversions when this package adds the rotation pipeline without touching any call site.

Features

  • CoordinateFrame string-literal union — exhaustively switchable.
  • convertFrame(coord, from, to, observer?) — generic frame-to-frame conversion entry point.
  • toHeliocentric(coord, observer) — convenience wrapper for the most common conversion (observer-relative to heliocentric).
  • toGalactic(coord) — observer-independent rotation into galactic coordinates.
  • Identity short-circuit when from === to.
  • Observer parameter accepts the full ObserverPosition discriminated union (surface / atmospheric / space).

Usage: Basic Example

import { convertFrame } from "@suaveplan/universe";

const coord = { latitude: 10, longitude: 20 };
const same = convertFrame(coord, "heliocentric", "heliocentric");
// same === coord (identity short-circuit)

Usage: Advanced Example

import {
    convertFrame,
    toGalactic,
    toHeliocentric,
    type CoordinateFrame,
} from "@suaveplan/universe";

const target: CoordinateFrame = "galactic";
const observer = {
    kind: "surface" as const,
    planet: {
        name: "Earth",
        mass: 1,
        radius: 1,
        polarRadius: 1,
        surfaceGravity: 1,
        rotationPeriod: 1,
        axialTilt: 23.4,
        atmosphere: null,
        satellites: [],
    },
    coord: { latitude: 51.5, longitude: -0.12 },
};

const skyDirection = { latitude: 45, longitude: 270 };
const heliocentric = toHeliocentric(skyDirection, observer);
const galactic = toGalactic(heliocentric);
const fromHelio = convertFrame(skyDirection, "heliocentric", target, observer);

API Reference

type CoordinateFrame

"heliocentric" | "galactic" | "custom" — string-literal union safe to switch on with exhaustiveness checking.

convertFrame(coord, from, to, observer?)

Param Type Description
coord SphericalCoord Latitude/longitude pair in source frame.
from CoordinateFrame Source frame.
to CoordinateFrame Target frame.
observer ObserverPosition? Required for any observer-dependent conversion (e.g. topocentric → heliocentric).

Returns a SphericalCoord in the target frame. Returns coord unchanged when from === to.

toHeliocentric(coord, observer)

Convenience wrapper that conceptually corresponds to convertFrame(coord, observer-frame, "heliocentric", observer).

toGalactic(coord)

Observer-independent rotation from equatorial / heliocentric into galactic coordinates.

Implementation Notes

The body of every function is currently the identity, which keeps the API contract stable while the rotation matrices (J2000 → galactic, ICRS → heliocentric ecliptic, axial-tilt / sidereal-time corrections) are implemented in follow-up changes. Consumers should treat "custom" as an extension point — any future conversion that requires caller-supplied basis vectors is expected to flow through convertFrame(..., "custom", ...). Do not bake the identity behaviour into call sites: the contract is "returns the coordinate in the target frame," not "returns the coordinate unchanged."