#[derive(Debug, Clone, Copy, PartialEq)]
pub enum CloudType {
AmmoniaIce,
AmmoniumHydrosulfide,
WaterIce,
DeepWater,
HighAltitudeHaze,
}
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 ammoniaice() -> Self {
Self {
cloudtype: CloudType::AmmoniaIce,
basealtitudem: 30000.0,
thicknessm: 15000.0,
coverage: 0.85,
density: 0.6,
windspeedms: 150.0,
winddirection: [1.0, 0.0],
}
}
pub fn ammoniumhydrosulfide() -> Self {
Self {
cloudtype: CloudType::AmmoniumHydrosulfide,
basealtitudem: 10000.0,
thicknessm: 20000.0,
coverage: 0.75,
density: 0.7,
windspeedms: 120.0,
winddirection: [0.9, 0.3],
}
}
pub fn waterice() -> Self {
Self {
cloudtype: CloudType::WaterIce,
basealtitudem: -20000.0,
thicknessm: 30000.0,
coverage: 0.65,
density: 0.5,
windspeedms: 80.0,
winddirection: [0.8, 0.4],
}
}
pub fn deepwater() -> Self {
Self {
cloudtype: CloudType::DeepWater,
basealtitudem: -80000.0,
thicknessm: 40000.0,
coverage: 0.9,
density: 0.95,
windspeedms: 40.0,
winddirection: [0.7, 0.5],
}
}
pub fn highaltitudehaze() -> Self {
Self {
cloudtype: CloudType::HighAltitudeHaze,
basealtitudem: 50000.0,
thicknessm: 25000.0,
coverage: 0.4,
density: 0.08,
windspeedms: 200.0,
winddirection: [1.0, 0.1],
}
}
}
pub struct CloudSystem {
pub layers: Vec<CloudLayer>,
pub timeoffsets: f64,
}
impl CloudSystem {
pub fn jupiterdefault() -> Self {
Self {
layers: vec![
CloudLayer::highaltitudehaze(),
CloudLayer::ammoniaice(),
CloudLayer::ammoniumhydrosulfide(),
CloudLayer::waterice(),
CloudLayer::deepwater(),
],
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 bandfactor = 1.0 + 0.5 * (6.0 * lat.to_radians()).cos();
let geofactor = 0.0 * lon.to_radians().cos();
(total * bandfactor + geofactor).min(1.0)
}
}