Skip to content

Introduce Center, Body and Position domain objects#270

Merged
rhannequin merged 3 commits into
mainfrom
center-position-domain-objects
Jun 6, 2026
Merged

Introduce Center, Body and Position domain objects#270
rhannequin merged 3 commits into
mainfrom
center-position-domain-objects

Conversation

@rhannequin
Copy link
Copy Markdown
Owner

Summary

This PR improves three existing concepts in model, turning incidental behaviour into a guaranteed, documented contract:

  • Astronoby::Center: a value object replacing the ad-hoc center_identifier union on reference frames.
  • Astronoby::Body: a role for a catalog definition that can position itself at an instant.
  • Astronoby::Position: a role for a target resolved at an instant, yielding the reference frame chain.

Motivation

Two concepts leaked through the otherwise clean value-object design.

First, the centre of a frame was a primitive union. Frames carried center_identifier, an Integer (SolarSystemBody::EARTH / SOLAR_SYSTEM_BARYCENTER) for barycentric/geocentric frames or an [longitude, latitude] array for topocentric frames.

Second, "an observable target" was implicit. SolarSystemBody and DeepSkyObjectPosition both produced the frame chain but shared no abstraction, so cross-type operations worked only by coincidence.

Changes

Center value object

  • New Astronoby::Center with barycentric / geocentric (memoized singletons) and topocentric(observer) constructors, plus #barycentric?, #geocentric?, #topocentric?, #observer_dependent? and #observer.
  • Two topocentric centres are equal when their observers share the same latitude, longitude and elevation. Atmospheric parameters (temperature, pressure) are intentionally ignored, since they do not affect the geometric centre.
  • ReferenceFrame#separation_from now compares frames with center == other.center.
  • All frame builders (Geometric, Astrometric, MeanOfDate, Apparent, Topocentric, Teme) and DeepSkyObjectPosition updated accordingly.

Body role

  • New marker module Astronoby::Body for a definition that responds to at(instant, ephem:) and returns a Position.
  • SolarSystemBody extends it (the body classes themselves are Bodys); DeepSkyObject includes it (instances are Bodys).

Position role

  • New module Astronoby::Position, included by SolarSystemBody and DeepSkyObjectPosition, holding the shared observed_by implementation (previously duplicated in both classes).

target_body made consistent

  • ReferenceFrame#target_body is now always a Body: solar system body frames carry the class, deep-sky object frames carry the DeepSkyObject definition (threaded into DeepSkyObjectPosition).
  • LightTimeDelay is unchanged. It reads target_body.geometric(ephem:, instant:) only off Geometric frames, which already carried the class. What used to be an implicit reliance is now a documented role contract.

Breaking changes

  • ReferenceFrame#center_identifier is replaced by #center, which returns an Astronoby::Center instead of an Integer/Array. See UPGRADING.md.
  • ReferenceFrame#target_body is now consistently an Astronoby::Body (previously a class or an instance depending on the frame).
# Before
frame.center_identifier # => 399 or [longitude, latitude]

# After
frame.center                                  # => #<Astronoby::Center ...>
frame.center.geocentric?                      # => true
frame.center == Astronoby::Center.geocentric  # => true
frame.center.observer                         # => the Observer, for topocentric frames

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces three new domain abstractions—Astronoby::Center, Astronoby::Body, and Astronoby::Position—to formalize previously incidental contracts around reference-frame centers and “targets resolved at an instant”. It refactors the reference frame chain to use Center instead of the center_identifier union, and standardizes how frames expose their target_body across solar-system and deep-sky targets.

Changes:

  • Replace ReferenceFrame#center_identifier with #center returning a new Astronoby::Center value object, and update all frame builders accordingly.
  • Introduce Astronoby::Body (marker role) and Astronoby::Position (shared observed_by behavior), wiring them into solar-system bodies and deep-sky objects/positions.
  • Update specs and documentation (UPGRADING.md, reference frame docs, glossary) to reflect the new contracts.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
UPGRADING.md Documents the breaking change from center_identifier to center and Astronoby::Center semantics.
docs/reference_frames.md Adds #center to the documented reference-frame interface.
docs/glossary.md Defines the new “Body”, “Centre/Center”, and “Position” concepts for user-facing docs.
lib/astronoby.rb Requires the new center, body, and position definitions.
lib/astronoby/center.rb Adds the Astronoby::Center value object (barycentric/geocentric/topocentric).
lib/astronoby/body.rb Adds the Astronoby::Body marker module.
lib/astronoby/position.rb Adds the Astronoby::Position role with shared observed_by implementation.
lib/astronoby/reference_frame.rb Swaps center_identifier for center and compares centers via value semantics in separation_from.
lib/astronoby/reference_frames/topocentric.rb Threads Center.topocentric(observer) through the Topocentric frame construction and initializer.
lib/astronoby/reference_frames/teme.rb Migrates TEME frames to use Center (geocentric/topocentric) instead of center_identifier.
lib/astronoby/reference_frames/mean_of_date.rb Migrates MeanOfDate builder to use Center.geocentric.
lib/astronoby/reference_frames/geometric.rb Migrates Geometric frame to use Center.barycentric.
lib/astronoby/reference_frames/astrometric.rb Migrates Astrometric builder to use Center.geocentric.
lib/astronoby/reference_frames/apparent.rb Migrates Apparent builder to use Center.geocentric.
lib/astronoby/bodies/solar_system_body.rb Makes solar-system body instances Position, body classes Body, and threads target_body as the body definition.
lib/astronoby/bodies/deep_sky_object.rb Makes DeepSkyObject instances fulfill Body and threads the definition into DeepSkyObjectPosition.
lib/astronoby/bodies/deep_sky_object_position.rb Makes deep-sky positions fulfill Position and changes frames to carry the body definition as target_body.
spec/astronoby/reference_frames/teme_spec.rb Updates expectations to assert center == Astronoby::Center.geocentric.
spec/astronoby/reference_frames/mean_of_date_spec.rb Updates argument expectations from center_identifier: to center:.
spec/astronoby/reference_frames/astrometric_spec.rb Updates argument expectations from center_identifier: to center:.
spec/astronoby/reference_frame_spec.rb Adds a comparison test asserting differing-elevation observers yield incompatible centers.
spec/astronoby/position_spec.rb Adds tests for the Position role and target_body being a Body throughout the chain.
spec/astronoby/center_spec.rb Adds tests for Center constructors, equality, and hashing semantics.
spec/astronoby/body_spec.rb Adds tests asserting solar-system body classes and deep-sky objects fulfill Body.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/astronoby/reference_frame.rb Outdated
Comment thread lib/astronoby/reference_frame.rb
Comment thread lib/astronoby/bodies/deep_sky_object_position.rb
Comment thread lib/astronoby/bodies/deep_sky_object_position.rb
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated 2 comments.

Comment thread lib/astronoby/center.rb
Comment thread lib/astronoby/bodies/deep_sky_object_position.rb
@rhannequin rhannequin merged commit 24eded7 into main Jun 6, 2026
28 checks passed
@rhannequin rhannequin deleted the center-position-domain-objects branch June 6, 2026 21:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants