@ -165,8 +165,9 @@ void update_simulation(SimulationState* sim) {
sim - > time + = sim - > dt ;
sim - > time + = sim - > dt ;
}
}
static void compute_orbital_velocity_from_vis_viva ( CelestialBody * body ,
// Calculate orbital velocity using vis-viva equation
CelestialBody * parent ) {
// Returns velocity vector for body relative to parent
static Vec3 calc_orbital_velocity ( CelestialBody * body , CelestialBody * parent ) {
Vec3 r = vec3_sub ( body - > position , parent - > position ) ;
Vec3 r = vec3_sub ( body - > position , parent - > position ) ;
double distance = vec3_magnitude ( r ) ;
double distance = vec3_magnitude ( r ) ;
double e = body - > eccentricity ;
double e = body - > eccentricity ;
@ -193,86 +194,39 @@ static void compute_orbital_velocity_from_vis_viva(CelestialBody* body,
}
}
vel_dir = vec3_normalize ( vel_dir ) ;
vel_dir = vec3_normalize ( vel_dir ) ;
body - > velocity = vec3_scale ( vel_dir , speed ) ;
Vec3 velocity = vec3_scale ( vel_dir , speed ) ;
body - > velocity = vec3_add ( body - > velocity , parent - > velocity ) ;
return vec3_add ( velocity , parent - > velocity ) ;
}
}
void calculate_initial_velocities ( SimulationState * sim ) {
// Calculate SOI radius for a single body
for ( int i = 0 ; i < sim - > body_count ; i + + ) {
// r_soi = a * (m/M)^(2/5) where a = semi-major axis, m = body mass, M = parent mass
CelestialBody * body = & sim - > bodies [ i ] ;
// Returns SOI radius in meters
double calculate_soi_radius ( CelestialBody * body , CelestialBody * parent ) {
if ( body - > parent_index = = - 1 ) {
assert ( body ! = nullptr & & parent ! = nullptr ) ;
body - > velocity = { 0.0 , 0.0 , 0.0 } ;
double mass_ratio = body - > mass / parent - > mass ;
} else if ( body - > parent_index > = 0 & & body - > parent_index < sim - > body_count ) {
return body - > semi_major_axis * pow ( mass_ratio , 0.4 ) ; // 2/5 = 0.4
CelestialBody * parent = & sim - > bodies [ body - > parent_index ] ;
compute_orbital_velocity_from_vis_viva ( body , parent ) ;
}
}
}
}
// Calculate SOI radii for all bodies
// r_soi = a * (m/M)^(2/5) where a = semi-major axis, m = body mass, M = parent mass
// Combined initialization - sets velocities, SOI radii, and local coordinates in single loop
// Combined initialization - sets velocities, SOI radii, and local coordinates in single loop
void initialize_bodies ( SimulationState * sim ) {
void initialize_bodies ( SimulationState * sim ) {
for ( int i = 0 ; i < sim - > body_count ; i + + ) {
for ( int i = 0 ; i < sim - > body_count ; i + + ) {
CelestialBody * body = & sim - > bodies [ i ] ;
CelestialBody * body = & sim - > bodies [ i ] ;
CelestialBody * parent = NULL ;
// Initialize velocities
// Set parent pointer if not root body
if ( body - > parent_index = = - 1 ) {
if ( body - > parent_index > = 0 & & body - > parent_index < sim - > body_count ) {
body - > velocity = { 0.0 , 0.0 , 0.0 } ;
parent = & sim - > bodies [ body - > parent_index ] ;
} else if ( body - > parent_index > = 0 & & body - > parent_index < sim - > body_count ) {
body - > velocity = calc_orbital_velocity ( body , parent ) ;
CelestialBody * parent = & sim - > bodies [ body - > parent_index ] ;
compute_orbital_velocity_from_vis_viva ( body , parent ) ;
}
// Calculate SOI radii
if ( body - > parent_index = = - 1 ) {
body - > soi_radius = 1e15 ;
} else if ( body - > parent_index > = 0 & & body - > parent_index < sim - > body_count ) {
CelestialBody * parent = & sim - > bodies [ body - > parent_index ] ;
double mass_ratio = body - > mass / parent - > mass ;
body - > soi_radius = body - > semi_major_axis * pow ( mass_ratio , 0.4 ) ;
}
// Initialize local coordinates
if ( body - > parent_index = = - 1 ) {
body - > local_position = body - > position ;
body - > local_velocity = body - > velocity ;
} else if ( body - > parent_index > = 0 & & body - > parent_index < sim - > body_count ) {
CelestialBody * parent = & sim - > bodies [ body - > parent_index ] ;
body - > local_position = vec3_sub ( body - > position , parent - > position ) ;
body - > local_position = vec3_sub ( body - > position , parent - > position ) ;
body - > local_velocity = vec3_sub ( body - > velocity , parent - > velocity ) ;
body - > local_velocity = vec3_sub ( body - > velocity , parent - > velocity ) ;
}
body - > soi_radius = calculate_soi_radius ( body , parent ) ;
}
} else { // root body
}
body - > velocity = { 0.0 , 0.0 , 0.0 } ;
// Calculate SOI radii for all bodies (kept for individual testing)
// r_soi = a * (m/M)^(2/5) where a = semi-major axis, m = body mass, M = parent mass
void calculate_soi_radii ( SimulationState * sim ) {
for ( int i = 0 ; i < sim - > body_count ; i + + ) {
CelestialBody * body = & sim - > bodies [ i ] ;
if ( body - > parent_index = = - 1 ) {
body - > soi_radius = 1e15 ;
} else if ( body - > parent_index > = 0 & & body - > parent_index < sim - > body_count ) {
CelestialBody * parent = & sim - > bodies [ body - > parent_index ] ;
double mass_ratio = body - > mass / parent - > mass ;
body - > soi_radius = body - > semi_major_axis * pow ( mass_ratio , 0.4 ) ;
}
}
}
void initialize_local_coordinates ( SimulationState * sim ) {
for ( int i = 0 ; i < sim - > body_count ; i + + ) {
CelestialBody * body = & sim - > bodies [ i ] ;
if ( body - > parent_index = = - 1 ) {
body - > local_position = body - > position ;
body - > local_position = body - > position ;
body - > local_velocity = body - > velocity ;
body - > local_velocity = body - > velocity ;
} else if ( body - > parent_index > = 0 & & body - > parent_index < sim - > body_count ) {
CelestialBody * parent = & sim - > bodies [ body - > parent_index ] ;
// Root body (like Sun) has infinite SOI, use a large value
body - > local_position = vec3_sub ( body - > position , parent - > position ) ;
body - > soi_radius = 1e15 ; // 1000 AU in meters
body - > local_velocity = vec3_sub ( body - > velocity , parent - > velocity ) ;
}
}
}
}
}
}