use super::*;
macro_rules! impl_planet_center_shift {
($center:ty, $planet:ident) => {
impl<F> CenterShiftProvider<$center, Barycentric, F> for ()
where
F: affn::ReferenceFrame,
(): FrameRotationProvider<EclipticMeanJ2000, F>,
{
#[inline]
fn try_shift<Eph: Ephemeris, Eop: EopProvider, Nut: NutationModel>(
jd: JulianDate,
ctx: &AstroContext<Eph, Eop>,
) -> Result<AuShift, CenterShiftError> {
let position =
Eph::try_planet_barycentric(crate::ephemeris::MajorPlanet::$planet, jd)?;
Ok(rotate_shift_from_ecliptic::<_, F, Eph, Eop, Nut>(
position, jd, ctx,
))
}
}
impl_reverse_center_shifts!($center);
};
}
impl_planet_center_shift!(Mercurycentric, Mercury);
impl_planet_center_shift!(Venuscentric, Venus);
impl_planet_center_shift!(Marscentric, Mars);
impl_planet_center_shift!(Jovicentric, Jupiter);
impl_planet_center_shift!(Saturnocentric, Saturn);
impl_planet_center_shift!(Uranocentric, Uranus);
impl_planet_center_shift!(Neptunocentric, Neptune);
impl<F> CenterShiftProvider<Plutocentric, Barycentric, F> for ()
where
F: affn::ReferenceFrame,
(): FrameRotationProvider<EclipticMeanJ2000, F>,
{
#[inline]
fn try_shift<Eph: Ephemeris, Eop: EopProvider, Nut: NutationModel>(
jd: JulianDate,
ctx: &AstroContext<Eph, Eop>,
) -> Result<AuShift, CenterShiftError> {
let bary_pos = Eph::try_pluto_barycentric(jd)?;
Ok(rotate_shift_from_ecliptic::<_, F, Eph, Eop, Nut>(
bary_pos, jd, ctx,
))
}
}
impl_reverse_center_shifts!(Plutocentric);
impl<F> CenterShiftProvider<Selenocentric, Barycentric, F> for ()
where
F: affn::ReferenceFrame,
(): FrameRotationProvider<EclipticMeanJ2000, F>,
{
#[inline]
fn try_shift<Eph: Ephemeris, Eop: EopProvider, Nut: NutationModel>(
jd: JulianDate,
ctx: &AstroContext<Eph, Eop>,
) -> Result<AuShift, CenterShiftError> {
let moon_geo_au = Eph::try_moon_geocentric(jd)?.to_unit::<crate::qtty::AstronomicalUnit>();
let earth_bary = Eph::try_earth_barycentric(jd)?;
let seleno_bary =
Position::<Barycentric, EclipticMeanJ2000, crate::qtty::AstronomicalUnit>::new(
moon_geo_au.x() + earth_bary.x(),
moon_geo_au.y() + earth_bary.y(),
moon_geo_au.z() + earth_bary.z(),
);
Ok(rotate_shift_from_ecliptic::<_, F, Eph, Eop, Nut>(
seleno_bary,
jd,
ctx,
))
}
}
impl<F> CenterShiftProvider<Geocentric, Selenocentric, F> for ()
where
F: affn::ReferenceFrame,
(): FrameRotationProvider<EclipticMeanJ2000, F>,
{
#[inline]
fn try_shift<Eph: Ephemeris, Eop: EopProvider, Nut: NutationModel>(
jd: JulianDate,
ctx: &AstroContext<Eph, Eop>,
) -> Result<AuShift, CenterShiftError> {
let moon_geo_au = Eph::try_moon_geocentric(jd)?.to_unit::<crate::qtty::AstronomicalUnit>();
let geo_to_seleno =
Position::<Geocentric, EclipticMeanJ2000, crate::qtty::AstronomicalUnit>::new(
-moon_geo_au.x(),
-moon_geo_au.y(),
-moon_geo_au.z(),
);
Ok(rotate_shift_from_ecliptic::<_, F, Eph, Eop, Nut>(
geo_to_seleno,
jd,
ctx,
))
}
}
impl_reverse_center_shifts_without_geocentric!(Selenocentric);
impl<F> CenterShiftProvider<Selenocentric, Geocentric, F> for ()
where
F: affn::ReferenceFrame,
(): FrameRotationProvider<EclipticMeanJ2000, F>,
{
#[inline]
fn try_shift<Eph: Ephemeris, Eop: EopProvider, Nut: NutationModel>(
jd: JulianDate,
ctx: &AstroContext<Eph, Eop>,
) -> Result<AuShift, CenterShiftError> {
try_inverse_shift::<Selenocentric, Geocentric, F, Eph, Eop, Nut>(jd, ctx)
}
}