diff --git a/src/structure.rs b/src/structure.rs index abcd450..8721e51 100644 --- a/src/structure.rs +++ b/src/structure.rs @@ -603,6 +603,13 @@ where } } + /// Return the angle, normalized to the range `[-turn_div_2, turn_div_2)`. + #[inline] + fn normalize_signed(self) -> Self { + let rem = self.normalize(); + if Self::turn_div_2() < rem { rem - Self::full_turn() } else { rem } + } + /// Return the angle rotated by half a turn. #[inline] fn opposite(self) -> Self { diff --git a/tests/angle.rs b/tests/angle.rs index 309bd48..ddaeb52 100644 --- a/tests/angle.rs +++ b/tests/angle.rs @@ -17,7 +17,25 @@ extern crate approx; extern crate cgmath; -use cgmath::{Deg, Rad}; +use cgmath::{Angle, Deg, Rad}; + +#[test] +fn test_normalize_signed() { + let angle: Rad = Rad::full_turn().normalize_signed(); + assert_ulps_eq!(&angle, &Rad(0f64)); + + let angle: Rad = (Rad::full_turn() + Rad::turn_div_4()).normalize_signed(); + assert_ulps_eq!(&angle, &Rad::turn_div_4()); + + let angle: Rad = (Rad::full_turn() - Rad::turn_div_4()).normalize_signed(); + assert_ulps_eq!(&angle, &-Rad::turn_div_4()); + + let angle: Rad = Rad::turn_div_2().normalize_signed(); + assert_ulps_eq!(&angle, &Rad::turn_div_2()); + + let angle: Rad = (-Rad::turn_div_2()).normalize_signed(); + assert_ulps_eq!(&angle, &Rad::turn_div_2()); +} #[test] fn test_conv() {