#pragma once #include #include #include "util.h" struct ellipse_parameters { double a; // NOTE: semi-major axis double b; // NOTE: semi-minor axis double e; // NOTE: eccentricity double c; // NOTE: linear eccentricity double p; // NOTE: semilatus rectum glm::vec2 f1; glm::vec2 f2; }; struct orbital_elements { ellipse_parameters ep; double iota; // NOTE: (ι) inclination double omega; // NOTE: (ω) argument of periapsis double mu; // NOTE: (μ) gravittional parameter double nu; // NOTE: (ν) true anomaly }; struct ellipse_3d { ellipse_parameters ep; glm::vec3* vertices; uint vert_count; }; ellipse_parameters constructEllipse(double a, double b); // NOTE: create vertices for a 3d ellipse // NOTE: all vertices are in the x/y plane with z = 0 ellipse_3d constructEllipse3D(ellipse_parameters ep, uint vert_count); /* NOTE: how-to propagate orbit position given initial true anomaly, semimajor * axis, mean motion, and eccentricity: ref) section 4.4, Kepler's Problem, * "Space Flight Dynamics" by Craig A. Kluever * * obtain initial eccentric anomaly (E1) from true anomaly (ϴ1) and e: * tan(E1/2) = sqrt((1-e)/(1+e)) * tan(ϴ1/2) * * obtain inital mean anomaly: * M1 = E1 - e*sin(E1) * * obtain propagated mean anomaly, mean motion (n) is sqrt(μ/a^3): * M2 = M1 + n(t2 - t1) * * express Kepler's equation in terms of propagated mean anomly: * M2 = E2 - e*sin(E2) * * Use Newton's method to search for an E2 that satisfies Kepler's equation: * guess a starting value for E2_k (k indicates iteration index): * E2_1 = M2 + e*sin(M2) + ((e^2 / 2) * sin(2 * M2)) * * test if guess is a solution: * F(E2_1) = E2_1 - e*sin(E2) - M2 * * if the result of the error function is not below some small value * (1 * 10^-8), compute the derivative, and and iterate again: * f'(E2_1) = 1 - e*cos(E2_1) * * use Newton's method to compute the next trial value of E2: * E2_2 = E2_1 - (f(E2_1) / f'(E2_1)) * * after we converge on a solution, convert eccentric anomaly back to true * anomoly: * tan(ϴ2/2) = sqrt((1+e) / (1-e)) * tan(E2/2) */ double getPropagatedTrueAnomaly(orbital_elements orbit, double initial_anom, unsigned int time_step); // NOTE: aka) the trajectory equation (eq. 2.45) // NOTE: returns radial distance in kilometers double getRadialPosition(ellipse_parameters ep, double true_anom); glm::vec2 polarToRect(double true_anom, double r);