#ifndef ORBITAL_MECHANICS_H #define ORBITAL_MECHANICS_H #include "physics.h" static const double PARABOLIC_TOLERANCE = 1e-3; struct OrbitalElements { union { double semi_major_axis; // for elliptical (e<1) and hyperbolic (e>1) double semi_latus_rectum; // for parabolic (e≈1) }; double eccentricity; double true_anomaly; double inclination; double longitude_of_ascending_node; double argument_of_periapsis; }; void orbital_elements_to_cartesian(OrbitalElements elements, double parent_mass, Vec3* out_position, Vec3* out_velocity); OrbitalElements cartesian_to_orbital_elements(Vec3 position, Vec3 velocity, double parent_mass); // Initial guess for Newton-Raphson: M + e·sin(M) + (e²/2)·sin(2M) double get_initial_trial_value(double mean_anomaly, double eccentricity); // Elliptical Kepler equation solver: E - e·sin(E) = M double solve_kepler_elliptical(double mean_anomaly, double eccentricity); // Hyperbolic Kepler equation solver: H - e·sinh(H) = M double solve_kepler_hyperbolic(double mean_anomaly, double eccentricity); // Conversions between anomaly types double eccentric_to_true_anomaly(double eccentric_anomaly, double eccentricity); double hyperbolic_to_true_anomaly(double hyperbolic_anomaly, double eccentricity); // Unified mean anomaly to true anomaly conversion // Automatically dispatches to elliptical or hyperbolic based on eccentricity double mean_anomaly_to_true_anomaly(double mean_anomaly, double eccentricity); // Barker's equation: D + D³/3 = M, where D = tan(ν/2) double solve_barker_equation(double mean_anomaly); OrbitalElements propagate_orbital_elements(const OrbitalElements& elements, double dt, double parent_mass); #endif