#[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"
}
}