diff --git a/src/angle.rs b/src/angle.rs index 530455d..5fad139 100644 --- a/src/angle.rs +++ b/src/angle.rs @@ -79,11 +79,21 @@ pub trait Angle where Self: PartialEq + PartialOrd, // FIXME: Ugly type signatures - blocked by rust-lang/rust#24092 Self: ApproxEq::Unitless>, - Self: Neg, Self: Into::Unitless>>, Self: Into::Unitless>>, Self: ScalarConv<::Unitless>, Self: fmt::Debug, + + Self: Neg, + + Self: Add, + Self: Sub, + Self: Div::Unitless>, + Self: Rem::Unitless>, + + Self: Mul<::Unitless, Output = Self>, + Self: Div<::Unitless, Output = Self>, + Self: Rem<::Unitless, Output = Self>, { type Unitless: BaseFloat; @@ -93,40 +103,23 @@ pub trait Angle where /// Negate this angle, in-place. #[inline] fn neg_self(&mut self) { *self = -*self } - /// Add this angle with another, returning the new angle. - #[inline] fn add_a(&self, other: Self) -> Self { ScalarConv::from(*self.s() + *other.s()) } - /// Subtract another angle from this one, returning the new angle. - #[inline] fn sub_a(&self, other: Self) -> Self { ScalarConv::from(*self.s() - *other.s()) } - /// Divide this angle by another, returning the ratio. - #[inline] fn div_a(&self, other: Self) -> Self::Unitless { *self.s() / *other.s() } - /// Take the remainder of this angle with another. - #[inline] fn rem_a(&self, other: Self) -> Self::Unitless { *self.s() % *other.s() } - - /// Multiply this angle by a scalar, returning the new angle. - #[inline] fn mul_s(&self, scalar: Self::Unitless) -> Self { ScalarConv::from(*self.s() * scalar) } - /// Divide this angle by a scalar, returing the new angle. - #[inline] fn div_s(&self, scalar: Self::Unitless) -> Self { ScalarConv::from(*self.s() / scalar) } - /// Take the remainder of this angle by a scalar, returning the new angle. - #[inline] fn rem_s(&self, scalar: Self::Unitless) -> Self { ScalarConv::from(*self.s() % scalar) } - /// Add this angle with another, in-place. - #[inline] fn add_self_a(&mut self, other: Self) { *self.mut_s() = *self.s() + *other.s() } + #[inline] fn add_self_a(&mut self, other: Self) { *self = *self + other } /// Subtract another angle from this one, in-place. - #[inline] fn sub_self_a(&mut self, other: Self) { *self.mut_s() = *self.s() - *other.s() } + #[inline] fn sub_self_a(&mut self, other: Self) { *self = *self - other } /// Multiply this angle by a scalar, in-place. - #[inline] fn mul_self_s(&mut self, scalar: Self::Unitless) { *self.mut_s() = *self.s() * scalar } + #[inline] fn mul_self_s(&mut self, scalar: Self::Unitless) { *self = *self * scalar } /// Divide this angle by a scalar, in-place. - #[inline] fn div_self_s(&mut self, scalar: Self::Unitless) { *self.mut_s() = *self.s() / scalar } + #[inline] fn div_self_s(&mut self, scalar: Self::Unitless) { *self = *self / scalar } /// Take the remainder of this angle by a scalar, in-place. - #[inline] fn rem_self_s(&mut self, scalar: Self::Unitless) { *self.mut_s() = *self.s() % scalar } + #[inline] fn rem_self_s(&mut self, scalar: Self::Unitless) { *self = *self % scalar } /// Return the angle, normalized to the range `[0, full_turn)`. #[inline] - fn normalize(&self) -> Self { - let mut a = self.clone(); - a.normalize_self(); - a + fn normalize(mut self) -> Self { + self.normalize_self(); + self } /// Normalize the angle to the range `[0, full_turn)`. @@ -139,25 +132,28 @@ pub trait Angle where /// Return the angle rotated by half a turn #[inline] - fn opposite(&self) -> Self { - self.add_a(Self::turn_div_2()).normalize() + fn opposite(self) -> Self { + Self::normalize(self + Self::turn_div_2()) } /// Returns the interior bisector of the two angles #[inline] - fn bisect(&self, other: Self) -> Self { - self.add_a(self.sub_a(other).mul_s(cast(0.5f64).unwrap())).normalize() + fn bisect(self, other: Self) -> Self { + let half = cast(0.5f64).unwrap(); + Self::normalize((self - other) * half + self) } fn zero() -> Self; fn full_turn() -> Self; + fn turn_div_2() -> Self; + fn turn_div_3() -> Self; + fn turn_div_4() -> Self; + fn turn_div_6() -> Self; - #[inline] fn turn_div_2() -> Self { Self::full_turn().div_s(cast(2i8).unwrap()) } - #[inline] fn turn_div_3() -> Self { Self::full_turn().div_s(cast(3i8).unwrap()) } - #[inline] fn turn_div_4() -> Self { Self::full_turn().div_s(cast(4i8).unwrap()) } - #[inline] fn turn_div_6() -> Self { Self::full_turn().div_s(cast(6i8).unwrap()) } - - #[inline] fn equiv(&self, other: &Self) -> bool { self.normalize() == other.normalize() } + #[inline] + fn equiv(&self, other: &Self) -> bool { + self.normalize() == other.normalize() + } } #[inline] pub fn bisect(a: A, b: A) -> A { a.bisect(b) } @@ -187,8 +183,11 @@ macro_rules! impl_angle { #[inline] fn from>(theta: A) -> $Angle { theta.into() } - #[inline] - fn full_turn() -> $Angle { ScalarConv::from(cast($full_turn).unwrap()) } + #[inline] fn full_turn() -> $Angle { ScalarConv::from(cast($full_turn).unwrap()) } + #[inline] fn turn_div_2() -> $Angle { let factor: S = cast(2).unwrap(); $Angle::full_turn() / factor } + #[inline] fn turn_div_3() -> $Angle { let factor: S = cast(3).unwrap(); $Angle::full_turn() / factor } + #[inline] fn turn_div_4() -> $Angle { let factor: S = cast(4).unwrap(); $Angle::full_turn() / factor } + #[inline] fn turn_div_6() -> $Angle { let factor: S = cast(6).unwrap(); $Angle::full_turn() / factor } } impl Neg for $Angle { diff --git a/src/projection.rs b/src/projection.rs index e583930..4987c63 100644 --- a/src/projection.rs +++ b/src/projection.rs @@ -74,7 +74,8 @@ pub struct PerspectiveFov { impl PerspectiveFov { pub fn to_perspective(&self) -> Perspective { - let angle = self.fovy.div_s(cast(2i8).unwrap()); + let two: S = cast(2).unwrap(); + let angle = self.fovy / two; let ymax = self.near * tan(angle); let xmax = ymax * self.aspect; @@ -98,8 +99,8 @@ impl From> for Matrix4 { assert!(persp.far > S::zero(), "The far plane distance cannot be below zero, found: {:?}", persp.far); assert!(persp.far > persp.near, "The far plane cannot be closer than the near plane, found: far: {:?}, near: {:?}", persp.far, persp.near); - let f = cot(persp.fovy.div_s(cast(2i8).unwrap())); - let two: S = cast(2i8).unwrap(); + let two: S = cast(2).unwrap(); + let f = cot(persp.fovy / two); let c0r0 = f / persp.aspect; let c0r1 = S::zero(); @@ -187,7 +188,7 @@ pub struct Ortho { impl From> for Matrix4 { fn from(ortho: Ortho) -> Matrix4 { - let two: S = cast(2i8).unwrap(); + let two: S = cast(2).unwrap(); let c0r0 = two / (ortho.right - ortho.left); let c0r1 = S::zero(); diff --git a/src/quaternion.rs b/src/quaternion.rs index d770885..f0816c3 100644 --- a/src/quaternion.rs +++ b/src/quaternion.rs @@ -212,8 +212,8 @@ impl Quaternion { let theta: Rad = acos(robust_dot.clone()); - let scale1 = sin(theta.mul_s(S::one() - amount)); - let scale2 = sin(theta.mul_s(amount)); + let scale1 = sin(theta * (S::one() - amount)); + let scale2 = sin(theta * amount); (self * scale1 + other * scale2) * sin(theta).recip() } @@ -362,16 +362,16 @@ impl Rotation> for Quaternion { impl Rotation3 for Quaternion { #[inline] fn from_axis_angle(axis: Vector3, angle: Rad) -> Quaternion { - let (s, c) = sin_cos(angle.mul_s(cast(0.5f64).unwrap())); + let (s, c) = sin_cos(angle * cast(0.5f64).unwrap()); Quaternion::from_sv(c, axis * s) } /// - [Maths - Conversion Euler to Quaternion] /// (http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm) fn from_euler(x: Rad, y: Rad, z: Rad) -> Quaternion { - let (s1, c1) = sin_cos(x.mul_s(cast(0.5f64).unwrap())); - let (s2, c2) = sin_cos(y.mul_s(cast(0.5f64).unwrap())); - let (s3, c3) = sin_cos(z.mul_s(cast(0.5f64).unwrap())); + let (s1, c1) = sin_cos(x * cast(0.5f64).unwrap()); + let (s2, c2) = sin_cos(y * cast(0.5f64).unwrap()); + let (s3, c3) = sin_cos(z * cast(0.5f64).unwrap()); Quaternion::new(c1 * c2 * c3 - s1 * s2 * s3, s1 * s2 * c3 + c1 * c2 * s3, diff --git a/tests/angle.rs b/tests/angle.rs index 02bf6f0..6a5643d 100644 --- a/tests/angle.rs +++ b/tests/angle.rs @@ -41,9 +41,9 @@ fn conv() { fn equiv() { assert!(Deg::::full_turn().equiv(&-Deg::::full_turn())); assert!(Deg::::turn_div_2().equiv(&-Deg::::turn_div_2())); - assert!(Deg::::turn_div_3().sub_a(Deg::::full_turn()).equiv(&Deg::::turn_div_3())); + assert!((Deg::::turn_div_3() - Deg::::full_turn()).equiv(&Deg::::turn_div_3())); assert!(Rad::::full_turn().equiv(&-Rad::::full_turn())); assert!(Rad::::turn_div_2().equiv(&-Rad::::turn_div_2())); - assert!(Rad::::turn_div_3().sub_a(Rad::::full_turn()).equiv(&Rad::::turn_div_3())); + assert!((Rad::::turn_div_3() - Rad::::full_turn()).equiv(&Rad::::turn_div_3())); }