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

/// Absolute magnitude H from radius (m) and geometric albedo
/// H = constant - 5 log10(D_km) - 2.5 log10(albedo)
pub fn absolute_magnitude(radius: f64, albedo: f64) -> f64 {
    let d_km = 2.0 * radius / 1000.0;
    if d_km < 1.0e-3 || albedo < 1.0e-6 {
        return 99.0;
    }
    let h_sun: f64 = -26.74; // apparent mag of Sun
    let au_km: f64 = parameters::AU / 1000.0;
    // H = H_sun + 5 log10(AU/km) - 5 log10(D_km) - 2.5 log10(albedo) - 2.5 log10(pi)
    // Simplified: H ≈ 15.618 - 5 log10(D_km) - 2.5 log10(p_v)
    h_sun + 5.0 * (au_km).log10()
        - 5.0 * d_km.log10()
        - 2.5 * albedo.log10()
        - 2.5 * parameters::PI.log10()
}

/// Apparent visual magnitude at distance r (AU) from the Sun and
/// delta (AU) from the observer, with phase angle alpha (degrees)
pub fn apparent_magnitude(abs_mag: f64, r_au: f64, delta_au: f64, phase_deg: f64) -> f64 {
    let alpha = phase_deg.to_radians();
    // IAU H-G system with G=0.15 (typical TNO)
    let g_param: f64 = 0.15;
    let phi1 = (-3.33 * (alpha / 2.0).tan().powf(0.63)).exp();
    let phi2 = (-1.87 * (alpha / 2.0).tan().powf(1.22)).exp();
    let phi = (1.0 - g_param) * phi1 + g_param * phi2;
    if phi < 1.0e-20 {
        return 99.0;
    }
    abs_mag + 5.0 * (r_au * delta_au).log10() - 2.5 * phi.log10()
}

/// Thermal flux (W/m²) from a dwarf planet at distance delta (AU) from the
/// observer, assuming blackbody emission at equilibrium temperature
pub fn thermal_flux(radius: f64, albedo: f64, r_au: f64, delta_au: f64) -> f64 {
    let temp = parameters::equilibrium_temperature(r_au * parameters::AU, albedo);
    let luminosity =
        4.0 * parameters::PI * radius * radius * parameters::STEFAN_BOLTZMANN * temp.powi(4);
    let d = delta_au * parameters::AU;
    if d < 1.0 {
        return 0.0;
    }
    luminosity / (4.0 * parameters::PI * d * d)
}

/// Color index (B-V) estimate from albedo and surface type
/// Ultra-red TNOs: B-V ≈ 1.2-1.5; neutral: B-V ≈ 0.6-0.8
pub fn color_index_bv(albedo: f64, is_ultra_red: bool) -> f64 {
    let base = if is_ultra_red { 1.35 } else { 0.70 };
    // Slight albedo dependence
    base - 0.1 * (albedo - 0.1)
}

/// Angular diameter (arcsec) at distance delta (AU)
pub fn angular_diameter(radius: f64, delta_au: f64) -> f64 {
    let d = delta_au * parameters::AU;
    if d < 1.0 {
        return 0.0;
    }
    2.0 * radius / d * 206265.0
}