use crate::archive::pluto_tables::{ARGUMENTS, LATITUDE_TERMS, LONGITUDE_TERMS, RADIUS_TERMS};
use crate::coordinates::{cartesian, centers::Heliocentric, frames::EclipticMeanJ2000, spherical};
use crate::qtty::{AstronomicalUnit, Degrees, Radian, AU};
use crate::time::JulianDate;
pub struct Pluto;
impl Pluto {
pub fn get_heliocentric(
jd: JulianDate,
) -> cartesian::Position<Heliocentric, EclipticMeanJ2000, AstronomicalUnit> {
let t = jd.julian_centuries();
let jupiter_lon = Degrees::new(34.35 + 3034.9057 * t);
let saturn_lon = Degrees::new(50.08 + 1222.1138 * t);
let pluto_lon = Degrees::new(238.96 + 144.9600 * t);
let mut sum_longitude = Degrees::new(0.0);
let mut sum_latitude = Degrees::new(0.0);
let mut sum_radius = 0.0;
for i in 0..ARGUMENTS.len() {
let a = jupiter_lon * ARGUMENTS[i].j
+ saturn_lon * ARGUMENTS[i].s
+ pluto_lon * ARGUMENTS[i].p;
let (sin_a, cos_a) = a.to::<Radian>().sin_cos();
sum_longitude +=
Degrees::new(LONGITUDE_TERMS[i].a * sin_a + LONGITUDE_TERMS[i].b * cos_a);
sum_latitude += Degrees::new(LATITUDE_TERMS[i].a * sin_a + LATITUDE_TERMS[i].b * cos_a);
sum_radius += RADIUS_TERMS[i].a * sin_a + RADIUS_TERMS[i].b * cos_a;
}
let lon = sum_longitude * 0.000001 + Degrees::new(238.958116 + 144.96 * t);
let lat = sum_latitude * 0.000001 - Degrees::new(3.908239);
let rad = sum_radius * 0.0000001 + 40.7241346;
spherical::Position::<Heliocentric, EclipticMeanJ2000, AstronomicalUnit>::new(
lon,
lat,
rad * AU,
)
.to_cartesian()
}
}
#[cfg(test)]
mod tests {
use crate::calculus::pluto::Pluto;
use crate::qtty::AstronomicalUnits;
use crate::time::JulianDate;
#[test]
fn pluto_heliocentric_position_j2000() {
let pos = Pluto::get_heliocentric(JulianDate::J2000);
assert!(
(pos.x() - AstronomicalUnits::new(-9.875333629852145))
.abs()
.value()
< 1e-6
);
assert!(
(pos.y() - AstronomicalUnits::new(-27.958786187190157))
.abs()
.value()
< 1e-6
);
assert!(
(pos.z() - AstronomicalUnits::new(5.850444258527083))
.abs()
.value()
< 1e-6
);
}
}