use crate::config::parameters::*;
pub struct BinaryAsteroid {
pub radius_primary: f64,
pub radius_secondary: f64,
pub density: f64,
pub mass_primary: f64,
pub mass_secondary: f64,
pub separation: f64,
pub semi_major_axis_helio: f64,
pub eccentricity_helio: f64,
pub eccentricity_mutual: f64,
pub albedo: f64,
}
impl BinaryAsteroid {
pub fn new(
radius_primary_m: f64,
radius_secondary_m: f64,
density: f64,
separation_m: f64,
) -> Self {
let r1 = radius_primary_m.clamp(100.0, MAX_ASTEROID_RADIUS);
let r2 = radius_secondary_m.clamp(10.0, r1);
let d = density.clamp(500.0, 8000.0);
let m1 = sphere_mass(r1, d);
let m2 = sphere_mass(r2, d);
let sep = separation_m.max(r1 + r2 + 1.0);
Self {
radius_primary: r1,
radius_secondary: r2,
density: d,
mass_primary: m1,
mass_secondary: m2,
separation: sep,
semi_major_axis_helio: 2.5,
eccentricity_helio: 0.1,
eccentricity_mutual: 0.0,
albedo: 0.15,
}
}
pub fn with_heliocentric_orbit(mut self, semi_major_au: f64, ecc: f64) -> Self {
self.semi_major_axis_helio = semi_major_au.max(0.1);
self.eccentricity_helio = ecc.clamp(0.0, 0.999);
self
}
pub fn with_mutual_eccentricity(mut self, e: f64) -> Self {
self.eccentricity_mutual = e.clamp(0.0, 0.9);
self
}
pub fn total_mass(&self) -> f64 {
self.mass_primary + self.mass_secondary
}
pub fn mass_ratio(&self) -> f64 {
self.mass_secondary / self.mass_primary
}
pub fn size_ratio(&self) -> f64 {
self.radius_secondary / self.radius_primary
}
pub fn mutual_orbital_period(&self) -> f64 {
2.0 * std::f64::consts::PI * (self.separation.powi(3) / (G * self.total_mass())).sqrt()
}
pub fn mutual_orbital_velocity_primary(&self) -> f64 {
let total = self.total_mass();
let a1 = self.separation * self.mass_secondary / total;
(G * total / self.separation).sqrt() * a1 / self.separation
}
pub fn mutual_orbital_velocity_secondary(&self) -> f64 {
let total = self.total_mass();
let a2 = self.separation * self.mass_primary / total;
(G * total / self.separation).sqrt() * a2 / self.separation
}
pub fn heliocentric_period(&self) -> f64 {
orbital_period(self.semi_major_axis_helio, SOLAR_MASS)
}
pub fn heliocentric_period_years(&self) -> f64 {
self.heliocentric_period() / YEAR
}
pub fn hill_sphere_radius(&self) -> f64 {
hill_sphere(
self.semi_major_axis_helio * AU,
self.total_mass(),
SOLAR_MASS,
)
}
pub fn is_stable(&self) -> bool {
self.separation < self.hill_sphere_radius() / 3.0
}
pub fn surface_gravity_primary(&self) -> f64 {
surface_gravity(self.mass_primary, self.radius_primary)
}
pub fn escape_velocity_primary(&self) -> f64 {
escape_velocity(self.mass_primary, self.radius_primary)
}
pub fn roche_limit(&self) -> f64 {
let rho_ratio = 1.0_f64;
self.radius_primary * 2.456 * rho_ratio.powf(1.0 / 3.0)
}
pub fn is_contact_binary(&self) -> bool {
self.separation <= self.radius_primary + self.radius_secondary
}
}