spaceman 0.1.0

A WIP library for calculating common orbital maneuvers in Kerbal Space Program.
Documentation
use std::f64::consts::TAU;

use crate::GRAVITATIONAL_CONSTANT;

/// A celestial body, such as a planet or moon.
#[derive(Copy, Clone, Debug)]
pub struct CelestialBody {
    /// The mass of the celestial body.
    pub mass: f64,
    /// The radius of the celestial body.
    pub radius: f64,
    /// The semi major axis of the celestial body's orbit.
    pub semi_major_axis: f64,
}

impl CelestialBody {
    /// Create a new celestial body.
    pub const fn new(mass: f64, radius: f64, semi_major_axis: f64) -> Self {
        Self {
            mass,
            radius,
            semi_major_axis,
        }
    }

    /// Calculate the velocity of a body (with a small mass compared to `self`) orbiting `self`,
    /// given its altitude above the surface and the orbit's semi major axis.
    pub fn velocity(&self, altitude: f64, semi_major_axis: f64) -> f64 {
        (GRAVITATIONAL_CONSTANT
            * self.mass
            * ((2.0 / (altitude + self.radius)) - (1.0 / semi_major_axis)))
            .sqrt()
    }

    /// Calculate the velocity of a body orbiting `self` in a circular orbit at the given altitude.
    pub fn circular_velocity(&self, altitude: f64) -> f64 {
        self.velocity(altitude, self.radius + altitude)
    }

    /// Calculate the orbital period of a body orbiting `self` for a given altitude.
    pub fn orbital_period(&self, semi_major_axis: f64) -> f64 {
        TAU * (semi_major_axis.powi(3) / (GRAVITATIONAL_CONSTANT * self.mass)).sqrt()
    }

    /// Calculate the gravitational acceleration of `self` at a given altitude.
    pub fn acceleration(&self, altitude: f64) -> f64 {
        GRAVITATIONAL_CONSTANT * self.mass * (self.radius + altitude).powi(-2)
    }
}

pub mod stock {
    //! The celestial bodies of the Kerbol System.
    use super::CelestialBody;

    pub const KERBOL: CelestialBody = CelestialBody::new(1.7565459e28, 2.616e8, 0.0);
    pub const MOHO: CelestialBody = CelestialBody::new(2.5263314e21, 2.5e5, 5.263138304e9);
    pub const EVE: CelestialBody = CelestialBody::new(1.2243980e23, 7e5, 9.832684544e9);
    pub const GILLY: CelestialBody = CelestialBody::new(1.2420363e17, 13e3, 3.15e7);
    pub const KERBIN: CelestialBody = CelestialBody::new(5.2915158e22, 6e5, 1.3599840256e10);
    pub const MUN: CelestialBody = CelestialBody::new(9.7599066e20, 2e5, 1.2e7);
    pub const MINMUS: CelestialBody = CelestialBody::new(2.6457580e19, 6e4, 4.7e7);
    pub const DUNA: CelestialBody = CelestialBody::new(4.5154270e21, 3.2e5, 2.0726155264e10);
    pub const IKE: CelestialBody = CelestialBody::new(2.7821615e20, 1.3e5, 3.2e6);
    pub const DRES: CelestialBody = CelestialBody::new(3.2190937e20, 1.38e5, 4.0839348203e10);
    pub const JOOL: CelestialBody = CelestialBody::new(4.2332127e24, 6e6, 6.8773560320e10);
    pub const LAYTHE: CelestialBody = CelestialBody::new(2.9397311e22, 5e5, 2.7184e7);
    pub const VALL: CelestialBody = CelestialBody::new(3.1087655e21, 3e5, 4.3152e7);
    pub const TYLO: CelestialBody = CelestialBody::new(4.2332127e22, 6e5, 6.85e7);
    pub const BOP: CelestialBody = CelestialBody::new(3.7261090e19, 6.5e4, 1.285e8);
    pub const POL: CelestialBody = CelestialBody::new(1.0813507e19, 4.4e4, 1.7989e8);
    pub const EELOO: CelestialBody = CelestialBody::new(1.1149224e21, 2.1e5, 9.011882e10);
}

pub mod beyond_home {
    //! The celestial bodies of the Tempus System from [Beyond Home](https://github.com/Gameslinx/BeyondHomePlanetMod).
    use super::CelestialBody;

