vibe coding an orbital mechanics simulation to try out claude code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

166 lines
5.7 KiB

#include <catch2/catch_test_macros.hpp>
#include "../src/physics.h"
#include "../src/simulation.h"
#include "../src/config_loader.h"
#include <cmath>
#include <vector>
struct TransitionEvent {
double time_seconds;
double time_days;
int old_parent;
int new_parent;
char old_name[64];
char new_name[64];
double x_position;
double y_position;
double z_position;
};
TEST_CASE("Root body transition - Earth to Sun", "[root][transition]") {
const double TIME_STEP = 60.0;
const double DAYS_TO_SIMULATE = 500.0;
const double SECONDS_PER_DAY = 86400.0;
const double AU = 1.496e11;
SimulationState* sim = create_simulation(10, 0, 0, TIME_STEP);
REQUIRE(load_system_config(sim, "tests/test_root_body_transitions.toml"));
const int PROBE_INDEX = 3;
const int SUN_INDEX = 0;
std::vector<TransitionEvent> transitions;
int previous_parent = sim->bodies[PROBE_INDEX].parent_index;
INFO("Initial parent: " << sim->bodies[PROBE_INDEX].name
<< " (parent_index: " << previous_parent << ")");
double max_time = DAYS_TO_SIMULATE * SECONDS_PER_DAY;
while (sim->time < max_time) {
update_simulation(sim);
int current_parent = sim->bodies[PROBE_INDEX].parent_index;
if (current_parent != previous_parent) {
TransitionEvent event;
event.time_seconds = sim->time;
event.time_days = sim->time / SECONDS_PER_DAY;
event.old_parent = previous_parent;
event.new_parent = current_parent;
if (previous_parent >= 0 && previous_parent < sim->body_count) {
strcpy(event.old_name, sim->bodies[previous_parent].name);
} else {
strcpy(event.old_name, "Sun");
}
if (current_parent >= 0 && current_parent < sim->body_count) {
strcpy(event.new_name, sim->bodies[current_parent].name);
} else {
strcpy(event.new_name, "Sun");
}
event.x_position = sim->bodies[PROBE_INDEX].global_position.x;
event.y_position = sim->bodies[PROBE_INDEX].global_position.y;
event.z_position = sim->bodies[PROBE_INDEX].global_position.z;
transitions.push_back(event);
previous_parent = current_parent;
INFO("Transition at day " << event.time_days
<< ": " << event.old_name << " -> " << event.new_name);
}
}
INFO("Total transitions: " << transitions.size());
REQUIRE(transitions.size() > 0);
bool found_sun_transition = false;
for (const auto& event : transitions) {
if (event.new_parent == SUN_INDEX || event.old_parent == SUN_INDEX) {
found_sun_transition = true;
INFO("Sun transition at day " << event.time_days
<< ": " << event.old_name << " -> " << event.new_name
<< " at position (" << event.x_position/AU << ", "
<< event.y_position/AU << ", " << event.z_position/AU << ") AU");
}
}
REQUIRE(found_sun_transition);
destroy_simulation(sim);
}
TEST_CASE("Root body round-trip - Earth -> Sun -> Mars -> Sun", "[root][round-trip]") {
const double TIME_STEP = 60.0;
const double DAYS_TO_SIMULATE = 1000.0;
const double SECONDS_PER_DAY = 86400.0;
SimulationState* sim = create_simulation(10, 0, 0, TIME_STEP);
REQUIRE(load_system_config(sim, "tests/test_root_body_transitions.toml"));
const int PROBE_INDEX = 3;
const int SUN_INDEX = 0;
std::vector<TransitionEvent> transitions;
int previous_parent = sim->bodies[PROBE_INDEX].parent_index;
INFO("Initial parent: " << sim->bodies[PROBE_INDEX].name
<< " (parent_index: " << previous_parent << ")");
double max_time = DAYS_TO_SIMULATE * SECONDS_PER_DAY;
while (sim->time < max_time) {
update_simulation(sim);
int current_parent = sim->bodies[PROBE_INDEX].parent_index;
if (current_parent != previous_parent) {
TransitionEvent event;
event.time_seconds = sim->time;
event.time_days = sim->time / SECONDS_PER_DAY;
event.old_parent = previous_parent;
event.new_parent = current_parent;
if (previous_parent >= 0 && previous_parent < sim->body_count) {
strcpy(event.old_name, sim->bodies[previous_parent].name);
} else {
strcpy(event.old_name, "Sun");
}
if (current_parent >= 0 && current_parent < sim->body_count) {
strcpy(event.new_name, sim->bodies[current_parent].name);
} else {
strcpy(event.new_name, "Sun");
}
event.x_position = sim->bodies[PROBE_INDEX].global_position.x;
event.y_position = sim->bodies[PROBE_INDEX].global_position.y;
event.z_position = sim->bodies[PROBE_INDEX].global_position.z;
transitions.push_back(event);
previous_parent = current_parent;
INFO("Transition at day " << event.time_days
<< ": " << event.old_name << " -> " << event.new_name);
}
}
INFO("Total transitions: " << transitions.size());
REQUIRE(transitions.size() > 0);
int sun_transitions = 0;
for (const auto& event : transitions) {
if (event.new_parent == SUN_INDEX || event.old_parent == SUN_INDEX) {
sun_transitions++;
INFO("Sun transition #" << sun_transitions << " at day " << event.time_days
<< ": " << event.old_name << " -> " << event.new_name);
}
}
REQUIRE(sun_transitions >= 1);
INFO("Root body transitions validated: " << sun_transitions << " Sun transitions detected");
destroy_simulation(sim);
}