mercurys 0.0.3

Mercury celestial simulation crate for the MilkyWay SolarSystem workspace
Documentation
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SurfaceType {
    IntercraterPlains,
    SmoothPlains,
    CrateredHighlands,
    CraterFloor,
    CraterRim,
    LobateScarp,
    Hollows,
    PolarIce,
}

impl SurfaceType {
    pub fn base_albedo(&self) -> f32 {
        match self {
            Self::IntercraterPlains => 0.10,
            Self::SmoothPlains => 0.12,
            Self::CrateredHighlands => 0.09,
            Self::CraterFloor => 0.11,
            Self::CraterRim => 0.08,
            Self::LobateScarp => 0.10,
            Self::Hollows => 0.25,
            Self::PolarIce => 0.80,
        }
    }

    pub fn roughness(&self) -> f32 {
        match self {
            Self::IntercraterPlains => 0.7,
            Self::SmoothPlains => 0.5,
            Self::CrateredHighlands => 0.9,
            Self::CraterFloor => 0.6,
            Self::CraterRim => 0.85,
            Self::LobateScarp => 0.75,
            Self::Hollows => 0.4,
            Self::PolarIce => 0.3,
        }
    }
}

pub struct SplatWeights {
    pub intercrater: f32,
    pub smooth: f32,
    pub highlands: f32,
    pub ice: f32,
}

impl SplatWeights {
    pub fn normalize(&mut self) {
        let total = self.intercrater + self.smooth + self.highlands + self.ice;
        if total > 0.0 {
            self.intercrater /= total;
            self.smooth /= total;
            self.highlands /= total;
            self.ice /= total;
        }
    }
}

pub fn classify_surface(lat: f64, lon: f64, elevation_m: f64) -> SurfaceType {
    if !(lat.is_finite() && lon.is_finite() && elevation_m.is_finite()) {
        return SurfaceType::IntercraterPlains;
    }

    if lat.abs() > 85.0 && elevation_m < -1000.0 {
        return SurfaceType::PolarIce;
    }
    if elevation_m > 1500.0 {
        return SurfaceType::CraterRim;
    }
    if elevation_m < -2000.0 {
        return SurfaceType::CraterFloor;
    }
    if lat.abs() > 60.0 {
        return SurfaceType::SmoothPlains;
    }
    if lat.abs() < 30.0 {
        SurfaceType::IntercraterPlains
    } else {
        SurfaceType::CrateredHighlands
    }
}

pub fn biome(lat: f64, lon: f64) -> &'static str {
    if !(lat.is_finite() && lon.is_finite()) {
        return "unknown";
    }

    if lat.abs() < 10.0 {
        "equatorial"
    } else if lat.abs() < 60.0 {
        "mid-latitude"
    } else {
        "polar"
    }
}