use crate::config::parameters;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DormancyState {
Dormant,
Extinct,
}
#[derive(Debug)]
pub struct Extinct {
pub nucleus_radius: f64,
pub density: f64,
pub albedo: f64,
pub semi_major_axis: f64,
pub eccentricity: f64,
pub inclination: f64,
pub mantle_thickness: f64,
pub residual_ice_fraction: f64,
pub state: DormancyState,
}
impl Extinct {
pub fn new(nucleus_radius: f64, semi_major_axis: f64, eccentricity: f64) -> Self {
Self {
nucleus_radius: nucleus_radius.max(10.0),
density: 1200.0,
albedo: 0.04,
semi_major_axis: semi_major_axis.clamp(1.0, 50.0),
eccentricity: eccentricity.clamp(0.0, 0.99),
inclination: 15.0,
mantle_thickness: 1.0,
residual_ice_fraction: 0.0,
state: DormancyState::Extinct,
}
}
pub fn with_density(mut self, density: f64) -> Self {
self.density = density.clamp(500.0, 3500.0);
self
}
pub fn with_albedo(mut self, albedo: f64) -> Self {
self.albedo = albedo.clamp(0.01, 0.5);
self
}
pub fn with_inclination(mut self, inclination: f64) -> Self {
self.inclination = inclination.clamp(0.0, 180.0);
self
}
pub fn with_mantle_thickness(mut self, thickness: f64) -> Self {
self.mantle_thickness = thickness.clamp(0.01, 100.0);
self
}
pub fn with_residual_ice(mut self, fraction: f64) -> Self {
self.residual_ice_fraction = fraction.clamp(0.0, 0.3);
if self.residual_ice_fraction > 0.001 {
self.state = DormancyState::Dormant;
}
self
}
pub fn mass(&self) -> f64 {
parameters::sphere_mass(self.nucleus_radius, self.density)
}
pub fn perihelion(&self) -> f64 {
parameters::perihelion_au(self.semi_major_axis, self.eccentricity)
}
pub fn aphelion(&self) -> f64 {
parameters::aphelion_au(self.semi_major_axis, self.eccentricity)
}
pub fn orbital_period_years(&self) -> f64 {
parameters::orbital_period(self.semi_major_axis, parameters::SOLAR_MASS) / parameters::YEAR
}
pub fn tisserand_jupiter(&self) -> f64 {
let a_j = 5.2;
let ratio = a_j / self.semi_major_axis;
let inc_rad = self.inclination.to_radians();
ratio
+ 2.0
* ((1.0 - self.eccentricity * self.eccentricity) * (self.semi_major_axis / a_j))
.sqrt()
* inc_rad.cos()
}
pub fn is_neo_like(&self) -> bool {
self.perihelion() < 1.3
}
pub fn can_reactivate(&self) -> bool {
self.residual_ice_fraction > 0.001
}
pub fn surface_gravity(&self) -> f64 {
parameters::surface_gravity(self.mass(), self.nucleus_radius)
}
pub fn escape_velocity(&self) -> f64 {
parameters::escape_velocity(self.mass(), self.nucleus_radius)
}
}