@ -5,6 +5,7 @@
# include "orbital_mechanics.h"
# include <cmath>
# include <cstdio>
# include <cstring>
Vec3 calculate_prograde_dir ( Vec3 local_velocity ) {
return vec3_normalize ( local_velocity ) ;
@ -54,6 +55,27 @@ Vec3 get_burn_direction_vector(BurnDirection direction, Vec3 local_pos, Vec3 loc
}
}
const char * get_burn_direction_name ( BurnDirection direction ) {
switch ( direction ) {
case BURN_PROGRADE :
return " Prograde " ;
case BURN_RETROGRADE :
return " Retrograde " ;
case BURN_NORMAL :
return " Normal " ;
case BURN_ANTINORMAL :
return " Antinormal " ;
case BURN_RADIAL_IN :
return " Radial In " ;
case BURN_RADIAL_OUT :
return " Radial Out " ;
case BURN_CUSTOM :
return " Custom " ;
default :
return " Unknown " ;
}
}
void apply_impulsive_burn ( Spacecraft * craft , BurnDirection direction , double delta_v ) {
Vec3 dir = get_burn_direction_vector ( direction , craft - > local_position , craft - > local_velocity ) ;
@ -67,6 +89,27 @@ void apply_custom_burn(Spacecraft* craft, Vec3 delta_v_local) {
craft - > global_velocity = vec3_add ( craft - > global_velocity , delta_v_local ) ;
}
OrbitalElements preview_burn_result ( const Spacecraft * craft , BurnDirection direction , double delta_v , const SimulationState * sim ) {
OrbitalElements current_elements = craft - > orbit ;
if ( craft - > parent_index < 0 | | craft - > parent_index > = sim - > body_count ) {
return current_elements ;
}
CelestialBody * parent = & sim - > bodies [ craft - > parent_index ] ;
double parent_mass = parent - > mass ;
Vec3 pos ;
Vec3 vel ;
orbital_elements_to_cartesian ( current_elements , parent_mass , & pos , & vel ) ;
Vec3 burn_dir = get_burn_direction_vector ( direction , pos , vel ) ;
Vec3 delta_v_vec = vec3_scale ( burn_dir , delta_v ) ;
Vec3 new_vel = vec3_add ( vel , delta_v_vec ) ;
return cartesian_to_orbital_elements ( pos , new_vel , parent_mass ) ;
}
bool check_maneuver_trigger ( Maneuver * maneuver , Spacecraft * craft , SimulationState * sim ) {
switch ( maneuver - > trigger_type ) {
case TRIGGER_TIME :
@ -163,6 +206,20 @@ bool check_maneuver_trigger(Maneuver* maneuver, Spacecraft* craft, SimulationSta
}
}
Maneuver create_maneuver ( const char * name , int craft_index , BurnDirection direction , double delta_v , TriggerType trigger_type , double trigger_value ) {
Maneuver m ;
strncpy ( m . name , name , 63 ) ;
m . name [ 63 ] = ' \0 ' ;
m . craft_index = craft_index ;
m . direction = direction ;
m . delta_v = delta_v ;
m . trigger_type = trigger_type ;
m . trigger_value = trigger_value ;
m . executed = false ;
m . executed_time = 0.0 ;
return m ;
}
void execute_maneuver ( Maneuver * maneuver , Spacecraft * craft , SimulationState * sim , double current_time ) {
apply_impulsive_burn ( craft , maneuver - > direction , maneuver - > delta_v ) ;
@ -174,3 +231,73 @@ void execute_maneuver(Maneuver* maneuver, Spacecraft* craft, SimulationState* si
maneuver - > executed = true ;
maneuver - > executed_time = current_time ;
}
int add_maneuver_to_simulation ( SimulationState * sim , Maneuver * maneuver ) {
if ( sim - > maneuver_count > = sim - > max_maneuvers ) {
return - 1 ;
}
for ( int i = 0 ; i < sim - > maneuver_count ; i + + ) {
if ( strcmp ( sim - > maneuvers [ i ] . name , maneuver - > name ) = = 0 ) {
return - 1 ;
}
}
if ( maneuver - > craft_index < 0 | | maneuver - > craft_index > = sim - > craft_count ) {
return - 1 ;
}
int new_idx = sim - > maneuver_count ;
sim - > maneuvers [ new_idx ] = * maneuver ;
sim - > maneuvers [ new_idx ] . executed = false ;
sim - > maneuvers [ new_idx ] . executed_time = 0.0 ;
sim - > maneuver_count + + ;
return new_idx ;
}
bool remove_maneuver_by_index ( SimulationState * sim , int index ) {
if ( index < 0 | | index > = sim - > maneuver_count ) {
return false ;
}
int elements_to_move = sim - > maneuver_count - index - 1 ;
if ( elements_to_move > 0 ) {
memmove ( & sim - > maneuvers [ index ] , & sim - > maneuvers [ index + 1 ] ,
elements_to_move * sizeof ( Maneuver ) ) ;
}
sim - > maneuver_count - - ;
return true ;
}
HohmannTransfer calculate_hohmann_transfer ( double r1 , double r2 , double central_mass ) {
HohmannTransfer result ;
double a_transfer = ( r1 + r2 ) / 2.0 ;
double mu = G * central_mass ;
double v1 = sqrt ( mu / r1 ) ;
double v_transfer1 = sqrt ( mu * ( 2.0 / r1 - 1.0 / a_transfer ) ) ;
result . dv1 = v_transfer1 - v1 ;
double v2 = sqrt ( mu / r2 ) ;
double v_transfer2 = sqrt ( mu * ( 2.0 / r2 - 1.0 / a_transfer ) ) ;
result . dv2 = v2 - v_transfer2 ;
result . transfer_time = M_PI * sqrt ( pow ( a_transfer , 3.0 ) / mu ) ;
result . true_anomaly_2 = M_PI ;
return result ;
}
bool validate_burn_parameters ( const Spacecraft * craft , BurnDirection direction , double delta_v , double parent_mass ) {
if ( delta_v < 0 ) {
return false ;
}
if ( delta_v > 50000.0 ) {
return false ;
}
return true ;
}