satellitesfactory 0.0.2

Satellite factory — classify, build and catalogue natural satellites for any planetary system: Solar System moons (Moon, Galileans, Titan, Triton…) or custom configurations.
Documentation
use crate::config::parameters::*;
use crate::engine::orbits::OrbitalElements;

pub type Vec3 = [f64; 3];

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SatelliteClass {
    Regular,
    Impact,
}

#[derive(Debug, Clone)]
pub struct RegularSatellite {
    pub name: String,
    pub parent: String,
    pub mass: f64,
    pub radius: f64,
    pub j2: f64,
    pub obliquity: f64,
    pub elements: OrbitalElements,
    pub class: SatelliteClass,
    pub albedo: f64,
    pub ice_fraction: f64,
    pub rock_fraction: f64,
}

impl RegularSatellite {
    pub fn new(
        name: &str,
        parent: &str,
        mass: f64,
        radius: f64,
        j2: f64,
        obliquity: f64,
        elements: OrbitalElements,
    ) -> Self {
        Self {
            name: name.to_string(),
            parent: parent.to_string(),
            mass,
            radius,
            j2,
            obliquity,
            elements,
            class: SatelliteClass::Regular,
            albedo: 0.20,
            ice_fraction: 0.0,
            rock_fraction: 0.80,
        }
    }

    pub fn with_composition(
        mut self,
        class: SatelliteClass,
        albedo: f64,
        ice_fraction: f64,
        rock_fraction: f64,
    ) -> Self {
        self.class = class;
        self.albedo = albedo;
        self.ice_fraction = ice_fraction;
        self.rock_fraction = rock_fraction;
        self
    }

    pub fn mass_moon(&self) -> f64 {
        self.mass / MOON_MASS
    }

    pub fn radius_moon(&self) -> f64 {
        self.radius / MOON_RADIUS
    }

    pub fn surface_gravity(&self) -> f64 {
        surface_gravity(self.mass, self.radius)
    }

    pub fn escape_velocity(&self) -> f64 {
        escape_velocity(self.mass, self.radius)
    }

    pub fn mean_density(&self) -> f64 {
        mean_density(self.mass, self.radius)
    }

    pub fn period(&self, parent_mass: f64) -> f64 {
        self.elements.period(G * (parent_mass + self.mass))
    }

    pub fn to_cartesian(&self, parent_mass: f64) -> (Vec3, Vec3) {
        crate::engine::orbits::elements_to_state(&self.elements, parent_mass + self.mass)
    }

    pub fn ice_mass(&self) -> f64 {
        self.mass * self.ice_fraction
    }

    pub fn rock_mass(&self) -> f64 {
        self.mass * self.rock_fraction
    }

    pub fn metal_mass(&self) -> f64 {
        self.mass * (1.0 - self.ice_fraction - self.rock_fraction).max(0.0)
    }

    pub fn moment_of_inertia_factor(&self) -> f64 {
        let f_metal = 1.0 - self.ice_fraction - self.rock_fraction;
        0.4 - 0.06 * f_metal.max(0.0)
    }
}