diff --git a/src/config_validator.cpp b/src/config_validator.cpp index 48ea67b..500524b 100644 --- a/src/config_validator.cpp +++ b/src/config_validator.cpp @@ -200,6 +200,62 @@ bool validate_nested_orbits(SimulationState* sim) { return true; } +bool validate_true_anomaly_ranges(SimulationState* sim) { + for (int i = 0; i < sim->body_count; i++) { + CelestialBody* body = &sim->bodies[i]; + + if (body->parent_index < 0) { + continue; + } + + double e = body->orbit.eccentricity; + double nu = body->orbit.true_anomaly; + + // Normalize nu to [0, 2π] + while (nu < 0.0) nu += 2.0 * M_PI; + while (nu >= 2.0 * M_PI) nu -= 2.0 * M_PI; + + // Check hyperbolic orbit anomaly limits + if (e > 1.0) { + double max_nu = acos(-1.0 / e); + if (nu > max_nu && nu < (2.0 * M_PI - max_nu)) { + printf("Error: Body '%s' has invalid true_anomaly for hyperbolic orbit\n", + body->name); + printf(" Eccentricity: %.4f\n", e); + printf(" True anomaly: %.4f rad\n", nu); + printf(" Valid range: [0, %.4f] ∪ [%.4f, 2π]\n", max_nu, 2.0 * M_PI - max_nu); + return false; + } + } + } + + for (int i = 0; i < sim->craft_count; i++) { + Spacecraft* craft = &sim->spacecraft[i]; + + double e = craft->orbit.eccentricity; + double nu = craft->orbit.true_anomaly; + + // Normalize nu to [0, 2π] + while (nu < 0.0) nu += 2.0 * M_PI; + while (nu >= 2.0 * M_PI) nu -= 2.0 * M_PI; + + // Check hyperbolic orbit anomaly limits + if (e > 1.0) { + double max_nu = acos(-1.0 / e); + if (nu > max_nu && nu < (2.0 * M_PI - max_nu)) { + printf("Error: Spacecraft '%s' has invalid true_anomaly for hyperbolic orbit\n", + craft->name); + printf(" Eccentricity: %.4f\n", e); + printf(" True anomaly: %.4f rad\n", nu); + printf(" Valid range: [0, %.4f] ∪ [%.4f, 2π]\n", max_nu, 2.0 * M_PI - max_nu); + return false; + } + } + } + + return true; +} + bool validate_initial_positions(SimulationState* sim) { for (int i = 0; i < sim->body_count; i++) { CelestialBody* body = &sim->bodies[i]; @@ -249,6 +305,10 @@ bool run_all_config_validations(SimulationState* sim) { return false; } + if (!validate_true_anomaly_ranges(sim)) { + return false; + } + if (!validate_mass_ratios(sim)) { return false; }