    pub const TEMPUS_SYSTEM_BARYCENTER: CelestialBody = CelestialBody::new(2.9130918e28, 1e6, 0.0);
    pub const DESTINY: CelestialBody =
        CelestialBody::new(1.75654591319326e28, 5.25e8, 1.43281479698e9);
    pub const FATE: CelestialBody = CelestialBody::new(1.15654591319326e28, 1.25e8, 3.172009791e9);
    pub const FURY: CelestialBody = CelestialBody::new(7.418166699129497e22, 7e5, 1.1479623815e10);
    pub const ANGER: CelestialBody =
        CelestialBody::new(4.944464588046687e18, 2.9e4, 1.1479623815e10);
    pub const HYDRUS: CelestialBody =
        CelestialBody::new(2.646773069835039e21, 2.45e5, 2.0984359719e10);
    pub const HYDRON: CelestialBody = CelestialBody::new(4.470561762282188e18, 2.31e4, 2.106784e6);
    pub const RHODE: CelestialBody =
        CelestialBody::new(2.321576045427985e22, 4.5e5, 2.7884359719e10);
    pub const LUA: CelestialBody = CelestialBody::new(5.8661927453066245e20, 1.56e5, 4.45e6);
    pub const ARMSTRONG: CelestialBody = CelestialBody::new(2.645670707040439e18, 2e4, 8.506784e6);
    pub const ASH: CelestialBody = CelestialBody::new(2.755906986500457e21, 2.5e5, 4.0707030e7);
    pub const SCAYTHE: CelestialBody =
        CelestialBody::new(1.316956085282352e22, 4e5, 4.0186247496e10);
    pub const SCINDO: CelestialBody = CelestialBody::new(1.4898697736092176e20, 1.23e5, 5.4e6);
    pub const GATEWAY: CelestialBody = CelestialBody::new(5.23e24, 1e7, 4.8847418599e10);
    pub const PROXIM: CelestialBody = CelestialBody::new(3.6745426486672765e19, 5e4, 2.2822055e7);
    pub const KOHM: CelestialBody = CelestialBody::new(2.3811036363363954e22, 4.5e5, 4.3867839e7);
    pub const EIDOS: CelestialBody = CelestialBody::new(3.703938989856616e19, 6e4, 6.5566488e7);
    pub const ANSIA: CelestialBody = CelestialBody::new(1.6535441919002743e19, 5e4, 7.1636615e7);
    pub const JADE: CelestialBody = CelestialBody::new(8.000508218090286e21, 3.6e5, 1.58061909e8);
    pub const ROCK: CelestialBody = CelestialBody::new(8.000508218090286e21, 5e5, 5.8302471634e10);
    pub const VASTO: CelestialBody =
        CelestialBody::new(1.2464048664279404e22, 4e5, 8.5640607902e10);
    pub const VOSS: CelestialBody = CelestialBody::new(3.6399431550874255e20, 1.33e5, 8.456654e6);
    pub const KERBOL: CelestialBody = CelestialBody::new(2.314e27, 3.181e6, 7.26973116445e11);
    pub const TRIBUTE: CelestialBody =
        CelestialBody::new(4.321262154832717e19, 7e4, 1.3599840256e10);
    pub const DYNASTY: CelestialBody =
        CelestialBody::new(4.9058818902356816e22, 6.5e5, 2.0726155264e10);
    pub const DROHZE: CelestialBody =
        CelestialBody::new(5.8212104640186994e20, 1.78e5, 4.0839348203e10);
    pub const JANUS: CelestialBody =
        CelestialBody::new(2.2047255892003658e24, 5e6, 6.8773560320e10);
    pub const TAU: CelestialBody = CelestialBody::new(2.9396341189338215e22, 5e5, 2.7184e7);
    pub const ETERNA: CelestialBody =
        CelestialBody::new(7.382156181172558e21, 3.5e5, 4.86020562963505e7);
    pub const TALON: CelestialBody = CelestialBody::new(2.4619435746070756e22, 5e5, 6.85e7);
    pub const LOND: CelestialBody = CelestialBody::new(1.9092016597945736e20, 9.9199e4, 1.7989e8);
    pub const VERNA: CelestialBody = CelestialBody::new(1.3545834020047047e21, 2.4e5, 9.011882e10);
}