Files
orbital-test/frame_transition.py
Lucy 655f1c9af6 Initial commit: Keplerian orbital mechanics with patched-conics SOI transitions
- orbital_elements.py: elliptical + hyperbolic orbit support
- orbit_drawer.py: orbit point generation with SOI truncation
- soi_calculator.py: SOI crossing time calculator
- frame_transition.py: reference frame switching
- test_orbital.py: 147 assertions, all passing
- visual_test.py: pygame flyby visualization
2026-05-21 20:31:17 +02:00

91 lines
2.3 KiB
Python

"""
Reference-frame transitions for patched-conics SOI handling.
When a body enters a planet's sphere of influence its orbital
elements must be re-expressed relative to the planet. On exit
the reverse transition occurs.
"""
from typing import Tuple
from orbital_elements import OrbitalElements, orbital_elements_from_cartesian
def sun_state_to_planet_orbit(
body_x: float,
body_y: float,
body_vx: float,
body_vy: float,
planet_x: float,
planet_y: float,
planet_vx: float,
planet_vy: float,
mu_planet: float,
epoch: float,
) -> OrbitalElements:
"""
Convert a body's sun-frame state to a planet-relative orbit.
Parameters
----------
body_* — body position & velocity in sun frame
planet_* — planet position & velocity in sun frame
mu_planet — planet's gravitational parameter
epoch — time of transition
Returns
-------
OrbitalElements describing the body's trajectory around the planet.
"""
x_rel = body_x - planet_x
y_rel = body_y - planet_y
vx_rel = body_vx - planet_vx
vy_rel = body_vy - planet_vy
return orbital_elements_from_cartesian(
x_rel, y_rel, vx_rel, vy_rel, mu_planet, epoch,
)
def planet_orbit_to_sun_state(
orbit_planet: OrbitalElements,
planet_x: float,
planet_y: float,
planet_vx: float,
planet_vy: float,
t: float,
) -> Tuple[float, float, float, float]:
"""
Convert a planet-relative orbit back to sun-frame state at time t.
Returns (x, y, vx, vy) in sun frame.
"""
x_rel, y_rel, vx_rel, vy_rel = orbit_planet.compute_state_at(t)
return (
x_rel + planet_x,
y_rel + planet_y,
vx_rel + planet_vx,
vy_rel + planet_vy,
)
def planet_orbit_to_sun_orbit(
orbit_planet: OrbitalElements,
planet_x: float,
planet_y: float,
planet_vx: float,
planet_vy: float,
mu_sun: float,
t: float,
) -> OrbitalElements:
"""
Full round-trip: planet-relative orbit → sun-frame orbital elements.
Used after SOI exit to put the body back into a heliocentric orbit.
"""
x_sun, y_sun, vx_sun, vy_sun = planet_orbit_to_sun_state(
orbit_planet, planet_x, planet_y, planet_vx, planet_vy, t,
)
return orbital_elements_from_cartesian(
x_sun, y_sun, vx_sun, vy_sun, mu_sun, t,
)