Merge the Rotatable, Translatable, Transformable traits with their corresponding Rotation, Translation, Transformation.

This commit is contained in:
Sébastien Crozet 2013-08-22 17:47:37 +02:00
parent 347883caa1
commit 6999444575
10 changed files with 43 additions and 97 deletions

View File

@ -6,7 +6,7 @@ use traits::cross::Cross;
use traits::dim::Dim; use traits::dim::Dim;
use traits::inv::Inv; use traits::inv::Inv;
use traits::transpose::Transpose; use traits::transpose::Transpose;
use traits::rotation::{Rotation, Rotate, Rotatable}; use traits::rotation::{Rotation, Rotate};
use traits::transformation::{Transform}; // FIXME: implement Transformation and Transformable use traits::transformation::{Transform}; // FIXME: implement Transformation and Transformable
use traits::homogeneous::ToHomogeneous; use traits::homogeneous::ToHomogeneous;
use traits::indexable::Indexable; use traits::indexable::Indexable;
@ -136,10 +136,7 @@ Rotation<Vec1<N>> for Rotmat<Mat2<N>> {
fn rotate_by(&mut self, rot: &Vec1<N>) { fn rotate_by(&mut self, rot: &Vec1<N>) {
*self = self.rotated(rot) *self = self.rotated(rot)
} }
}
impl<N: Trigonometric + Num + Clone>
Rotatable<Vec1<N>, Rotmat<Mat2<N>>> for Rotmat<Mat2<N>> {
#[inline] #[inline]
fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>> { fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>> {
Rotmat::from_angle(rot.x.clone()) * *self Rotmat::from_angle(rot.x.clone()) * *self
@ -163,10 +160,7 @@ Rotation<Vec3<N>> for Rotmat<Mat3<N>> {
fn rotate_by(&mut self, rot: &Vec3<N>) { fn rotate_by(&mut self, rot: &Vec3<N>) {
*self = self.rotated(rot) *self = self.rotated(rot)
} }
}
impl<N: Clone + Trigonometric + Num + Algebraic>
Rotatable<Vec3<N>, Rotmat<Mat3<N>>> for Rotmat<Mat3<N>> {
#[inline] #[inline]
fn rotated(&self, axisangle: &Vec3<N>) -> Rotmat<Mat3<N>> { fn rotated(&self, axisangle: &Vec3<N>) -> Rotmat<Mat3<N>> {
Rotmat::from_axis_angle(axisangle.clone()) * *self Rotmat::from_axis_angle(axisangle.clone()) * *self

View File

@ -3,10 +3,10 @@ use std::rand::{Rand, Rng, RngUtil};
use std::cmp::ApproxEq; use std::cmp::ApproxEq;
use traits::dim::Dim; use traits::dim::Dim;
use traits::inv::Inv; use traits::inv::Inv;
use traits::rotation::{Rotation, Rotate, Rotatable}; use traits::rotation::{Rotation, Rotate};
use traits::translation::{Translation, Translate, Translatable}; use traits::translation::{Translation, Translate};
use Ts = traits::transformation::Transform; use Ts = traits::transformation::Transform;
use traits::transformation::{Transformation, Transformable}; use traits::transformation::{Transformation};
use traits::rlmul::{RMul, LMul}; use traits::rlmul::{RMul, LMul};
use traits::homogeneous::{ToHomogeneous, FromHomogeneous}; use traits::homogeneous::{ToHomogeneous, FromHomogeneous};
use traits::column::Column; use traits::column::Column;
@ -138,7 +138,7 @@ impl<M: LMul<V>, V: Add<V, V>> LMul<V> for Transform<M, V> {
} }
} }
impl<M, V: Translation<V>> Translation<V> for Transform<M, V> { impl<M: Clone, V: Translation<V>> Translation<V> for Transform<M, V> {
#[inline] #[inline]
fn translation(&self) -> V { fn translation(&self) -> V {
self.subtrans.translation() self.subtrans.translation()
@ -153,6 +153,11 @@ impl<M, V: Translation<V>> Translation<V> for Transform<M, V> {
fn translate_by(&mut self, t: &V) { fn translate_by(&mut self, t: &V) {
self.subtrans.translate_by(t) self.subtrans.translate_by(t)
} }
#[inline]
fn translated(&self, t: &V) -> Transform<M, V> {
Transform::new(self.submat.clone(), self.subtrans.translated(t))
}
} }
impl<M: Translate<V>, V, _0> Translate<V> for Transform<M, _0> { impl<M: Translate<V>, V, _0> Translate<V> for Transform<M, _0> {
@ -167,14 +172,6 @@ impl<M: Translate<V>, V, _0> Translate<V> for Transform<M, _0> {
} }
} }
impl<M: Clone, V: Translatable<V, V> + Translation<V>>
Translatable<V, Transform<M, V>> for Transform<M, V> {
#[inline]
fn translated(&self, t: &V) -> Transform<M, V> {
Transform::new(self.submat.clone(), self.subtrans.translated(t))
}
}
impl<M: Rotation<AV> + RMul<V> + One, V, AV> impl<M: Rotation<AV> + RMul<V> + One, V, AV>
Rotation<AV> for Transform<M, V> { Rotation<AV> for Transform<M, V> {
#[inline] #[inline]
@ -196,6 +193,14 @@ Rotation<AV> for Transform<M, V> {
self.submat.rotate_by(rot); self.submat.rotate_by(rot);
self.subtrans = delta.rmul(&self.subtrans); self.subtrans = delta.rmul(&self.subtrans);
} }
#[inline]
fn rotated(&self, rot: &AV) -> Transform<M, V> {
// FIXME: this does not seem opitmal
let delta = One::one::<M>().rotated(rot);
Transform::new(self.submat.rotated(rot), delta.rmul(&self.subtrans))
}
} }
impl<M: Rotate<V>, V, _0> Rotate<V> for Transform<M, _0> { impl<M: Rotate<V>, V, _0> Rotate<V> for Transform<M, _0> {
@ -210,17 +215,6 @@ impl<M: Rotate<V>, V, _0> Rotate<V> for Transform<M, _0> {
} }
} }
impl<M: Rotatable<AV, Res> + One, Res: Rotation<AV> + RMul<V> + One, V, AV>
Rotatable<AV, Transform<Res, V>> for Transform<M, V> {
#[inline]
fn rotated(&self, rot: &AV) -> Transform<Res, V> {
// FIXME: this does not seem opitmal
let delta = One::one::<M>().rotated(rot);
Transform::new(self.submat.rotated(rot), delta.rmul(&self.subtrans))
}
}
impl<M: Inv + RMul<V> + Mul<M, M> + Clone, V: Add<V, V> + Neg<V> + Clone> impl<M: Inv + RMul<V> + Mul<M, M> + Clone, V: Add<V, V> + Neg<V> + Clone>
Transformation<Transform<M, V>> for Transform<M, V> { Transformation<Transform<M, V>> for Transform<M, V> {
fn transformation(&self) -> Transform<M, V> { fn transformation(&self) -> Transform<M, V> {
@ -238,6 +232,10 @@ Transformation<Transform<M, V>> for Transform<M, V> {
fn transform_by(&mut self, other: &Transform<M, V>) { fn transform_by(&mut self, other: &Transform<M, V>) {
*self = other * *self *self = other * *self
} }
fn transformed(&self, t: &Transform<M, V>) -> Transform<M, V> {
t * *self
}
} }
impl<M: Ts<V>, V: Add<V, V> + Sub<V, V>> impl<M: Ts<V>, V: Add<V, V> + Sub<V, V>>
@ -253,16 +251,6 @@ Ts<V> for Transform<M, V> {
} }
} }
// FIXME: constraints are too restrictive.
// Should be: Transformable<M2, // Transform<Res, V> ...
impl<M: RMul<V> + Mul<M, M> + Inv + Clone, V: Add<V, V> + Neg<V> + Clone>
Transformable<Transform<M, V>, Transform<M, V>> for Transform<M, V> {
fn transformed(&self, t: &Transform<M, V>) -> Transform<M, V> {
t * *self
}
}
impl<M: Inv + RMul<V> + Clone, V: Neg<V> + Clone> impl<M: Inv + RMul<V> + Clone, V: Neg<V> + Clone>
Inv for Transform<M, V> { Inv for Transform<M, V> {
#[inline] #[inline]

View File

@ -5,7 +5,7 @@ use std::cmp::ApproxEq;
use std::iterator::FromIterator; use std::iterator::FromIterator;
use traits::vector::{Vec, AlgebraicVec}; use traits::vector::{Vec, AlgebraicVec};
use traits::iterable::{Iterable, IterableMut}; use traits::iterable::{Iterable, IterableMut};
use traits::translation::{Translation, Translatable}; use traits::translation::Translation;
use traits::scalar_op::{ScalarAdd, ScalarSub}; use traits::scalar_op::{ScalarAdd, ScalarSub};
/// Vector with a dimension unknown at compile-time. /// Vector with a dimension unknown at compile-time.
@ -219,9 +219,7 @@ impl<N: Add<N, N> + Neg<N> + Clone> Translation<DVec<N>> for DVec<N> {
fn translate_by(&mut self, t: &DVec<N>) { fn translate_by(&mut self, t: &DVec<N>) {
*self = *self + *t; *self = *self + *t;
} }
}
impl<N: Add<N, N> + Neg<N> + Clone> Translatable<DVec<N>, DVec<N>> for DVec<N> {
#[inline] #[inline]
fn translated(&self, t: &DVec<N>) -> DVec<N> { fn translated(&self, t: &DVec<N>) -> DVec<N> {
self + *t self + *t

View File

@ -7,7 +7,7 @@ use std::cmp::ApproxEq;
#[test] #[test]
use traits::inv::Inv; use traits::inv::Inv;
#[test] #[test]
use traits::rotation::{Rotation, Rotatable}; use traits::rotation::Rotation;
#[test] #[test]
use traits::indexable::Indexable; use traits::indexable::Indexable;
#[test] #[test]

View File

@ -1,4 +1,4 @@
use traits::translation::{Translation, Translatable}; use traits::translation::Translation;
/// Trait of object which represent a rotation, and to wich new rotations can /// Trait of object which represent a rotation, and to wich new rotations can
/// be appended. A rotation is assumed to be an isomitry without translation /// be appended. A rotation is assumed to be an isomitry without translation
@ -10,17 +10,11 @@ pub trait Rotation<V> {
/// Gets the inverse rotation associated with this object. /// Gets the inverse rotation associated with this object.
fn inv_rotation(&self) -> V; fn inv_rotation(&self) -> V;
/// In-place version of `rotated` (see the `Rotatable` trait). /// In-place version of `rotated`.
fn rotate_by(&mut self, &V); fn rotate_by(&mut self, &V);
}
/// Trait of objects which can be put on an alternate form which represent a rotation. This is /// Appends a rotation.
/// typically implemented by structures requiring an internal restructuration to be able to fn rotated(&self, &V) -> Self;
/// represent a rotation.
pub trait Rotatable<V, Res: Rotation<V>> {
/// Appends a rotation from an alternative representation. Such
/// representation has the same format as the one returned by `rotation`.
fn rotated(&self, &V) -> Res;
} }
/// Trait of objects able to rotate other objects. This is typically implemented by matrices which /// Trait of objects able to rotate other objects. This is typically implemented by matrices which
@ -40,14 +34,13 @@ pub trait Rotate<V> {
* - `point`: the center of rotation. * - `point`: the center of rotation.
*/ */
#[inline] #[inline]
pub fn rotated_wrt_point<M: Translatable<LV, M2>, pub fn rotated_wrt_point<M: Translation<LV> + Rotation<AV>,
M2: Rotation<AV> + Translation<LV>,
LV: Neg<LV>, LV: Neg<LV>,
AV>( AV>(
m: &M, m: &M,
ammount: &AV, ammount: &AV,
center: &LV) center: &LV)
-> M2 { -> M {
let mut res = m.translated(&-center); let mut res = m.translated(&-center);
res.rotate_by(ammount); res.rotate_by(ammount);
@ -82,13 +75,12 @@ pub fn rotate_wrt_point<M: Rotation<AV> + Translation<LV>,
* * `ammount` - the rotation to apply. * * `ammount` - the rotation to apply.
*/ */
#[inline] #[inline]
pub fn rotated_wrt_center<M: Translatable<LV, M2> + Translation<LV>, pub fn rotated_wrt_center<M: Rotation<AV> + Translation<LV>,
M2: Rotation<AV> + Translation<LV>,
LV: Neg<LV>, LV: Neg<LV>,
AV>( AV>(
m: &M, m: &M,
ammount: &AV) ammount: &AV)
-> M2 { -> M {
rotated_wrt_point(m, ammount, &m.translation()) rotated_wrt_point(m, ammount, &m.translation())
} }
@ -100,7 +92,7 @@ pub fn rotated_wrt_center<M: Translatable<LV, M2> + Translation<LV>,
* * `ammount` - the rotation to apply. * * `ammount` - the rotation to apply.
*/ */
#[inline] #[inline]
pub fn rotate_wrt_center<M: Translatable<LV, M> + Translation<LV> + Rotation<AV>, pub fn rotate_wrt_center<M: Translation<LV> + Rotation<AV>,
LV: Neg<LV>, LV: Neg<LV>,
AV>( AV>(
m: &mut M, m: &mut M,

View File

@ -8,8 +8,11 @@ pub trait Transformation<M> {
/// Gets the inverse transformation associated with this object. /// Gets the inverse transformation associated with this object.
fn inv_transformation(&self) -> M; fn inv_transformation(&self) -> M;
/// In-place version of `transformed` (see the `Transformable` trait). /// In-place version of `transformed`.
fn transform_by(&mut self, &M); fn transform_by(&mut self, &M);
/// Appends a transformation.
fn transformed(&self, &M) -> Self;
} }
/// Trait of objects able to transform other objects. This is typically implemented by matrices which /// Trait of objects able to transform other objects. This is typically implemented by matrices which
@ -20,12 +23,3 @@ pub trait Transform<V> {
/// Apply an inverse transformation to an object. /// Apply an inverse transformation to an object.
fn inv_transform(&self, &V) -> V; fn inv_transform(&self, &V) -> V;
} }
/// Trait of objects which can be put on an alternate form which represent a transformation. This is
/// typically implemented by structures requiring an internal restructuration to be able to
/// represent a transformation.
pub trait Transformable<M, Res: Transformation<M>> {
/// Appends a transformation from an alternative representation. Such
/// representation has the same format as the one returned by `transformation`.
fn transformed(&self, &M) -> Res;
}

View File

@ -8,8 +8,11 @@ pub trait Translation<V> {
/// Gets the inverse translation associated with this object. /// Gets the inverse translation associated with this object.
fn inv_translation(&self) -> V; fn inv_translation(&self) -> V;
/// In-place version of `translated` (see the `Translatable` trait). /// In-place version of `translated`.
fn translate_by(&mut self, &V); fn translate_by(&mut self, &V);
/// Appends a translation.
fn translated(&self, &V) -> Self;
} }
/// Trait of objects able to rotate other objects. This is typically implemented by matrices which /// Trait of objects able to rotate other objects. This is typically implemented by matrices which
@ -20,12 +23,3 @@ pub trait Translate<V> {
/// Apply an inverse translation to an object. /// Apply an inverse translation to an object.
fn inv_translate(&self, &V) -> V; fn inv_translate(&self, &V) -> V;
} }
/// Trait of objects which can be put on an alternate form which represent a translation. This is
/// typically implemented by structures requiring an internal restructuration to be able to
/// represent a translation.
pub trait Translatable<V, Res: Translation<V>> {
/// Appends a translation from an alternative representation. Such
/// representation has the same format as the one returned by `translation`.
fn translated(&self, &V) -> Res;
}

View File

@ -6,7 +6,7 @@ use std::iterator::{Iterator, FromIterator};
use std::cmp::ApproxEq; use std::cmp::ApproxEq;
use traits::basis::Basis; use traits::basis::Basis;
use traits::dim::Dim; use traits::dim::Dim;
use traits::translation::{Translation, Translatable}; use traits::translation::Translation;
use traits::homogeneous::{FromHomogeneous, ToHomogeneous}; use traits::homogeneous::{FromHomogeneous, ToHomogeneous};
use traits::indexable::Indexable; use traits::indexable::Indexable;
use traits::scalar_op::{ScalarAdd, ScalarSub}; use traits::scalar_op::{ScalarAdd, ScalarSub};
@ -45,7 +45,6 @@ scalar_div_impl!(Vec1, x)
scalar_add_impl!(Vec1, x) scalar_add_impl!(Vec1, x)
scalar_sub_impl!(Vec1, x) scalar_sub_impl!(Vec1, x)
translation_impl!(Vec1) translation_impl!(Vec1)
translatable_impl!(Vec1)
norm_impl!(Vec1) norm_impl!(Vec1)
approx_eq_impl!(Vec1, x) approx_eq_impl!(Vec1, x)
round_impl!(Vec1, x) round_impl!(Vec1, x)
@ -84,7 +83,6 @@ scalar_div_impl!(Vec2, x, y)
scalar_add_impl!(Vec2, x, y) scalar_add_impl!(Vec2, x, y)
scalar_sub_impl!(Vec2, x, y) scalar_sub_impl!(Vec2, x, y)
translation_impl!(Vec2) translation_impl!(Vec2)
translatable_impl!(Vec2)
norm_impl!(Vec2) norm_impl!(Vec2)
approx_eq_impl!(Vec2, x, y) approx_eq_impl!(Vec2, x, y)
round_impl!(Vec2, x, y) round_impl!(Vec2, x, y)
@ -125,7 +123,6 @@ scalar_div_impl!(Vec3, x, y, z)
scalar_add_impl!(Vec3, x, y, z) scalar_add_impl!(Vec3, x, y, z)
scalar_sub_impl!(Vec3, x, y, z) scalar_sub_impl!(Vec3, x, y, z)
translation_impl!(Vec3) translation_impl!(Vec3)
translatable_impl!(Vec3)
norm_impl!(Vec3) norm_impl!(Vec3)
approx_eq_impl!(Vec3, x, y, z) approx_eq_impl!(Vec3, x, y, z)
round_impl!(Vec3, x, y, z) round_impl!(Vec3, x, y, z)
@ -168,7 +165,6 @@ scalar_div_impl!(Vec4, x, y, z, w)
scalar_add_impl!(Vec4, x, y, z, w) scalar_add_impl!(Vec4, x, y, z, w)
scalar_sub_impl!(Vec4, x, y, z, w) scalar_sub_impl!(Vec4, x, y, z, w)
translation_impl!(Vec4) translation_impl!(Vec4)
translatable_impl!(Vec4)
norm_impl!(Vec4) norm_impl!(Vec4)
approx_eq_impl!(Vec4, x, y, z, w) approx_eq_impl!(Vec4, x, y, z, w)
round_impl!(Vec4, x, y, z, w) round_impl!(Vec4, x, y, z, w)
@ -213,7 +209,6 @@ scalar_div_impl!(Vec5, x, y, z, w, a)
scalar_add_impl!(Vec5, x, y, z, w, a) scalar_add_impl!(Vec5, x, y, z, w, a)
scalar_sub_impl!(Vec5, x, y, z, w, a) scalar_sub_impl!(Vec5, x, y, z, w, a)
translation_impl!(Vec5) translation_impl!(Vec5)
translatable_impl!(Vec5)
norm_impl!(Vec5) norm_impl!(Vec5)
approx_eq_impl!(Vec5, x, y, z, w, a) approx_eq_impl!(Vec5, x, y, z, w, a)
round_impl!(Vec5, x, y, z, w, a) round_impl!(Vec5, x, y, z, w, a)
@ -260,7 +255,6 @@ scalar_div_impl!(Vec6, x, y, z, w, a, b)
scalar_add_impl!(Vec6, x, y, z, w, a, b) scalar_add_impl!(Vec6, x, y, z, w, a, b)
scalar_sub_impl!(Vec6, x, y, z, w, a, b) scalar_sub_impl!(Vec6, x, y, z, w, a, b)
translation_impl!(Vec6) translation_impl!(Vec6)
translatable_impl!(Vec6)
norm_impl!(Vec6) norm_impl!(Vec6)
approx_eq_impl!(Vec6, x, y, z, w, a, b) approx_eq_impl!(Vec6, x, y, z, w, a, b)
round_impl!(Vec6, x, y, z, w, a, b) round_impl!(Vec6, x, y, z, w, a, b)

View File

@ -6,7 +6,7 @@ use std::cmp::ApproxEq;
use traits::iterable::{Iterable, IterableMut}; use traits::iterable::{Iterable, IterableMut};
use traits::basis::Basis; use traits::basis::Basis;
use traits::dim::Dim; use traits::dim::Dim;
use traits::translation::{Translation, Translatable}; use traits::translation::Translation;
use traits::scalar_op::{ScalarAdd, ScalarSub}; use traits::scalar_op::{ScalarAdd, ScalarSub};
use traits::indexable::Indexable; use traits::indexable::Indexable;
use traits::vector::{Vec, AlgebraicVec}; use traits::vector::{Vec, AlgebraicVec};
@ -156,9 +156,7 @@ impl<N: Clone + Add<N, N> + Neg<N>> Translation<vec::Vec0<N>> for vec::Vec0<N> {
fn translate_by(&mut self, t: &vec::Vec0<N>) { fn translate_by(&mut self, t: &vec::Vec0<N>) {
*self = *self + *t; *self = *self + *t;
} }
}
impl<N: Add<N, N> + Neg<N> + Clone> Translatable<vec::Vec0<N>, vec::Vec0<N>> for vec::Vec0<N> {
#[inline] #[inline]
fn translated(&self, t: &vec::Vec0<N>) -> vec::Vec0<N> { fn translated(&self, t: &vec::Vec0<N>) -> vec::Vec0<N> {
self + *t self + *t

View File

@ -353,13 +353,7 @@ macro_rules! translation_impl(
fn translate_by(&mut self, t: &$t<N>) { fn translate_by(&mut self, t: &$t<N>) {
*self = *self + *t; *self = *self + *t;
} }
}
)
)
macro_rules! translatable_impl(
($t: ident) => (
impl<N: Add<N, N> + Neg<N> + Clone> Translatable<$t<N>, $t<N>> for $t<N> {
#[inline] #[inline]
fn translated(&self, t: &$t<N>) -> $t<N> { fn translated(&self, t: &$t<N>) -> $t<N> {
self + *t self + *t