dwarfplanetsfactory 0.0.2

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
use crate::config::parameters;

/// Detached object: trans-Neptunian object whose perihelion is far enough
/// from Neptune (q > 40 AU) that it is dynamically decoupled.
#[derive(Debug)]
pub struct Detached {
    pub radius: f64,
    pub density: f64,
    pub albedo: f64,
    pub semi_major_axis: f64,
    pub eccentricity: f64,
    pub inclination: f64,
    pub rotation_period: f64,
}

impl Detached {
    pub fn new(radius: f64, semi_major_axis: f64, eccentricity: f64) -> Self {
        let e = eccentricity.clamp(0.1, 0.8);
        let a = semi_major_axis.clamp(40.0, 500.0);
        Self {
            radius: radius.clamp(parameters::MIN_DWARF_RADIUS, parameters::MAX_DWARF_RADIUS),
            density: 1700.0,
            albedo: 0.09,
            semi_major_axis: a,
            eccentricity: e,
            inclination: 15.0,
            rotation_period: 12.0 * 3600.0,
        }
    }

    pub fn with_density(mut self, density: f64) -> Self {
        self.density = density.clamp(500.0, 3500.0);
        self
    }

    pub fn with_albedo(mut self, albedo: f64) -> Self {
        self.albedo = albedo.clamp(0.01, 0.99);
        self
    }

    pub fn with_inclination(mut self, inc: f64) -> Self {
        self.inclination = inc.clamp(0.0, 90.0);
        self
    }

    pub fn with_rotation_period(mut self, period_s: f64) -> Self {
        self.rotation_period = period_s.clamp(3600.0, 1.0e7);
        self
    }

    pub fn mass(&self) -> f64 {
        parameters::sphere_mass(self.radius, self.density)
    }

    pub fn perihelion(&self) -> f64 {
        parameters::perihelion_au(self.semi_major_axis, self.eccentricity)
    }

    pub fn aphelion(&self) -> f64 {
        parameters::aphelion_au(self.semi_major_axis, self.eccentricity)
    }

    pub fn orbital_period_years(&self) -> f64 {
        parameters::orbital_period(self.semi_major_axis, parameters::SOLAR_MASS) / parameters::YEAR
    }

    /// Is this truly detached from Neptune's influence? (q > 40 AU)
    pub fn is_truly_detached(&self) -> bool {
        self.perihelion() > 40.0
    }

    /// Could be influenced by a hypothetical Planet Nine
    pub fn planet_nine_candidate(&self) -> bool {
        self.semi_major_axis > 150.0 && self.perihelion() > 40.0
    }

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

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

    pub fn equilibrium_temp(&self) -> f64 {
        parameters::equilibrium_temperature(self.semi_major_axis * parameters::AU, self.albedo)
    }
}