diff --git a/src/renderer.cpp b/src/renderer.cpp index 6f91b12..9f44b2f 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -174,7 +174,7 @@ static void render_elliptical_orbit(double a, double e, OrbitalBasis basis, } static void render_hyperbolic_orbit(double p, double e, OrbitalBasis basis, - Vec3 parent_pos, RenderState* render_state, Color color) { + Vec3 parent_pos, RenderState* render_state, Color color) { double max_true_anomaly = (e > 1.01) ? acos(-1.0 / e) * 0.95 : PI * 0.48; int segments = 60; @@ -194,6 +194,27 @@ static void render_hyperbolic_orbit(double p, double e, OrbitalBasis basis, } } +static void render_parabolic_orbit(double p, OrbitalBasis basis, + Vec3 parent_pos, RenderState* render_state, Color color) { + double max_true_anomaly = PI * 0.95; + + int segments = 80; + for (int i = 0; i < segments; i++) { + float theta1 = -max_true_anomaly + (float)i / segments * 2.0f * max_true_anomaly; + float theta2 = -max_true_anomaly + (float)(i + 1) / segments * 2.0f * max_true_anomaly; + + double r1 = p / (1.0 + cos(theta1)); + double r2 = p / (1.0 + cos(theta2)); + + double x1 = r1 * cos(theta1); + double y1 = r1 * sin(theta1); + double x2 = r2 * cos(theta2); + double y2 = r2 * sin(theta2); + + draw_orbit_segment(x1, y1, x2, y2, basis, parent_pos, render_state, color); + } +} + // Render orbit path for a body void render_orbit(CelestialBody* body, CelestialBody* parent, RenderState* render_state) { if (body->parent_index == -1 || parent == NULL) { @@ -232,13 +253,25 @@ void render_orbit(CelestialBody* body, CelestialBody* parent, RenderState* rende if (a <= 0.0) return; render_elliptical_orbit(a, e, basis, parent->position, render_state, orbit_color); - } else { - double a = (e > 1.01) ? mu / (2.0 * (-specific_energy)) : r / (1.0 + e); + } else if (e > 1.02) { + double a = mu / (2.0 * (-specific_energy)); double p = a * (1.0 - e * e); if (p <= 0.0) return; render_hyperbolic_orbit(p, e, basis, parent->position, render_state, orbit_color); + } else { + Vec3 h_vec = { + r_vec.y * body->velocity.z - r_vec.z * body->velocity.y, + r_vec.z * body->velocity.x - r_vec.x * body->velocity.z, + r_vec.x * body->velocity.y - r_vec.y * body->velocity.x + }; + double h_squared = h_vec.x * h_vec.x + h_vec.y * h_vec.y + h_vec.z * h_vec.z; + double p = h_squared / mu; + + if (p <= 0.0) return; + + render_parabolic_orbit(p, basis, parent->position, render_state, orbit_color); } }