Browse Source
- Add OrbitalElements struct with Keplerian elements - Implement orbital_elements_to_cartesian() for all orbit types - Handle circular, elliptical, parabolic, and hyperbolic orbits - Support planar orbits (3D orientation deferred) - Update planning documentmain
3 changed files with 92 additions and 5 deletions
@ -0,0 +1,69 @@
|
||||
#include "orbital_mechanics.h" |
||||
#include <cmath> |
||||
#include <cassert> |
||||
|
||||
void orbital_elements_to_cartesian(OrbitalElements elements, double parent_mass, |
||||
Vec3* out_position, Vec3* out_velocity) { |
||||
double a = elements.semi_major_axis; |
||||
double e = elements.eccentricity; |
||||
double nu = elements.true_anomaly; |
||||
|
||||
double mu = G * parent_mass; |
||||
|
||||
double r, v_mag; |
||||
|
||||
if (fabs(e) < 1e-10) { |
||||
r = a; |
||||
v_mag = sqrt(mu / a); |
||||
} else if (e < 1.0) { |
||||
r = a * (1.0 - e * e) / (1.0 + e * cos(nu)); |
||||
v_mag = sqrt(mu * (2.0 / r - 1.0 / a)); |
||||
} else if (fabs(e - 1.0) < 1e-10) { |
||||
r = 2.0 * a / (1.0 + cos(nu)); |
||||
v_mag = sqrt(2.0 * mu / r); |
||||
} else { |
||||
r = a * (1.0 - e * e) / (1.0 + e * cos(nu)); |
||||
v_mag = sqrt(mu * (2.0 / r - 1.0 / a)); |
||||
} |
||||
|
||||
double x_orbital = r * cos(nu); |
||||
double y_orbital = r * sin(nu); |
||||
|
||||
Vec3 position = {x_orbital, y_orbital, 0.0}; |
||||
|
||||
double sin_nu = sin(nu); |
||||
double cos_nu = cos(nu); |
||||
|
||||
double vx_orbital, vy_orbital; |
||||
|
||||
if (fabs(e) < 1e-10) { |
||||
vx_orbital = 0.0; |
||||
vy_orbital = v_mag; |
||||
} else if (e < 1.0) { |
||||
double p = a * (1.0 - e * e); |
||||
double h = sqrt(mu * p); |
||||
vx_orbital = -sqrt(mu / p) * sin_nu; |
||||
vy_orbital = sqrt(mu / p) * (e + cos_nu); |
||||
vx_orbital *= h; |
||||
vy_orbital *= h; |
||||
} else if (fabs(e - 1.0) < 1e-10) { |
||||
double p = 2.0 * a; |
||||
double h = sqrt(mu * p); |
||||
vx_orbital = -sqrt(mu / p) * sin_nu; |
||||
vy_orbital = sqrt(mu / p) * (1.0 + cos_nu); |
||||
vx_orbital *= h; |
||||
vy_orbital *= h; |
||||
} else { |
||||
double p = a * (1.0 - e * e); |
||||
double h = sqrt(mu * p); |
||||
vx_orbital = -sqrt(mu / p) * sin_nu; |
||||
vy_orbital = sqrt(mu / p) * (e + cos_nu); |
||||
vx_orbital *= h; |
||||
vy_orbital *= h; |
||||
} |
||||
|
||||
Vec3 velocity = {vx_orbital, vy_orbital, 0.0}; |
||||
|
||||
*out_position = position; |
||||
*out_velocity = velocity; |
||||
} |
||||
@ -0,0 +1,18 @@
|
||||
#ifndef ORBITAL_MECHANICS_H |
||||
#define ORBITAL_MECHANICS_H |
||||
|
||||
#include "physics.h" |
||||
|
||||
struct OrbitalElements { |
||||
double semi_major_axis; |
||||
double eccentricity; |
||||
double inclination; |
||||
double longitude_of_ascending_node; |
||||
double argument_of_periapsis; |
||||
double true_anomaly; |
||||
}; |
||||
|
||||
void orbital_elements_to_cartesian(OrbitalElements elements, double parent_mass, |
||||
Vec3* out_position, Vec3* out_velocity); |
||||
|
||||
#endif |
||||
Loading…
Reference in new issue