Add rotation and translation traits.

This commit is contained in:
Sébastien Crozet 2013-05-19 11:44:27 +00:00
parent a0ada142a6
commit dc0757b2e5
11 changed files with 149 additions and 22 deletions

View File

@ -4,6 +4,7 @@ all:
test:
rust test src/nalgebra.rc
rm nalgebratest~
doc:
rust test src/nalgebra.rc

View File

@ -6,6 +6,8 @@ use traits::workarounds::trigonometric::Trigonometric;
use traits::dim::Dim;
use traits::inv::Inv;
use traits::transpose::Transpose;
use traits::rotation::Rotation;
use dim1::vec1::{Vec1, vec1};
use dim2::mat2::{Mat2, mat2};
use dim3::mat3::{Mat3, mat3};
use dim3::vec3::{Vec3};
@ -57,13 +59,40 @@ pub fn rotmat3<T: Copy + Trigonometric + Neg<T> + One + Sub<T, T> + Add<T, T> +
}
}
impl<T:Copy + Rand + Trigonometric + Neg<T>> Rand for Rotmat<Mat2<T>>
impl<T: Quot<T, T> + Trigonometric + Neg<T> + Mul<T, T> + Add<T, T> + Copy>
Rotation<Vec1<T>> for Rotmat<Mat2<T>>
{
fn rotation(&self) -> Vec1<T>
{ vec1(-Trigonometric::atan(self.submat.m12 / self.submat.m11)) }
fn rotated(&self, rot: &Vec1<T>) -> Rotmat<Mat2<T>>
{ rotmat2(rot.x) * *self }
fn rotate(&mut self, rot: &Vec1<T>)
{ *self = self.rotated(rot) }
}
impl<T: Quot<T, T> + Trigonometric + Neg<T> + Mul<T, T> + Add<T, T> + Copy +
One + Sub<T, T>>
Rotation<(Vec3<T>, T)> for Rotmat<Mat3<T>>
{
fn rotation(&self) -> (Vec3<T>, T)
{ fail!("Not yet implemented.") }
fn rotated(&self, &(axis, angle): &(Vec3<T>, T)) -> Rotmat<Mat3<T>>
{ rotmat3(&axis, angle) * *self }
fn rotate(&mut self, rot: &(Vec3<T>, T))
{ *self = self.rotated(rot) }
}
impl<T: Copy + Rand + Trigonometric + Neg<T>> Rand for Rotmat<Mat2<T>>
{
fn rand<R: Rng>(rng: &R) -> Rotmat<Mat2<T>>
{ rotmat2(rng.gen()) }
}
impl<T:Copy + Rand + Trigonometric + Neg<T> + One + Sub<T, T> + Add<T, T> +
impl<T: Copy + Rand + Trigonometric + Neg<T> + One + Sub<T, T> + Add<T, T> +
Mul<T, T>>
Rand for Rotmat<Mat3<T>>
{
@ -77,13 +106,13 @@ impl<M: Dim> Dim for Rotmat<M>
{ Dim::dim::<M>() }
}
impl<M:Copy + One + Zero> One for Rotmat<M>
impl<M: Copy + One + Zero> One for Rotmat<M>
{
fn one() -> Rotmat<M>
{ Rotmat { submat: One::one() } }
}
impl<M:Copy + Mul<M, M>> Mul<Rotmat<M>, Rotmat<M>> for Rotmat<M>
impl<M: Copy + Mul<M, M>> Mul<Rotmat<M>, Rotmat<M>> for Rotmat<M>
{
fn mul(&self, other: &Rotmat<M>) -> Rotmat<M>
{ Rotmat { submat: self.submat.mul(&other.submat) } }
@ -101,7 +130,7 @@ impl<V, M: LMul<V>> LMul<V> for Rotmat<M>
{ self.submat.lmul(other) }
}
impl<M:Copy + Transpose>
impl<M: Copy + Transpose>
Inv for Rotmat<M>
{
fn invert(&mut self)
@ -111,7 +140,7 @@ Inv for Rotmat<M>
{ self.transposed() }
}
impl<M:Copy + Transpose>
impl<M: Copy + Transpose>
Transpose for Rotmat<M>
{
fn transposed(&self) -> Rotmat<M>
@ -121,7 +150,7 @@ Transpose for Rotmat<M>
{ self.submat.transpose() }
}
impl<T, M:FuzzyEq<T>> FuzzyEq<T> for Rotmat<M>
impl<T, M: FuzzyEq<T>> FuzzyEq<T> for Rotmat<M>
{
fn fuzzy_eq(&self, other: &Rotmat<M>) -> bool
{ self.submat.fuzzy_eq(&other.submat) }
@ -130,7 +159,7 @@ impl<T, M:FuzzyEq<T>> FuzzyEq<T> for Rotmat<M>
{ self.submat.fuzzy_eq_eps(&other.submat, epsilon) }
}
impl<M:ToStr> ToStr for Rotmat<M>
impl<M: ToStr> ToStr for Rotmat<M>
{
fn to_str(&self) -> ~str
{ ~"Rotmat {" + " submat: " + self.submat.to_str() + " }" }

View File

@ -3,6 +3,8 @@ use core::rand::{Rand, Rng, RngUtil};
use std::cmp::FuzzyEq;
use traits::dim::Dim;
use traits::inv::Inv;
use traits::rotation::Rotation;
use traits::translation::Translation;
use traits::transpose::Transpose;
use traits::workarounds::rlmul::{RMul, LMul};
@ -58,6 +60,30 @@ impl<M: LMul<V>, V> LMul<V> for Transform<M, V>
{ self.submat.lmul(other) }
}
impl<M: Copy, V: Copy + Translation<V>> Translation<V> for Transform<M, V>
{
fn translation(&self) -> V
{ self.subtrans.translation() }
fn translated(&self, t: &V) -> Transform<M, V>
{ transform(&self.submat, &self.subtrans.translated(t)) }
fn translate(&mut self, t: &V)
{ self.subtrans.translate(t) }
}
impl<M: Rotation<V> + Copy, V: Copy> Rotation<V> for Transform<M, V>
{
fn rotation(&self) -> V
{ self.submat.rotation() }
fn rotated(&self, rot: &V) -> Transform<M, V>
{ transform(&self.submat.rotated(rot), &self.subtrans) }
fn rotate(&mut self, rot: &V)
{ self.submat.rotate(rot) }
}
impl<M:Copy + Transpose + Inv + RMul<V>, V:Copy + Neg<V>>
Inv for Transform<M, V>
{

View File

@ -1,10 +1,11 @@
use core::num::{Zero, One, Algebraic};
use core::rand::{Rand, Rng, RngUtil};
use std::cmp::FuzzyEq;
use traits::dot::Dot;
use traits::dim::Dim;
use traits::basis::Basis;
use traits::dim::Dim;
use traits::dot::Dot;
use traits::norm::Norm;
use traits::translation::Translation;
use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
#[deriving(Eq)]
@ -73,6 +74,18 @@ ScalarSub<T> for Vec1<T>
{ self.x -= *s; }
}
impl<T: Copy + Add<T, T>> Translation<Vec1<T>> for Vec1<T>
{
fn translation(&self) -> Vec1<T>
{ *self }
fn translated(&self, t: &Vec1<T>) -> Vec1<T>
{ self + *t }
fn translate(&mut self, t: &Vec1<T>)
{ *self += *t }
}
impl<T:Copy + Mul<T, T> + Add<T, T> + Algebraic> Dot<T> for Vec1<T>
{
fn dot(&self, other : &Vec1<T>) -> T

View File

@ -1,12 +1,13 @@
use core::num::{Zero, One, Algebraic};
use core::rand::{Rand, Rng, RngUtil};
use std::cmp::FuzzyEq;
use traits::dot::Dot;
use traits::dim::Dim;
use traits::cross::Cross;
use traits::basis::Basis;
use traits::norm::Norm;
use dim1::vec1::{Vec1, vec1};
use std::cmp::FuzzyEq;
use traits::basis::Basis;
use traits::cross::Cross;
use traits::dim::Dim;
use traits::dot::Dot;
use traits::norm::Norm;
use traits::translation::Translation;
use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
#[deriving(Eq)]
@ -90,6 +91,18 @@ ScalarSub<T> for Vec2<T>
}
}
impl<T: Copy + Add<T, T>> Translation<Vec2<T>> for Vec2<T>
{
fn translation(&self) -> Vec2<T>
{ *self }
fn translated(&self, t: &Vec2<T>) -> Vec2<T>
{ self + *t }
fn translate(&mut self, t: &Vec2<T>)
{ *self += *t; }
}
impl<T:Copy + Mul<T, T> + Add<T, T> + Algebraic> Dot<T> for Vec2<T>
{
fn dot(&self, other : &Vec2<T>) -> T

View File

@ -1,11 +1,12 @@
use core::num::{Zero, One, Algebraic, abs};
use core::rand::{Rand, Rng, RngUtil};
use std::cmp::FuzzyEq;
use traits::basis::Basis;
use traits::cross::Cross;
use traits::dim::Dim;
use traits::dot::Dot;
use traits::cross::Cross;
use traits::basis::Basis;
use traits::norm::Norm;
use traits::translation::Translation;
use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
#[deriving(Eq)]
@ -94,6 +95,19 @@ ScalarSub<T> for Vec3<T>
}
}
impl<T: Copy + Add<T, T>> Translation<Vec3<T>> for Vec3<T>
{
fn translation(&self) -> Vec3<T>
{ *self }
fn translated(&self, t: &Vec3<T>) -> Vec3<T>
{ self + *t }
fn translate(&mut self, t: &Vec3<T>)
{ *self += *t; }
}
impl<T:Copy + Neg<T>> Neg<Vec3<T>> for Vec3<T>
{

View File

@ -46,6 +46,8 @@ mod traits
mod dim;
mod basis;
mod norm;
mod rotation;
mod translation;
mod workarounds
{

View File

@ -2,10 +2,11 @@ use core::num::{Zero, One, Algebraic};
use core::rand::{Rand, Rng, RngUtil};
use core::vec::{map_zip, from_elem, map, all, all2};
use std::cmp::FuzzyEq;
use traits::basis::Basis;
use traits::dim::Dim;
use traits::dot::Dot;
use traits::norm::Norm;
use traits::basis::Basis;
use traits::translation::Translation;
use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
// D is a phantom parameter, used only as a dimensional token.
@ -118,6 +119,18 @@ ScalarSub<T> for NVec<D, T>
}
}
impl<D: Dim, T: Clone + Copy + Add<T, T>> Translation<NVec<D, T>> for NVec<D, T>
{
fn translation(&self) -> NVec<D, T>
{ self.clone() }
fn translated(&self, t: &NVec<D, T>) -> NVec<D, T>
{ self + *t }
fn translate(&mut self, t: &NVec<D, T>)
{ *self = *self + *t; }
}
impl<D: Dim, T: Copy + Mul<T, T> + Add<T, T> + Quot<T, T> + Algebraic + Zero +
Clone>
Norm<T> for NVec<D, T>

6
src/traits/rotation.rs Normal file
View File

@ -0,0 +1,6 @@
pub trait Rotation<V>
{
fn rotation(&self) -> V;
fn rotated(&self, &V) -> Self;
fn rotate(&mut self, &V);
}

View File

@ -0,0 +1,6 @@
pub trait Translation<V>
{
fn translation(&self) -> V;
fn translated(&self, &V) -> Self;
fn translate(&mut self, &V);
}

View File

@ -1,12 +1,13 @@
// Trigonometric is available in core, but compilation fails with internal
// error.
use core::f64::{cos, sin};
use core::f64::{cos, sin, atan};
pub trait Trigonometric
{
fn cos(Self) -> Self;
fn sin(Self) -> Self;
fn cos(Self) -> Self;
fn sin(Self) -> Self;
fn atan(Self) -> Self;
}
impl Trigonometric for f64
@ -16,4 +17,7 @@ impl Trigonometric for f64
fn sin(a: f64) -> f64
{ sin(a) }
fn atan(a: f64) -> f64
{ atan(a) }
}