From a1d8eaed1004c5e986addc6d1ee17ed2f835689c Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Thu, 12 May 2016 08:31:45 +1000 Subject: [PATCH] Make Rotation trait depend on One --- src/quaternion.rs | 25 ++++++------------- src/rotation.rs | 61 +++++++++++++++++------------------------------ src/transform.rs | 2 +- tests/rotation.rs | 4 ++-- 4 files changed, 32 insertions(+), 60 deletions(-) diff --git a/src/quaternion.rs b/src/quaternion.rs index 8f72c88..1b5a1ff 100644 --- a/src/quaternion.rs +++ b/src/quaternion.rs @@ -58,12 +58,6 @@ impl Quaternion { Quaternion { s: s, v: v } } - /// The multiplicative identity. - #[inline] - pub fn one() -> Quaternion { - Quaternion::from_sv(S::one(), Vector3::zero()) - } - /// The conjugate of the quaternion. #[inline] pub fn conjugate(self) -> Quaternion { @@ -131,6 +125,13 @@ impl Zero for Quaternion { } } +impl One for Quaternion { + #[inline] + fn one() -> Quaternion { + Quaternion::from_sv(S::one(), Vector3::zero()) + } +} + impl VectorSpace for Quaternion { type Scalar = S; } @@ -332,9 +333,6 @@ impl From> for Basis3 { } impl Rotation> for Quaternion { - #[inline] - fn one() -> Quaternion { Quaternion::one() } - #[inline] fn look_at(dir: Vector3, up: Vector3) -> Quaternion { Matrix3::look_at(dir, up).into() @@ -350,17 +348,8 @@ impl Rotation> for Quaternion { #[inline] fn rotate_vector(&self, vec: Vector3) -> Vector3 { self * vec } - #[inline] - fn concat(&self, other: &Quaternion) -> Quaternion { self * other } - - #[inline] - fn concat_self(&mut self, other: &Quaternion) { *self = &*self * other; } - #[inline] fn invert(&self) -> Quaternion { self.conjugate() / self.magnitude2() } - - #[inline] - fn invert_self(&mut self) { *self = self.invert() } } impl Rotation3 for Quaternion { diff --git a/src/rotation.rs b/src/rotation.rs index 6a2dba5..d819de0 100644 --- a/src/rotation.rs +++ b/src/rotation.rs @@ -14,6 +14,7 @@ // limitations under the License. use std::fmt; +use std::ops::*; use structure::*; @@ -28,14 +29,11 @@ use vector::{Vector2, Vector3}; /// A trait for a generic rotation. A rotation is a transformation that /// creates a circular motion, and preserves at least one point in the space. -pub trait Rotation: PartialEq + Sized where +pub trait Rotation: Sized + Copy + One where // FIXME: Ugly type signatures - blocked by rust-lang/rust#24092 Self: ApproxEq::Scalar>,

