use crate::constants::{DAYS_PER_JULIAN_CENTURY, J2000_JD, PI, TWOPI};
#[inline]
pub fn jd_to_centuries(jd1: f64, jd2: f64) -> f64 {
((jd1 - J2000_JD) + jd2) / DAYS_PER_JULIAN_CENTURY
}
#[inline]
pub fn normalize_longitude(lon: f64) -> f64 {
let mut normalized = lon % 360.0;
if normalized > 180.0 {
normalized -= 360.0;
} else if normalized < -180.0 {
normalized += 360.0;
}
normalized
}
#[inline]
pub fn normalize_latitude(lat: f64) -> f64 {
lat.clamp(-90.0, 90.0)
}
#[inline]
pub fn normalize_angle_rad(angle: f64) -> f64 {
let mut normalized = angle % TWOPI;
if normalized > PI {
normalized -= TWOPI;
} else if normalized < -PI {
normalized += TWOPI;
}
normalized
}
#[inline]
pub fn normalize_angle_to_positive(angle: f64) -> f64 {
let mut a = angle % TWOPI;
if a < 0.0 {
a += TWOPI;
}
a
}
#[inline]
pub fn angular_difference(a: f64, b: f64) -> f64 {
let mut diff = a - b;
if diff > 180.0 {
diff -= 360.0;
} else if diff < -180.0 {
diff += 360.0;
}
diff
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_jd_to_centuries_j2000() {
let t = jd_to_centuries(J2000_JD, 0.0);
assert_eq!(t, 0.0);
}
#[test]
fn test_jd_to_centuries_one_century() {
let t = jd_to_centuries(J2000_JD, crate::constants::DAYS_PER_JULIAN_CENTURY);
assert_eq!(t, 1.0);
}
#[test]
fn test_jd_to_centuries_negative() {
let t = jd_to_centuries(J2000_JD, -crate::constants::DAYS_PER_JULIAN_CENTURY);
assert_eq!(t, -1.0);
}
#[test]
fn test_jd_to_centuries_two_part() {
let t = jd_to_centuries(crate::constants::MJD_ZERO_POINT, 51544.5);
assert_eq!(t, 0.0);
}
#[test]
fn test_jd_to_centuries_precision() {
let jd2 = 0.123456789;
let t = jd_to_centuries(J2000_JD, jd2);
let expected = 0.123456789 / crate::constants::DAYS_PER_JULIAN_CENTURY;
assert!((t - expected).abs() < 1e-15);
}
#[test]
fn test_normalize_longitude() {
assert_eq!(normalize_longitude(0.0), 0.0);
assert_eq!(normalize_longitude(180.0), 180.0);
assert_eq!(normalize_longitude(-180.0), -180.0);
assert_eq!(normalize_longitude(181.0), -179.0);
assert_eq!(normalize_longitude(-181.0), 179.0);
assert_eq!(normalize_longitude(360.0), 0.0);
assert_eq!(normalize_longitude(720.0), 0.0);
assert_eq!(normalize_longitude(450.0), 90.0);
}
#[test]
fn test_normalize_latitude() {
assert_eq!(normalize_latitude(0.0), 0.0);
assert_eq!(normalize_latitude(45.0), 45.0);
assert_eq!(normalize_latitude(-45.0), -45.0);
assert_eq!(normalize_latitude(90.0), 90.0);
assert_eq!(normalize_latitude(-90.0), -90.0);
assert_eq!(normalize_latitude(100.0), 90.0);
assert_eq!(normalize_latitude(-100.0), -90.0);
}
#[test]
fn test_normalize_angle_rad() {
assert_eq!(normalize_angle_rad(0.0), 0.0);
assert!((normalize_angle_rad(PI) - PI).abs() < 1e-15);
assert!((normalize_angle_rad(-PI) - (-PI)).abs() < 1e-15);
assert!((normalize_angle_rad(TWOPI)).abs() < 1e-15);
assert!((normalize_angle_rad(3.0 * PI) - PI).abs() < 1e-15);
}
#[test]
fn test_angular_difference() {
assert_eq!(angular_difference(0.0, 0.0), 0.0);
assert_eq!(angular_difference(90.0, 45.0), 45.0);
assert_eq!(angular_difference(45.0, 90.0), -45.0);
assert!((angular_difference(10.0, 350.0) - 20.0).abs() < 1e-12);
assert!((angular_difference(-170.0, 170.0) - 20.0).abs() < 1e-12);
assert!((angular_difference(350.0, 10.0) + 20.0).abs() < 1e-12);
}
#[test]
fn test_normalize_angle_to_positive() {
assert_eq!(normalize_angle_to_positive(0.0), 0.0);
assert!((normalize_angle_to_positive(TWOPI)).abs() < 1e-15);
assert!((normalize_angle_to_positive(-PI) - PI).abs() < 1e-15);
assert!((normalize_angle_to_positive(3.0 * PI) - PI).abs() < 1e-15);
assert!(normalize_angle_to_positive(1.0) >= 0.0);
assert!(normalize_angle_to_positive(-1.0) >= 0.0);
assert!(normalize_angle_to_positive(-1.0) < TWOPI);
}
}