use crate::SIDEREAL_ORBIT_PERIOD_S;
use std::f64::consts::PI;
pub const SEMI_MAJOR_AXIS_M: f64 = 421_700_000.0;
pub const ECCENTRICITY: f64 = 0.0041;
pub const INCLINATION_DEG: f64 = 0.036;
pub const JUPITER_GRAVITATIONAL_PARAMETER: f64 = 1.266_86e17;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct IoOrbit {
pub semi_major_axis_m: f64,
pub eccentricity: f64,
pub inclination_deg: f64,
pub true_anomaly_rad: f64,
}
impl Default for IoOrbit {
fn default() -> Self {
Self::new()
}
}
impl IoOrbit {
pub fn new() -> Self {
Self {
semi_major_axis_m: SEMI_MAJOR_AXIS_M,
eccentricity: ECCENTRICITY,
inclination_deg: INCLINATION_DEG,
true_anomaly_rad: 0.0,
}
}
pub fn orbital_period_s(&self) -> f64 {
SIDEREAL_ORBIT_PERIOD_S
}
pub fn mean_motion_rad_s(&self) -> f64 {
2.0 * PI / self.orbital_period_s()
}
pub fn periapsis_m(&self) -> f64 {
self.semi_major_axis_m * (1.0 - self.eccentricity)
}
pub fn apoapsis_m(&self) -> f64 {
self.semi_major_axis_m * (1.0 + self.eccentricity)
}
pub fn current_distance_m(&self) -> f64 {
let num = self.semi_major_axis_m * (1.0 - self.eccentricity.powi(2));
num / (1.0 + self.eccentricity * self.true_anomaly_rad.cos())
}
pub fn orbital_speed_m_s(&self, distance_m: f64) -> f64 {
(JUPITER_GRAVITATIONAL_PARAMETER * (2.0 / distance_m - 1.0 / self.semi_major_axis_m)).sqrt()
}
}