- 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
91 lines
2.3 KiB
Python
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,
|
|
)
|