dwarfplanetsfactory 0.0.1

Dwarf planet factory — classify, build and catalogue dwarf planets of any type: Kuiper belt, scattered disk, plutino, cold classical, detached, binary, Ceres-type, and sednoid.
Documentation
pub use sciforge::hub::prelude::constants::{C, G, K_B, SOLAR_MASS};

pub const PI: f64 = std::f64::consts::PI;
pub const AU: f64 = 1.496e11;
pub const YEAR: f64 = 365.25 * 86400.0;
pub const SOLAR_LUMINOSITY: f64 = 3.828e26;
pub const EARTH_MASS: f64 = 5.972e24;
pub const EARTH_RADIUS: f64 = 6.371e6;
pub const STEFAN_BOLTZMANN: f64 = 5.6704e-8;

/// Neptune semi-major axis (AU)
pub const NEPTUNE_A: f64 = 30.07;
/// Neptune mass (kg)
pub const NEPTUNE_MASS: f64 = 1.024e26;
/// Pluto mass (kg)
pub const PLUTO_MASS: f64 = 1.303e22;
/// Ceres mass (kg)
pub const CERES_MASS: f64 = 9.393e20;
/// Eris mass (kg)
pub const ERIS_MASS: f64 = 1.6466e22;

/// Minimum radius for a body to be roughly self-gravitating (m)
pub const MIN_DWARF_RADIUS: f64 = 2.0e5;
/// Maximum dwarf planet radius — beyond this it's a planet (m)
pub const MAX_DWARF_RADIUS: f64 = 1.5e6;

pub fn sphere_volume(radius: f64) -> f64 {
    (4.0 / 3.0) * PI * radius.powi(3)
}

pub fn sphere_mass(radius: f64, density: f64) -> f64 {
    sphere_volume(radius) * density
}

pub fn surface_gravity(mass: f64, radius: f64) -> f64 {
    if radius < 1.0 {
        return 0.0;
    }
    G * mass / (radius * radius)
}

pub fn escape_velocity(mass: f64, radius: f64) -> f64 {
    if radius < 1.0 {
        return 0.0;
    }
    (2.0 * G * mass / radius).sqrt()
}

pub fn orbital_period(semi_major_au: f64, central_mass: f64) -> f64 {
    let a = semi_major_au * AU;
    2.0 * PI * (a.powi(3) / (G * central_mass)).sqrt()
}

pub fn vis_viva(central_mass: f64, r: f64, a: f64) -> f64 {
    (G * central_mass * (2.0 / r - 1.0 / a)).sqrt()
}

pub fn hill_sphere(a: f64, m_body: f64, m_central: f64) -> f64 {
    a * (m_body / (3.0 * m_central)).powf(1.0 / 3.0)
}

/// Perihelion distance (AU)
pub fn perihelion_au(semi_major_au: f64, eccentricity: f64) -> f64 {
    semi_major_au * (1.0 - eccentricity)
}

/// Aphelion distance (AU)
pub fn aphelion_au(semi_major_au: f64, eccentricity: f64) -> f64 {
    semi_major_au * (1.0 + eccentricity)
}

/// Equilibrium temperature at distance r (m) from the Sun (K)
pub fn equilibrium_temperature(r_m: f64, albedo: f64) -> f64 {
    if r_m < 1.0 {
        return 0.0;
    }
    (SOLAR_LUMINOSITY * (1.0 - albedo) / (16.0 * PI * STEFAN_BOLTZMANN * r_m * r_m)).powf(0.25)
}