use crate::astro::orbit::Orbit;
use crate::time::JulianDate;
use qtty::{AstronomicalUnits, Degrees, Kilometers};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum OrbitFrame {
Heliocentric,
Barycentric,
}
#[derive(Clone, Debug)]
pub struct Comet<'a> {
pub name: &'a str,
pub tail_length: Kilometers,
pub orbit: Orbit,
pub reference: OrbitFrame,
}
impl<'a> Comet<'a> {
pub const fn new_const(
name: &'a str,
tail_length: Kilometers,
orbit: Orbit,
reference: OrbitFrame,
) -> Self {
Self {
name,
tail_length,
orbit,
reference,
}
}
pub fn builder() -> CometBuilder<'a> {
CometBuilder::default()
}
}
#[derive(Default, Debug, Clone)]
pub struct CometBuilder<'a> {
name: Option<&'a str>,
tail_length: Option<Kilometers>,
orbit: Option<Orbit>,
reference: Option<OrbitFrame>,
}
impl<'a> CometBuilder<'a> {
pub fn name(mut self, name: &'a str) -> Self {
self.name = Some(name);
self
}
pub fn tail_length(mut self, len: Kilometers) -> Self {
self.tail_length = Some(len);
self
}
pub fn orbit(mut self, orbit: Orbit) -> Self {
self.orbit = Some(orbit);
self
}
pub fn reference(mut self, frame: OrbitFrame) -> Self {
self.reference = Some(frame);
self
}
pub fn build(self) -> Comet<'a> {
Comet {
name: self.name.expect("missing name"),
tail_length: self.tail_length.expect("missing tail_length"),
orbit: self.orbit.expect("missing orbit"),
reference: self.reference.unwrap_or(OrbitFrame::Heliocentric),
}
}
}
impl<'a> Comet<'a> {
pub fn period_years(&self) -> f64 {
let a = self.orbit.semi_major_axis;
a.value().powf(1.5)
}
}
pub const HALLEY: Comet = Comet::new_const(
"1P/Halley",
Kilometers::new(1.0e7),
Orbit::new(
AstronomicalUnits::new(17.834144),
0.967_142_9,
Degrees::new(162.262_69),
Degrees::new(58.42008),
Degrees::new(111.33249),
Degrees::new(38.384),
JulianDate::J2000,
),
OrbitFrame::Heliocentric,
);
pub const ENCKE: Comet = Comet::new_const(
"2P/Encke",
Kilometers::new(5.0e6),
Orbit::new(
AstronomicalUnits::new(2.215_080),
0.850_219,
Degrees::new(11.780),
Degrees::new(334.568),
Degrees::new(186.545),
Degrees::new(163.105),
JulianDate::J2000,
),
OrbitFrame::Heliocentric,
);
pub const HALE_BOPP: Comet = Comet::new_const(
"C/1995 O1 (Hale‑Bopp)",
Kilometers::new(1.0e8),
Orbit::new(
AstronomicalUnits::new(286.538),
0.995_086,
Degrees::new(89.425),
Degrees::new(282.472),
Degrees::new(130.589),
Degrees::new(17.258),
JulianDate::J2000,
),
OrbitFrame::Barycentric,
);
pub const COMET_PRESETS: &[&Comet] = &[&HALLEY, &ENCKE, &HALE_BOPP];