::Scalar: BaseFloat, { - /// Create the identity transform (causes no transformation). - fn one() -> Self; - /// Create a rotation to a given direction with an 'up' vector fn look_at(dir: P::Diff, up: P::Diff) -> Self; @@ -53,24 +51,9 @@ pub trait Rotation: PartialEq + Sized where P::from_vec(self.rotate_vector(point.to_vec())) } - /// Create a new rotation which combines both this rotation, and another. - fn concat(&self, other: &Self) -> Self; - /// Create a new rotation which "un-does" this rotation. That is, - /// `r.concat(r.invert())` is the identity. + /// `r * r.invert()` is the identity. fn invert(&self) -> Self; - - /// Modify this rotation in-place by combining it with another. - #[inline] - fn concat_self(&mut self, other: &Self) { - *self = Self::concat(self, other); - } - - /// Invert this rotation in-place. - #[inline] - fn invert_self(&mut self) { - *self = self.invert(); - } } /// A two-dimensional rotation. @@ -151,7 +134,7 @@ pub trait Rotation3: Rotation> /// /// // Note that we can also concatenate rotations: /// let rot_half: Basis2 = Rotation2::from_angle(rad(0.25f64 * f64::consts::PI)); -/// let unit_y3 = rot_half.concat(&rot_half).rotate_vector(unit_x); +/// let unit_y3 = (rot_half * rot_half).rotate_vector(unit_x); /// assert!(unit_y3.approx_eq(&unit_y2)); /// ``` #[derive(PartialEq, Copy, Clone, RustcEncodable, RustcDecodable)] @@ -172,9 +155,6 @@ impl From> for Matrix2 { } impl Rotation> for Basis2 { - #[inline] - fn one() -> Basis2 { Basis2 { mat: Matrix2::identity() } } - #[inline] fn look_at(dir: Vector2, up: Vector2) -> Basis2 { Basis2 { mat: Matrix2::look_at(dir, up) } @@ -188,18 +168,21 @@ impl Rotation> for Basis2 { #[inline] fn rotate_vector(&self, vec: Vector2) -> Vector2 { self.mat * vec } - #[inline] - fn concat(&self, other: &Basis2) -> Basis2 { Basis2 { mat: self.mat * other.mat } } - - #[inline] - fn concat_self(&mut self, other: &Basis2) { self.mat = self.mat * other.mat; } - // TODO: we know the matrix is orthogonal, so this could be re-written // to be faster #[inline] fn invert(&self) -> Basis2 { Basis2 { mat: self.mat.invert().unwrap() } } } +impl One for Basis2 { + #[inline] + fn one() -> Basis2 { Basis2 { mat: Matrix2::one() } } +} + +impl_operator!( Mul > for Basis2 { + fn mul(lhs, rhs) -> Basis2 { Basis2 { mat: lhs.mat * rhs.mat } } +}); + impl ApproxEq for Basis2 { type Epsilon = S; @@ -257,9 +240,6 @@ impl From> for Quaternion { } impl Rotation> for Basis3 { - #[inline] - fn one() -> Basis3 { Basis3 { mat: Matrix3::identity() } } - #[inline] fn look_at(dir: Vector3, up: Vector3) -> Basis3 { Basis3 { mat: Matrix3::look_at(dir, up) } @@ -274,18 +254,21 @@ impl Rotation> for Basis3 { #[inline] fn rotate_vector(&self, vec: Vector3) -> Vector3 { self.mat * vec } - #[inline] - fn concat(&self, other: &Basis3) -> Basis3 { Basis3 { mat: self.mat * other.mat } } - - #[inline] - fn concat_self(&mut self, other: &Basis3) { self.mat = self.mat * other.mat; } - // TODO: we know the matrix is orthogonal, so this could be re-written // to be faster #[inline] fn invert(&self) -> Basis3 { Basis3 { mat: self.mat.invert().unwrap() } } } +impl One for Basis3 { + #[inline] + fn one() -> Basis3 { Basis3 { mat: Matrix3::one() } } +} + +impl_operator!( Mul > for Basis3 { + fn mul(lhs, rhs) -> Basis3 { Basis3 { mat: lhs.mat * rhs.mat } } +}); + impl ApproxEq for Basis3 { type Epsilon = S; diff --git a/src/transform.rs b/src/transform.rs index a50e0d6..9ad25e8 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -102,7 +102,7 @@ impl> Transform

for Decomposed fn concat(&self, other: &Decomposed) -> Decomposed { Decomposed { scale: self.scale * other.scale, - rot: self.rot.concat(&other.rot), + rot: self.rot * other.rot, disp: self.disp + other.disp, } } diff --git a/tests/rotation.rs b/tests/rotation.rs index 2ebe1a3..0f41611 100644 --- a/tests/rotation.rs +++ b/tests/rotation.rs @@ -33,7 +33,7 @@ mod rotation { #[test] fn test_invert_basis2() { let a: Basis2<_> = rotation::a2(); - let a = a.concat(&a.invert()); + let a = a * a.invert(); let a: &Matrix2<_> = a.as_ref(); assert!(a.is_identity()); } @@ -41,7 +41,7 @@ fn test_invert_basis2() { #[test] fn test_invert_basis3() { let a: Basis3<_> = rotation::a3(); - let a = a.concat(&a.invert()); + let a = a * a.invert(); let a: &Matrix3<_> = a.as_ref(); assert!(a.is_identity()); }