use crate::DeriveReferenceFrame;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "dec", azimuth = "ra", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ICRS;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "dec", azimuth = "ra")]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ICRF;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "dec", azimuth = "ra", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct EquatorialMeanJ2000;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "dec", azimuth = "ra", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct EME2000;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "dec", azimuth = "ra", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct EquatorialMeanOfDate;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "dec", azimuth = "ra", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct EquatorialTrueOfDate;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "dec", azimuth = "ra", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct GCRS;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "dec", azimuth = "ra", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CIRS;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "dec", azimuth = "ra", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct TIRS;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "alt", azimuth = "az", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Horizontal;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "lat", azimuth = "lon", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct EclipticMeanJ2000;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "lat", azimuth = "lon", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct EclipticOfDate;
pub type EclipticMeanOfDate = EclipticOfDate;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "lat", azimuth = "lon", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct EclipticTrueOfDate;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(
polar = "lat",
azimuth = "lon",
distance = "altitude",
inherent,
ellipsoid = "Grs80"
)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ITRF;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(
polar = "lat",
azimuth = "lon",
distance = "altitude",
inherent,
ellipsoid = "Wgs84"
)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ECEF;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "b", azimuth = "l", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Galactic;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "dec", azimuth = "ra", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct FK4B1950;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "dec", azimuth = "ra", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct TEME;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "lat", azimuth = "lon", distance = "radius", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct MercuryFixed;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "lat", azimuth = "lon", distance = "radius", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct VenusFixed;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "lat", azimuth = "lon", distance = "radius", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct MarsFixed;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "lat", azimuth = "lon", distance = "radius", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct MoonPrincipalAxes;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "lat", azimuth = "lon", distance = "radius", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct JupiterSystemIII;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "lat", azimuth = "lon", distance = "radius", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct SaturnFixed;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "lat", azimuth = "lon", distance = "radius", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct UranusFixed;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "lat", azimuth = "lon", distance = "radius", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct NeptuneFixed;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, DeriveReferenceFrame)]
#[frame(polar = "lat", azimuth = "lon", distance = "radius", inherent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PlutoFixed;
#[cfg(test)]
mod tests {
use super::*;
use crate::centers::{AffineCenter, ReferenceCenter};
use crate::frames::{ReferenceFrame, SphericalNaming};
use crate::spherical::{Direction, Position};
use qtty::*;
#[test]
fn test_frame_names() {
assert_eq!(ICRS::frame_name(), "ICRS");
assert_eq!(ICRF::frame_name(), "ICRF");
assert_eq!(EME2000::frame_name(), "EME2000");
assert_eq!(Horizontal::frame_name(), "Horizontal");
assert_eq!(EclipticMeanJ2000::frame_name(), "EclipticMeanJ2000");
assert_eq!(EclipticOfDate::frame_name(), "EclipticOfDate");
assert_eq!(EclipticTrueOfDate::frame_name(), "EclipticTrueOfDate");
assert_eq!(EclipticMeanOfDate::frame_name(), "EclipticOfDate");
assert_eq!(Galactic::frame_name(), "Galactic");
assert_eq!(ITRF::frame_name(), "ITRF");
assert_eq!(ECEF::frame_name(), "ECEF");
assert_eq!(FK4B1950::frame_name(), "FK4B1950");
assert_eq!(TEME::frame_name(), "TEME");
assert_eq!(MercuryFixed::frame_name(), "MercuryFixed");
assert_eq!(VenusFixed::frame_name(), "VenusFixed");
assert_eq!(MarsFixed::frame_name(), "MarsFixed");
assert_eq!(MoonPrincipalAxes::frame_name(), "MoonPrincipalAxes");
assert_eq!(JupiterSystemIII::frame_name(), "JupiterSystemIII");
assert_eq!(SaturnFixed::frame_name(), "SaturnFixed");
assert_eq!(UranusFixed::frame_name(), "UranusFixed");
assert_eq!(NeptuneFixed::frame_name(), "NeptuneFixed");
assert_eq!(PlutoFixed::frame_name(), "PlutoFixed");
}
#[test]
fn test_spherical_naming() {
assert_eq!(ICRS::polar_name(), "dec");
assert_eq!(ICRS::azimuth_name(), "ra");
assert_eq!(EME2000::polar_name(), "dec");
assert_eq!(EME2000::azimuth_name(), "ra");
assert_eq!(Horizontal::polar_name(), "alt");
assert_eq!(Horizontal::azimuth_name(), "az");
assert_eq!(EclipticMeanJ2000::polar_name(), "lat");
assert_eq!(EclipticMeanJ2000::azimuth_name(), "lon");
assert_eq!(EclipticOfDate::polar_name(), "lat");
assert_eq!(EclipticOfDate::azimuth_name(), "lon");
assert_eq!(EclipticTrueOfDate::polar_name(), "lat");
assert_eq!(EclipticTrueOfDate::azimuth_name(), "lon");
assert_eq!(Galactic::polar_name(), "b");
assert_eq!(Galactic::azimuth_name(), "l");
assert_eq!(ITRF::distance_name(), "altitude");
assert_eq!(MercuryFixed::polar_name(), "lat");
assert_eq!(MercuryFixed::azimuth_name(), "lon");
assert_eq!(MercuryFixed::distance_name(), "radius");
assert_eq!(MarsFixed::polar_name(), "lat");
assert_eq!(MarsFixed::azimuth_name(), "lon");
assert_eq!(MarsFixed::distance_name(), "radius");
}
#[test]
fn test_icrs_direction_new() {
let d = Direction::<ICRS>::new(120.0 * DEG, 45.0 * DEG);
assert_eq!(d.ra(), 120.0 * DEG);
assert_eq!(d.dec(), 45.0 * DEG);
}
#[test]
fn test_horizontal_direction_new() {
let d = Direction::<Horizontal>::new(30.0 * DEG, 180.0 * DEG);
assert_eq!(d.alt(), 30.0 * DEG);
assert_eq!(d.az(), 180.0 * DEG);
}
#[test]
fn test_ecliptic_direction_new() {
let d = Direction::<EclipticMeanJ2000>::new(270.0 * DEG, -10.0 * DEG);
assert_eq!(d.lon(), 270.0 * DEG);
assert_eq!(d.lat(), -10.0 * DEG);
}
#[test]
fn test_galactic_direction_new() {
let d = Direction::<Galactic>::new(45.0 * DEG, 20.0 * DEG);
assert_eq!(d.l(), 45.0 * DEG);
assert_eq!(d.b(), 20.0 * DEG);
}
#[test]
fn test_direction_canonicalization() {
let d = Direction::<ICRS>::new(370.0 * DEG, 45.0 * DEG);
assert!((d.ra().value() - 10.0).abs() < 1e-10);
assert_eq!(d.dec(), 45.0 * DEG);
let d = Direction::<ICRS>::new(0.0 * DEG, 100.0 * DEG);
assert!((d.dec().value() - 80.0).abs() < 1e-10);
}
#[derive(Debug, Copy, Clone)]
struct TestCenter;
impl ReferenceCenter for TestCenter {
type Params = ();
fn center_name() -> &'static str {
"TestCenter"
}
}
impl AffineCenter for TestCenter {}
#[test]
fn test_icrs_position_new() {
let p = Position::<TestCenter, ICRS, Parsec>::new(120.0 * DEG, 45.0 * DEG, 10.0);
assert_eq!(p.ra(), 120.0 * DEG);
assert_eq!(p.dec(), 45.0 * DEG);
}
#[test]
fn test_horizontal_position_new() {
let p = Position::<TestCenter, Horizontal, Kilometer>::new(30.0 * DEG, 180.0 * DEG, 100.0);
assert_eq!(p.alt(), 30.0 * DEG);
assert_eq!(p.az(), 180.0 * DEG);
}
#[test]
fn test_position_accessors_any_center() {
#[derive(Debug, Copy, Clone)]
struct ParamCenter;
impl ReferenceCenter for ParamCenter {
type Params = f64;
fn center_name() -> &'static str {
"ParamCenter"
}
}
let p = Position::<ParamCenter, ICRS, Parsec>::new_raw_with_params(
42.0,
45.0 * DEG,
120.0 * DEG,
Quantity::<Parsec>::new(10.0),
);
assert_eq!(p.ra(), 120.0 * DEG);
assert_eq!(p.dec(), 45.0 * DEG);
}
}