forked from M-Labs/nalgebra
Refined traits for rotation/translation/transformation.
This commit is contained in:
parent
ffbcf4882a
commit
6723693b49
@ -5,7 +5,7 @@ use traits::rlmul::{RMul, LMul};
|
||||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::transpose::Transpose;
|
||||
use traits::rotation::Rotation;
|
||||
use traits::rotation::{Rotation, Rotatable};
|
||||
use traits::delta_transform::{DeltaTransform, DeltaTransformVector};
|
||||
use dim1::vec1::Vec1;
|
||||
use dim2::mat2::Mat2;
|
||||
@ -57,38 +57,47 @@ pub fn rotmat3<N: Copy + Trigonometric + Neg<N> + One + Sub<N, N> + Add<N, N> +
|
||||
}
|
||||
|
||||
impl<N: Div<N, N> + Trigonometric + Neg<N> + Mul<N, N> + Add<N, N> + Copy>
|
||||
Rotation<Vec1<N>, Rotmat<Mat2<N>>> for Rotmat<Mat2<N>>
|
||||
Rotation<Vec1<N>> for Rotmat<Mat2<N>>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn rotation(&self) -> Vec1<N>
|
||||
{ Vec1::new(-(self.submat.m12 / self.submat.m11).atan()) }
|
||||
|
||||
#[inline(always)]
|
||||
fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>>
|
||||
{ rotmat2(copy rot.x) * *self }
|
||||
|
||||
#[inline(always)]
|
||||
fn rotate(&mut self, rot: &Vec1<N>)
|
||||
{ *self = self.rotated(rot) }
|
||||
}
|
||||
|
||||
impl<N: Div<N, N> + Trigonometric + Neg<N> + Mul<N, N> + Add<N, N> + Copy>
|
||||
Rotatable<Vec1<N>, Rotmat<Mat2<N>>> for Rotmat<Mat2<N>>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>>
|
||||
{ rotmat2(copy rot.x) * *self }
|
||||
}
|
||||
|
||||
impl<N: Div<N, N> + Trigonometric + Neg<N> + Mul<N, N> + Add<N, N> + Copy +
|
||||
One + Sub<N, N>>
|
||||
Rotation<(Vec3<N>, N), Rotmat<Mat3<N>>> for Rotmat<Mat3<N>>
|
||||
Rotation<(Vec3<N>, N)> for Rotmat<Mat3<N>>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn rotation(&self) -> (Vec3<N>, N)
|
||||
{ fail!("Not yet implemented.") }
|
||||
|
||||
#[inline(always)]
|
||||
fn rotated(&self, &(axis, angle): &(Vec3<N>, N)) -> Rotmat<Mat3<N>>
|
||||
{ rotmat3(&axis, angle) * *self }
|
||||
|
||||
#[inline(always)]
|
||||
fn rotate(&mut self, rot: &(Vec3<N>, N))
|
||||
{ *self = self.rotated(rot) }
|
||||
}
|
||||
|
||||
impl<N: Div<N, N> + Trigonometric + Neg<N> + Mul<N, N> + Add<N, N> + Copy +
|
||||
One + Sub<N, N>>
|
||||
Rotatable<(Vec3<N>, N), Rotmat<Mat3<N>>> for Rotmat<Mat3<N>>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn rotated(&self, &(axis, angle): &(Vec3<N>, N)) -> Rotmat<Mat3<N>>
|
||||
{ rotmat3(&axis, angle) * *self }
|
||||
}
|
||||
|
||||
impl<N: Copy + Rand + Trigonometric + Neg<N>> Rand for Rotmat<Mat2<N>>
|
||||
{
|
||||
#[inline(always)]
|
||||
|
@ -3,8 +3,9 @@ use std::rand::{Rand, Rng, RngUtil};
|
||||
use std::cmp::ApproxEq;
|
||||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::rotation::Rotation;
|
||||
use traits::translation::Translation;
|
||||
use traits::rotation::{Rotation, Rotatable};
|
||||
use traits::translation::{Translation, Translatable};
|
||||
use traits::transformation::{Transformation, Transformable};
|
||||
use traits::transpose::Transpose;
|
||||
use traits::delta_transform::{DeltaTransform, DeltaTransformVector};
|
||||
use traits::rlmul::{RMul, LMul};
|
||||
@ -73,31 +74,51 @@ impl<M: LMul<V>, V: Add<V, V>> LMul<V> for Transform<M, V>
|
||||
{ self.submat.lmul(other) + self.subtrans }
|
||||
}
|
||||
|
||||
impl<M: Copy, V: Translation<V, Res>, Res> Translation<V, Transform<M, Res>> for Transform<M, V>
|
||||
impl<M, V: Translation<V>> Translation<V> for Transform<M, V>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn translation(&self) -> V
|
||||
{ self.subtrans.translation() }
|
||||
|
||||
#[inline(always)]
|
||||
fn translated(&self, t: &V) -> Transform<M, Res>
|
||||
{ Transform::new(copy self.submat, self.subtrans.translated(t)) }
|
||||
|
||||
#[inline(always)]
|
||||
fn translate(&mut self, t: &V)
|
||||
{ self.subtrans.translate(t) }
|
||||
}
|
||||
|
||||
impl<M: Rotation<AV, Res> + One,
|
||||
Res: RMul<V>,
|
||||
impl<M: Copy, V: Translatable<V, Res>, Res: Translation<V>>
|
||||
Translatable<V, Transform<M, Res>> for Transform<M, V>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn translated(&self, t: &V) -> Transform<M, Res>
|
||||
{ Transform::new(copy self.submat, self.subtrans.translated(t)) }
|
||||
}
|
||||
|
||||
impl<M: Rotation<AV> + RMul<V> + One,
|
||||
V,
|
||||
AV>
|
||||
Rotation<AV, Transform<Res, V>> for Transform<M, V>
|
||||
Rotation<AV> for Transform<M, V>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn rotation(&self) -> AV
|
||||
{ self.submat.rotation() }
|
||||
|
||||
#[inline(always)]
|
||||
fn rotate(&mut self, rot: &AV)
|
||||
{
|
||||
// FIXME: this does not seem opitmal
|
||||
let mut delta = One::one::<M>();
|
||||
delta.rotate(rot);
|
||||
self.submat.rotate(rot);
|
||||
self.subtrans = delta.rmul(&self.subtrans);
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: Rotatable<AV, Res> + One,
|
||||
Res: Rotation<AV> + RMul<V>,
|
||||
V,
|
||||
AV>
|
||||
Rotatable<AV, Transform<Res, V>> for Transform<M, V>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn rotated(&self, rot: &AV) -> Transform<Res, V>
|
||||
{
|
||||
@ -106,15 +127,24 @@ Rotation<AV, Transform<Res, V>> for Transform<M, V>
|
||||
|
||||
Transform::new(self.submat.rotated(rot), delta.rmul(&self.subtrans))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn rotate(&mut self, rot: &AV)
|
||||
{
|
||||
// FIXME: this does not seem opitmal
|
||||
let delta = One::one::<M>().rotated(rot);
|
||||
self.submat.rotate(rot);
|
||||
self.subtrans = delta.rmul(&self.subtrans);
|
||||
}
|
||||
|
||||
impl<M: RMul<V> + Mul<M, M> + Copy, V: Add<V, V> + Copy> Transformation<Transform<M, V>> for Transform<M, V>
|
||||
{
|
||||
fn transformation(&self) -> Transform<M, V>
|
||||
{ copy *self }
|
||||
|
||||
fn transform_by(&mut self, other: &Transform<M, V>)
|
||||
{ *self = other * *self; }
|
||||
}
|
||||
|
||||
// FIXME: constraints are too restrictive.
|
||||
// Should be: Transformable<M2, // Transform<Res, V> ...
|
||||
impl<M: RMul<V> + Mul<M, M>, V: Add<V, V>>
|
||||
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: Copy, V> DeltaTransform<M> for Transform<M, V>
|
||||
|
@ -5,7 +5,7 @@ use traits::basis::Basis;
|
||||
use traits::dim::Dim;
|
||||
use traits::dot::Dot;
|
||||
use traits::norm::Norm;
|
||||
use traits::translation::Translation;
|
||||
use traits::translation::{Translation, Translatable};
|
||||
use traits::sub_dot::SubDot;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
@ -91,21 +91,24 @@ ScalarSub<N> for Vec1<N>
|
||||
{ self.x = self.x - *s; }
|
||||
}
|
||||
|
||||
impl<N: Copy + Add<N, N>> Translation<Vec1<N>, Vec1<N>> for Vec1<N>
|
||||
impl<N: Copy + Add<N, N>> Translation<Vec1<N>> for Vec1<N>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn translation(&self) -> Vec1<N>
|
||||
{ copy *self }
|
||||
|
||||
#[inline(always)]
|
||||
fn translated(&self, t: &Vec1<N>) -> Vec1<N>
|
||||
{ self + *t }
|
||||
|
||||
#[inline(always)]
|
||||
fn translate(&mut self, t: &Vec1<N>)
|
||||
{ *self = *self + *t }
|
||||
}
|
||||
|
||||
impl<N: Add<N, N>> Translatable<Vec1<N>, Vec1<N>> for Vec1<N>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn translated(&self, t: &Vec1<N>) -> Vec1<N>
|
||||
{ self + *t }
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N>> Dot<N> for Vec1<N>
|
||||
{
|
||||
#[inline(always)]
|
||||
|
@ -9,7 +9,7 @@ use traits::dot::Dot;
|
||||
use traits::sub_dot::SubDot;
|
||||
use traits::norm::Norm;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::translation::Translation;
|
||||
use traits::translation::{Translation, Translatable};
|
||||
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
|
||||
#[deriving(Eq, Ord, ToStr)]
|
||||
@ -108,21 +108,24 @@ ScalarSub<N> for Vec2<N>
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Add<N, N>> Translation<Vec2<N>, Vec2<N>> for Vec2<N>
|
||||
impl<N: Copy + Add<N, N>> Translation<Vec2<N>> for Vec2<N>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn translation(&self) -> Vec2<N>
|
||||
{ copy *self }
|
||||
|
||||
#[inline(always)]
|
||||
fn translated(&self, t: &Vec2<N>) -> Vec2<N>
|
||||
{ self + *t }
|
||||
|
||||
#[inline(always)]
|
||||
fn translate(&mut self, t: &Vec2<N>)
|
||||
{ *self = *self + *t; }
|
||||
}
|
||||
|
||||
impl<N: Add<N, N>> Translatable<Vec2<N>, Vec2<N>> for Vec2<N>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn translated(&self, t: &Vec2<N>) -> Vec2<N>
|
||||
{ self + *t }
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N> + Add<N, N>> Dot<N> for Vec2<N>
|
||||
{
|
||||
#[inline(always)]
|
||||
|
@ -8,7 +8,7 @@ use traits::dot::Dot;
|
||||
use traits::sub_dot::SubDot;
|
||||
use traits::norm::Norm;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::translation::Translation;
|
||||
use traits::translation::{Translation, Translatable};
|
||||
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
|
||||
#[deriving(Eq, Ord, ToStr)]
|
||||
@ -112,21 +112,24 @@ ScalarSub<N> for Vec3<N>
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Add<N, N>> Translation<Vec3<N>, Vec3<N>> for Vec3<N>
|
||||
impl<N: Copy + Add<N, N>> Translation<Vec3<N>> for Vec3<N>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn translation(&self) -> Vec3<N>
|
||||
{ copy *self }
|
||||
|
||||
#[inline(always)]
|
||||
fn translated(&self, t: &Vec3<N>) -> Vec3<N>
|
||||
{ self + *t }
|
||||
|
||||
#[inline(always)]
|
||||
fn translate(&mut self, t: &Vec3<N>)
|
||||
{ *self = *self + *t; }
|
||||
}
|
||||
|
||||
impl<N: Add<N, N>> Translatable<Vec3<N>, Vec3<N>> for Vec3<N>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn translated(&self, t: &Vec3<N>) -> Vec3<N>
|
||||
{ self + *t }
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl<N: Neg<N>> Neg<Vec3<N>> for Vec3<N>
|
||||
|
@ -64,6 +64,7 @@ pub mod traits
|
||||
pub mod norm;
|
||||
pub mod rotation;
|
||||
pub mod translation;
|
||||
pub mod transformation;
|
||||
pub mod delta_transform;
|
||||
pub mod vector_space;
|
||||
pub mod ring;
|
||||
|
@ -8,7 +8,7 @@ use traits::division_ring::DivisionRing;
|
||||
use traits::dot::Dot;
|
||||
use traits::sub_dot::SubDot;
|
||||
use traits::norm::Norm;
|
||||
use traits::translation::Translation;
|
||||
use traits::translation::{Translation, Translatable};
|
||||
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
|
||||
#[deriving(Eq, Ord, ToStr, Clone)]
|
||||
@ -196,21 +196,24 @@ ScalarSub<N> for DVec<N>
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Copy + Add<N, N>> Translation<DVec<N>, DVec<N>> for DVec<N>
|
||||
impl<N: Clone + Copy + Add<N, N>> Translation<DVec<N>> for DVec<N>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn translation(&self) -> DVec<N>
|
||||
{ self.clone() }
|
||||
|
||||
#[inline(always)]
|
||||
fn translated(&self, t: &DVec<N>) -> DVec<N>
|
||||
{ self + *t }
|
||||
|
||||
#[inline(always)]
|
||||
fn translate(&mut self, t: &DVec<N>)
|
||||
{ *self = *self + *t; }
|
||||
}
|
||||
|
||||
impl<N: Add<N, N> + Copy> Translatable<DVec<N>, DVec<N>> for DVec<N>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn translated(&self, t: &DVec<N>) -> DVec<N>
|
||||
{ self + *t }
|
||||
}
|
||||
|
||||
impl<N: Copy + DivisionRing + Algebraic + Clone>
|
||||
Norm<N> for DVec<N>
|
||||
{
|
||||
|
@ -11,7 +11,7 @@ use traits::dim::Dim;
|
||||
use traits::dot::Dot;
|
||||
use traits::sub_dot::SubDot;
|
||||
use traits::norm::Norm;
|
||||
use traits::translation::Translation;
|
||||
use traits::translation::{Translation, Translatable};
|
||||
use traits::flatten::Flatten;
|
||||
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
|
||||
@ -123,21 +123,24 @@ ScalarSub<N> for NVec<D, N>
|
||||
{ self.at.scalar_sub_inplace(s) }
|
||||
}
|
||||
|
||||
impl<D: Dim, N: Clone + Copy + Add<N, N>> Translation<NVec<D, N>, NVec<D, N>> for NVec<D, N>
|
||||
impl<D: Dim, N: Clone + Copy + Add<N, N>> Translation<NVec<D, N>> for NVec<D, N>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn translation(&self) -> NVec<D, N>
|
||||
{ self.clone() }
|
||||
|
||||
#[inline(always)]
|
||||
fn translated(&self, t: &NVec<D, N>) -> NVec<D, N>
|
||||
{ self + *t }
|
||||
|
||||
#[inline(always)]
|
||||
fn translate(&mut self, t: &NVec<D, N>)
|
||||
{ *self = *self + *t; }
|
||||
}
|
||||
|
||||
impl<D: Dim, N: Add<N, N> + Copy> Translatable<NVec<D, N>, NVec<D, N>> for NVec<D, N>
|
||||
{
|
||||
#[inline(always)]
|
||||
fn translated(&self, t: &NVec<D, N>) -> NVec<D, N>
|
||||
{ self + *t }
|
||||
}
|
||||
|
||||
impl<D: Dim, N: Copy + DivisionRing + Algebraic + Clone>
|
||||
Norm<N> for NVec<D, N>
|
||||
{
|
||||
|
@ -3,13 +3,13 @@ use std::vec;
|
||||
#[test]
|
||||
use std::num::{Real, Zero, One, abs};
|
||||
#[test]
|
||||
use std::rand::{random};
|
||||
use std::rand::random;
|
||||
#[test]
|
||||
use std::cmp::ApproxEq;
|
||||
#[test]
|
||||
use traits::inv::Inv;
|
||||
#[test]
|
||||
use traits::rotation::Rotation;
|
||||
use traits::rotation::{Rotation, Rotatable};
|
||||
#[test]
|
||||
use traits::dim::d7;
|
||||
#[test]
|
||||
|
@ -1,19 +1,22 @@
|
||||
use traits::translation::Translation;
|
||||
use traits::translation::{Translation, Translatable};
|
||||
|
||||
/// 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
|
||||
/// and without reflexion.
|
||||
pub trait Rotation<V, Res>
|
||||
pub trait Rotation<V>
|
||||
{
|
||||
/// Gets the rotation associated with this object.
|
||||
fn rotation(&self) -> V;
|
||||
|
||||
/// In-place version of `rotated`.
|
||||
fn rotate(&mut self, &V);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/// In-place version of `rotated`.
|
||||
fn rotate(&mut self, &V);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -24,13 +27,11 @@ pub trait Rotation<V, Res>
|
||||
* - `point`: the center of rotation.
|
||||
*/
|
||||
#[inline(always)]
|
||||
pub fn rotate_wrt_point<M: Translation<LV, ResT>,
|
||||
ResT: Rotation<AV, Res> + Translation<LV, ResT2>,
|
||||
ResT2,
|
||||
Res,
|
||||
pub fn rotate_wrt_point<M: Translatable<LV, M2>,
|
||||
M2: Rotation<AV> + Translation<LV>,
|
||||
LV: Neg<LV>,
|
||||
AV>
|
||||
(m: &M, ammount: &AV, center: &LV) -> ResT
|
||||
(m: &M, ammount: &AV, center: &LV) -> M2
|
||||
{
|
||||
let mut res = m.translated(&-center);
|
||||
|
||||
|
13
src/traits/transformation.rs
Normal file
13
src/traits/transformation.rs
Normal file
@ -0,0 +1,13 @@
|
||||
pub trait Transformation<M>
|
||||
{
|
||||
fn transformation(&self) -> M;
|
||||
|
||||
// XXX: we must use "transform_by" instead of "transform" because of a
|
||||
// conflict with some iterator function…
|
||||
fn transform_by(&mut self, &M);
|
||||
}
|
||||
|
||||
pub trait Transformable<M, Res: Transformation<M>>
|
||||
{
|
||||
fn transformed(&self, &M) -> Res;
|
||||
}
|
@ -1,14 +1,18 @@
|
||||
/// Trait of object which represent a translation, and to wich new translation
|
||||
/// can be appended.
|
||||
pub trait Translation<V, Res>
|
||||
pub trait Translation<V>
|
||||
{
|
||||
// FIXME: add a "from translation: translantion(V) -> Self ?
|
||||
/// Gets the translation associated with this object.
|
||||
fn translation(&self) -> 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;
|
||||
|
||||
/// In-place version of `translate`.
|
||||
fn translate(&mut self, &V);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user