pub struct DustSystemEndpoint {
pub base_altitude_m: f64,
pub top_altitude_m: f64,
pub optical_depth: f64,
pub single_scatter_albedo: f64,
pub asymmetry_parameter: f64,
pub particle_effective_radius_um: f64,
pub color_linear: [f64; 3],
}
impl DustSystemEndpoint {
pub fn mars_background() -> Self {
Self {
base_altitude_m: 0.0,
top_altitude_m: 40_000.0,
optical_depth: crate::MEAN_DUST_OPTICAL_DEPTH,
single_scatter_albedo: 0.92,
asymmetry_parameter: 0.63,
particle_effective_radius_um: 1.5,
color_linear: [0.72, 0.45, 0.20],
}
}
pub fn mars_global_storm() -> Self {
Self {
base_altitude_m: 0.0,
top_altitude_m: 80_000.0,
optical_depth: crate::GLOBAL_STORM_OPTICAL_DEPTH,
single_scatter_albedo: 0.94,
asymmetry_parameter: 0.65,
particle_effective_radius_um: 2.5,
color_linear: [0.68, 0.40, 0.18],
}
}
pub fn density_at_altitude(&self, alt_m: f64) -> f64 {
if alt_m < self.base_altitude_m || alt_m > self.top_altitude_m {
return 0.0;
}
let scale_h = (self.top_altitude_m - self.base_altitude_m) / 4.0;
let h = alt_m - self.base_altitude_m;
self.optical_depth * (-h / scale_h).exp()
}
pub fn surface_solar_fraction(&self) -> f64 {
(-self.optical_depth).exp()
}
pub fn phase_function(&self, cos_theta: f64) -> f64 {
let g = self.asymmetry_parameter;
(1.0 - g * g) / (4.0 * std::f64::consts::PI * (1.0 + g * g - 2.0 * g * cos_theta).powf(1.5))
}
pub fn effective_radius_um(&self) -> f64 {
self.particle_effective_radius_um
}
}