438: Angle: add the normalize_zero method r=kvark a=mathstuf

This method is like `normalize` except that it normalizes to have an
absolute value of no more than `turn_div_2`.

---
This is useful for making sure that an angle is no more than some offset from a target angle (e.g., implementing maximum turn rates in games).

Co-authored-by: Ben Boeckel <mathstuf@gmail.com>
This commit is contained in:
bors[bot] 2019-01-16 22:30:23 +00:00
commit 8bc3af42ef
2 changed files with 38 additions and 1 deletions

View file

@ -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. /// Return the angle rotated by half a turn.
#[inline] #[inline]
fn opposite(self) -> Self { fn opposite(self) -> Self {

View file

@ -17,7 +17,37 @@
extern crate approx; extern crate approx;
extern crate cgmath; extern crate cgmath;
use cgmath::{Deg, Rad}; use cgmath::{Angle, Deg, Rad};
#[test]
fn test_normalize() {
let angle: Rad<f64> = Rad::full_turn().normalize();
assert_ulps_eq!(&angle, &Rad(0f64));
let angle: Rad<f64> = (Rad::full_turn() + Rad::turn_div_4()).normalize();
assert_ulps_eq!(&angle, &Rad::turn_div_4());
let angle: Rad<f64> = (-Rad::turn_div_4()).normalize();
assert_ulps_eq!(&angle, &(Rad::full_turn() - Rad::turn_div_4()));
}
#[test]
fn test_normalize_signed() {
let angle: Rad<f64> = Rad::full_turn().normalize_signed();
assert_ulps_eq!(&angle, &Rad(0f64));
let angle: Rad<f64> = (Rad::full_turn() + Rad::turn_div_4()).normalize_signed();
assert_ulps_eq!(&angle, &Rad::turn_div_4());
let angle: Rad<f64> = (Rad::full_turn() - Rad::turn_div_4()).normalize_signed();
assert_ulps_eq!(&angle, &-Rad::turn_div_4());
let angle: Rad<f64> = Rad::turn_div_2().normalize_signed();
assert_ulps_eq!(&angle, &Rad::turn_div_2());
let angle: Rad<f64> = (-Rad::turn_div_2()).normalize_signed();
assert_ulps_eq!(&angle, &Rad::turn_div_2());
}
#[test] #[test]
fn test_conv() { fn test_conv() {