Fix angle wrapping

This commit is contained in:
Brendan Zabarauskas 2012-12-02 15:39:49 +10:00
parent 2b931aee21
commit 90802b1713
2 changed files with 24 additions and 8 deletions

View file

@ -14,7 +14,9 @@ pub trait Angle<T>: Add<self,self>
, Sub<self,self>
, Mul<T,self>
, Div<T,self>
// , Div<self,T>
, Modulo<T,self>
// , Modulo<self,T>
, Neg<self>
, Eq, Ord {
static pure fn full_turn() -> self;
@ -50,7 +52,14 @@ pub impl<T:Copy Num NumCast Eq Ord> Radians<T>: Angle<T> {
#[inline(always)]
pure fn wrap(&self) -> Radians<T> {
(*self) % cast(2.0 * pi) // TODO: keep in the domain of 0 to two_pi
let theta = (*self) % cast(2.0 * pi);
// keep in the domain of 0 to 1 rad
if theta >= Angle::zero() {
theta
} else {
theta + Angle::full_turn()
}
}
#[inline(always)]
@ -137,7 +146,14 @@ pub impl<T:Copy Num NumCast Eq Ord> Degrees<T>: Angle<T> {
#[inline(always)]
pure fn wrap(&self) -> Degrees<T> {
(*self) % cast(360) // TODO: keep in the domain of 0 to 360
let theta = (*self) % cast(360);
// keep in the domain of 0 to 360 degrees
if theta >= Angle::zero() {
theta
} else {
theta + Angle::full_turn()
}
}
#[inline(always)]

View file

@ -21,14 +21,14 @@ fn test_radians() {
assert Radians(pi).wrap() == Radians(pi);
assert Radians(3.0 * pi).wrap() == Radians(pi);
assert Radians(2.0 * pi).wrap() == Radians(0.0);
assert Radians(-pi).wrap() == Radians(-pi); // FIXME: should be in the domain of 0 to two_pi
assert Radians(-3.0 * pi).wrap() == Radians(-pi); // FIXME: should be in the domain of 0 to two_pi
assert Radians(-pi).wrap() == Radians(pi);
assert Radians(-3.0 * pi).wrap() == Radians(pi);
assert Radians(-2.0 * pi).wrap() == Radians(0.0);
assert Radians(0.0).opposite() == Radians(pi as float);
assert Radians(pi / 2.0).opposite() == Radians((pi / 2.0) * 3.0);
assert Radians(pi * 3.0).opposite() == Radians(0.0);
assert Radians(-2.0 * pi).opposite() == Radians(-pi); // FIXME: should be in the domain of 0 to two_pi
assert Radians(-2.0 * pi).opposite() == Radians(pi);
assert Radians(pi) + Radians(pi) == Radians(2.0 * pi);
assert Radians(2.0 * pi) - Radians(pi) == Radians(pi);
@ -57,14 +57,14 @@ fn test_degrees() {
assert Degrees(90.0).wrap() == Degrees(90.0);
assert Degrees(450.0).wrap() == Degrees(90.0);
assert Degrees(360.0).wrap() == Degrees(0.0);
assert Degrees(-90.0).wrap() == Degrees(-90.0); // FIXME: should be in the domain of 0 to 360
assert Degrees(-450.0).wrap() == Degrees(-90.0); // FIXME: should be in the domain of 0 to 360
assert Degrees(-90.0).wrap() == Degrees(270.0);
assert Degrees(-450.0).wrap() == Degrees(270.0);
assert Degrees(-360.0).wrap() == Degrees(0.0);
assert Degrees(0.0).opposite() == Degrees(180.0);
assert Degrees(90.0).opposite() == Degrees(270.0);
assert Degrees(540.0).opposite() == Degrees(0.0);
assert Degrees(-360.0).opposite() == Degrees(-180.0); // FIXME: should be in the domain of 0 to 360
assert Degrees(-360.0).opposite() == Degrees(180.0);
assert Degrees(180.0) + Degrees(180.0) == Degrees(360.0);
assert Degrees(360.0) - Degrees(180.0) == Degrees(180.0);