pub mod position;
pub use position::Position;
pub mod direction;
pub use direction::Direction;
#[inline]
pub fn canonicalize_azimuth(angle: qtty::angular::Degrees) -> qtty::angular::Degrees {
angle.normalize()
}
#[inline]
pub fn canonicalize_polar(angle: qtty::angular::Degrees) -> qtty::angular::Degrees {
use qtty::angular::Degrees;
let wrapped = angle.wrap_signed(); if wrapped > Degrees::new(90.0) {
Degrees::new(180.0) - wrapped
} else if wrapped < Degrees::new(-90.0) {
Degrees::new(-180.0) - wrapped
} else {
wrapped
}
}
#[inline]
#[must_use]
pub fn canonicalize_polar_azimuth(
polar: qtty::angular::Degrees,
azimuth: qtty::angular::Degrees,
) -> (qtty::angular::Degrees, qtty::angular::Degrees) {
use qtty::angular::Degrees;
let wrapped = polar.wrap_signed();
let mut azimuth = azimuth;
let polar = if wrapped > Degrees::new(90.0) {
azimuth += Degrees::new(180.0);
Degrees::new(180.0) - wrapped
} else if wrapped < Degrees::new(-90.0) {
azimuth += Degrees::new(180.0);
Degrees::new(-180.0) - wrapped
} else {
wrapped
};
(polar, azimuth.normalize())
}
#[inline]
pub(crate) fn xyz_to_polar_azimuth(
x: f64,
y: f64,
z: f64,
) -> (qtty::angular::Degrees, qtty::angular::Degrees) {
use qtty::angular::Degrees;
let z_clamped = z.clamp(-1.0, 1.0);
let polar = Degrees::new(z_clamped.asin().to_degrees());
let azimuth = Degrees::new(y.atan2(x).to_degrees()).normalize();
(polar, azimuth)
}
#[inline]
pub(crate) fn angular_separation_impl(
polar1: qtty::angular::Degrees,
azimuth1: qtty::angular::Degrees,
polar2: qtty::angular::Degrees,
azimuth2: qtty::angular::Degrees,
) -> qtty::angular::Degrees {
use qtty::angular::Radians;
use qtty::units::{Degree, Radian};
let az1 = azimuth1.to::<Radian>();
let po1 = polar1.to::<Radian>();
let az2 = azimuth2.to::<Radian>();
let po2 = polar2.to::<Radian>();
let x = (po1.cos() * po2.sin()) - (po1.sin() * po2.cos() * (az2 - az1).cos());
let y = po2.cos() * (az2 - az1).sin();
let z = (po1.sin() * po2.sin()) + (po1.cos() * po2.cos() * (az2 - az1).cos());
let angle_rad = (x * x + y * y).sqrt().atan2(z);
Radians::new(angle_rad).to::<Degree>()
}