use crate::config::parameters::*;
pub struct Centaur {
pub radius: f64,
pub density: f64,
pub mass: f64,
pub semi_major_axis: f64,
pub eccentricity: f64,
pub inclination: f64,
pub albedo: f64,
pub coma_active: bool,
pub perihelion_distance: f64,
}
impl Centaur {
pub fn new(radius_m: f64, density: f64, semi_major_au: f64, eccentricity: f64) -> Self {
let radius = radius_m.clamp(MIN_ASTEROID_RADIUS, MAX_ASTEROID_RADIUS);
let density = density.clamp(300.0, 3000.0);
let mass = sphere_mass(radius, density);
let ecc = eccentricity.clamp(0.0, 0.999);
let perihelion = semi_major_au * (1.0 - ecc);
let coma_active = perihelion < 12.0;
Self {
radius,
density,
mass,
semi_major_axis: semi_major_au,
eccentricity: ecc,
inclination: 0.0,
albedo: 0.07,
coma_active,
perihelion_distance: perihelion,
}
}
pub fn with_inclination(mut self, inc_deg: f64) -> Self {
self.inclination = inc_deg.to_radians();
self
}
pub fn with_albedo(mut self, a: f64) -> Self {
self.albedo = a.clamp(0.01, 0.5);
self
}
pub fn perihelion_au(&self) -> f64 {
self.perihelion_distance
}
pub fn aphelion_au(&self) -> f64 {
self.semi_major_axis * (1.0 + self.eccentricity)
}
pub fn orbital_period(&self) -> f64 {
orbital_period(self.semi_major_axis, SOLAR_MASS)
}
pub fn orbital_period_years(&self) -> f64 {
self.orbital_period() / YEAR
}
pub fn surface_gravity(&self) -> f64 {
surface_gravity(self.mass, self.radius)
}
pub fn escape_velocity(&self) -> f64 {
escape_velocity(self.mass, self.radius)
}
pub fn tisserand_jupiter(&self) -> f64 {
tisserand_parameter(
self.semi_major_axis * AU,
self.eccentricity,
self.inclination,
5.2 * AU,
)
}
pub fn tisserand_neptune(&self) -> f64 {
tisserand_parameter(
self.semi_major_axis * AU,
self.eccentricity,
self.inclination,
30.07 * AU,
)
}
pub fn dynamical_lifetime_estimate(&self) -> f64 {
1e7 * YEAR * (self.semi_major_axis / 10.0).powf(1.5)
}
pub fn is_cometary(&self) -> bool {
self.coma_active
}
pub fn equilibrium_temperature(&self) -> f64 {
equilibrium_temperature(SOLAR_LUMINOSITY, self.semi_major_axis * AU, self.albedo)
}
pub fn sublimation_distance_water(&self) -> f64 {
2.7
}
pub fn is_inside_snow_line(&self) -> bool {
self.perihelion_distance < self.sublimation_distance_water()
}
}