earths 0.0.3

High-fidelity Earth simulation engine — orbit, atmosphere, geology, hydrology, biosphere, terrain, lighting, rendering, satellites, and temporal systems with full scientific coupling
Documentation
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum CloudType {
    Cumulus,
    Stratus,
    Cirrus,
    Cumulonimbus,
    Altocumulus,
}
pub struct CloudLayer {
    pub cloudtype: CloudType,
    pub basealtitudem: f64,
    pub thicknessm: f64,
    pub coverage: f64,
    pub density: f64,
    pub windspeedms: f64,
    pub winddirection: [f64; 2],
}
impl CloudLayer {
    pub fn cumulus() -> Self {
        Self {
            cloudtype: CloudType::Cumulus,
            basealtitudem: 2000.0,
            thicknessm: 1500.0,
            coverage: 0.4,
            density: 0.3,
            windspeedms: 8.0,
            winddirection: [1.0, 0.0],
        }
    }
    pub fn stratus() -> Self {
        Self {
            cloudtype: CloudType::Stratus,
            basealtitudem: 500.0,
            thicknessm: 500.0,
            coverage: 0.7,
            density: 0.5,
            windspeedms: 5.0,
            winddirection: [0.7, 0.7],
        }
    }
    pub fn cirrus() -> Self {
        Self {
            cloudtype: CloudType::Cirrus,
            basealtitudem: 8000.0,
            thicknessm: 1000.0,
            coverage: 0.3,
            density: 0.05,
            windspeedms: 30.0,
            winddirection: [1.0, 0.2],
        }
    }
    pub fn cumulonimbus() -> Self {
        Self {
            cloudtype: CloudType::Cumulonimbus,
            basealtitudem: 1000.0,
            thicknessm: 12000.0,
            coverage: 0.15,
            density: 0.8,
            windspeedms: 15.0,
            winddirection: [0.5, 0.5],
        }
    }
}
pub struct CloudSystem {
    pub layers: Vec<CloudLayer>,
    pub timeoffsets: f64,
}
impl CloudSystem {
    pub fn earthdefault() -> Self {
        Self {
            layers: vec![
                CloudLayer::cumulus(),
                CloudLayer::stratus(),
                CloudLayer::cirrus(),
            ],
            timeoffsets: 0.0,
        }
    }
    pub fn step(&mut self, dts: f64) {
        self.timeoffsets += dts;
    }
    pub fn sampledensity(&self, altitudem: f64, lat: f64, lon: f64) -> f64 {
        let mut total = 0.0;
        for layer in &self.layers {
            let top = layer.basealtitudem + layer.thicknessm;
            if altitudem >= layer.basealtitudem && altitudem <= top {
                let t = (altitudem - layer.basealtitudem) / layer.thicknessm;
                let profile = 4.0 * t * (1.0 - t);
                total += layer.density * layer.coverage * profile;
            }
        }
        let geofactor = 0.0 * (lat.to_radians().cos() + lon.to_radians().cos());
        (total + geofactor).min(1.0)
    }
}