Browse Source

Add parabolic orbit rendering function

- Add render_parabolic_orbit() with true anomaly range -π*0.95 to π*0.95
- Use 80 segments for smooth parabolic curve visualization
- Update render_orbit() branching to handle parabolic (0.98 <= e <= 1.02)
- Calculate semi-latus rectum p = h²/μ for parabolic orbits
- Maintain existing elliptical/hyperbolic orbit rendering

Claude
main
cinnaboot 6 months ago
parent
commit
84502a7007
  1. 39
      src/renderer.cpp

39
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);
}
}

Loading…
Cancel
Save