Refactor vec{1, 2, 3} implemenation + add some useful traits.
This commit is contained in:
parent
8abcdeeedc
commit
cd355dfb30
|
@ -5,12 +5,12 @@ use traits::rlmul::{RMul, LMul};
|
|||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::transpose::Transpose;
|
||||
use traits::rotation::{Rotation, Rotatable};
|
||||
use traits::delta_transform::{DeltaTransform, DeltaTransformVector};
|
||||
use dim1::vec1::Vec1;
|
||||
use traits::rotation::{Rotation, Rotate, Rotatable};
|
||||
use traits::transformation::{Transform}; // FIXME: implement Transformation and Transformable
|
||||
use vec::Vec1;
|
||||
use dim2::mat2::Mat2;
|
||||
use dim3::mat3::Mat3;
|
||||
use dim3::vec3::{Vec3};
|
||||
use vec::Vec3;
|
||||
|
||||
#[deriving(Eq, ToStr)]
|
||||
pub struct Rotmat<M>
|
||||
|
@ -30,9 +30,9 @@ pub fn rotmat3<N: Copy + Trigonometric + Neg<N> + One + Sub<N, N> + Add<N, N> +
|
|||
(axis: &Vec3<N>, angle: N) -> Rotmat<Mat3<N>>
|
||||
{
|
||||
let _1 = One::one::<N>();
|
||||
let ux = copy axis.x;
|
||||
let uy = copy axis.y;
|
||||
let uz = copy axis.z;
|
||||
let ux = copy axis.at[0];
|
||||
let uy = copy axis.at[1];
|
||||
let uz = copy axis.at[2];
|
||||
let sqx = ux * ux;
|
||||
let sqy = uy * uy;
|
||||
let sqz = uz * uz;
|
||||
|
@ -61,10 +61,14 @@ Rotation<Vec1<N>> for Rotmat<Mat2<N>>
|
|||
{
|
||||
#[inline]
|
||||
fn rotation(&self) -> Vec1<N>
|
||||
{ Vec1::new(-(self.submat.m12 / self.submat.m11).atan()) }
|
||||
{ Vec1::new([-(self.submat.m12 / self.submat.m11).atan()]) }
|
||||
|
||||
#[inline]
|
||||
fn rotate(&mut self, rot: &Vec1<N>)
|
||||
fn inv_rotation(&self) -> Vec1<N>
|
||||
{ -self.rotation() }
|
||||
|
||||
#[inline]
|
||||
fn rotate_by(&mut self, rot: &Vec1<N>)
|
||||
{ *self = self.rotated(rot) }
|
||||
}
|
||||
|
||||
|
@ -73,7 +77,7 @@ Rotatable<Vec1<N>, Rotmat<Mat2<N>>> for Rotmat<Mat2<N>>
|
|||
{
|
||||
#[inline]
|
||||
fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>>
|
||||
{ rotmat2(copy rot.x) * *self }
|
||||
{ rotmat2(copy rot.at[0]) * *self }
|
||||
}
|
||||
|
||||
impl<N: Div<N, N> + Trigonometric + Neg<N> + Mul<N, N> + Add<N, N> + Copy +
|
||||
|
@ -83,9 +87,14 @@ Rotation<(Vec3<N>, N)> for Rotmat<Mat3<N>>
|
|||
#[inline]
|
||||
fn rotation(&self) -> (Vec3<N>, N)
|
||||
{ fail!("Not yet implemented.") }
|
||||
#[inline]
|
||||
|
||||
fn inv_rotation(&self) -> (Vec3<N>, N)
|
||||
{ fail!("Not yet implemented.") }
|
||||
|
||||
|
||||
#[inline]
|
||||
fn rotate(&mut self, rot: &(Vec3<N>, N))
|
||||
fn rotate_by(&mut self, rot: &(Vec3<N>, N))
|
||||
{ *self = self.rotated(rot) }
|
||||
}
|
||||
|
||||
|
@ -105,6 +114,28 @@ impl<N: Copy + Rand + Trigonometric + Neg<N>> Rand for Rotmat<Mat2<N>>
|
|||
{ rotmat2(rng.gen()) }
|
||||
}
|
||||
|
||||
impl<M: RMul<V> + LMul<V>, V> Rotate<V> for Rotmat<M>
|
||||
{
|
||||
#[inline]
|
||||
fn rotate(&self, v: &V) -> V
|
||||
{ self.rmul(v) }
|
||||
|
||||
#[inline]
|
||||
fn inv_rotate(&self, v: &V) -> V
|
||||
{ self.lmul(v) }
|
||||
}
|
||||
|
||||
impl<M: RMul<V> + LMul<V>, V> Transform<V> for Rotmat<M>
|
||||
{
|
||||
#[inline]
|
||||
fn transform_vec(&self, v: &V) -> V
|
||||
{ self.rotate(v) }
|
||||
|
||||
#[inline]
|
||||
fn inv_transform(&self, v: &V) -> V
|
||||
{ self.inv_rotate(v) }
|
||||
}
|
||||
|
||||
impl<N: Copy + Rand + Trigonometric + Neg<N> + One + Sub<N, N> + Add<N, N> +
|
||||
Mul<N, N>>
|
||||
Rand for Rotmat<Mat3<N>>
|
||||
|
@ -149,20 +180,6 @@ impl<V, M: LMul<V>> LMul<V> for Rotmat<M>
|
|||
{ self.submat.lmul(other) }
|
||||
}
|
||||
|
||||
impl<M: Copy> DeltaTransform<M> for Rotmat<M>
|
||||
{
|
||||
#[inline]
|
||||
fn delta_transform(&self) -> M
|
||||
{ copy self.submat }
|
||||
}
|
||||
|
||||
impl<M: RMul<V>, V> DeltaTransformVector<V> for Rotmat<M>
|
||||
{
|
||||
#[inline]
|
||||
fn delta_transform_vector(&self, v: &V) -> V
|
||||
{ self.submat.rmul(v) }
|
||||
}
|
||||
|
||||
impl<M: Transpose> Inv for Rotmat<M>
|
||||
{
|
||||
#[inline]
|
||||
|
|
|
@ -3,11 +3,10 @@ use std::rand::{Rand, Rng, RngUtil};
|
|||
use std::cmp::ApproxEq;
|
||||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::rotation::{Rotation, Rotatable};
|
||||
use traits::translation::{Translation, Translatable};
|
||||
use traits::rotation::{Rotation, Rotate, Rotatable};
|
||||
use traits::translation::{Translation, Translate, Translatable};
|
||||
use traits::transformation;
|
||||
use traits::transformation::{Transformation, Transformable};
|
||||
use traits::transpose::Transpose;
|
||||
use traits::delta_transform::{DeltaTransform, DeltaTransformVector};
|
||||
use traits::rlmul::{RMul, LMul};
|
||||
|
||||
#[deriving(Eq, ToStr)]
|
||||
|
@ -81,8 +80,23 @@ impl<M, V: Translation<V>> Translation<V> for Transform<M, V>
|
|||
{ self.subtrans.translation() }
|
||||
|
||||
#[inline]
|
||||
fn translate(&mut self, t: &V)
|
||||
{ self.subtrans.translate(t) }
|
||||
fn inv_translation(&self) -> V
|
||||
{ self.subtrans.inv_translation() }
|
||||
|
||||
#[inline]
|
||||
fn translate_by(&mut self, t: &V)
|
||||
{ self.subtrans.translate_by(t) }
|
||||
}
|
||||
|
||||
impl<M: Translate<V>, V, _0> Translate<V> for Transform<M, _0>
|
||||
{
|
||||
#[inline]
|
||||
fn translate(&self, v: &V) -> V
|
||||
{ self.submat.translate(v) }
|
||||
|
||||
#[inline]
|
||||
fn inv_translate(&self, v: &V) -> V
|
||||
{ self.submat.inv_translate(v) }
|
||||
}
|
||||
|
||||
impl<M: Copy, V: Translatable<V, Res>, Res: Translation<V>>
|
||||
|
@ -103,16 +117,32 @@ Rotation<AV> for Transform<M, V>
|
|||
{ self.submat.rotation() }
|
||||
|
||||
#[inline]
|
||||
fn rotate(&mut self, rot: &AV)
|
||||
fn inv_rotation(&self) -> AV
|
||||
{ self.submat.inv_rotation() }
|
||||
|
||||
|
||||
#[inline]
|
||||
fn rotate_by(&mut self, rot: &AV)
|
||||
{
|
||||
// FIXME: this does not seem opitmal
|
||||
let mut delta = One::one::<M>();
|
||||
delta.rotate(rot);
|
||||
self.submat.rotate(rot);
|
||||
delta.rotate_by(rot);
|
||||
self.submat.rotate_by(rot);
|
||||
self.subtrans = delta.rmul(&self.subtrans);
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: Rotate<V>, V, _0> Rotate<V> for Transform<M, _0>
|
||||
{
|
||||
#[inline]
|
||||
fn rotate(&self, v: &V) -> V
|
||||
{ self.submat.rotate(v) }
|
||||
|
||||
#[inline]
|
||||
fn inv_rotate(&self, v: &V) -> V
|
||||
{ self.submat.inv_rotate(v) }
|
||||
}
|
||||
|
||||
impl<M: Rotatable<AV, Res> + One,
|
||||
Res: Rotation<AV> + RMul<V>,
|
||||
V,
|
||||
|
@ -129,15 +159,32 @@ Rotatable<AV, Transform<Res, V>> for Transform<M, V>
|
|||
}
|
||||
}
|
||||
|
||||
impl<M: RMul<V> + Mul<M, M> + Copy, V: Add<V, V> + Copy> Transformation<Transform<M, V>> for Transform<M, V>
|
||||
impl<M: Inv + RMul<V> + Mul<M, M> + Copy, V: Add<V, V> + Neg<V> + Copy>
|
||||
Transformation<Transform<M, V>> for Transform<M, V>
|
||||
{
|
||||
fn transformation(&self) -> Transform<M, V>
|
||||
{ copy *self }
|
||||
|
||||
fn inv_transformation(&self) -> Transform<M, V>
|
||||
{ self.inverse() }
|
||||
|
||||
fn transform_by(&mut self, other: &Transform<M, V>)
|
||||
{ *self = other * *self; }
|
||||
}
|
||||
|
||||
impl<M: transformation::Transform<V>, V: Add<V, V> + Sub<V, V>>
|
||||
transformation::Transform<V> for Transform<M, V>
|
||||
{
|
||||
#[inline]
|
||||
fn transform_vec(&self, v: &V) -> V
|
||||
{ self.submat.transform_vec(v) + self.subtrans }
|
||||
|
||||
#[inline]
|
||||
fn inv_transform(&self, v: &V) -> V
|
||||
{ self.submat.inv_transform(&(v - self.subtrans)) }
|
||||
}
|
||||
|
||||
|
||||
// FIXME: constraints are too restrictive.
|
||||
// Should be: Transformable<M2, // Transform<Res, V> ...
|
||||
impl<M: RMul<V> + Mul<M, M>, V: Add<V, V>>
|
||||
|
@ -147,21 +194,7 @@ Transformable<Transform<M, V>, Transform<M, V>> for Transform<M, V>
|
|||
{ t * *self }
|
||||
}
|
||||
|
||||
impl<M: Copy, V> DeltaTransform<M> for Transform<M, V>
|
||||
{
|
||||
#[inline]
|
||||
fn delta_transform(&self) -> M
|
||||
{ copy self.submat }
|
||||
}
|
||||
|
||||
impl<M: RMul<V>, V> DeltaTransformVector<V> for Transform<M, V>
|
||||
{
|
||||
#[inline]
|
||||
fn delta_transform_vector(&self, v: &V) -> V
|
||||
{ self.submat.rmul(v) }
|
||||
}
|
||||
|
||||
impl<M:Copy + Transpose + Inv + RMul<V>, V: Copy + Neg<V>>
|
||||
impl<M: Copy + Inv + RMul<V>, V: Copy + Neg<V>>
|
||||
Inv for Transform<M, V>
|
||||
{
|
||||
#[inline]
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use std::num::{One, Zero};
|
||||
use std::rand::{Rand, Rng, RngUtil};
|
||||
use std::cmp::ApproxEq;
|
||||
use traits::division_ring::DivisionRing;
|
||||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::transpose::Transpose;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::transformation::Transform; // FIXME: implement Transformable, Transformation
|
||||
use traits::rlmul::{RMul, LMul};
|
||||
use dim1::vec1::Vec1;
|
||||
use vec::Vec1;
|
||||
|
||||
#[deriving(Eq, ToStr)]
|
||||
pub struct Mat1<N>
|
||||
|
@ -54,21 +55,33 @@ impl<N: Mul<N, N> + Add<N, N>> Mul<Mat1<N>, Mat1<N>> for Mat1<N>
|
|||
{ Mat1::new(self.m11 * other.m11) }
|
||||
}
|
||||
|
||||
impl<N: Copy + DivisionRing>
|
||||
Transform<Vec1<N>> for Mat1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn transform_vec(&self, v: &Vec1<N>) -> Vec1<N>
|
||||
{ self.rmul(v) }
|
||||
|
||||
#[inline]
|
||||
fn inv_transform(&self, v: &Vec1<N>) -> Vec1<N>
|
||||
{ self.inverse().transform_vec(v) }
|
||||
}
|
||||
|
||||
impl<N: Add<N, N> + Mul<N, N>> RMul<Vec1<N>> for Mat1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn rmul(&self, other: &Vec1<N>) -> Vec1<N>
|
||||
{ Vec1::new(self.m11 * other.x) }
|
||||
{ Vec1::new([self.m11 * other.at[0]]) }
|
||||
}
|
||||
|
||||
impl<N: Add<N, N> + Mul<N, N>> LMul<Vec1<N>> for Mat1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn lmul(&self, other: &Vec1<N>) -> Vec1<N>
|
||||
{ Vec1::new(self.m11 * other.x) }
|
||||
{ Vec1::new([self.m11 * other.at[0]]) }
|
||||
}
|
||||
|
||||
impl<N:Copy + Mul<N, N> + Div<N, N> + Sub<N, N> + Neg<N> + Zero + One>
|
||||
impl<N: Copy + DivisionRing>
|
||||
Inv for Mat1<N>
|
||||
{
|
||||
#[inline]
|
||||
|
@ -101,7 +114,7 @@ impl<N: Copy> Transpose for Mat1<N>
|
|||
{ }
|
||||
}
|
||||
|
||||
impl<N:ApproxEq<N>> ApproxEq<N> for Mat1<N>
|
||||
impl<N: ApproxEq<N>> ApproxEq<N> for Mat1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn approx_epsilon() -> N
|
||||
|
@ -116,28 +129,9 @@ impl<N:ApproxEq<N>> ApproxEq<N> for Mat1<N>
|
|||
{ self.m11.approx_eq_eps(&other.m11, epsilon) }
|
||||
}
|
||||
|
||||
impl<N: Rand > Rand for Mat1<N>
|
||||
impl<N: Rand> Rand for Mat1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> Mat1<N>
|
||||
{ Mat1::new(rng.gen()) }
|
||||
}
|
||||
|
||||
impl<N: Copy> Flatten<N> for Mat1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn flat_size() -> uint
|
||||
{ 1 }
|
||||
|
||||
#[inline]
|
||||
fn from_flattened(l: &[N], off: uint) -> Mat1<N>
|
||||
{ Mat1::new(copy l[off]) }
|
||||
|
||||
#[inline]
|
||||
fn flatten(&self) -> ~[N]
|
||||
{ ~[ copy self.m11 ] }
|
||||
|
||||
#[inline]
|
||||
fn flatten_to(&self, l: &mut [N], off: uint)
|
||||
{ l[off] = copy self.m11 }
|
||||
}
|
||||
|
|
234
src/dim1/vec1.rs
234
src/dim1/vec1.rs
|
@ -1,234 +0,0 @@
|
|||
use std::num::{Zero, One, Algebraic, Bounded};
|
||||
use std::rand::{Rand, Rng, RngUtil};
|
||||
use std::cmp::ApproxEq;
|
||||
use traits::basis::Basis;
|
||||
use traits::dim::Dim;
|
||||
use traits::dot::Dot;
|
||||
use traits::norm::Norm;
|
||||
use traits::translation::{Translation, Translatable};
|
||||
use traits::sub_dot::SubDot;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
|
||||
#[deriving(Eq, Ord, ToStr)]
|
||||
pub struct Vec1<N>
|
||||
{ x : N }
|
||||
|
||||
impl<N> Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
pub fn new(x: N) -> Vec1<N>
|
||||
{ Vec1 {x: x} }
|
||||
}
|
||||
|
||||
impl<N> Dim for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn dim() -> uint
|
||||
{ 1 }
|
||||
}
|
||||
|
||||
impl<N: Add<N, N>> Add<Vec1<N>, Vec1<N>> for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn add(&self, other: &Vec1<N>) -> Vec1<N>
|
||||
{ Vec1::new(self.x + other.x) }
|
||||
}
|
||||
|
||||
impl<N: Sub<N, N>> Sub<Vec1<N>, Vec1<N>> for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn sub(&self, other: &Vec1<N>) -> Vec1<N>
|
||||
{ Vec1::new(self.x - other.x) }
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N>>
|
||||
ScalarMul<N> for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn scalar_mul(&self, s: &N) -> Vec1<N>
|
||||
{ Vec1 { x: self.x * *s } }
|
||||
|
||||
#[inline]
|
||||
fn scalar_mul_inplace(&mut self, s: &N)
|
||||
{ self.x = self.x * *s; }
|
||||
}
|
||||
|
||||
|
||||
impl<N: Div<N, N>>
|
||||
ScalarDiv<N> for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn scalar_div(&self, s: &N) -> Vec1<N>
|
||||
{ Vec1 { x: self.x / *s } }
|
||||
|
||||
#[inline]
|
||||
fn scalar_div_inplace(&mut self, s: &N)
|
||||
{ self.x = self.x / *s; }
|
||||
}
|
||||
|
||||
impl<N: Add<N, N>>
|
||||
ScalarAdd<N> for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn scalar_add(&self, s: &N) -> Vec1<N>
|
||||
{ Vec1 { x: self.x + *s } }
|
||||
|
||||
#[inline]
|
||||
fn scalar_add_inplace(&mut self, s: &N)
|
||||
{ self.x = self.x + *s; }
|
||||
}
|
||||
|
||||
impl<N: Sub<N, N>>
|
||||
ScalarSub<N> for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn scalar_sub(&self, s: &N) -> Vec1<N>
|
||||
{ Vec1 { x: self.x - *s } }
|
||||
|
||||
#[inline]
|
||||
fn scalar_sub_inplace(&mut self, s: &N)
|
||||
{ self.x = self.x - *s; }
|
||||
}
|
||||
|
||||
impl<N: Copy + Add<N, N>> Translation<Vec1<N>> for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn translation(&self) -> Vec1<N>
|
||||
{ copy *self }
|
||||
|
||||
#[inline]
|
||||
fn translate(&mut self, t: &Vec1<N>)
|
||||
{ *self = *self + *t }
|
||||
}
|
||||
|
||||
impl<N: Add<N, N>> Translatable<Vec1<N>, Vec1<N>> for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn translated(&self, t: &Vec1<N>) -> Vec1<N>
|
||||
{ self + *t }
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N>> Dot<N> for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn dot(&self, other : &Vec1<N>) -> N
|
||||
{ self.x * other.x }
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N> + Sub<N, N>> SubDot<N> for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn sub_dot(&self, a: &Vec1<N>, b: &Vec1<N>) -> N
|
||||
{ (self.x - a.x) * b.x }
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N> + Add<N, N> + Div<N, N> + Algebraic>
|
||||
Norm<N> for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn sqnorm(&self) -> N
|
||||
{ self.dot(self) }
|
||||
|
||||
#[inline]
|
||||
fn norm(&self) -> N
|
||||
{ self.sqnorm().sqrt() }
|
||||
|
||||
#[inline]
|
||||
fn normalized(&self) -> Vec1<N>
|
||||
{ Vec1::new(self.x / self.norm()) }
|
||||
|
||||
#[inline]
|
||||
fn normalize(&mut self) -> N
|
||||
{
|
||||
let l = self.norm();
|
||||
|
||||
self.x = self.x / l;
|
||||
|
||||
l
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Neg<N>> Neg<Vec1<N>> for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn neg(&self) -> Vec1<N>
|
||||
{ Vec1::new(-self.x) }
|
||||
}
|
||||
|
||||
impl<N: Zero> Zero for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn zero() -> Vec1<N>
|
||||
{
|
||||
let _0 = Zero::zero();
|
||||
Vec1::new(_0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool
|
||||
{ self.x.is_zero() }
|
||||
}
|
||||
|
||||
impl<N: One> Basis for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn canonical_basis() -> ~[Vec1<N>]
|
||||
{ ~[ Vec1::new(One::one()) ] } // FIXME: this should be static
|
||||
|
||||
#[inline]
|
||||
fn orthogonal_subspace_basis(&self) -> ~[Vec1<N>]
|
||||
{ ~[] }
|
||||
}
|
||||
|
||||
impl<N:ApproxEq<N>> ApproxEq<N> for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn approx_epsilon() -> N
|
||||
{ ApproxEq::approx_epsilon::<N, N>() }
|
||||
|
||||
#[inline]
|
||||
fn approx_eq(&self, other: &Vec1<N>) -> bool
|
||||
{ self.x.approx_eq(&other.x) }
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Vec1<N>, epsilon: &N) -> bool
|
||||
{ self.x.approx_eq_eps(&other.x, epsilon) }
|
||||
}
|
||||
|
||||
impl<N: Rand> Rand for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> Vec1<N>
|
||||
{ Vec1::new(rng.gen()) }
|
||||
}
|
||||
|
||||
impl<N: Copy> Flatten<N> for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn flat_size() -> uint
|
||||
{ 1 }
|
||||
|
||||
#[inline]
|
||||
fn from_flattened(l: &[N], off: uint) -> Vec1<N>
|
||||
{ Vec1::new(copy l[off]) }
|
||||
|
||||
#[inline]
|
||||
fn flatten(&self) -> ~[N]
|
||||
{ ~[ copy self.x ] }
|
||||
|
||||
#[inline]
|
||||
fn flatten_to(&self, l: &mut [N], off: uint)
|
||||
{ l[off] = copy self.x }
|
||||
}
|
||||
|
||||
impl<N: Bounded> Bounded for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn max_value() -> Vec1<N>
|
||||
{ Vec1::new(Bounded::max_value()) }
|
||||
|
||||
#[inline]
|
||||
fn min_value() -> Vec1<N>
|
||||
{ Vec1::new(Bounded::min_value()) }
|
||||
}
|
|
@ -2,12 +2,13 @@ use std::num::{One, Zero};
|
|||
use std::rand::{Rand, Rng, RngUtil};
|
||||
use std::cmp::ApproxEq;
|
||||
use std::util::swap;
|
||||
use traits::transformation::Transform;
|
||||
use traits::division_ring::DivisionRing;
|
||||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::transpose::Transpose;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::rlmul::{RMul, LMul};
|
||||
use dim2::vec2::Vec2;
|
||||
use vec::Vec2;
|
||||
|
||||
#[deriving(Eq, ToStr)]
|
||||
pub struct Mat2<N>
|
||||
|
@ -79,14 +80,26 @@ impl<N: Mul<N, N> + Add<N, N>> Mul<Mat2<N>, Mat2<N>> for Mat2<N>
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + DivisionRing>
|
||||
Transform<Vec2<N>> for Mat2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn transform_vec(&self, v: &Vec2<N>) -> Vec2<N>
|
||||
{ self.rmul(v) }
|
||||
|
||||
#[inline]
|
||||
fn inv_transform(&self, v: &Vec2<N>) -> Vec2<N>
|
||||
{ self.inverse().transform_vec(v) }
|
||||
}
|
||||
|
||||
impl<N: Add<N, N> + Mul<N, N>> RMul<Vec2<N>> for Mat2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn rmul(&self, other: &Vec2<N>) -> Vec2<N>
|
||||
{
|
||||
Vec2::new(
|
||||
self.m11 * other.x + self.m12 * other.y,
|
||||
self.m21 * other.x + self.m22 * other.y
|
||||
[ self.m11 * other.at[0] + self.m12 * other.at[1],
|
||||
self.m21 * other.at[0] + self.m22 * other.at[1] ]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -97,13 +110,13 @@ impl<N: Add<N, N> + Mul<N, N>> LMul<Vec2<N>> for Mat2<N>
|
|||
fn lmul(&self, other: &Vec2<N>) -> Vec2<N>
|
||||
{
|
||||
Vec2::new(
|
||||
self.m11 * other.x + self.m21 * other.y,
|
||||
self.m12 * other.x + self.m22 * other.y
|
||||
[ self.m11 * other.at[0] + self.m21 * other.at[1],
|
||||
self.m12 * other.at[0] + self.m22 * other.at[1] ]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N:Copy + Mul<N, N> + Div<N, N> + Sub<N, N> + Neg<N> + Zero>
|
||||
impl<N: Copy + DivisionRing>
|
||||
Inv for Mat2<N>
|
||||
{
|
||||
#[inline]
|
||||
|
@ -175,27 +188,3 @@ impl<N: Rand> Rand for Mat2<N>
|
|||
fn rand<R: Rng>(rng: &mut R) -> Mat2<N>
|
||||
{ Mat2::new(rng.gen(), rng.gen(), rng.gen(), rng.gen()) }
|
||||
}
|
||||
|
||||
impl<N: Copy> Flatten<N> for Mat2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn flat_size() -> uint
|
||||
{ 4 }
|
||||
|
||||
#[inline]
|
||||
fn from_flattened(l: &[N], off: uint) -> Mat2<N>
|
||||
{ Mat2::new(copy l[off], copy l[off + 1], copy l[off + 2], copy l[off + 3]) }
|
||||
|
||||
#[inline]
|
||||
fn flatten(&self) -> ~[N]
|
||||
{ ~[ copy self.m11, copy self.m12, copy self.m21, copy self.m22 ] }
|
||||
|
||||
#[inline]
|
||||
fn flatten_to(&self, l: &mut [N], off: uint)
|
||||
{
|
||||
l[off] = copy self.m11;
|
||||
l[off + 1] = copy self.m12;
|
||||
l[off + 2] = copy self.m21;
|
||||
l[off + 3] = copy self.m22;
|
||||
}
|
||||
}
|
||||
|
|
270
src/dim2/vec2.rs
270
src/dim2/vec2.rs
|
@ -1,270 +0,0 @@
|
|||
use std::num::{Zero, One, Algebraic, Bounded};
|
||||
use std::rand::{Rand, Rng, RngUtil};
|
||||
use dim1::vec1::Vec1;
|
||||
use std::cmp::ApproxEq;
|
||||
use traits::basis::Basis;
|
||||
use traits::cross::Cross;
|
||||
use traits::dim::Dim;
|
||||
use traits::dot::Dot;
|
||||
use traits::sub_dot::SubDot;
|
||||
use traits::norm::Norm;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::translation::{Translation, Translatable};
|
||||
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
|
||||
#[deriving(Eq, Ord, ToStr)]
|
||||
pub struct Vec2<N>
|
||||
{
|
||||
x : N,
|
||||
y : N
|
||||
}
|
||||
|
||||
impl<N> Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
pub fn new(x: N, y: N) -> Vec2<N>
|
||||
{ Vec2 {x: x, y: y} }
|
||||
}
|
||||
|
||||
impl<N> Dim for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn dim() -> uint
|
||||
{ 2 }
|
||||
}
|
||||
|
||||
impl<N: Add<N,N>> Add<Vec2<N>, Vec2<N>> for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn add(&self, other: &Vec2<N>) -> Vec2<N>
|
||||
{ Vec2::new(self.x + other.x, self.y + other.y) }
|
||||
}
|
||||
|
||||
impl<N: Sub<N,N>> Sub<Vec2<N>, Vec2<N>> for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn sub(&self, other: &Vec2<N>) -> Vec2<N>
|
||||
{ Vec2::new(self.x - other.x, self.y - other.y) }
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N>>
|
||||
ScalarMul<N> for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn scalar_mul(&self, s: &N) -> Vec2<N>
|
||||
{ Vec2 { x: self.x * *s, y: self.y * *s } }
|
||||
|
||||
#[inline]
|
||||
fn scalar_mul_inplace(&mut self, s: &N)
|
||||
{
|
||||
self.x = self.x * *s;
|
||||
self.y = self.y * *s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<N: Div<N, N>>
|
||||
ScalarDiv<N> for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn scalar_div(&self, s: &N) -> Vec2<N>
|
||||
{ Vec2 { x: self.x / *s, y: self.y / *s } }
|
||||
|
||||
#[inline]
|
||||
fn scalar_div_inplace(&mut self, s: &N)
|
||||
{
|
||||
self.x = self.x / *s;
|
||||
self.y = self.y / *s;
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Add<N, N>>
|
||||
ScalarAdd<N> for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn scalar_add(&self, s: &N) -> Vec2<N>
|
||||
{ Vec2 { x: self.x + *s, y: self.y + *s } }
|
||||
|
||||
#[inline]
|
||||
fn scalar_add_inplace(&mut self, s: &N)
|
||||
{
|
||||
self.x = self.x + *s;
|
||||
self.y = self.y + *s;
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Sub<N, N>>
|
||||
ScalarSub<N> for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn scalar_sub(&self, s: &N) -> Vec2<N>
|
||||
{ Vec2 { x: self.x - *s, y: self.y - *s } }
|
||||
|
||||
#[inline]
|
||||
fn scalar_sub_inplace(&mut self, s: &N)
|
||||
{
|
||||
self.x = self.x - *s;
|
||||
self.y = self.y - *s;
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Add<N, N>> Translation<Vec2<N>> for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn translation(&self) -> Vec2<N>
|
||||
{ copy *self }
|
||||
|
||||
#[inline]
|
||||
fn translate(&mut self, t: &Vec2<N>)
|
||||
{ *self = *self + *t; }
|
||||
}
|
||||
|
||||
impl<N: Add<N, N>> Translatable<Vec2<N>, Vec2<N>> for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn translated(&self, t: &Vec2<N>) -> Vec2<N>
|
||||
{ self + *t }
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N> + Add<N, N>> Dot<N> for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn dot(&self, other : &Vec2<N>) -> N
|
||||
{ self.x * other.x + self.y * other.y }
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N> + Add<N, N> + Sub<N, N>> SubDot<N> for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn sub_dot(&self, a: &Vec2<N>, b: &Vec2<N>) -> N
|
||||
{ (self.x - a.x) * b.x + (self.y - a.y) * b.y }
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N> + Add<N, N> + Div<N, N> + Algebraic>
|
||||
Norm<N> for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn sqnorm(&self) -> N
|
||||
{ self.dot(self) }
|
||||
|
||||
#[inline]
|
||||
fn norm(&self) -> N
|
||||
{ self.sqnorm().sqrt() }
|
||||
|
||||
#[inline]
|
||||
fn normalized(&self) -> Vec2<N>
|
||||
{
|
||||
let l = self.norm();
|
||||
|
||||
Vec2::new(self.x / l, self.y / l)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn normalize(&mut self) -> N
|
||||
{
|
||||
let l = self.norm();
|
||||
|
||||
self.x = self.x / l;
|
||||
self.y = self.y / l;
|
||||
|
||||
l
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec1<N>> for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn cross(&self, other : &Vec2<N>) -> Vec1<N>
|
||||
{ Vec1::new(self.x * other.y - self.y * other.x) }
|
||||
}
|
||||
|
||||
impl<N: Neg<N>> Neg<Vec2<N>> for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn neg(&self) -> Vec2<N>
|
||||
{ Vec2::new(-self.x, -self.y) }
|
||||
}
|
||||
|
||||
impl<N: Zero> Zero for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn zero() -> Vec2<N>
|
||||
{ Vec2::new(Zero::zero(), Zero::zero()) }
|
||||
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool
|
||||
{ self.x.is_zero() && self.y.is_zero() }
|
||||
}
|
||||
|
||||
impl<N: Copy + One + Zero + Neg<N>> Basis for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn canonical_basis() -> ~[Vec2<N>]
|
||||
{
|
||||
// FIXME: this should be static
|
||||
~[ Vec2::new(One::one(), Zero::zero()),
|
||||
Vec2::new(Zero::zero(), One::one()) ]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn orthogonal_subspace_basis(&self) -> ~[Vec2<N>]
|
||||
{ ~[ Vec2::new(-self.y, copy self.x) ] }
|
||||
}
|
||||
|
||||
impl<N:ApproxEq<N>> ApproxEq<N> for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn approx_epsilon() -> N
|
||||
{ ApproxEq::approx_epsilon::<N, N>() }
|
||||
|
||||
#[inline]
|
||||
fn approx_eq(&self, other: &Vec2<N>) -> bool
|
||||
{ self.x.approx_eq(&other.x) && self.y.approx_eq(&other.y) }
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Vec2<N>, epsilon: &N) -> bool
|
||||
{
|
||||
self.x.approx_eq_eps(&other.x, epsilon) &&
|
||||
self.y.approx_eq_eps(&other.y, epsilon)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N:Rand> Rand for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> Vec2<N>
|
||||
{ Vec2::new(rng.gen(), rng.gen()) }
|
||||
}
|
||||
|
||||
impl<N: Copy> Flatten<N> for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn flat_size() -> uint
|
||||
{ 2 }
|
||||
|
||||
#[inline]
|
||||
fn from_flattened(l: &[N], off: uint) -> Vec2<N>
|
||||
{ Vec2::new(copy l[off], copy l[off + 1]) }
|
||||
|
||||
#[inline]
|
||||
fn flatten(&self) -> ~[N]
|
||||
{ ~[ copy self.x, copy self.y ] }
|
||||
|
||||
#[inline]
|
||||
fn flatten_to(&self, l: &mut [N], off: uint)
|
||||
{
|
||||
l[off] = copy self.x;
|
||||
l[off + 1] = copy self.y;
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Bounded> Bounded for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn max_value() -> Vec2<N>
|
||||
{ Vec2::new(Bounded::max_value(), Bounded::max_value()) }
|
||||
|
||||
#[inline]
|
||||
fn min_value() -> Vec2<N>
|
||||
{ Vec2::new(Bounded::min_value(), Bounded::min_value()) }
|
||||
}
|
|
@ -4,10 +4,11 @@ use std::cmp::ApproxEq;
|
|||
use std::util::swap;
|
||||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::transformation::Transform;
|
||||
use traits::division_ring::DivisionRing;
|
||||
use traits::transpose::Transpose;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::rlmul::{RMul, LMul};
|
||||
use dim3::vec3::Vec3;
|
||||
use vec::Vec3;
|
||||
|
||||
#[deriving(Eq, ToStr)]
|
||||
pub struct Mat3<N>
|
||||
|
@ -93,15 +94,27 @@ impl<N: Mul<N, N> + Add<N, N>> Mul<Mat3<N>, Mat3<N>> for Mat3<N>
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + DivisionRing>
|
||||
Transform<Vec3<N>> for Mat3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn transform_vec(&self, v: &Vec3<N>) -> Vec3<N>
|
||||
{ self.rmul(v) }
|
||||
|
||||
#[inline]
|
||||
fn inv_transform(&self, v: &Vec3<N>) -> Vec3<N>
|
||||
{ self.inverse().transform_vec(v) }
|
||||
}
|
||||
|
||||
impl<N: Add<N, N> + Mul<N, N>> RMul<Vec3<N>> for Mat3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn rmul(&self, other: &Vec3<N>) -> Vec3<N>
|
||||
{
|
||||
Vec3::new(
|
||||
self.m11 * other.x + self.m12 * other.y + self.m13 * other.z,
|
||||
self.m21 * other.x + self.m22 * other.y + self.m33 * other.z,
|
||||
self.m31 * other.x + self.m32 * other.y + self.m33 * other.z
|
||||
[self.m11 * other.at[0] + self.m12 * other.at[1] + self.m13 * other.at[2],
|
||||
self.m21 * other.at[0] + self.m22 * other.at[1] + self.m33 * other.at[2],
|
||||
self.m31 * other.at[0] + self.m32 * other.at[1] + self.m33 * other.at[2]]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -112,14 +125,14 @@ impl<N: Add<N, N> + Mul<N, N>> LMul<Vec3<N>> for Mat3<N>
|
|||
fn lmul(&self, other: &Vec3<N>) -> Vec3<N>
|
||||
{
|
||||
Vec3::new(
|
||||
self.m11 * other.x + self.m21 * other.y + self.m31 * other.z,
|
||||
self.m12 * other.x + self.m22 * other.y + self.m32 * other.z,
|
||||
self.m13 * other.x + self.m23 * other.y + self.m33 * other.z
|
||||
[self.m11 * other.at[0] + self.m21 * other.at[1] + self.m31 * other.at[2],
|
||||
self.m12 * other.at[0] + self.m22 * other.at[1] + self.m32 * other.at[2],
|
||||
self.m13 * other.at[0] + self.m23 * other.at[1] + self.m33 * other.at[2]]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N:Copy + Mul<N, N> + Div<N, N> + Sub<N, N> + Add<N, N> + Neg<N> + Zero>
|
||||
impl<N: Copy + DivisionRing>
|
||||
Inv for Mat3<N>
|
||||
{
|
||||
#[inline]
|
||||
|
@ -229,40 +242,3 @@ impl<N: Rand> Rand for Mat3<N>
|
|||
rng.gen(), rng.gen(), rng.gen())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy> Flatten<N> for Mat3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn flat_size() -> uint
|
||||
{ 9 }
|
||||
|
||||
#[inline]
|
||||
fn from_flattened(l: &[N], off: uint) -> Mat3<N>
|
||||
{ Mat3::new(copy l[off + 0], copy l[off + 1], copy l[off + 2],
|
||||
copy l[off + 3], copy l[off + 4], copy l[off + 5],
|
||||
copy l[off + 6], copy l[off + 7], copy l[off + 8]) }
|
||||
|
||||
#[inline]
|
||||
fn flatten(&self) -> ~[N]
|
||||
{
|
||||
~[
|
||||
copy self.m11, copy self.m12, copy self.m13,
|
||||
copy self.m21, copy self.m22, copy self.m23,
|
||||
copy self.m31, copy self.m32, copy self.m33
|
||||
]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flatten_to(&self, l: &mut [N], off: uint)
|
||||
{
|
||||
l[off + 0] = copy self.m11;
|
||||
l[off + 1] = copy self.m12;
|
||||
l[off + 2] = copy self.m13;
|
||||
l[off + 3] = copy self.m21;
|
||||
l[off + 4] = copy self.m22;
|
||||
l[off + 5] = copy self.m23;
|
||||
l[off + 6] = copy self.m31;
|
||||
l[off + 7] = copy self.m32;
|
||||
l[off + 8] = copy self.m33;
|
||||
}
|
||||
}
|
||||
|
|
300
src/dim3/vec3.rs
300
src/dim3/vec3.rs
|
@ -1,300 +0,0 @@
|
|||
use std::num::{Zero, One, Algebraic, abs, Bounded};
|
||||
use std::rand::{Rand, Rng, RngUtil};
|
||||
use std::cmp::ApproxEq;
|
||||
use traits::basis::Basis;
|
||||
use traits::cross::Cross;
|
||||
use traits::dim::Dim;
|
||||
use traits::dot::Dot;
|
||||
use traits::sub_dot::SubDot;
|
||||
use traits::norm::Norm;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::translation::{Translation, Translatable};
|
||||
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
|
||||
#[deriving(Eq, Ord, ToStr)]
|
||||
pub struct Vec3<N>
|
||||
{
|
||||
x : N,
|
||||
y : N,
|
||||
z : N
|
||||
}
|
||||
|
||||
impl<N> Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
pub fn new(x: N, y: N, z: N) -> Vec3<N>
|
||||
{ Vec3 {x: x, y: y, z: z} }
|
||||
}
|
||||
|
||||
impl<N> Dim for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn dim() -> uint
|
||||
{ 3 }
|
||||
}
|
||||
|
||||
impl<N: Add<N,N>> Add<Vec3<N>, Vec3<N>> for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn add(&self, other: &Vec3<N>) -> Vec3<N>
|
||||
{ Vec3::new(self.x + other.x, self.y + other.y, self.z + other.z) }
|
||||
}
|
||||
|
||||
impl<N: Sub<N,N>> Sub<Vec3<N>, Vec3<N>> for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn sub(&self, other: &Vec3<N>) -> Vec3<N>
|
||||
{ Vec3::new(self.x - other.x, self.y - other.y, self.z - other.z) }
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N>>
|
||||
ScalarMul<N> for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn scalar_mul(&self, s: &N) -> Vec3<N>
|
||||
{ Vec3 { x: self.x * *s, y: self.y * *s, z: self.z * *s } }
|
||||
|
||||
#[inline]
|
||||
fn scalar_mul_inplace(&mut self, s: &N)
|
||||
{
|
||||
self.x = self.x * *s;
|
||||
self.y = self.y * *s;
|
||||
self.z = self.z * *s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<N: Div<N, N>>
|
||||
ScalarDiv<N> for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn scalar_div(&self, s: &N) -> Vec3<N>
|
||||
{ Vec3 { x: self.x / *s, y: self.y / *s, z: self.z / *s } }
|
||||
|
||||
#[inline]
|
||||
fn scalar_div_inplace(&mut self, s: &N)
|
||||
{
|
||||
self.x = self.x / *s;
|
||||
self.y = self.y / *s;
|
||||
self.z = self.z / *s;
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Add<N, N>>
|
||||
ScalarAdd<N> for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn scalar_add(&self, s: &N) -> Vec3<N>
|
||||
{ Vec3 { x: self.x + *s, y: self.y + *s, z: self.z + *s } }
|
||||
|
||||
#[inline]
|
||||
fn scalar_add_inplace(&mut self, s: &N)
|
||||
{
|
||||
self.x = self.x + *s;
|
||||
self.y = self.y + *s;
|
||||
self.z = self.z + *s;
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Sub<N, N>>
|
||||
ScalarSub<N> for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn scalar_sub(&self, s: &N) -> Vec3<N>
|
||||
{ Vec3 { x: self.x - *s, y: self.y - *s, z: self.z - *s } }
|
||||
|
||||
#[inline]
|
||||
fn scalar_sub_inplace(&mut self, s: &N)
|
||||
{
|
||||
self.x = self.x - *s;
|
||||
self.y = self.y - *s;
|
||||
self.z = self.z - *s;
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Add<N, N>> Translation<Vec3<N>> for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn translation(&self) -> Vec3<N>
|
||||
{ copy *self }
|
||||
|
||||
#[inline]
|
||||
fn translate(&mut self, t: &Vec3<N>)
|
||||
{ *self = *self + *t; }
|
||||
}
|
||||
|
||||
impl<N: Add<N, N>> Translatable<Vec3<N>, Vec3<N>> for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn translated(&self, t: &Vec3<N>) -> Vec3<N>
|
||||
{ self + *t }
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl<N: Neg<N>> Neg<Vec3<N>> for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn neg(&self) -> Vec3<N>
|
||||
{ Vec3::new(-self.x, -self.y, -self.z) }
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N> + Add<N, N>> Dot<N> for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn dot(&self, other : &Vec3<N>) -> N
|
||||
{ self.x * other.x + self.y * other.y + self.z * other.z }
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N> + Add<N, N> + Sub<N, N>> SubDot<N> for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn sub_dot(&self, a: &Vec3<N>, b: &Vec3<N>) -> N
|
||||
{ (self.x - a.x) * b.x + (self.y - a.y) * b.y + (self.z - a.z) * b.z }
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N> + Add<N, N> + Div<N, N> + Algebraic>
|
||||
Norm<N> for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn sqnorm(&self) -> N
|
||||
{ self.dot(self) }
|
||||
|
||||
#[inline]
|
||||
fn norm(&self) -> N
|
||||
{ self.sqnorm().sqrt() }
|
||||
|
||||
#[inline]
|
||||
fn normalized(&self) -> Vec3<N>
|
||||
{
|
||||
let l = self.norm();
|
||||
|
||||
Vec3::new(self.x / l, self.y / l, self.z / l)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn normalize(&mut self) -> N
|
||||
{
|
||||
let l = self.norm();
|
||||
|
||||
self.x = self.x / l;
|
||||
self.y = self.y / l;
|
||||
self.z = self.z / l;
|
||||
|
||||
l
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec3<N>> for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn cross(&self, other : &Vec3<N>) -> Vec3<N>
|
||||
{
|
||||
Vec3::new(
|
||||
self.y * other.z - self.z * other.y,
|
||||
self.z * other.x - self.x * other.z,
|
||||
self.x * other.y - self.y * other.x
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Zero> Zero for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn zero() -> Vec3<N>
|
||||
{ Vec3::new(Zero::zero(), Zero::zero(), Zero::zero()) }
|
||||
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool
|
||||
{ self.x.is_zero() && self.y.is_zero() && self.z.is_zero() }
|
||||
}
|
||||
|
||||
impl<N: Copy + One + Zero + Neg<N> + Ord + Mul<N, N> + Sub<N, N> + Add<N, N> +
|
||||
Div<N, N> + Algebraic>
|
||||
Basis for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn canonical_basis() -> ~[Vec3<N>]
|
||||
{
|
||||
// FIXME: this should be static
|
||||
~[ Vec3::new(One::one(), Zero::zero(), Zero::zero()),
|
||||
Vec3::new(Zero::zero(), One::one(), Zero::zero()),
|
||||
Vec3::new(Zero::zero(), Zero::zero(), One::one()) ]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn orthogonal_subspace_basis(&self) -> ~[Vec3<N>]
|
||||
{
|
||||
let a =
|
||||
if abs(copy self.x) > abs(copy self.y)
|
||||
{ Vec3::new(copy self.z, Zero::zero(), -copy self.x).normalized() }
|
||||
else
|
||||
{ Vec3::new(Zero::zero(), -self.z, copy self.y).normalized() };
|
||||
|
||||
~[ a.cross(self), a ]
|
||||
}
|
||||
}
|
||||
|
||||
impl<N:ApproxEq<N>> ApproxEq<N> for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn approx_epsilon() -> N
|
||||
{ ApproxEq::approx_epsilon::<N, N>() }
|
||||
|
||||
#[inline]
|
||||
fn approx_eq(&self, other: &Vec3<N>) -> bool
|
||||
{
|
||||
self.x.approx_eq(&other.x) &&
|
||||
self.y.approx_eq(&other.y) &&
|
||||
self.z.approx_eq(&other.z)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Vec3<N>, epsilon: &N) -> bool
|
||||
{
|
||||
self.x.approx_eq_eps(&other.x, epsilon) &&
|
||||
self.y.approx_eq_eps(&other.y, epsilon) &&
|
||||
self.z.approx_eq_eps(&other.z, epsilon)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Rand> Rand for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> Vec3<N>
|
||||
{ Vec3::new(rng.gen(), rng.gen(), rng.gen()) }
|
||||
}
|
||||
|
||||
impl<N: Copy> Flatten<N> for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn flat_size() -> uint
|
||||
{ 3 }
|
||||
|
||||
#[inline]
|
||||
fn from_flattened(l: &[N], off: uint) -> Vec3<N>
|
||||
{ Vec3::new(copy l[off], copy l[off + 1], copy l[off + 2]) }
|
||||
|
||||
#[inline]
|
||||
fn flatten(&self) -> ~[N]
|
||||
{ ~[ copy self.x, copy self.y, copy self.z ] }
|
||||
|
||||
#[inline]
|
||||
fn flatten_to(&self, l: &mut [N], off: uint)
|
||||
{
|
||||
l[off] = copy self.x;
|
||||
l[off + 1] = copy self.y;
|
||||
l[off + 2] = copy self.z;
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Bounded> Bounded for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn max_value() -> Vec3<N>
|
||||
{ Vec3::new(Bounded::max_value(), Bounded::max_value(), Bounded::max_value()) }
|
||||
|
||||
#[inline]
|
||||
fn min_value() -> Vec3<N>
|
||||
{ Vec3::new(Bounded::min_value(), Bounded::min_value(), Bounded::min_value()) }
|
||||
}
|
|
@ -15,24 +15,23 @@
|
|||
|
||||
extern mod std;
|
||||
|
||||
pub mod vec;
|
||||
|
||||
/// 1-dimensional linear algebra.
|
||||
pub mod dim1
|
||||
{
|
||||
pub mod vec1;
|
||||
pub mod mat1;
|
||||
}
|
||||
|
||||
/// 2-dimensional linear algebra.
|
||||
pub mod dim2
|
||||
{
|
||||
pub mod vec2;
|
||||
pub mod mat2;
|
||||
}
|
||||
|
||||
/// 3-dimensional linear algebra.
|
||||
pub mod dim3
|
||||
{
|
||||
pub mod vec3;
|
||||
pub mod mat3;
|
||||
}
|
||||
|
||||
|
@ -55,6 +54,7 @@ pub mod adaptors
|
|||
/// Useful linear-algebra related traits.
|
||||
pub mod traits
|
||||
{
|
||||
pub mod iterable;
|
||||
pub mod dot;
|
||||
pub mod cross;
|
||||
pub mod inv;
|
||||
|
@ -65,12 +65,10 @@ pub mod traits
|
|||
pub mod rotation;
|
||||
pub mod translation;
|
||||
pub mod transformation;
|
||||
pub mod delta_transform;
|
||||
pub mod vector_space;
|
||||
pub mod ring;
|
||||
pub mod division_ring;
|
||||
pub mod sub_dot;
|
||||
pub mod flatten;
|
||||
pub mod rlmul;
|
||||
pub mod scalar_op;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use std::uint::iterate;
|
||||
use std::num::{Zero, One, Algebraic};
|
||||
use std::vec::{VecIterator, VecMutIterator};
|
||||
use std::vec::{map_zip, map, from_elem};
|
||||
use std::cmp::ApproxEq;
|
||||
use std::iterator::IteratorUtil;
|
||||
use std::iterator::{FromIterator, IteratorUtil};
|
||||
use traits::iterable::{Iterable, IterableMut};
|
||||
use traits::ring::Ring;
|
||||
use traits::division_ring::DivisionRing;
|
||||
use traits::dot::Dot;
|
||||
|
@ -25,6 +27,31 @@ pub fn zero_vec_with_dim<N: Zero + Copy>(dim: uint) -> DVec<N>
|
|||
pub fn is_zero_vec<N: Zero>(vec: &DVec<N>) -> bool
|
||||
{ vec.at.iter().all(|e| e.is_zero()) }
|
||||
|
||||
impl<N> Iterable<N> for DVec<N>
|
||||
{
|
||||
fn iter<'l>(&'l self) -> VecIterator<'l, N>
|
||||
{ self.at.iter() }
|
||||
}
|
||||
|
||||
impl<N> IterableMut<N> for DVec<N>
|
||||
{
|
||||
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N>
|
||||
{ self.at.mut_iter() }
|
||||
}
|
||||
|
||||
impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for DVec<N>
|
||||
{
|
||||
fn from_iterator(param: &mut Iter) -> DVec<N>
|
||||
{
|
||||
let mut res = DVec { at: ~[] };
|
||||
|
||||
for param.advance |e|
|
||||
{ res.at.push(e) }
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: is Clone needed?
|
||||
impl<N: Copy + DivisionRing + Algebraic + Clone + ApproxEq<N>> DVec<N>
|
||||
{
|
||||
|
@ -196,14 +223,18 @@ ScalarSub<N> for DVec<N>
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Copy + Add<N, N>> Translation<DVec<N>> for DVec<N>
|
||||
impl<N: Clone + Copy + Add<N, N> + Neg<N>> Translation<DVec<N>> for DVec<N>
|
||||
{
|
||||
#[inline]
|
||||
fn translation(&self) -> DVec<N>
|
||||
{ self.clone() }
|
||||
|
||||
#[inline]
|
||||
fn translate(&mut self, t: &DVec<N>)
|
||||
fn inv_translation(&self) -> DVec<N>
|
||||
{ -self }
|
||||
|
||||
#[inline]
|
||||
fn translate_by(&mut self, t: &DVec<N>)
|
||||
{ *self = *self + *t; }
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ use traits::dim::Dim;
|
|||
use traits::inv::Inv;
|
||||
use traits::division_ring::DivisionRing;
|
||||
use traits::transpose::Transpose;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::rlmul::{RMul, LMul};
|
||||
use ndim::dmat::{DMat, one_mat_with_dim, zero_mat_with_dim, is_zero_mat};
|
||||
use ndim::nvec::NVec;
|
||||
|
@ -183,43 +182,3 @@ impl<D: Dim, N: Rand + Zero + Copy> Rand for NMat<D, N>
|
|||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Dim, N: Zero + Copy> Flatten<N> for NMat<D, N>
|
||||
{
|
||||
#[inline]
|
||||
fn flat_size() -> uint
|
||||
{ Dim::dim::<D>() * Dim::dim::<D>() }
|
||||
|
||||
#[inline]
|
||||
fn from_flattened(l: &[N], off: uint) -> NMat<D, N>
|
||||
{
|
||||
let dim = Dim::dim::<D>();
|
||||
let mut res = Zero::zero::<NMat<D, N>>();
|
||||
|
||||
for iterate(0u, dim * dim) |i|
|
||||
{ res.mij.mij[i] = copy l[off + i] }
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flatten(&self) -> ~[N]
|
||||
{
|
||||
let dim = Dim::dim::<D>();
|
||||
let mut res = ~[];
|
||||
|
||||
for iterate(0u, dim * dim) |i|
|
||||
{ res.push(copy self.mij.mij[i]) }
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flatten_to(&self, l: &mut [N], off: uint)
|
||||
{
|
||||
let dim = Dim::dim::<D>();
|
||||
|
||||
for iterate(0u, dim * dim) |i|
|
||||
{ l[off + i] = copy self.mij.mij[i] }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use std::uint::iterate;
|
||||
use std::num::{Zero, Algebraic, Bounded};
|
||||
use std::rand::{Rand, Rng, RngUtil};
|
||||
use std::vec::{map};
|
||||
use std::vec::{VecIterator, VecMutIterator};
|
||||
use std::cmp::ApproxEq;
|
||||
use std::iterator::{IteratorUtil, FromIterator};
|
||||
use ndim::dvec::{DVec, zero_vec_with_dim, is_zero_vec};
|
||||
use traits::iterable::{Iterable, IterableMut};
|
||||
use traits::basis::Basis;
|
||||
use traits::ring::Ring;
|
||||
use traits::division_ring::DivisionRing;
|
||||
|
@ -12,7 +14,6 @@ use traits::dot::Dot;
|
|||
use traits::sub_dot::SubDot;
|
||||
use traits::norm::Norm;
|
||||
use traits::translation::{Translation, Translatable};
|
||||
use traits::flatten::Flatten;
|
||||
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
|
||||
// D is a phantom parameter, used only as a dimensional token.
|
||||
|
@ -38,6 +39,35 @@ impl<D, N: Clone> Clone for NVec<D, N>
|
|||
{ NVec{ at: self.at.clone() } }
|
||||
}
|
||||
|
||||
impl<D, N> Iterable<N> for NVec<D, N>
|
||||
{
|
||||
fn iter<'l>(&'l self) -> VecIterator<'l, N>
|
||||
{ self.at.iter() }
|
||||
}
|
||||
|
||||
impl<D, N> IterableMut<N> for NVec<D, N>
|
||||
{
|
||||
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N>
|
||||
{ self.at.mut_iter() }
|
||||
}
|
||||
|
||||
impl<D: Dim, N: Zero + Copy, Iter: Iterator<N>> FromIterator<N, Iter> for NVec<D, N>
|
||||
{
|
||||
fn from_iterator(param: &mut Iter) -> NVec<D, N>
|
||||
{
|
||||
let mut res: NVec<D, N> = Zero::zero();
|
||||
let mut i = 0;
|
||||
|
||||
for param.advance |e|
|
||||
{
|
||||
res.at.at[i] = e;
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl<D, N: Copy + Add<N,N>> Add<NVec<D, N>, NVec<D, N>> for NVec<D, N>
|
||||
{
|
||||
#[inline]
|
||||
|
@ -123,14 +153,19 @@ 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>> for NVec<D, N>
|
||||
impl<D: Dim, N: Clone + Copy + Add<N, N> + Neg<N>> Translation<NVec<D, N>> for NVec<D, N>
|
||||
{
|
||||
#[inline]
|
||||
fn translation(&self) -> NVec<D, N>
|
||||
{ self.clone() }
|
||||
|
||||
#[inline]
|
||||
fn translate(&mut self, t: &NVec<D, N>)
|
||||
fn inv_translation(&self) -> NVec<D, N>
|
||||
{ -self.clone() }
|
||||
|
||||
|
||||
#[inline]
|
||||
fn translate_by(&mut self, t: &NVec<D, N>)
|
||||
{ *self = *self + *t; }
|
||||
}
|
||||
|
||||
|
@ -173,11 +208,11 @@ Basis for NVec<D, N>
|
|||
{
|
||||
#[inline]
|
||||
fn canonical_basis() -> ~[NVec<D, N>]
|
||||
{ map(DVec::canonical_basis_with_dim(Dim::dim::<D>()), |&e| NVec { at: e }) }
|
||||
{ DVec::canonical_basis_with_dim(Dim::dim::<D>()).map(|&e| NVec { at: e }) }
|
||||
|
||||
#[inline]
|
||||
fn orthogonal_subspace_basis(&self) -> ~[NVec<D, N>]
|
||||
{ map(self.at.orthogonal_subspace_basis(), |&e| NVec { at: e }) }
|
||||
{ self.at.orthogonal_subspace_basis().map(|&e| NVec { at: e }) }
|
||||
}
|
||||
|
||||
// FIXME: I dont really know how te generalize the cross product int
|
||||
|
@ -229,46 +264,6 @@ impl<D: Dim, N: Rand + Zero + Copy> Rand for NVec<D, N>
|
|||
}
|
||||
}
|
||||
|
||||
impl<D: Dim, N: Zero + Copy> Flatten<N> for NVec<D, N>
|
||||
{
|
||||
#[inline]
|
||||
fn flat_size() -> uint
|
||||
{ Dim::dim::<D>() }
|
||||
|
||||
#[inline]
|
||||
fn from_flattened(l: &[N], off: uint) -> NVec<D, N>
|
||||
{
|
||||
let dim = Dim::dim::<D>();
|
||||
let mut res = Zero::zero::<NVec<D, N>>();
|
||||
|
||||
for iterate(0u, dim) |i|
|
||||
{ res.at.at[i] = copy l[off + i] }
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flatten(&self) -> ~[N]
|
||||
{
|
||||
let dim = Dim::dim::<D>();
|
||||
let mut res = ~[];
|
||||
|
||||
for iterate(0u, dim) |i|
|
||||
{ res.push(copy self.at.at[i]) }
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flatten_to(&self, l: &mut [N], off: uint)
|
||||
{
|
||||
let dim = Dim::dim::<D>();
|
||||
|
||||
for iterate(0u, dim) |i|
|
||||
{ l[off + i] = copy self.at.at[i] }
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Dim, N: Bounded + Zero + Add<N, N> + Copy> Bounded for NVec<D, N>
|
||||
{
|
||||
#[inline]
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#[test]
|
||||
use std::vec;
|
||||
#[test]
|
||||
use std::num::{Real, Zero, One, abs};
|
||||
use std::num::{Real, One, abs};
|
||||
#[test]
|
||||
use std::rand::random;
|
||||
#[test]
|
||||
|
@ -11,9 +9,7 @@ use traits::inv::Inv;
|
|||
#[test]
|
||||
use traits::rotation::{Rotation, Rotatable};
|
||||
#[test]
|
||||
use traits::dim::d7;
|
||||
#[test]
|
||||
use dim1::vec1::Vec1;
|
||||
use vec::Vec1;
|
||||
#[test]
|
||||
use dim1::mat1::Mat1;
|
||||
#[test]
|
||||
|
@ -21,11 +17,7 @@ use dim2::mat2::Mat2;
|
|||
#[test]
|
||||
use dim3::mat3::Mat3;
|
||||
#[test]
|
||||
use ndim::nmat::NMat;
|
||||
#[test]
|
||||
use adaptors::rotmat::Rotmat;
|
||||
#[test]
|
||||
use traits::flatten::Flatten;
|
||||
|
||||
macro_rules! test_inv_mat_impl(
|
||||
($t: ty) => (
|
||||
|
@ -38,21 +30,6 @@ macro_rules! test_inv_mat_impl(
|
|||
);
|
||||
)
|
||||
|
||||
macro_rules! test_flatten_impl(
|
||||
($t: ty, $n: ty) => (
|
||||
for 10000.times
|
||||
{
|
||||
let v: $t = random();
|
||||
let mut l: ~[$n] = vec::from_elem(42 + Flatten::flat_size::<$n, $t>(), Zero::zero::<$n>());
|
||||
|
||||
v.flatten_to(l, 42);
|
||||
|
||||
assert!(Flatten::from_flattened::<$n, $t>(v.flatten(), 0) == v);
|
||||
assert!(Flatten::from_flattened::<$n, $t>(l, 42) == v);
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
#[test]
|
||||
fn test_inv_mat1()
|
||||
{ test_inv_mat_impl!(Mat1<f64>); }
|
||||
|
@ -70,29 +47,13 @@ fn test_inv_mat3()
|
|||
// fn test_inv_nmat()
|
||||
// { test_inv_mat_impl!(NMat<d7, f64>); }
|
||||
|
||||
#[test]
|
||||
fn test_flatten_mat1()
|
||||
{ test_flatten_impl!(Mat1<f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_flatten_mat2()
|
||||
{ test_flatten_impl!(Mat2<f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_flatten_mat3()
|
||||
{ test_flatten_impl!(Mat3<f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_flatten_nmat()
|
||||
{ test_flatten_impl!(NMat<d7, f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_rotation2()
|
||||
{
|
||||
for 10000.times
|
||||
{
|
||||
let randmat = One::one::<Rotmat<Mat2<f64>>>();
|
||||
let ang = &Vec1::new(abs::<f64>(random()) % Real::pi());
|
||||
let ang = &Vec1::new([abs::<f64>(random()) % Real::pi()]);
|
||||
|
||||
assert!(randmat.rotated(ang).rotation().approx_eq(ang));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#[test]
|
||||
use std::vec;
|
||||
#[test]
|
||||
use std::iterator::IteratorUtil;
|
||||
#[test]
|
||||
use std::num::{Zero, One};
|
||||
|
@ -9,11 +7,7 @@ use std::rand::{random};
|
|||
#[test]
|
||||
use std::cmp::ApproxEq;
|
||||
#[test]
|
||||
use dim3::vec3::Vec3;
|
||||
#[test]
|
||||
use dim2::vec2::Vec2;
|
||||
#[test]
|
||||
use dim1::vec1::Vec1;
|
||||
use vec::{Vec1, Vec2, Vec3};
|
||||
#[test]
|
||||
use ndim::nvec::NVec;
|
||||
#[test]
|
||||
|
@ -27,10 +21,28 @@ use traits::dot::Dot;
|
|||
#[test]
|
||||
use traits::norm::Norm;
|
||||
#[test]
|
||||
use traits::flatten::Flatten;
|
||||
use traits::iterable::{Iterable, IterableMut};
|
||||
#[test]
|
||||
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
|
||||
macro_rules! test_iterator_impl(
|
||||
($t: ty, $n: ty) => (
|
||||
for 10000.times
|
||||
{
|
||||
let v: $t = random();
|
||||
let mut mv: $t = copy v;
|
||||
let n: $n = random();
|
||||
|
||||
let nv: $t = v.iter().transform(|e| e * n).collect();
|
||||
|
||||
for mv.mut_iter().advance |e|
|
||||
{ *e = *e * n }
|
||||
|
||||
assert!(nv == mv && nv == v.scalar_mul(&n));
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! test_commut_dot_impl(
|
||||
($t: ty) => (
|
||||
for 10000.times
|
||||
|
@ -105,21 +117,6 @@ macro_rules! test_subspace_basis_impl(
|
|||
);
|
||||
)
|
||||
|
||||
macro_rules! test_flatten_impl(
|
||||
($t: ty, $n: ty) => (
|
||||
for 10000.times
|
||||
{
|
||||
let v: $t = random();
|
||||
let mut l: ~[$n] = vec::from_elem(42 + Flatten::flat_size::<$n, $t>(), Zero::zero::<$n>());
|
||||
|
||||
v.flatten_to(l, 42);
|
||||
|
||||
assert!(Flatten::from_flattened::<$n, $t>(v.flatten(), 0) == v);
|
||||
assert!(Flatten::from_flattened::<$n, $t>(l, 42) == v);
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
#[test]
|
||||
fn test_cross_vec3()
|
||||
{
|
||||
|
@ -182,22 +179,6 @@ fn test_subspace_basis_vec3()
|
|||
fn test_subspace_basis_nvec()
|
||||
{ test_subspace_basis_impl!(NVec<d7, f64>); }
|
||||
|
||||
#[test]
|
||||
fn test_flatten_vec1()
|
||||
{ test_flatten_impl!(Vec1<f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_flatten_vec2()
|
||||
{ test_flatten_impl!(Vec2<f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_flatten_vec3()
|
||||
{ test_flatten_impl!(Vec3<f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_flatten_nvec()
|
||||
{ test_flatten_impl!(NVec<d7, f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_scalar_op_vec1()
|
||||
{ test_scalar_op_impl!(Vec1<f64>, f64); }
|
||||
|
@ -213,3 +194,19 @@ fn test_scalar_op_vec3()
|
|||
#[test]
|
||||
fn test_scalar_op_nvec()
|
||||
{ test_scalar_op_impl!(NVec<d7, f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_iterator_vec1()
|
||||
{ test_iterator_impl!(Vec1<f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_iterator_vec2()
|
||||
{ test_iterator_impl!(Vec2<f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_iterator_vec3()
|
||||
{ test_iterator_impl!(Vec3<f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_iterator_nvec()
|
||||
{ test_iterator_impl!(NVec<d7, f64>, f64); }
|
||||
|
|
|
@ -2,6 +2,7 @@ pub trait Basis
|
|||
{
|
||||
/// Computes the canonical basis of the space in which this object lives.
|
||||
// FIXME: need type-associated values
|
||||
// FIXME: this will make allocations… this is bad
|
||||
fn canonical_basis() -> ~[Self];
|
||||
fn orthogonal_subspace_basis(&self) -> ~[Self];
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/**
|
||||
* A delta-transformation is the generalization of rotation. A delta transform
|
||||
* can apply any transformation to the object without translating it.
|
||||
* In partilular, 0 is neutral wrt. the delta-transform.
|
||||
*/
|
||||
pub trait DeltaTransform<DT>
|
||||
{
|
||||
/// Extracts the delta transformation associated with this transformation.
|
||||
fn delta_transform(&self) -> DT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trait of delta-transformations on vectors.
|
||||
*/
|
||||
pub trait DeltaTransformVector<V>
|
||||
{
|
||||
/// Applies a delta-transform to a vector.
|
||||
fn delta_transform_vector(&self, &V) -> V;
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/// Trait of objects which can be written as a list of values, and read from
|
||||
/// that list.
|
||||
pub trait Flatten<N>
|
||||
{
|
||||
/// The number of elements needed to flatten this object.
|
||||
fn flat_size() -> uint;
|
||||
|
||||
/**
|
||||
* Creates a new object from its flattened version. Its flattened version is
|
||||
* a continuous list of values. It is assumet that `flat_size` elements will
|
||||
* be read.
|
||||
*
|
||||
* - `l`: list from which the flat version must be read.
|
||||
* - `off`: index from which (included) the flat version read must begin.
|
||||
* It is assumed that the caller gives a valid input.
|
||||
*/
|
||||
fn from_flattened(l: &[N], off: uint) -> Self; // FIXME: keep (vector + index) or use an iterator?
|
||||
|
||||
/**
|
||||
* Creates a flattened version of `self`. The result vector must be of size
|
||||
* `flat_size`.
|
||||
*/
|
||||
fn flatten(&self) -> ~[N];
|
||||
|
||||
/**
|
||||
* Creates a flattened version of `self` on a vector. It is assumed that
|
||||
* `flat_size` elements will be written contiguously.
|
||||
*
|
||||
* - `l`: list to which the flat version must be written.
|
||||
* - `off`: index from which (included) the flat version write must begin.
|
||||
* It is assumed that the caller allocated a long enough list.
|
||||
*/
|
||||
fn flatten_to(&self, l: &mut [N], off: uint); // FIXME: keep (vector + index) or use an iterator (to a mutable value…)?
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
use std::vec;
|
||||
|
||||
pub trait Iterable<N>
|
||||
{
|
||||
fn iter<'l>(&'l self) -> vec::VecIterator<'l, N>;
|
||||
}
|
||||
|
||||
pub trait IterableMut<N>
|
||||
{
|
||||
fn mut_iter<'l>(&'l mut self) -> vec::VecMutIterator<'l, N>;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: the prevous traits are only workarounds.
|
||||
* It should be something like:
|
||||
|
||||
pub trait Iterable<'self, N, I: Iterator<N>>
|
||||
{
|
||||
fn iter(&'self self) -> I;
|
||||
}
|
||||
|
||||
pub trait IterableMut<'self, N, I: Iterator<N>>
|
||||
{
|
||||
fn mut_iter(&'self self) -> I;
|
||||
}
|
||||
|
||||
* but this gives an ICE =(
|
||||
* For now, we oblige the iterator to be one specific type which works with
|
||||
* everything on this lib.
|
||||
*/
|
||||
|
||||
pub trait FromAnyIterator<N>
|
||||
{
|
||||
fn from_iterator<'l>(&mut vec::VecIterator<'l, N>) -> Self;
|
||||
fn from_mut_iterator<'l>(&mut vec::VecMutIterator<'l, N>) -> Self;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: the previous trait is only a workaround.
|
||||
* It should be something like:
|
||||
pub trait FromAnyIterator<N>
|
||||
{
|
||||
fn from_iterator<I: Iterator<N>>(&mut I) -> Self;
|
||||
}
|
||||
|
||||
* but this gives a wierd error message (the compile seems to mistake N with
|
||||
* I…).
|
||||
* For now, we oblige the iterator to be one specific type which works with
|
||||
* everything on this lib.
|
||||
*
|
||||
* Note that we dont use the standard std::iterator::FromIterator<N, I: Iterator<N>>
|
||||
* because it is too hard to work with on generic code (as a type bound)
|
||||
* because we have to name explicitly the type of the iterator.
|
||||
*
|
||||
*/
|
|
@ -8,8 +8,10 @@ pub trait Rotation<V>
|
|||
/// Gets the rotation associated with this object.
|
||||
fn rotation(&self) -> V;
|
||||
|
||||
fn inv_rotation(&self) -> V;
|
||||
|
||||
/// In-place version of `rotated`.
|
||||
fn rotate(&mut self, &V);
|
||||
fn rotate_by(&mut self, &V);
|
||||
}
|
||||
|
||||
pub trait Rotatable<V, Res: Rotation<V>>
|
||||
|
@ -19,6 +21,12 @@ pub trait Rotatable<V, Res: Rotation<V>>
|
|||
fn rotated(&self, &V) -> Res;
|
||||
}
|
||||
|
||||
pub trait Rotate<V>
|
||||
{
|
||||
fn rotate(&self, &V) -> V;
|
||||
fn inv_rotate(&self, &V) -> V;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a rotation centered on a specific point.
|
||||
*
|
||||
|
@ -35,8 +43,8 @@ pub fn rotate_wrt_point<M: Translatable<LV, M2>,
|
|||
{
|
||||
let mut res = m.translated(&-center);
|
||||
|
||||
res.rotate(ammount);
|
||||
res.translate(center);
|
||||
res.rotate_by(ammount);
|
||||
res.translate_by(center);
|
||||
|
||||
res
|
||||
}
|
||||
|
|
|
@ -2,11 +2,19 @@ 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 inv_transformation(&self) -> M;
|
||||
|
||||
fn transform_by(&mut self, &M);
|
||||
}
|
||||
|
||||
pub trait Transform<V>
|
||||
{
|
||||
// XXX: sadly we cannot call this `transform` as it conflicts with the
|
||||
// iterators' `transform` function (which seems always exist).
|
||||
fn transform_vec(&self, &V) -> V;
|
||||
fn inv_transform(&self, &V) -> V;
|
||||
}
|
||||
|
||||
pub trait Transformable<M, Res: Transformation<M>>
|
||||
{
|
||||
fn transformed(&self, &M) -> Res;
|
||||
|
|
|
@ -6,8 +6,16 @@ pub trait Translation<V>
|
|||
/// Gets the translation associated with this object.
|
||||
fn translation(&self) -> V;
|
||||
|
||||
fn inv_translation(&self) -> V;
|
||||
|
||||
/// In-place version of `translate`.
|
||||
fn translate(&mut self, &V);
|
||||
fn translate_by(&mut self, &V);
|
||||
}
|
||||
|
||||
pub trait Translate<V>
|
||||
{
|
||||
fn translate(&self, &V) -> V;
|
||||
fn inv_translate(&self, &V) -> V;
|
||||
}
|
||||
|
||||
pub trait Translatable<V, Res: Translation<V>>
|
||||
|
|
|
@ -0,0 +1,705 @@
|
|||
use std::num::{abs, Zero, One, Algebraic, Bounded};
|
||||
use std::rand::{Rand, Rng, RngUtil};
|
||||
use std::vec::{VecIterator, VecMutIterator};
|
||||
use std::iterator::{Iterator, FromIterator};
|
||||
use std::cmp::ApproxEq;
|
||||
use traits::iterable::{Iterable, IterableMut, FromAnyIterator};
|
||||
use traits::basis::Basis;
|
||||
use traits::cross::Cross;
|
||||
use traits::dim::Dim;
|
||||
use traits::dot::Dot;
|
||||
use traits::sub_dot::SubDot;
|
||||
use traits::norm::Norm;
|
||||
use traits::translation::{Translation, Translatable};
|
||||
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
use std::uint::iterate;
|
||||
|
||||
use std::iterator::IteratorUtil;
|
||||
use traits::ring::Ring;
|
||||
use traits::division_ring::DivisionRing;
|
||||
|
||||
// FIXME: is there a way to split this file:
|
||||
// − one file for macros
|
||||
// − another file for macro calls and specializations
|
||||
// ?
|
||||
|
||||
macro_rules! new_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N> $t<N>
|
||||
{
|
||||
#[inline]
|
||||
pub fn new(at: [N, ..$dim]) -> $t<N>
|
||||
{ $t { at: at } }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! new_repeat_impl(
|
||||
($t: ident, $param: ident, [ $($elem: ident)|+ ]) => (
|
||||
impl<N: Copy> $t<N>
|
||||
{
|
||||
#[inline]
|
||||
pub fn new_repeat($param: N) -> $t<N>
|
||||
{ $t{ at: [ $( copy $elem, )+ ] } }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! iterable_impl(
|
||||
($t: ident) => (
|
||||
impl<N> Iterable<N> for $t<N>
|
||||
{
|
||||
fn iter<'l>(&'l self) -> VecIterator<'l, N>
|
||||
{ self.at.iter() }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! iterable_mut_impl(
|
||||
($t: ident) => (
|
||||
impl<N> IterableMut<N> for $t<N>
|
||||
{
|
||||
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N>
|
||||
{ self.at.mut_iter() }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! eq_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Eq> Eq for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &$t<N>) -> bool
|
||||
{ self.at.iter().zip(other.at.iter()).all(|(a, b)| a == b) }
|
||||
|
||||
#[inline]
|
||||
fn ne(&self, other: &$t<N>) -> bool
|
||||
{ self.at.iter().zip(other.at.iter()).all(|(a, b)| a != b) }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! dim_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N> Dim for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn dim() -> uint
|
||||
{ $dim }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
// FIXME: add the possibility to specialize that
|
||||
macro_rules! basis_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Copy + DivisionRing + Algebraic + ApproxEq<N>> Basis for $t<N>
|
||||
{
|
||||
pub fn canonical_basis() -> ~[$t<N>]
|
||||
{
|
||||
let mut res : ~[$t<N>] = ~[];
|
||||
|
||||
for iterate(0u, $dim) |i|
|
||||
{
|
||||
let mut basis_element : $t<N> = Zero::zero();
|
||||
|
||||
basis_element.at[i] = One::one();
|
||||
|
||||
res.push(basis_element);
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
pub fn orthogonal_subspace_basis(&self) -> ~[$t<N>]
|
||||
{
|
||||
// compute the basis of the orthogonal subspace using Gram-Schmidt
|
||||
// orthogonalization algorithm
|
||||
let mut res : ~[$t<N>] = ~[];
|
||||
|
||||
for iterate(0u, $dim) |i|
|
||||
{
|
||||
let mut basis_element : $t<N> = Zero::zero();
|
||||
|
||||
basis_element.at[i] = One::one();
|
||||
|
||||
if res.len() == $dim - 1
|
||||
{ break; }
|
||||
|
||||
let mut elt = copy basis_element;
|
||||
|
||||
elt = elt - self.scalar_mul(&basis_element.dot(self));
|
||||
|
||||
for res.iter().advance |v|
|
||||
{ elt = elt - v.scalar_mul(&elt.dot(v)) };
|
||||
|
||||
if !elt.sqnorm().approx_eq(&Zero::zero())
|
||||
{ res.push(elt.normalized()); }
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! add_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Copy + Add<N,N>> Add<$t<N>, $t<N>> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn add(&self, other: &$t<N>) -> $t<N>
|
||||
{
|
||||
self.at.iter()
|
||||
.zip(other.at.iter())
|
||||
.transform(|(a, b)| { *a + *b })
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! sub_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Copy + Sub<N,N>> Sub<$t<N>, $t<N>> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn sub(&self, other: &$t<N>) -> $t<N>
|
||||
{
|
||||
self.at.iter()
|
||||
.zip(other.at.iter())
|
||||
.transform(| (a, b) | { *a - *b })
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! neg_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Neg<N>> Neg<$t<N>> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn neg(&self) -> $t<N>
|
||||
{ self.at.iter().transform(|a| -a).collect() }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! dot_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Ring> Dot<N> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn dot(&self, other: &$t<N>) -> N
|
||||
{
|
||||
let mut res = Zero::zero::<N>();
|
||||
|
||||
for iterate(0u, $dim) |i|
|
||||
{ res = res + self.at[i] * other.at[i]; }
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! sub_dot_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Ring> SubDot<N> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn sub_dot(&self, a: &$t<N>, b: &$t<N>) -> N
|
||||
{
|
||||
let mut res = Zero::zero::<N>();
|
||||
|
||||
for iterate(0u, $dim) |i|
|
||||
{ res = res + (self.at[i] - a.at[i]) * b.at[i]; }
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! scalar_mul_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Mul<N, N>> ScalarMul<N> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn scalar_mul(&self, s: &N) -> $t<N>
|
||||
{ self.at.iter().transform(|a| a * *s).collect() }
|
||||
|
||||
#[inline]
|
||||
fn scalar_mul_inplace(&mut self, s: &N)
|
||||
{
|
||||
for iterate(0u, $dim) |i|
|
||||
{ self.at[i] = self.at[i] * *s; }
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
macro_rules! scalar_div_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Div<N, N>> ScalarDiv<N> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn scalar_div(&self, s: &N) -> $t<N>
|
||||
{ self.at.iter().transform(|a| a / *s).collect() }
|
||||
|
||||
#[inline]
|
||||
fn scalar_div_inplace(&mut self, s: &N)
|
||||
{
|
||||
for iterate(0u, $dim) |i|
|
||||
{ self.at[i] = self.at[i] / *s; }
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! scalar_add_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Add<N, N>> ScalarAdd<N> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn scalar_add(&self, s: &N) -> $t<N>
|
||||
{ self.at.iter().transform(|a| a + *s).collect() }
|
||||
|
||||
#[inline]
|
||||
fn scalar_add_inplace(&mut self, s: &N)
|
||||
{
|
||||
for iterate(0u, $dim) |i|
|
||||
{ self.at[i] = self.at[i] + *s; }
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! scalar_sub_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Sub<N, N>> ScalarSub<N> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn scalar_sub(&self, s: &N) -> $t<N>
|
||||
{ self.at.iter().transform(|a| a - *s).collect() }
|
||||
|
||||
#[inline]
|
||||
fn scalar_sub_inplace(&mut self, s: &N)
|
||||
{
|
||||
for iterate(0u, $dim) |i|
|
||||
{ self.at[i] = self.at[i] - *s; }
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! translation_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Copy + Add<N, N> + Neg<N>> Translation<$t<N>> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn translation(&self) -> $t<N>
|
||||
{ copy *self }
|
||||
|
||||
#[inline]
|
||||
fn inv_translation(&self) -> $t<N>
|
||||
{ -self }
|
||||
|
||||
#[inline]
|
||||
fn translate_by(&mut self, t: &$t<N>)
|
||||
{ *self = *self + *t; }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! translatable_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Add<N, N> + Copy> Translatable<$t<N>, $t<N>> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn translated(&self, t: &$t<N>) -> $t<N>
|
||||
{ self + *t }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! norm_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Copy + DivisionRing + Algebraic> Norm<N> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn sqnorm(&self) -> N
|
||||
{ self.dot(self) }
|
||||
|
||||
#[inline]
|
||||
fn norm(&self) -> N
|
||||
{ self.sqnorm().sqrt() }
|
||||
|
||||
#[inline]
|
||||
fn normalized(&self) -> $t<N>
|
||||
{
|
||||
let mut res : $t<N> = copy *self;
|
||||
|
||||
res.normalize();
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn normalize(&mut self) -> N
|
||||
{
|
||||
let l = self.norm();
|
||||
|
||||
for iterate(0u, $dim) |i|
|
||||
{ self.at[i] = self.at[i] / l; }
|
||||
|
||||
l
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! approx_eq_impl(
|
||||
($t: ident) => (
|
||||
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn approx_epsilon() -> N
|
||||
{ ApproxEq::approx_epsilon::<N, N>() }
|
||||
|
||||
#[inline]
|
||||
fn approx_eq(&self, other: &$t<N>) -> bool
|
||||
{
|
||||
let mut zip = self.at.iter().zip(other.at.iter());
|
||||
|
||||
do zip.all |(a, b)| { a.approx_eq(b) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N) -> bool
|
||||
{
|
||||
let mut zip = self.at.iter().zip(other.at.iter());
|
||||
|
||||
do zip.all |(a, b)| { a.approx_eq_eps(b, epsilon) }
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! zero_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Copy + Zero> Zero for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn zero() -> $t<N>
|
||||
{ $t::new_repeat(Zero::zero()) }
|
||||
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool
|
||||
{ self.at.iter().all(|e| e.is_zero()) }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! rand_impl(
|
||||
($t: ident, $param: ident, [ $($elem: ident)|+ ]) => (
|
||||
impl<N: Rand> Rand for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn rand<R: Rng>($param: &mut R) -> $t<N>
|
||||
{ $t::new([ $( $elem.gen(), )+ ]) }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! from_any_iterator_impl(
|
||||
($t: ident, $param: ident, [ $($elem: ident)|+ ]) => (
|
||||
impl<N: Copy> FromAnyIterator<N> for $t<N>
|
||||
{
|
||||
fn from_iterator<'l>($param: &mut VecIterator<'l, N>) -> $t<N>
|
||||
{ $t { at: [ $( copy *$elem.next().unwrap(), )+ ] } }
|
||||
|
||||
fn from_mut_iterator<'l>($param: &mut VecMutIterator<'l, N>) -> $t<N>
|
||||
{ $t { at: [ $( copy *$elem.next().unwrap(), )+ ] } }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! from_iterator_impl(
|
||||
($t: ident, $param: ident, [ $($elem: ident)|+ ]) => (
|
||||
impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for $t<N>
|
||||
{
|
||||
fn from_iterator($param: &mut Iter) -> $t<N>
|
||||
{ $t { at: [ $( $elem.next().unwrap(), )+ ] } }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! bounded_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Bounded + Copy> Bounded for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn max_value() -> $t<N>
|
||||
{ $t::new_repeat(Bounded::max_value()) }
|
||||
|
||||
#[inline]
|
||||
fn min_value() -> $t<N>
|
||||
{ $t::new_repeat(Bounded::min_value()) }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
#[deriving(Ord, ToStr)]
|
||||
pub struct Vec1<N>
|
||||
{ at: [N, ..1] }
|
||||
|
||||
new_impl!(Vec1, 1)
|
||||
new_repeat_impl!(Vec1, elem, [elem])
|
||||
dim_impl!(Vec1, 1)
|
||||
eq_impl!(Vec1)
|
||||
// (specialized) basis_impl!(Vec1, 1)
|
||||
add_impl!(Vec1)
|
||||
sub_impl!(Vec1)
|
||||
neg_impl!(Vec1)
|
||||
dot_impl!(Vec1, 1)
|
||||
sub_dot_impl!(Vec1, 1)
|
||||
scalar_mul_impl!(Vec1, 1)
|
||||
scalar_div_impl!(Vec1, 1)
|
||||
scalar_add_impl!(Vec1, 1)
|
||||
scalar_sub_impl!(Vec1, 1)
|
||||
translation_impl!(Vec1)
|
||||
translatable_impl!(Vec1)
|
||||
norm_impl!(Vec1, 1)
|
||||
approx_eq_impl!(Vec1)
|
||||
zero_impl!(Vec1)
|
||||
rand_impl!(Vec1, rng, [rng])
|
||||
from_iterator_impl!(Vec1, iterator, [iterator])
|
||||
from_any_iterator_impl!(Vec1, iterator, [iterator])
|
||||
bounded_impl!(Vec1)
|
||||
iterable_impl!(Vec1)
|
||||
iterable_mut_impl!(Vec1)
|
||||
|
||||
#[deriving(Ord, ToStr)]
|
||||
pub struct Vec2<N>
|
||||
{ at: [N, ..2] }
|
||||
|
||||
new_impl!(Vec2, 2)
|
||||
new_repeat_impl!(Vec2, elem, [elem | elem])
|
||||
dim_impl!(Vec2, 2)
|
||||
eq_impl!(Vec2)
|
||||
// (specialized) basis_impl!(Vec2, 2)
|
||||
add_impl!(Vec2)
|
||||
sub_impl!(Vec2)
|
||||
neg_impl!(Vec2)
|
||||
dot_impl!(Vec2, 2)
|
||||
sub_dot_impl!(Vec2, 2)
|
||||
scalar_mul_impl!(Vec2, 2)
|
||||
scalar_div_impl!(Vec2, 2)
|
||||
scalar_add_impl!(Vec2, 2)
|
||||
scalar_sub_impl!(Vec2, 2)
|
||||
translation_impl!(Vec2)
|
||||
translatable_impl!(Vec2)
|
||||
norm_impl!(Vec2, 2)
|
||||
approx_eq_impl!(Vec2)
|
||||
zero_impl!(Vec2)
|
||||
rand_impl!(Vec2, rng, [rng | rng])
|
||||
from_iterator_impl!(Vec2, iterator, [iterator | iterator])
|
||||
from_any_iterator_impl!(Vec2, iterator, [iterator | iterator])
|
||||
bounded_impl!(Vec2)
|
||||
iterable_impl!(Vec2)
|
||||
iterable_mut_impl!(Vec2)
|
||||
|
||||
#[deriving(Ord, ToStr)]
|
||||
pub struct Vec3<N>
|
||||
{ at: [N, ..3] }
|
||||
|
||||
new_impl!(Vec3, 3)
|
||||
new_repeat_impl!(Vec3, elem, [elem | elem | elem])
|
||||
dim_impl!(Vec3, 3)
|
||||
eq_impl!(Vec3)
|
||||
// (specialized) basis_impl!(Vec3, 3)
|
||||
add_impl!(Vec3)
|
||||
sub_impl!(Vec3)
|
||||
neg_impl!(Vec3)
|
||||
dot_impl!(Vec3, 3)
|
||||
sub_dot_impl!(Vec3, 3)
|
||||
scalar_mul_impl!(Vec3, 3)
|
||||
scalar_div_impl!(Vec3, 3)
|
||||
scalar_add_impl!(Vec3, 3)
|
||||
scalar_sub_impl!(Vec3, 3)
|
||||
translation_impl!(Vec3)
|
||||
translatable_impl!(Vec3)
|
||||
norm_impl!(Vec3, 3)
|
||||
approx_eq_impl!(Vec3)
|
||||
zero_impl!(Vec3)
|
||||
rand_impl!(Vec3, rng, [rng | rng | rng])
|
||||
from_iterator_impl!(Vec3, iterator, [iterator | iterator | iterator])
|
||||
from_any_iterator_impl!(Vec3, iterator, [iterator | iterator | iterator])
|
||||
bounded_impl!(Vec3)
|
||||
iterable_impl!(Vec3)
|
||||
iterable_mut_impl!(Vec3)
|
||||
|
||||
#[deriving(Ord, ToStr)]
|
||||
pub struct Vec4<N>
|
||||
{ at: [N, ..4] }
|
||||
|
||||
new_impl!(Vec4, 4)
|
||||
new_repeat_impl!(Vec4, elem, [elem | elem | elem | elem])
|
||||
dim_impl!(Vec4, 4)
|
||||
eq_impl!(Vec4)
|
||||
basis_impl!(Vec4, 4)
|
||||
add_impl!(Vec4)
|
||||
sub_impl!(Vec4)
|
||||
neg_impl!(Vec4)
|
||||
dot_impl!(Vec4, 4)
|
||||
sub_dot_impl!(Vec4, 4)
|
||||
scalar_mul_impl!(Vec4, 4)
|
||||
scalar_div_impl!(Vec4, 4)
|
||||
scalar_add_impl!(Vec4, 4)
|
||||
scalar_sub_impl!(Vec4, 4)
|
||||
translation_impl!(Vec4)
|
||||
translatable_impl!(Vec4)
|
||||
norm_impl!(Vec4, 4)
|
||||
approx_eq_impl!(Vec4)
|
||||
zero_impl!(Vec4)
|
||||
rand_impl!(Vec4, rng, [rng | rng | rng | rng])
|
||||
from_iterator_impl!(Vec4, iterator, [iterator | iterator | iterator | iterator])
|
||||
from_any_iterator_impl!(Vec4, iterator, [iterator | iterator | iterator | iterator])
|
||||
bounded_impl!(Vec4)
|
||||
iterable_impl!(Vec4)
|
||||
iterable_mut_impl!(Vec4)
|
||||
|
||||
#[deriving(Ord, ToStr)]
|
||||
pub struct Vec5<N>
|
||||
{ at: [N, ..5] }
|
||||
|
||||
new_impl!(Vec5, 5)
|
||||
new_repeat_impl!(Vec5, elem, [elem | elem | elem | elem | elem])
|
||||
dim_impl!(Vec5, 5)
|
||||
eq_impl!(Vec5)
|
||||
basis_impl!(Vec5, 5)
|
||||
add_impl!(Vec5)
|
||||
sub_impl!(Vec5)
|
||||
neg_impl!(Vec5)
|
||||
dot_impl!(Vec5, 5)
|
||||
sub_dot_impl!(Vec5, 5)
|
||||
scalar_mul_impl!(Vec5, 5)
|
||||
scalar_div_impl!(Vec5, 5)
|
||||
scalar_add_impl!(Vec5, 5)
|
||||
scalar_sub_impl!(Vec5, 5)
|
||||
translation_impl!(Vec5)
|
||||
translatable_impl!(Vec5)
|
||||
norm_impl!(Vec5, 5)
|
||||
approx_eq_impl!(Vec5)
|
||||
zero_impl!(Vec5)
|
||||
rand_impl!(Vec5, rng, [rng | rng | rng | rng | rng])
|
||||
from_iterator_impl!(Vec5, iterator, [iterator | iterator | iterator | iterator | iterator])
|
||||
from_any_iterator_impl!(Vec5, iterator, [iterator | iterator | iterator | iterator | iterator])
|
||||
bounded_impl!(Vec5)
|
||||
iterable_impl!(Vec5)
|
||||
iterable_mut_impl!(Vec5)
|
||||
|
||||
#[deriving(Ord, ToStr)]
|
||||
pub struct Vec6<N>
|
||||
{ at: [N, ..6] }
|
||||
|
||||
new_impl!(Vec6, 6)
|
||||
new_repeat_impl!(Vec6, elem, [elem | elem | elem | elem | elem | elem])
|
||||
dim_impl!(Vec6, 6)
|
||||
eq_impl!(Vec6)
|
||||
basis_impl!(Vec6, 6)
|
||||
add_impl!(Vec6)
|
||||
sub_impl!(Vec6)
|
||||
neg_impl!(Vec6)
|
||||
dot_impl!(Vec6, 6)
|
||||
sub_dot_impl!(Vec6, 6)
|
||||
scalar_mul_impl!(Vec6, 6)
|
||||
scalar_div_impl!(Vec6, 6)
|
||||
scalar_add_impl!(Vec6, 6)
|
||||
scalar_sub_impl!(Vec6, 6)
|
||||
translation_impl!(Vec6)
|
||||
translatable_impl!(Vec6)
|
||||
norm_impl!(Vec6, 6)
|
||||
approx_eq_impl!(Vec6)
|
||||
zero_impl!(Vec6)
|
||||
rand_impl!(Vec6, rng, [rng | rng | rng | rng | rng | rng])
|
||||
from_iterator_impl!(Vec6, iterator, [iterator | iterator | iterator | iterator | iterator | iterator])
|
||||
from_any_iterator_impl!(Vec6, iterator, [iterator | iterator | iterator | iterator | iterator | iterator])
|
||||
bounded_impl!(Vec6)
|
||||
iterable_impl!(Vec6)
|
||||
iterable_mut_impl!(Vec6)
|
||||
|
||||
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec1<N>> for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn cross(&self, other : &Vec2<N>) -> Vec1<N>
|
||||
{ Vec1::new([self.at[0] * other.at[1] - self.at[1] * other.at[0]]) }
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec3<N>> for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn cross(&self, other : &Vec3<N>) -> Vec3<N>
|
||||
{
|
||||
Vec3::new(
|
||||
[self.at[1] * other.at[2] - self.at[2] * other.at[1],
|
||||
self.at[2] * other.at[0] - self.at[0] * other.at[2],
|
||||
self.at[0] * other.at[1] - self.at[1] * other.at[0]]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: One> Basis for Vec1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn canonical_basis() -> ~[Vec1<N>]
|
||||
{ ~[ Vec1::new([One::one()]) ] } // FIXME: this should be static
|
||||
|
||||
#[inline]
|
||||
fn orthogonal_subspace_basis(&self) -> ~[Vec1<N>]
|
||||
{ ~[] }
|
||||
}
|
||||
|
||||
impl<N: Copy + One + Zero + Neg<N>> Basis for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn canonical_basis() -> ~[Vec2<N>]
|
||||
{
|
||||
// FIXME: this should be static
|
||||
~[ Vec2::new([One::one(), Zero::zero()]),
|
||||
Vec2::new([Zero::zero(), One::one()]) ]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn orthogonal_subspace_basis(&self) -> ~[Vec2<N>]
|
||||
{ ~[ Vec2::new([-self.at[1], copy self.at[0]]) ] }
|
||||
}
|
||||
|
||||
impl<N: Copy + DivisionRing + Ord + Algebraic>
|
||||
Basis for Vec3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn canonical_basis() -> ~[Vec3<N>]
|
||||
{
|
||||
// FIXME: this should be static
|
||||
~[ Vec3::new([One::one(), Zero::zero(), Zero::zero()]),
|
||||
Vec3::new([Zero::zero(), One::one(), Zero::zero()]),
|
||||
Vec3::new([Zero::zero(), Zero::zero(), One::one()]) ]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn orthogonal_subspace_basis(&self) -> ~[Vec3<N>]
|
||||
{
|
||||
let a =
|
||||
if abs(copy self.at[0]) > abs(copy self.at[1])
|
||||
{ Vec3::new([copy self.at[2], Zero::zero(), -copy self.at[0]]).normalized() }
|
||||
else
|
||||
{ Vec3::new([Zero::zero(), -self.at[2], copy self.at[1]]).normalized() };
|
||||
|
||||
~[ a.cross(self), a ]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue