diff --git a/src/simulation.cpp b/src/simulation.cpp index a6b02aa..5000393 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -69,48 +69,42 @@ int find_dominant_body(SimulationState* sim, int body_index) { CelestialBody* body = &sim->bodies[body_index]; int dominant = body->parent_index; - // Check if we're outside current parent's SOI - bool outside_current_soi = false; + // If within current parent's SOI → stay with current parent if (dominant >= 0 && dominant < sim->body_count) { - CelestialBody* current_parent = &sim->bodies[dominant]; - double dist_to_current = vec3_distance(body->position, current_parent->position); - outside_current_soi = dist_to_current > current_parent->soi_radius; + CelestialBody* parent = &sim->bodies[dominant]; + double distance = vec3_distance(body->position, parent->position); + + if (distance < parent->soi_radius) { + return dominant; + } } - // Check all other bodies to see if we're within their SOI + // Outside current parent's SOI (or has no parent) + // Find new parent: body we're within SOI of and closest to + int new_parent = -1; + double min_distance = INFINITY; + for (int i = 0; i < sim->body_count; i++) { if (i == body_index) continue; - CelestialBody* potential_parent = &sim->bodies[i]; - double distance = vec3_distance(body->position, potential_parent->position); - - // If we're outside current parent's SOI, consider all bodies - // Otherwise, only consider bodies within their SOI - bool can_switch = outside_current_soi || distance < potential_parent->soi_radius; + CelestialBody* potential = &sim->bodies[i]; + double distance = vec3_distance(body->position, potential->position); - if (can_switch && i != dominant) { - if (dominant == -1) { - dominant = i; - } else { - CelestialBody* current_parent = &sim->bodies[dominant]; - double dist_to_current = vec3_distance(body->position, current_parent->position); - - if (outside_current_soi) { - // Outside current SOI: switch to closest body - if (distance < dist_to_current) { - dominant = i; - } - } else { - // Inside current SOI: apply hysteresis to prevent oscillations - if (distance < dist_to_current * 0.5) { - dominant = i; - } - } + // Only consider bodies we're within SOI of + if (distance < potential->soi_radius) { + if (distance < min_distance) { + min_distance = distance; + new_parent = i; } } } - return dominant; + // If no body's SOI contains us, fall back to root (Sun) + if (new_parent == -1) { + new_parent = 0; + } + + return new_parent; } // Update sphere of influence radius using Hill sphere approximation diff --git a/tests/test_soi_transition.cpp b/tests/test_soi_transition.cpp index 3acd099..4891887 100644 --- a/tests/test_soi_transition.cpp +++ b/tests/test_soi_transition.cpp @@ -20,7 +20,7 @@ TEST_CASE("SOI transition - Sun to Mars", "[soi][transition]") { const double SECONDS_PER_DAY = 86400.0; const double AU = 1.496e11; - INFO("Note: Hysteresis (0.5 factor) prevents oscillations, allows Mars -> Sun exit when outside SOI"); + INFO("Note: SOI transitions use simple model (no hysteresis)"); SimulationState* sim = create_simulation(10, TIME_STEP);