use std::f64::consts::PI;
use crate::celestial_bodies::CelestialBody;
use crate::hohmann_transfer::HohmannTransfer;
use crate::Apsis;
#[derive(Copy, Clone, Debug)]
pub struct RelayNetwork {
pub satellite_count: usize,
pub celestial_body: CelestialBody,
}
impl RelayNetwork {
pub fn new(satellite_count: usize, celestial_body: CelestialBody) -> Self {
Self {
satellite_count,
celestial_body,
}
}
pub fn min_altitude(&self) -> Option<f64> {
if self.satellite_count < 3 {
return None;
}
Some(
self.celestial_body.radius / (PI / self.satellite_count as f64).cos()
- self.celestial_body.radius,
)
}
pub fn transfer(&self, relay_altitude: f64, apsis: Apsis) -> Option<HohmannTransfer> {
if relay_altitude < self.min_altitude()? {
return None;
}
let period_ratio = match apsis {
Apsis::Apo => (self.satellite_count as f64 + 1.0) / self.satellite_count as f64,
Apsis::Peri => (self.satellite_count as f64 - 1.0) / self.satellite_count as f64,
};
let semi_major_axis =
period_ratio.powf(2.0 / 3.0) * (self.celestial_body.radius + relay_altitude);
let transfer_altitude =
2.0 * (semi_major_axis - self.celestial_body.radius) - relay_altitude;
Some(HohmannTransfer::new(
transfer_altitude,
relay_altitude,
self.celestial_body,
))
}
}