Fix curly braces.

This commit is contained in:
Sébastien Crozet 2013-08-05 10:13:44 +02:00
parent a810bf6008
commit c59911168e
32 changed files with 1264 additions and 1336 deletions

View File

@ -20,40 +20,39 @@ use vec::Vec3;
/// the type-level) that it will always represent a rotation. Rotation matrices have some /// the type-level) that it will always represent a rotation. Rotation matrices have some
/// properties useful for performances, like the fact that the inversion is simply a transposition. /// properties useful for performances, like the fact that the inversion is simply a transposition.
#[deriving(Eq, ToStr, Clone)] #[deriving(Eq, ToStr, Clone)]
pub struct Rotmat<M> pub struct Rotmat<M> {
{ priv submat: M } priv submat: M
impl<M: Clone> Rotmat<M>
{
/// Gets a copy of the internal representation of the rotation.
pub fn submat(&self) -> M
{ self.submat.clone() }
} }
impl<N: Clone + Trigonometric + Neg<N>> Rotmat<Mat2<N>> impl<M: Clone> Rotmat<M> {
{ /// Gets a copy of the internal representation of the rotation.
/// Builds a 2 dimensional rotation matrix from an angle in radian. pub fn submat(&self) -> M {
pub fn from_angle(angle: N) -> Rotmat<Mat2<N>> self.submat.clone()
{
let (sia, coa) = angle.sin_cos();
Rotmat { submat: Mat2::new(coa.clone(), -sia, sia.clone(), coa) }
} }
} }
impl<N: Clone + Trigonometric + DivisionRing + Algebraic> Rotmat<Mat3<N>> impl<N: Clone + Trigonometric + Neg<N>> Rotmat<Mat2<N>> {
{ /// Builds a 2 dimensional rotation matrix from an angle in radian.
pub fn from_angle(angle: N) -> Rotmat<Mat2<N>> {
let (sia, coa) = angle.sin_cos();
Rotmat {
submat: Mat2::new(coa.clone(), -sia, sia.clone(), coa)
}
}
}
impl<N: Clone + Trigonometric + DivisionRing + Algebraic> Rotmat<Mat3<N>> {
/// Builds a 3 dimensional rotation matrix from an axis and an angle. /// Builds a 3 dimensional rotation matrix from an axis and an angle.
/// ///
/// # Arguments /// # Arguments
/// * `axisangle` - A vector representing the rotation. Its magnitude is the amount of rotation /// * `axisangle` - A vector representing the rotation. Its magnitude is the amount of rotation
/// in radian. Its direction is the axis of rotation. /// in radian. Its direction is the axis of rotation.
pub fn from_axis_angle(axisangle: Vec3<N>) -> Rotmat<Mat3<N>> pub fn from_axis_angle(axisangle: Vec3<N>) -> Rotmat<Mat3<N>> {
{ if axisangle.sqnorm().is_zero() {
if axisangle.sqnorm().is_zero() One::one()
{ One::one() } }
else else {
{
let mut axis = axisangle; let mut axis = axisangle;
let angle = axis.normalize(); let angle = axis.normalize();
let _1 = One::one::<N>(); let _1 = One::one::<N>();
@ -84,8 +83,7 @@ impl<N: Clone + Trigonometric + DivisionRing + Algebraic> Rotmat<Mat3<N>>
} }
} }
impl<N: Clone + DivisionRing + Algebraic> Rotmat<Mat3<N>> impl<N: Clone + DivisionRing + Algebraic> Rotmat<Mat3<N>> {
{
/// Reorient this matrix such that its local `x` axis points to a given point. Note that the /// Reorient this matrix such that its local `x` axis points to a given point. Note that the
/// usually known `look_at` function does the same thing but with the `z` axis. See `look_at_z` /// usually known `look_at` function does the same thing but with the `z` axis. See `look_at_z`
/// for that. /// for that.
@ -95,8 +93,7 @@ impl<N: Clone + DivisionRing + Algebraic> Rotmat<Mat3<N>>
/// with /// with
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear /// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
/// with `at`. Non-colinearity is not checked. /// with `at`. Non-colinearity is not checked.
pub fn look_at(&mut self, at: &Vec3<N>, up: &Vec3<N>) pub fn look_at(&mut self, at: &Vec3<N>, up: &Vec3<N>) {
{
let xaxis = at.normalized(); let xaxis = at.normalized();
let zaxis = up.cross(&xaxis).normalized(); let zaxis = up.cross(&xaxis).normalized();
let yaxis = zaxis.cross(&xaxis); let yaxis = zaxis.cross(&xaxis);
@ -113,8 +110,7 @@ impl<N: Clone + DivisionRing + Algebraic> Rotmat<Mat3<N>>
/// with /// with
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear /// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
/// with `at`. Non-colinearity is not checked. /// with `at`. Non-colinearity is not checked.
pub fn look_at_z(&mut self, at: &Vec3<N>, up: &Vec3<N>) pub fn look_at_z(&mut self, at: &Vec3<N>, up: &Vec3<N>) {
{
let zaxis = at.normalized(); let zaxis = at.normalized();
let xaxis = up.cross(&zaxis).normalized(); let xaxis = up.cross(&zaxis).normalized();
let yaxis = zaxis.cross(&xaxis); let yaxis = zaxis.cross(&xaxis);
@ -126,171 +122,179 @@ impl<N: Clone + DivisionRing + Algebraic> Rotmat<Mat3<N>>
} }
impl<N: Trigonometric + DivisionRing + Clone> impl<N: Trigonometric + DivisionRing + Clone>
Rotation<Vec1<N>> for Rotmat<Mat2<N>> Rotation<Vec1<N>> for Rotmat<Mat2<N>> {
{
#[inline] #[inline]
fn rotation(&self) -> Vec1<N> fn rotation(&self) -> Vec1<N> {
{ Vec1::new((-self.submat.at((0, 1))).atan2(&self.submat.at((0, 0)))) } Vec1::new((-self.submat.at((0, 1))).atan2(&self.submat.at((0, 0))))
}
#[inline] #[inline]
fn inv_rotation(&self) -> Vec1<N> fn inv_rotation(&self) -> Vec1<N> {
{ -self.rotation() } -self.rotation()
}
#[inline] #[inline]
fn rotate_by(&mut self, rot: &Vec1<N>) fn rotate_by(&mut self, rot: &Vec1<N>) {
{ *self = self.rotated(rot) } *self = self.rotated(rot)
}
} }
impl<N: Trigonometric + DivisionRing + Clone> impl<N: Trigonometric + DivisionRing + Clone>
Rotatable<Vec1<N>, Rotmat<Mat2<N>>> for Rotmat<Mat2<N>> Rotatable<Vec1<N>, Rotmat<Mat2<N>>> for Rotmat<Mat2<N>> {
{
#[inline] #[inline]
fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>> fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>> {
{ Rotmat::from_angle(rot.x.clone()) * *self } Rotmat::from_angle(rot.x.clone()) * *self
}
} }
impl<N: Clone + Trigonometric + DivisionRing + Algebraic> impl<N: Clone + Trigonometric + DivisionRing + Algebraic>
Rotation<Vec3<N>> for Rotmat<Mat3<N>> Rotation<Vec3<N>> for Rotmat<Mat3<N>> {
{
#[inline]
fn rotation(&self) -> Vec3<N>
{ fail!("Not yet implemented.") }
#[inline] #[inline]
fn rotation(&self) -> Vec3<N> {
fail!("Not yet implemented.")
}
fn inv_rotation(&self) -> Vec3<N> #[inline]
{ fail!("Not yet implemented.") } fn inv_rotation(&self) -> Vec3<N> {
fail!("Not yet implemented.")
}
#[inline] #[inline]
fn rotate_by(&mut self, rot: &Vec3<N>) fn rotate_by(&mut self, rot: &Vec3<N>) {
{ *self = self.rotated(rot) } *self = self.rotated(rot)
}
} }
impl<N: Clone + Trigonometric + DivisionRing + Algebraic> impl<N: Clone + Trigonometric + DivisionRing + Algebraic>
Rotatable<Vec3<N>, Rotmat<Mat3<N>>> for Rotmat<Mat3<N>> Rotatable<Vec3<N>, Rotmat<Mat3<N>>> for Rotmat<Mat3<N>> {
{
#[inline] #[inline]
fn rotated(&self, axisangle: &Vec3<N>) -> Rotmat<Mat3<N>> fn rotated(&self, axisangle: &Vec3<N>) -> Rotmat<Mat3<N>> {
{ Rotmat::from_axis_angle(axisangle.clone()) * *self } Rotmat::from_axis_angle(axisangle.clone()) * *self
}
} }
impl<N: Clone + Rand + Trigonometric + Neg<N>> Rand for Rotmat<Mat2<N>> impl<N: Clone + Rand + Trigonometric + Neg<N>> Rand for Rotmat<Mat2<N>> {
{
#[inline] #[inline]
fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat2<N>> fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat2<N>> {
{ Rotmat::from_angle(rng.gen()) } Rotmat::from_angle(rng.gen())
}
} }
impl<M: RMul<V> + LMul<V>, V> Rotate<V> for Rotmat<M> impl<M: RMul<V> + LMul<V>, V> Rotate<V> for Rotmat<M> {
{
#[inline] #[inline]
fn rotate(&self, v: &V) -> V fn rotate(&self, v: &V) -> V {
{ self.rmul(v) } self.rmul(v)
}
#[inline] #[inline]
fn inv_rotate(&self, v: &V) -> V fn inv_rotate(&self, v: &V) -> V {
{ self.lmul(v) } self.lmul(v)
}
} }
impl<M: RMul<V> + LMul<V>, V> Transform<V> for Rotmat<M> impl<M: RMul<V> + LMul<V>, V> Transform<V> for Rotmat<M> {
{
#[inline] #[inline]
fn transform_vec(&self, v: &V) -> V fn transform_vec(&self, v: &V) -> V {
{ self.rotate(v) } self.rotate(v)
}
#[inline] #[inline]
fn inv_transform(&self, v: &V) -> V fn inv_transform(&self, v: &V) -> V {
{ self.inv_rotate(v) } self.inv_rotate(v)
}
} }
impl<N: Clone + Rand + Trigonometric + DivisionRing + Algebraic> impl<N: Clone + Rand + Trigonometric + DivisionRing + Algebraic>
Rand for Rotmat<Mat3<N>> Rand for Rotmat<Mat3<N>> {
{
#[inline] #[inline]
fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat3<N>> fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat3<N>> {
{ Rotmat::from_axis_angle(rng.gen()) } Rotmat::from_axis_angle(rng.gen())
}
} }
impl<M: Dim> Dim for Rotmat<M> impl<M: Dim> Dim for Rotmat<M> {
{
#[inline] #[inline]
fn dim() -> uint fn dim() -> uint {
{ Dim::dim::<M>() } Dim::dim::<M>()
}
} }
impl<M: One + Zero> One for Rotmat<M> impl<M: One + Zero> One for Rotmat<M> {
{
#[inline] #[inline]
fn one() -> Rotmat<M> fn one() -> Rotmat<M> {
{ Rotmat { submat: One::one() } } Rotmat { submat: One::one() }
}
} }
impl<M: Mul<M, M>> Mul<Rotmat<M>, Rotmat<M>> for Rotmat<M> impl<M: Mul<M, M>> Mul<Rotmat<M>, Rotmat<M>> for Rotmat<M> {
{
#[inline] #[inline]
fn mul(&self, other: &Rotmat<M>) -> Rotmat<M> fn mul(&self, other: &Rotmat<M>) -> Rotmat<M> {
{ Rotmat { submat: self.submat.mul(&other.submat) } } Rotmat { submat: self.submat.mul(&other.submat) }
}
} }
impl<V, M: RMul<V>> RMul<V> for Rotmat<M> impl<V, M: RMul<V>> RMul<V> for Rotmat<M> {
{
#[inline] #[inline]
fn rmul(&self, other: &V) -> V fn rmul(&self, other: &V) -> V {
{ self.submat.rmul(other) } self.submat.rmul(other)
}
} }
impl<V, M: LMul<V>> LMul<V> for Rotmat<M> impl<V, M: LMul<V>> LMul<V> for Rotmat<M> {
{
#[inline] #[inline]
fn lmul(&self, other: &V) -> V fn lmul(&self, other: &V) -> V {
{ self.submat.lmul(other) } self.submat.lmul(other)
}
} }
impl<M: Transpose> Inv for Rotmat<M> impl<M: Transpose> Inv for Rotmat<M> {
{
#[inline] #[inline]
fn inplace_inverse(&mut self) -> bool fn inplace_inverse(&mut self) -> bool {
{
self.transpose(); self.transpose();
true true
} }
#[inline] #[inline]
fn inverse(&self) -> Option<Rotmat<M>> fn inverse(&self) -> Option<Rotmat<M>> {
{ Some(self.transposed()) } Some(self.transposed())
}
} }
impl<M: Transpose> impl<M: Transpose>
Transpose for Rotmat<M> Transpose for Rotmat<M> {
{
#[inline] #[inline]
fn transposed(&self) -> Rotmat<M> fn transposed(&self) -> Rotmat<M> {
{ Rotmat { submat: self.submat.transposed() } } Rotmat { submat: self.submat.transposed() }
}
#[inline] #[inline]
fn transpose(&mut self) fn transpose(&mut self) {
{ self.submat.transpose() } self.submat.transpose()
}
} }
// we loose the info that we are a rotation matrix // we loose the info that we are a rotation matrix
impl<M: ToHomogeneous<M2>, M2> ToHomogeneous<M2> for Rotmat<M> impl<M: ToHomogeneous<M2>, M2> ToHomogeneous<M2> for Rotmat<M> {
{ fn to_homogeneous(&self) -> M2 {
fn to_homogeneous(&self) -> M2 self.submat.to_homogeneous()
{ self.submat.to_homogeneous() } }
} }
impl<N: ApproxEq<N>, M: ApproxEq<N>> ApproxEq<N> for Rotmat<M> impl<N: ApproxEq<N>, M: ApproxEq<N>> ApproxEq<N> for Rotmat<M> {
{
#[inline] #[inline]
fn approx_epsilon() -> N fn approx_epsilon() -> N {
{ ApproxEq::approx_epsilon::<N, N>() } ApproxEq::approx_epsilon::<N, N>()
}
#[inline] #[inline]
fn approx_eq(&self, other: &Rotmat<M>) -> bool fn approx_eq(&self, other: &Rotmat<M>) -> bool {
{ self.submat.approx_eq(&other.submat) } self.submat.approx_eq(&other.submat)
}
#[inline] #[inline]
fn approx_eq_eps(&self, other: &Rotmat<M>, epsilon: &N) -> bool fn approx_eq_eps(&self, other: &Rotmat<M>, epsilon: &N) -> bool {
{ self.submat.approx_eq_eps(&other.submat, epsilon) } self.submat.approx_eq_eps(&other.submat, epsilon)
}
} }

View File

@ -23,35 +23,37 @@ use mat::Mat3;
/// underlying transform is a rotation (see `Rotmat`): this makes inversion much faster than /// underlying transform is a rotation (see `Rotmat`): this makes inversion much faster than
/// inverting the homogeneous matrix itself. /// inverting the homogeneous matrix itself.
#[deriving(Eq, ToStr, Clone)] #[deriving(Eq, ToStr, Clone)]
pub struct Transform<M, V> pub struct Transform<M, V> {
{
priv submat : M, priv submat : M,
priv subtrans : V priv subtrans : V
} }
impl<M, V> Transform<M, V> impl<M, V> Transform<M, V> {
{
/// Builds a new transform from a matrix and a vector. /// Builds a new transform from a matrix and a vector.
#[inline] #[inline]
pub fn new(mat: M, trans: V) -> Transform<M, V> pub fn new(mat: M, trans: V) -> Transform<M, V> {
{ Transform { submat: mat, subtrans: trans } } Transform {
submat: mat,
subtrans: trans
}
}
} }
impl<M: Clone, V: Clone> Transform<M, V> impl<M: Clone, V: Clone> Transform<M, V> {
{
/// Gets a copy of the internal matrix. /// Gets a copy of the internal matrix.
#[inline] #[inline]
pub fn submat(&self) -> M pub fn submat(&self) -> M {
{ self.submat.clone() } self.submat.clone()
}
/// Gets a copy of the internal translation. /// Gets a copy of the internal translation.
#[inline] #[inline]
pub fn subtrans(&self) -> V pub fn subtrans(&self) -> V {
{ self.subtrans.clone() } self.subtrans.clone()
}
} }
impl<N: Clone + DivisionRing + Algebraic> Transform<Rotmat<Mat3<N>>, Vec3<N>> impl<N: Clone + DivisionRing + Algebraic> Transform<Rotmat<Mat3<N>>, Vec3<N>> {
{
/// Reorient and translate this transformation such that its local `x` axis points to a given /// Reorient and translate this transformation such that its local `x` axis points to a given
/// direction. Note that the usually known `look_at` function does the same thing but with the /// direction. Note that the usually known `look_at` function does the same thing but with the
/// `z` axis. See `look_at_z` for that. /// `z` axis. See `look_at_z` for that.
@ -62,8 +64,7 @@ impl<N: Clone + DivisionRing + Algebraic> Transform<Rotmat<Mat3<N>>, Vec3<N>>
/// aligned with /// aligned with
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear /// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
/// with `at`. Non-colinearity is not checked. /// with `at`. Non-colinearity is not checked.
pub fn look_at(&mut self, eye: &Vec3<N>, at: &Vec3<N>, up: &Vec3<N>) pub fn look_at(&mut self, eye: &Vec3<N>, at: &Vec3<N>, up: &Vec3<N>) {
{
self.submat.look_at(&(*at - *eye), up); self.submat.look_at(&(*at - *eye), up);
self.subtrans = eye.clone(); self.subtrans = eye.clone();
} }
@ -77,112 +78,119 @@ impl<N: Clone + DivisionRing + Algebraic> Transform<Rotmat<Mat3<N>>, Vec3<N>>
/// aligned with /// aligned with
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear /// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
/// with `at`. Non-colinearity is not checked. /// with `at`. Non-colinearity is not checked.
pub fn look_at_z(&mut self, eye: &Vec3<N>, at: &Vec3<N>, up: &Vec3<N>) pub fn look_at_z(&mut self, eye: &Vec3<N>, at: &Vec3<N>, up: &Vec3<N>) {
{
self.submat.look_at_z(&(*at - *eye), up); self.submat.look_at_z(&(*at - *eye), up);
self.subtrans = eye.clone(); self.subtrans = eye.clone();
} }
} }
impl<M: Dim, V> Dim for Transform<M, V> impl<M: Dim, V> Dim for Transform<M, V> {
{
#[inline] #[inline]
fn dim() -> uint fn dim() -> uint {
{ Dim::dim::<M>() } Dim::dim::<M>()
}
impl<M: One, V: Zero> One for Transform<M, V>
{
#[inline]
fn one() -> Transform<M, V>
{ Transform { submat: One::one(), subtrans: Zero::zero() } }
}
impl<M: Zero, V: Zero> Zero for Transform<M, V>
{
#[inline]
fn zero() -> Transform<M, V>
{ Transform { submat: Zero::zero(), subtrans: Zero::zero() } }
#[inline]
fn is_zero(&self) -> bool
{ self.submat.is_zero() && self.subtrans.is_zero() }
}
impl<M: RMul<V> + Mul<M, M>, V: Add<V, V>>
Mul<Transform<M, V>, Transform<M, V>> for Transform<M, V>
{
#[inline]
fn mul(&self, other: &Transform<M, V>) -> Transform<M, V>
{
Transform { submat: self.submat * other.submat,
subtrans: self.subtrans + self.submat.rmul(&other.subtrans) }
} }
} }
impl<M: RMul<V>, V: Add<V, V>> RMul<V> for Transform<M, V> impl<M: One, V: Zero> One for Transform<M, V> {
{
#[inline] #[inline]
fn rmul(&self, other: &V) -> V fn one() -> Transform<M, V> {
{ self.submat.rmul(other) + self.subtrans } Transform {
submat: One::one(), subtrans: Zero::zero()
}
}
} }
impl<M: LMul<V>, V: Add<V, V>> LMul<V> for Transform<M, V> impl<M: Zero, V: Zero> Zero for Transform<M, V> {
{
#[inline] #[inline]
fn lmul(&self, other: &V) -> V fn zero() -> Transform<M, V> {
{ self.submat.lmul(other) + self.subtrans } Transform {
submat: Zero::zero(), subtrans: Zero::zero()
}
}
#[inline]
fn is_zero(&self) -> bool {
self.submat.is_zero() && self.subtrans.is_zero()
}
} }
impl<M, V: Translation<V>> Translation<V> for Transform<M, V> impl<M: RMul<V> + Mul<M, M>, V: Add<V, V>>
{ Mul<Transform<M, V>, Transform<M, V>> for Transform<M, V> {
#[inline] #[inline]
fn translation(&self) -> V fn mul(&self, other: &Transform<M, V>) -> Transform<M, V> {
{ self.subtrans.translation() } Transform {
submat: self.submat * other.submat,
#[inline] subtrans: self.subtrans + self.submat.rmul(&other.subtrans)
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> impl<M: RMul<V>, V: Add<V, V>> RMul<V> for Transform<M, V> {
{
#[inline] #[inline]
fn translate(&self, v: &V) -> V fn rmul(&self, other: &V) -> V {
{ self.submat.translate(v) } self.submat.rmul(other) + self.subtrans
}
}
impl<M: LMul<V>, V: Add<V, V>> LMul<V> for Transform<M, V> {
#[inline]
fn lmul(&self, other: &V) -> V {
self.submat.lmul(other) + self.subtrans
}
}
impl<M, V: Translation<V>> Translation<V> for Transform<M, V> {
#[inline]
fn translation(&self) -> V {
self.subtrans.translation()
}
#[inline] #[inline]
fn inv_translate(&self, v: &V) -> V fn inv_translation(&self) -> V {
{ self.submat.inv_translate(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: Clone, V: Translatable<V, V> + Translation<V>> impl<M: Clone, V: Translatable<V, V> + Translation<V>>
Translatable<V, Transform<M, V>> for Transform<M, V> Translatable<V, Transform<M, V>> for Transform<M, V> {
{
#[inline] #[inline]
fn translated(&self, t: &V) -> Transform<M, V> fn translated(&self, t: &V) -> Transform<M, V> {
{ Transform::new(self.submat.clone(), self.subtrans.translated(t)) } Transform::new(self.submat.clone(), self.subtrans.translated(t))
}
} }
impl<M: Rotation<AV> + RMul<V> + One, V, AV> impl<M: Rotation<AV> + RMul<V> + One, V, AV>
Rotation<AV> for Transform<M, V> Rotation<AV> for Transform<M, V> {
{
#[inline] #[inline]
fn rotation(&self) -> AV fn rotation(&self) -> AV {
{ self.submat.rotation() } self.submat.rotation()
}
#[inline] #[inline]
fn inv_rotation(&self) -> AV fn inv_rotation(&self) -> AV {
{ self.submat.inv_rotation() } self.submat.inv_rotation()
}
#[inline] #[inline]
fn rotate_by(&mut self, rot: &AV) fn rotate_by(&mut self, rot: &AV) {
{
// FIXME: this does not seem opitmal // FIXME: this does not seem opitmal
let mut delta = One::one::<M>(); let mut delta = One::one::<M>();
delta.rotate_by(rot); delta.rotate_by(rot);
@ -191,23 +199,22 @@ Rotation<AV> for Transform<M, V>
} }
} }
impl<M: Rotate<V>, V, _0> Rotate<V> for Transform<M, _0> impl<M: Rotate<V>, V, _0> Rotate<V> for Transform<M, _0> {
{
#[inline] #[inline]
fn rotate(&self, v: &V) -> V fn rotate(&self, v: &V) -> V {
{ self.submat.rotate(v) } self.submat.rotate(v)
}
#[inline] #[inline]
fn inv_rotate(&self, v: &V) -> V fn inv_rotate(&self, v: &V) -> V {
{ self.submat.inv_rotate(v) } self.submat.inv_rotate(v)
}
} }
impl<M: Rotatable<AV, Res> + One, Res: Rotation<AV> + RMul<V> + One, V, AV> impl<M: Rotatable<AV, Res> + One, Res: Rotation<AV> + RMul<V> + One, V, AV>
Rotatable<AV, Transform<Res, V>> for Transform<M, V> Rotatable<AV, Transform<Res, V>> for Transform<M, V> {
{
#[inline] #[inline]
fn rotated(&self, rot: &AV) -> Transform<Res, V> fn rotated(&self, rot: &AV) -> Transform<Res, V> {
{
// FIXME: this does not seem opitmal // FIXME: this does not seem opitmal
let delta = One::one::<M>().rotated(rot); let delta = One::one::<M>().rotated(rot);
@ -216,79 +223,76 @@ Rotatable<AV, Transform<Res, V>> for Transform<M, V>
} }
impl<M: Inv + RMul<V> + Mul<M, M> + Clone, V: Add<V, V> + Neg<V> + Clone> impl<M: Inv + RMul<V> + Mul<M, M> + Clone, V: Add<V, V> + Neg<V> + Clone>
Transformation<Transform<M, V>> for Transform<M, V> Transformation<Transform<M, V>> for Transform<M, V> {
{ fn transformation(&self) -> Transform<M, V> {
fn transformation(&self) -> Transform<M, V> self.clone()
{ self.clone() } }
fn inv_transformation(&self) -> Transform<M, V> fn inv_transformation(&self) -> Transform<M, V> {
{
// FIXME: fail or return a Some<Transform<M, V>> ? // FIXME: fail or return a Some<Transform<M, V>> ?
match self.inverse() match self.inverse() {
{
Some(t) => t, Some(t) => t,
None => fail!("This transformation was not inversible.") None => fail!("This transformation was not inversible.")
} }
} }
fn transform_by(&mut self, other: &Transform<M, V>) fn transform_by(&mut self, other: &Transform<M, V>) {
{ *self = other * *self; } *self = other * *self
}
} }
impl<M: Ts<V>, V: Add<V, V> + Sub<V, V>> impl<M: Ts<V>, V: Add<V, V> + Sub<V, V>>
Ts<V> for Transform<M, V> Ts<V> for Transform<M, V> {
{
#[inline] #[inline]
fn transform_vec(&self, v: &V) -> V fn transform_vec(&self, v: &V) -> V {
{ self.submat.transform_vec(v) + self.subtrans } self.submat.transform_vec(v) + self.subtrans
}
#[inline] #[inline]
fn inv_transform(&self, v: &V) -> V fn inv_transform(&self, v: &V) -> V {
{ self.submat.inv_transform(&(v - self.subtrans)) } self.submat.inv_transform(&(v - self.subtrans))
}
} }
// FIXME: constraints are too restrictive. // FIXME: constraints are too restrictive.
// Should be: Transformable<M2, // Transform<Res, V> ... // Should be: Transformable<M2, // Transform<Res, V> ...
impl<M: RMul<V> + Mul<M, M> + Inv + Clone, V: Add<V, V> + Neg<V> + Clone> impl<M: RMul<V> + Mul<M, M> + Inv + Clone, V: Add<V, V> + Neg<V> + Clone>
Transformable<Transform<M, V>, Transform<M, V>> for Transform<M, V> Transformable<Transform<M, V>, Transform<M, V>> for Transform<M, V> {
{ fn transformed(&self, t: &Transform<M, V>) -> Transform<M, V> {
fn transformed(&self, t: &Transform<M, V>) -> Transform<M, V> t * *self
{ t * *self } }
} }
impl<M: Inv + RMul<V> + Clone, V: Neg<V> + Clone> impl<M: Inv + RMul<V> + Clone, V: Neg<V> + Clone>
Inv for Transform<M, V> Inv for Transform<M, V> {
{
#[inline] #[inline]
fn inplace_inverse(&mut self) -> bool fn inplace_inverse(&mut self) -> bool {
{ if !self.submat.inplace_inverse() {
if !self.submat.inplace_inverse() false
{ false } }
else else {
{
self.subtrans = self.submat.rmul(&-self.subtrans); self.subtrans = self.submat.rmul(&-self.subtrans);
true true
} }
} }
#[inline] #[inline]
fn inverse(&self) -> Option<Transform<M, V>> fn inverse(&self) -> Option<Transform<M, V>> {
{
let mut res = self.clone(); let mut res = self.clone();
if res.inplace_inverse() if res.inplace_inverse() {
{ Some(res) } Some(res)
else }
{ None } else {
None
}
} }
} }
impl<M: ToHomogeneous<M2>, M2: Dim + Column<V>, V: Clone> impl<M: ToHomogeneous<M2>, M2: Dim + Column<V>, V: Clone>
ToHomogeneous<M2> for Transform<M, V> ToHomogeneous<M2> for Transform<M, V> {
{ fn to_homogeneous(&self) -> M2 {
fn to_homogeneous(&self) -> M2
{
let mut res = self.submat.to_homogeneous(); let mut res = self.submat.to_homogeneous();
// copy the translation // copy the translation
@ -301,39 +305,35 @@ ToHomogeneous<M2> for Transform<M, V>
} }
impl<M: Column<V> + Dim, M2: FromHomogeneous<M>, V> impl<M: Column<V> + Dim, M2: FromHomogeneous<M>, V>
FromHomogeneous<M> for Transform<M2, V> FromHomogeneous<M> for Transform<M2, V> {
{ fn from(m: &M) -> Transform<M2, V> {
fn from(m: &M) -> Transform<M2, V>
{
Transform::new(FromHomogeneous::from(m), m.column(Dim::dim::<M>() - 1)) Transform::new(FromHomogeneous::from(m), m.column(Dim::dim::<M>() - 1))
} }
} }
impl<N: ApproxEq<N>, M:ApproxEq<N>, V:ApproxEq<N>> impl<N: ApproxEq<N>, M:ApproxEq<N>, V:ApproxEq<N>>
ApproxEq<N> for Transform<M, V> ApproxEq<N> for Transform<M, V> {
{
#[inline] #[inline]
fn approx_epsilon() -> N fn approx_epsilon() -> N {
{ ApproxEq::approx_epsilon::<N, N>() } ApproxEq::approx_epsilon::<N, N>()
}
#[inline] #[inline]
fn approx_eq(&self, other: &Transform<M, V>) -> bool fn approx_eq(&self, other: &Transform<M, V>) -> bool {
{
self.submat.approx_eq(&other.submat) && self.submat.approx_eq(&other.submat) &&
self.subtrans.approx_eq(&other.subtrans) self.subtrans.approx_eq(&other.subtrans)
} }
#[inline] #[inline]
fn approx_eq_eps(&self, other: &Transform<M, V>, epsilon: &N) -> bool fn approx_eq_eps(&self, other: &Transform<M, V>, epsilon: &N) -> bool {
{
self.submat.approx_eq_eps(&other.submat, epsilon) && self.submat.approx_eq_eps(&other.submat, epsilon) &&
self.subtrans.approx_eq_eps(&other.subtrans, epsilon) self.subtrans.approx_eq_eps(&other.subtrans, epsilon)
} }
} }
impl<M: Rand, V: Rand> Rand for Transform<M, V> impl<M: Rand, V: Rand> Rand for Transform<M, V> {
{
#[inline] #[inline]
fn rand<R: Rng>(rng: &mut R) -> Transform<M, V> fn rand<R: Rng>(rng: &mut R) -> Transform<M, V> {
{ Transform::new(rng.gen(), rng.gen()) } Transform::new(rng.gen(), rng.gen())
}
} }

View File

@ -10,8 +10,7 @@ use dvec::{DVec, zero_vec_with_dim};
/// Square matrix with a dimension unknown at compile-time. /// Square matrix with a dimension unknown at compile-time.
#[deriving(Eq, ToStr, Clone)] #[deriving(Eq, ToStr, Clone)]
pub struct DMat<N> pub struct DMat<N> {
{
priv dim: uint, // FIXME: handle more than just square matrices priv dim: uint, // FIXME: handle more than just square matrices
priv mij: ~[N] priv mij: ~[N]
} }
@ -22,13 +21,15 @@ pub struct DMat<N>
/// * `dim` - The dimension of the matrix. A `dim`-dimensional matrix contains `dim * dim` /// * `dim` - The dimension of the matrix. A `dim`-dimensional matrix contains `dim * dim`
/// components. /// components.
#[inline] #[inline]
pub fn zero_mat_with_dim<N: Zero + Clone>(dim: uint) -> DMat<N> pub fn zero_mat_with_dim<N: Zero + Clone>(dim: uint) -> DMat<N> {
{ DMat { dim: dim, mij: from_elem(dim * dim, Zero::zero()) } } DMat { dim: dim, mij: from_elem(dim * dim, Zero::zero()) }
}
/// Tests if all components of the matrix are zeroes. /// Tests if all components of the matrix are zeroes.
#[inline] #[inline]
pub fn is_zero_mat<N: Zero>(mat: &DMat<N>) -> bool pub fn is_zero_mat<N: Zero>(mat: &DMat<N>) -> bool {
{ mat.mij.iter().all(|e| e.is_zero()) } mat.mij.iter().all(|e| e.is_zero())
}
/// Builds an identity matrix. /// Builds an identity matrix.
/// ///
@ -36,22 +37,22 @@ pub fn is_zero_mat<N: Zero>(mat: &DMat<N>) -> bool
/// * `dim` - The dimension of the matrix. A `dim`-dimensional matrix contains `dim * dim` /// * `dim` - The dimension of the matrix. A `dim`-dimensional matrix contains `dim * dim`
/// components. /// components.
#[inline] #[inline]
pub fn one_mat_with_dim<N: Clone + One + Zero>(dim: uint) -> DMat<N> pub fn one_mat_with_dim<N: Clone + One + Zero>(dim: uint) -> DMat<N> {
{
let mut res = zero_mat_with_dim(dim); let mut res = zero_mat_with_dim(dim);
let _1 = One::one::<N>(); let _1 = One::one::<N>();
for i in range(0u, dim) for i in range(0u, dim) {
{ res.set(i, i, &_1); } res.set(i, i, &_1);
}
res res
} }
impl<N: Clone> DMat<N> impl<N: Clone> DMat<N> {
{
#[inline] #[inline]
fn offset(&self, i: uint, j: uint) -> uint fn offset(&self, i: uint, j: uint) -> uint {
{ i * self.dim + j } i * self.dim + j
}
/// Changes the value of a component of the matrix. /// Changes the value of a component of the matrix.
/// ///
@ -59,8 +60,7 @@ impl<N: Clone> DMat<N>
/// * `i` - 0-based index of the line to be changed /// * `i` - 0-based index of the line to be changed
/// * `j` - 0-based index of the column to be changed /// * `j` - 0-based index of the column to be changed
#[inline] #[inline]
pub fn set(&mut self, i: uint, j: uint, t: &N) pub fn set(&mut self, i: uint, j: uint, t: &N) {
{
assert!(i < self.dim); assert!(i < self.dim);
assert!(j < self.dim); assert!(j < self.dim);
self.mij[self.offset(i, j)] = t.clone() self.mij[self.offset(i, j)] = t.clone()
@ -72,39 +72,35 @@ impl<N: Clone> DMat<N>
/// * `i` - 0-based index of the line to be read /// * `i` - 0-based index of the line to be read
/// * `j` - 0-based index of the column to be read /// * `j` - 0-based index of the column to be read
#[inline] #[inline]
pub fn at(&self, i: uint, j: uint) -> N pub fn at(&self, i: uint, j: uint) -> N {
{
assert!(i < self.dim); assert!(i < self.dim);
assert!(j < self.dim); assert!(j < self.dim);
self.mij[self.offset(i, j)].clone() self.mij[self.offset(i, j)].clone()
} }
} }
impl<N: Clone> Index<(uint, uint), N> for DMat<N> impl<N: Clone> Index<(uint, uint), N> for DMat<N> {
{
#[inline] #[inline]
fn index(&self, &(i, j): &(uint, uint)) -> N fn index(&self, &(i, j): &(uint, uint)) -> N {
{ self.at(i, j) } self.at(i, j)
}
} }
impl<N: Clone + Mul<N, N> + Add<N, N> + Zero> impl<N: Clone + Mul<N, N> + Add<N, N> + Zero>
Mul<DMat<N>, DMat<N>> for DMat<N> Mul<DMat<N>, DMat<N>> for DMat<N> {
{ fn mul(&self, other: &DMat<N>) -> DMat<N> {
fn mul(&self, other: &DMat<N>) -> DMat<N>
{
assert!(self.dim == other.dim); assert!(self.dim == other.dim);
let dim = self.dim; let dim = self.dim;
let mut res = zero_mat_with_dim(dim); let mut res = zero_mat_with_dim(dim);
for i in range(0u, dim) for i in range(0u, dim) {
{ for j in range(0u, dim) {
for j in range(0u, dim)
{
let mut acc = Zero::zero::<N>(); let mut acc = Zero::zero::<N>();
for k in range(0u, dim) for k in range(0u, dim) {
{ acc = acc + self.at(i, k) * other.at(k, j); } acc = acc + self.at(i, k) * other.at(k, j);
}
res.set(i, j, &acc); res.set(i, j, &acc);
} }
@ -115,19 +111,17 @@ Mul<DMat<N>, DMat<N>> for DMat<N>
} }
impl<N: Clone + Add<N, N> + Mul<N, N> + Zero> impl<N: Clone + Add<N, N> + Mul<N, N> + Zero>
RMul<DVec<N>> for DMat<N> RMul<DVec<N>> for DMat<N> {
{ fn rmul(&self, other: &DVec<N>) -> DVec<N> {
fn rmul(&self, other: &DVec<N>) -> DVec<N>
{
assert!(self.dim == other.at.len()); assert!(self.dim == other.at.len());
let dim = self.dim; let dim = self.dim;
let mut res : DVec<N> = zero_vec_with_dim(dim); let mut res : DVec<N> = zero_vec_with_dim(dim);
for i in range(0u, dim) for i in range(0u, dim) {
{ for j in range(0u, dim) {
for j in range(0u, dim) res.at[i] = res.at[i] + other.at[j] * self.at(i, j);
{ res.at[i] = res.at[i] + other.at[j] * self.at(i, j); } }
} }
res res
@ -135,19 +129,17 @@ RMul<DVec<N>> for DMat<N>
} }
impl<N: Clone + Add<N, N> + Mul<N, N> + Zero> impl<N: Clone + Add<N, N> + Mul<N, N> + Zero>
LMul<DVec<N>> for DMat<N> LMul<DVec<N>> for DMat<N> {
{ fn lmul(&self, other: &DVec<N>) -> DVec<N> {
fn lmul(&self, other: &DVec<N>) -> DVec<N>
{
assert!(self.dim == other.at.len()); assert!(self.dim == other.at.len());
let dim = self.dim; let dim = self.dim;
let mut res : DVec<N> = zero_vec_with_dim(dim); let mut res : DVec<N> = zero_vec_with_dim(dim);
for i in range(0u, dim) for i in range(0u, dim) {
{ for j in range(0u, dim) {
for j in range(0u, dim) res.at[i] = res.at[i] + other.at[j] * self.at(j, i);
{ res.at[i] = res.at[i] + other.at[j] * self.at(j, i); } }
} }
res res
@ -155,50 +147,47 @@ LMul<DVec<N>> for DMat<N>
} }
impl<N: Clone + Eq + DivisionRing> impl<N: Clone + Eq + DivisionRing>
Inv for DMat<N> Inv for DMat<N> {
{
#[inline] #[inline]
fn inverse(&self) -> Option<DMat<N>> fn inverse(&self) -> Option<DMat<N>> {
{
let mut res : DMat<N> = self.clone(); let mut res : DMat<N> = self.clone();
if res.inplace_inverse() if res.inplace_inverse() {
{ Some(res) } Some(res)
else }
{ None } else {
None
}
} }
fn inplace_inverse(&mut self) -> bool fn inplace_inverse(&mut self) -> bool {
{
let dim = self.dim; let dim = self.dim;
let mut res = one_mat_with_dim::<N>(dim); let mut res = one_mat_with_dim::<N>(dim);
let _0T = Zero::zero::<N>(); let _0T = Zero::zero::<N>();
// inversion using Gauss-Jordan elimination // inversion using Gauss-Jordan elimination
for k in range(0u, dim) for k in range(0u, dim) {
{
// search a non-zero value on the k-th column // search a non-zero value on the k-th column
// FIXME: would it be worth it to spend some more time searching for the // FIXME: would it be worth it to spend some more time searching for the
// max instead? // max instead?
let mut n0 = k; // index of a non-zero entry let mut n0 = k; // index of a non-zero entry
while (n0 != dim) while (n0 != dim) {
{ if self.at(n0, k) != _0T {
if self.at(n0, k) != _0T break;
{ break; } }
n0 = n0 + 1; n0 = n0 + 1;
} }
if n0 == dim if n0 == dim {
{ return false } return false
}
// swap pivot line // swap pivot line
if n0 != k if n0 != k {
{ for j in range(0u, dim) {
for j in range(0u, dim)
{
let off_n0_j = self.offset(n0, j); let off_n0_j = self.offset(n0, j);
let off_k_j = self.offset(k, j); let off_k_j = self.offset(k, j);
@ -209,32 +198,26 @@ Inv for DMat<N>
let pivot = self.at(k, k); let pivot = self.at(k, k);
for j in range(k, dim) for j in range(k, dim) {
{
let selfval = &(self.at(k, j) / pivot); let selfval = &(self.at(k, j) / pivot);
self.set(k, j, selfval); self.set(k, j, selfval);
} }
for j in range(0u, dim) for j in range(0u, dim) {
{
let resval = &(res.at(k, j) / pivot); let resval = &(res.at(k, j) / pivot);
res.set(k, j, resval); res.set(k, j, resval);
} }
for l in range(0u, dim) for l in range(0u, dim) {
{ if l != k {
if l != k
{
let normalizer = self.at(l, k); let normalizer = self.at(l, k);
for j in range(k, dim) for j in range(k, dim) {
{
let selfval = &(self.at(l, j) - self.at(k, j) * normalizer); let selfval = &(self.at(l, j) - self.at(k, j) * normalizer);
self.set(l, j, selfval); self.set(l, j, selfval);
} }
for j in range(0u, dim) for j in range(0u, dim) {
{
let resval = &(res.at(l, j) - res.at(k, j) * normalizer); let resval = &(res.at(l, j) - res.at(k, j) * normalizer);
res.set(l, j, resval); res.set(l, j, resval);
} }
@ -248,11 +231,9 @@ Inv for DMat<N>
} }
} }
impl<N: Clone> Transpose for DMat<N> impl<N: Clone> Transpose for DMat<N> {
{
#[inline] #[inline]
fn transposed(&self) -> DMat<N> fn transposed(&self) -> DMat<N> {
{
let mut res = self.clone(); let mut res = self.clone();
res.transpose(); res.transpose();
@ -260,14 +241,11 @@ impl<N: Clone> Transpose for DMat<N>
res res
} }
fn transpose(&mut self) fn transpose(&mut self) {
{
let dim = self.dim; let dim = self.dim;
for i in range(1u, dim) for i in range(1u, dim) {
{ for j in range(0u, dim - 1) {
for j in range(0u, dim - 1)
{
let off_i_j = self.offset(i, j); let off_i_j = self.offset(i, j);
let off_j_i = self.offset(j, i); let off_j_i = self.offset(j, i);
@ -277,25 +255,27 @@ impl<N: Clone> Transpose for DMat<N>
} }
} }
impl<N: ApproxEq<N>> ApproxEq<N> for DMat<N> impl<N: ApproxEq<N>> ApproxEq<N> for DMat<N> {
{
#[inline] #[inline]
fn approx_epsilon() -> N fn approx_epsilon() -> N {
{ ApproxEq::approx_epsilon::<N, N>() } ApproxEq::approx_epsilon::<N, N>()
#[inline]
fn approx_eq(&self, other: &DMat<N>) -> bool
{
let mut zip = self.mij.iter().zip(other.mij.iter());
do zip.all |(a, b)| { a.approx_eq(b) }
} }
#[inline] #[inline]
fn approx_eq_eps(&self, other: &DMat<N>, epsilon: &N) -> bool fn approx_eq(&self, other: &DMat<N>) -> bool {
{
let mut zip = self.mij.iter().zip(other.mij.iter()); let mut zip = self.mij.iter().zip(other.mij.iter());
do zip.all |(a, b)| { a.approx_eq_eps(b, epsilon) } do zip.all |(a, b)| {
a.approx_eq(b)
}
}
#[inline]
fn approx_eq_eps(&self, other: &DMat<N>, epsilon: &N) -> bool {
let mut zip = self.mij.iter().zip(other.mij.iter());
do zip.all |(a, b)| {
a.approx_eq_eps(b, epsilon)
}
} }
} }

View File

@ -14,8 +14,7 @@ use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
/// Vector with a dimension unknown at compile-time. /// Vector with a dimension unknown at compile-time.
#[deriving(Eq, Ord, ToStr, Clone)] #[deriving(Eq, Ord, ToStr, Clone)]
pub struct DVec<N> pub struct DVec<N> {
{
/// Components of the vector. Contains as much elements as the vector dimension. /// Components of the vector. Contains as much elements as the vector dimension.
at: ~[N] at: ~[N]
} }
@ -25,50 +24,48 @@ pub struct DVec<N>
/// # Arguments /// # Arguments
/// * `dim` - The dimension of the vector. /// * `dim` - The dimension of the vector.
#[inline] #[inline]
pub fn zero_vec_with_dim<N: Zero + Clone>(dim: uint) -> DVec<N> pub fn zero_vec_with_dim<N: Zero + Clone>(dim: uint) -> DVec<N> {
{ DVec { at: from_elem(dim, Zero::zero::<N>()) } } DVec { at: from_elem(dim, Zero::zero::<N>()) }
}
/// Tests if all components of the vector are zeroes. /// Tests if all components of the vector are zeroes.
#[inline] #[inline]
pub fn is_zero_vec<N: Zero>(vec: &DVec<N>) -> bool pub fn is_zero_vec<N: Zero>(vec: &DVec<N>) -> bool {
{ vec.at.iter().all(|e| e.is_zero()) } 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> impl<N> Iterable<N> for DVec<N> {
{ fn iter<'l>(&'l self) -> VecIterator<'l, N> {
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> self.at.iter()
{ self.at.mut_iter() } }
} }
impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for DVec<N> impl<N> IterableMut<N> for DVec<N> {
{ fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> {
fn from_iterator(mut param: &mut Iter) -> DVec<N> self.at.mut_iter()
{ }
}
impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for DVec<N> {
fn from_iterator(mut param: &mut Iter) -> DVec<N> {
let mut res = DVec { at: ~[] }; let mut res = DVec { at: ~[] };
for e in param for e in param {
{ res.at.push(e) } res.at.push(e)
}
res res
} }
} }
impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> DVec<N> impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> DVec<N> {
{
/// Computes the canonical basis for the given dimension. A canonical basis is a set of /// Computes the canonical basis for the given dimension. A canonical basis is a set of
/// vectors, mutually orthogonal, with all its component equal to 0.0 exept one which is equal /// vectors, mutually orthogonal, with all its component equal to 0.0 exept one which is equal
/// to 1.0. /// to 1.0.
pub fn canonical_basis_with_dim(dim: uint) -> ~[DVec<N>] pub fn canonical_basis_with_dim(dim: uint) -> ~[DVec<N>] {
{
let mut res : ~[DVec<N>] = ~[]; let mut res : ~[DVec<N>] = ~[];
for i in range(0u, dim) for i in range(0u, dim) {
{
let mut basis_element : DVec<N> = zero_vec_with_dim(dim); let mut basis_element : DVec<N> = zero_vec_with_dim(dim);
basis_element.at[i] = One::one(); basis_element.at[i] = One::one();
@ -81,31 +78,32 @@ impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> DVec<N>
/// Computes a basis of the space orthogonal to the vector. If the input vector is of dimension /// Computes a basis of the space orthogonal to the vector. If the input vector is of dimension
/// `n`, this will return `n - 1` vectors. /// `n`, this will return `n - 1` vectors.
pub fn orthogonal_subspace_basis(&self) -> ~[DVec<N>] pub fn orthogonal_subspace_basis(&self) -> ~[DVec<N>] {
{
// compute the basis of the orthogonal subspace using Gram-Schmidt // compute the basis of the orthogonal subspace using Gram-Schmidt
// orthogonalization algorithm // orthogonalization algorithm
let dim = self.at.len(); let dim = self.at.len();
let mut res : ~[DVec<N>] = ~[]; let mut res : ~[DVec<N>] = ~[];
for i in range(0u, dim) for i in range(0u, dim) {
{
let mut basis_element : DVec<N> = zero_vec_with_dim(self.at.len()); let mut basis_element : DVec<N> = zero_vec_with_dim(self.at.len());
basis_element.at[i] = One::one(); basis_element.at[i] = One::one();
if res.len() == dim - 1 if res.len() == dim - 1 {
{ break; } break;
}
let mut elt = basis_element.clone(); let mut elt = basis_element.clone();
elt = elt - self.scalar_mul(&basis_element.dot(self)); elt = elt - self.scalar_mul(&basis_element.dot(self));
for v in res.iter() for v in res.iter() {
{ elt = elt - v.scalar_mul(&elt.dot(v)) }; elt = elt - v.scalar_mul(&elt.dot(v))
};
if !elt.sqnorm().approx_eq(&Zero::zero()) if !elt.sqnorm().approx_eq(&Zero::zero()) {
{ res.push(elt.normalized()); } res.push(elt.normalized());
}
} }
assert!(res.len() == dim - 1); assert!(res.len() == dim - 1);
@ -114,11 +112,9 @@ impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> DVec<N>
} }
} }
impl<N: Add<N,N>> Add<DVec<N>, DVec<N>> for DVec<N> impl<N: Add<N,N>> Add<DVec<N>, DVec<N>> for DVec<N> {
{
#[inline] #[inline]
fn add(&self, other: &DVec<N>) -> DVec<N> fn add(&self, other: &DVec<N>) -> DVec<N> {
{
assert!(self.at.len() == other.at.len()); assert!(self.at.len() == other.at.len());
DVec { DVec {
at: self.at.iter().zip(other.at.iter()).transform(|(a, b)| *a + *b).collect() at: self.at.iter().zip(other.at.iter()).transform(|(a, b)| *a + *b).collect()
@ -126,11 +122,9 @@ impl<N: Add<N,N>> Add<DVec<N>, DVec<N>> for DVec<N>
} }
} }
impl<N: Sub<N,N>> Sub<DVec<N>, DVec<N>> for DVec<N> impl<N: Sub<N,N>> Sub<DVec<N>, DVec<N>> for DVec<N> {
{
#[inline] #[inline]
fn sub(&self, other: &DVec<N>) -> DVec<N> fn sub(&self, other: &DVec<N>) -> DVec<N> {
{
assert!(self.at.len() == other.at.len()); assert!(self.at.len() == other.at.len());
DVec { DVec {
at: self.at.iter().zip(other.at.iter()).transform(|(a, b)| *a - *b).collect() at: self.at.iter().zip(other.at.iter()).transform(|(a, b)| *a - *b).collect()
@ -138,135 +132,135 @@ impl<N: Sub<N,N>> Sub<DVec<N>, DVec<N>> for DVec<N>
} }
} }
impl<N: Neg<N>> Neg<DVec<N>> for DVec<N> impl<N: Neg<N>> Neg<DVec<N>> for DVec<N> {
{
#[inline] #[inline]
fn neg(&self) -> DVec<N> fn neg(&self) -> DVec<N> {
{ DVec { at: self.at.iter().transform(|a| -a).collect() } } DVec { at: self.at.iter().transform(|a| -a).collect() }
}
} }
impl<N: Ring> Dot<N> for DVec<N> impl<N: Ring> Dot<N> for DVec<N> {
{
#[inline] #[inline]
fn dot(&self, other: &DVec<N>) -> N fn dot(&self, other: &DVec<N>) -> N {
{
assert!(self.at.len() == other.at.len()); assert!(self.at.len() == other.at.len());
let mut res = Zero::zero::<N>(); let mut res = Zero::zero::<N>();
for i in range(0u, self.at.len()) for i in range(0u, self.at.len()) {
{ res = res + self.at[i] * other.at[i]; } res = res + self.at[i] * other.at[i];
}
res res
} }
} }
impl<N: Ring> SubDot<N> for DVec<N> impl<N: Ring> SubDot<N> for DVec<N> {
{
#[inline] #[inline]
fn sub_dot(&self, a: &DVec<N>, b: &DVec<N>) -> N fn sub_dot(&self, a: &DVec<N>, b: &DVec<N>) -> N {
{
let mut res = Zero::zero::<N>(); let mut res = Zero::zero::<N>();
for i in range(0u, self.at.len()) for i in range(0u, self.at.len()) {
{ res = res + (self.at[i] - a.at[i]) * b.at[i]; } res = res + (self.at[i] - a.at[i]) * b.at[i];
}
res res
} }
} }
impl<N: Mul<N, N>> ScalarMul<N> for DVec<N> impl<N: Mul<N, N>> ScalarMul<N> for DVec<N> {
{
#[inline] #[inline]
fn scalar_mul(&self, s: &N) -> DVec<N> fn scalar_mul(&self, s: &N) -> DVec<N> {
{ DVec { at: self.at.iter().transform(|a| a * *s).collect() } } DVec { at: self.at.iter().transform(|a| a * *s).collect() }
}
#[inline] #[inline]
fn scalar_mul_inplace(&mut self, s: &N) fn scalar_mul_inplace(&mut self, s: &N) {
{ for i in range(0u, self.at.len()) {
for i in range(0u, self.at.len()) self.at[i] = self.at[i] * *s;
{ self.at[i] = self.at[i] * *s; } }
} }
} }
impl<N: Div<N, N>> ScalarDiv<N> for DVec<N> impl<N: Div<N, N>> ScalarDiv<N> for DVec<N> {
{
#[inline] #[inline]
fn scalar_div(&self, s: &N) -> DVec<N> fn scalar_div(&self, s: &N) -> DVec<N> {
{ DVec { at: self.at.iter().transform(|a| a / *s).collect() } } DVec { at: self.at.iter().transform(|a| a / *s).collect() }
}
#[inline] #[inline]
fn scalar_div_inplace(&mut self, s: &N) fn scalar_div_inplace(&mut self, s: &N) {
{ for i in range(0u, self.at.len()) {
for i in range(0u, self.at.len()) self.at[i] = self.at[i] / *s;
{ self.at[i] = self.at[i] / *s; } }
} }
} }
impl<N: Add<N, N>> ScalarAdd<N> for DVec<N> impl<N: Add<N, N>> ScalarAdd<N> for DVec<N> {
{
#[inline] #[inline]
fn scalar_add(&self, s: &N) -> DVec<N> fn scalar_add(&self, s: &N) -> DVec<N> {
{ DVec { at: self.at.iter().transform(|a| a + *s).collect() } } DVec { at: self.at.iter().transform(|a| a + *s).collect() }
}
#[inline] #[inline]
fn scalar_add_inplace(&mut self, s: &N) fn scalar_add_inplace(&mut self, s: &N) {
{ for i in range(0u, self.at.len()) {
for i in range(0u, self.at.len()) self.at[i] = self.at[i] + *s;
{ self.at[i] = self.at[i] + *s; } }
} }
} }
impl<N: Sub<N, N>> ScalarSub<N> for DVec<N> impl<N: Sub<N, N>> ScalarSub<N> for DVec<N> {
{
#[inline] #[inline]
fn scalar_sub(&self, s: &N) -> DVec<N> fn scalar_sub(&self, s: &N) -> DVec<N> {
{ DVec { at: self.at.iter().transform(|a| a - *s).collect() } } DVec { at: self.at.iter().transform(|a| a - *s).collect() }
}
#[inline] #[inline]
fn scalar_sub_inplace(&mut self, s: &N) fn scalar_sub_inplace(&mut self, s: &N) {
{ for i in range(0u, self.at.len()) {
for i in range(0u, self.at.len()) self.at[i] = self.at[i] - *s;
{ self.at[i] = self.at[i] - *s; } }
} }
} }
impl<N: Add<N, N> + Neg<N> + Clone> Translation<DVec<N>> for DVec<N> impl<N: Add<N, N> + Neg<N> + Clone> Translation<DVec<N>> for DVec<N> {
{
#[inline] #[inline]
fn translation(&self) -> DVec<N> fn translation(&self) -> DVec<N> {
{ self.clone() } self.clone()
}
#[inline] #[inline]
fn inv_translation(&self) -> DVec<N> fn inv_translation(&self) -> DVec<N> {
{ -self } -self
}
#[inline] #[inline]
fn translate_by(&mut self, t: &DVec<N>) fn translate_by(&mut self, t: &DVec<N>) {
{ *self = *self + *t; } *self = *self + *t;
}
} }
impl<N: Add<N, N> + Neg<N> + Clone> Translatable<DVec<N>, DVec<N>> for DVec<N> impl<N: Add<N, N> + Neg<N> + Clone> Translatable<DVec<N>, DVec<N>> for DVec<N> {
{
#[inline] #[inline]
fn translated(&self, t: &DVec<N>) -> DVec<N> fn translated(&self, t: &DVec<N>) -> DVec<N> {
{ self + *t } self + *t
}
} }
impl<N: DivisionRing + Algebraic + Clone> Norm<N> for DVec<N> impl<N: DivisionRing + Algebraic + Clone> Norm<N> for DVec<N> {
{
#[inline] #[inline]
fn sqnorm(&self) -> N fn sqnorm(&self) -> N {
{ self.dot(self) } self.dot(self)
}
#[inline] #[inline]
fn norm(&self) -> N fn norm(&self) -> N {
{ self.sqnorm().sqrt() } self.sqnorm().sqrt()
}
#[inline] #[inline]
fn normalized(&self) -> DVec<N> fn normalized(&self) -> DVec<N> {
{
let mut res : DVec<N> = self.clone(); let mut res : DVec<N> = self.clone();
res.normalize(); res.normalize();
@ -275,36 +269,38 @@ impl<N: DivisionRing + Algebraic + Clone> Norm<N> for DVec<N>
} }
#[inline] #[inline]
fn normalize(&mut self) -> N fn normalize(&mut self) -> N {
{
let l = self.norm(); let l = self.norm();
for i in range(0u, self.at.len()) for i in range(0u, self.at.len()) {
{ self.at[i] = self.at[i] / l; } self.at[i] = self.at[i] / l;
}
l l
} }
} }
impl<N: ApproxEq<N>> ApproxEq<N> for DVec<N> impl<N: ApproxEq<N>> ApproxEq<N> for DVec<N> {
{
#[inline] #[inline]
fn approx_epsilon() -> N fn approx_epsilon() -> N {
{ ApproxEq::approx_epsilon::<N, N>() } ApproxEq::approx_epsilon::<N, N>()
#[inline]
fn approx_eq(&self, other: &DVec<N>) -> bool
{
let mut zip = self.at.iter().zip(other.at.iter());
do zip.all |(a, b)| { a.approx_eq(b) }
} }
#[inline] #[inline]
fn approx_eq_eps(&self, other: &DVec<N>, epsilon: &N) -> bool fn approx_eq(&self, other: &DVec<N>) -> bool {
{
let mut zip = self.at.iter().zip(other.at.iter()); let mut zip = self.at.iter().zip(other.at.iter());
do zip.all |(a, b)| { a.approx_eq_eps(b, epsilon) } do zip.all |(a, b)| {
a.approx_eq(b)
}
}
#[inline]
fn approx_eq_eps(&self, other: &DVec<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)
}
} }
} }

View File

@ -31,8 +31,7 @@ mod mat_macros;
/// Square matrix of dimension 1. /// Square matrix of dimension 1.
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] #[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
pub struct Mat1<N> pub struct Mat1<N> {
{
m11: N m11: N
} }
@ -56,8 +55,7 @@ from_homogeneous_impl!(Mat1, Mat2, 1, 2)
/// Square matrix of dimension 2. /// Square matrix of dimension 2.
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] #[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
pub struct Mat2<N> pub struct Mat2<N> {
{
m11: N, m12: N, m11: N, m12: N,
m21: N, m22: N m21: N, m22: N
} }
@ -85,8 +83,7 @@ from_homogeneous_impl!(Mat2, Mat3, 2, 3)
/// Square matrix of dimension 3. /// Square matrix of dimension 3.
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] #[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
pub struct Mat3<N> pub struct Mat3<N> {
{
m11: N, m12: N, m13: N, m11: N, m12: N, m13: N,
m21: N, m22: N, m23: N, m21: N, m22: N, m23: N,
m31: N, m32: N, m33: N m31: N, m32: N, m33: N
@ -118,8 +115,7 @@ from_homogeneous_impl!(Mat3, Mat4, 3, 4)
/// Square matrix of dimension 4. /// Square matrix of dimension 4.
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] #[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
pub struct Mat4<N> pub struct Mat4<N> {
{
m11: N, m12: N, m13: N, m14: N, m11: N, m12: N, m13: N, m14: N,
m21: N, m22: N, m23: N, m24: N, m21: N, m22: N, m23: N, m24: N,
m31: N, m32: N, m33: N, m34: N, m31: N, m32: N, m33: N, m34: N,
@ -159,8 +155,7 @@ from_homogeneous_impl!(Mat4, Mat5, 4, 5)
/// Square matrix of dimension 5. /// Square matrix of dimension 5.
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] #[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
pub struct Mat5<N> pub struct Mat5<N> {
{
m11: N, m12: N, m13: N, m14: N, m15: N, m11: N, m12: N, m13: N, m14: N, m15: N,
m21: N, m22: N, m23: N, m24: N, m25: N, m21: N, m22: N, m23: N, m24: N, m25: N,
m31: N, m32: N, m33: N, m34: N, m35: N, m31: N, m32: N, m33: N, m34: N, m35: N,
@ -206,8 +201,7 @@ from_homogeneous_impl!(Mat5, Mat6, 5, 6)
/// Square matrix of dimension 6. /// Square matrix of dimension 6.
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] #[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
pub struct Mat6<N> pub struct Mat6<N> {
{
m11: N, m12: N, m13: N, m14: N, m15: N, m16: N, m11: N, m12: N, m13: N, m14: N, m15: N, m16: N,
m21: N, m22: N, m23: N, m24: N, m25: N, m26: N, m21: N, m22: N, m23: N, m24: N, m25: N, m26: N,
m31: N, m32: N, m33: N, m34: N, m35: N, m36: N, m31: N, m32: N, m33: N, m34: N, m35: N, m36: N,

View File

@ -2,11 +2,9 @@
macro_rules! mat_impl( macro_rules! mat_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N> $t<N> impl<N> $t<N> {
{
#[inline] #[inline]
pub fn new($comp0: N $(, $compN: N )*) -> $t<N> pub fn new($comp0: N $(, $compN: N )*) -> $t<N> {
{
$t { $t {
$comp0: $comp0 $comp0: $comp0
$(, $compN: $compN )* $(, $compN: $compN )*
@ -18,42 +16,44 @@ macro_rules! mat_impl(
macro_rules! mat_cast_impl( macro_rules! mat_cast_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<Nin: NumCast + Clone, Nout: NumCast> MatCast<$t<Nout>> for $t<Nin> impl<Nin: NumCast + Clone, Nout: NumCast> MatCast<$t<Nout>> for $t<Nin> {
{
#[inline] #[inline]
pub fn from(m: $t<Nin>) -> $t<Nout> pub fn from(m: $t<Nin>) -> $t<Nout> {
{ $t::new(NumCast::from(m.$comp0.clone()) $(, NumCast::from(m.$compN.clone()) )*) } $t::new(NumCast::from(m.$comp0.clone()) $(, NumCast::from(m.$compN.clone()) )*)
}
} }
) )
) )
macro_rules! iterable_impl( macro_rules! iterable_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N> Iterable<N> for $t<N> impl<N> Iterable<N> for $t<N> {
{ fn iter<'l>(&'l self) -> VecIterator<'l, N> {
fn iter<'l>(&'l self) -> VecIterator<'l, N> unsafe {
{ unsafe { cast::transmute::<&'l $t<N>, &'l [N, ..$dim * $dim]>(self).iter() } } cast::transmute::<&'l $t<N>, &'l [N, ..$dim * $dim]>(self).iter()
}
}
} }
) )
) )
macro_rules! iterable_mut_impl( macro_rules! iterable_mut_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N> IterableMut<N> for $t<N> impl<N> IterableMut<N> for $t<N> {
{ fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> {
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> unsafe {
{ unsafe { cast::transmute::<&'l mut $t<N>, &'l mut [N, ..$dim * $dim]>(self).mut_iter() } } cast::transmute::<&'l mut $t<N>, &'l mut [N, ..$dim * $dim]>(self).mut_iter()
}
}
} }
) )
) )
macro_rules! one_impl( macro_rules! one_impl(
($t: ident, $value0: ident $(, $valueN: ident)* ) => ( ($t: ident, $value0: ident $(, $valueN: ident)* ) => (
impl<N: Clone + One + Zero> One for $t<N> impl<N: Clone + One + Zero> One for $t<N> {
{
#[inline] #[inline]
fn one() -> $t<N> fn one() -> $t<N> {
{
let (_0, _1) = (Zero::zero::<N>(), One::one::<N>()); let (_0, _1) = (Zero::zero::<N>(), One::one::<N>());
return $t::new($value0.clone() $(, $valueN.clone() )*) return $t::new($value0.clone() $(, $valueN.clone() )*)
} }
@ -63,30 +63,34 @@ macro_rules! one_impl(
macro_rules! dim_impl( macro_rules! dim_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N> Dim for $t<N> impl<N> Dim for $t<N> {
{
#[inline] #[inline]
fn dim() -> uint fn dim() -> uint {
{ $dim } $dim
}
} }
) )
) )
macro_rules! indexable_impl( macro_rules! indexable_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N: Clone> Indexable<(uint, uint), N> for $t<N> impl<N: Clone> Indexable<(uint, uint), N> for $t<N> {
{
#[inline] #[inline]
pub fn at(&self, (i, j): (uint, uint)) -> N pub fn at(&self, (i, j): (uint, uint)) -> N {
{ unsafe { cast::transmute::<&$t<N>, &[N, ..$dim * $dim]>(self)[i * $dim + j].clone() } } unsafe {
cast::transmute::<&$t<N>, &[N, ..$dim * $dim]>(self)[i * $dim + j].clone()
}
}
#[inline] #[inline]
pub fn set(&mut self, (i, j): (uint, uint), val: N) pub fn set(&mut self, (i, j): (uint, uint), val: N) {
{ unsafe { cast::transmute::<&mut $t<N>, &mut [N, ..$dim * $dim]>(self)[i * $dim + j] = val } } unsafe {
cast::transmute::<&mut $t<N>, &mut [N, ..$dim * $dim]>(self)[i * $dim + j] = val
}
}
#[inline] #[inline]
pub fn swap(&mut self, (i1, j1): (uint, uint), (i2, j2): (uint, uint)) pub fn swap(&mut self, (i1, j1): (uint, uint), (i2, j2): (uint, uint)) {
{
unsafe { unsafe {
cast::transmute::<&mut $t<N>, &mut [N, ..$dim * $dim]>(self) cast::transmute::<&mut $t<N>, &mut [N, ..$dim * $dim]>(self)
.swap(i1 * $dim + j1, i2 * $dim + j2) .swap(i1 * $dim + j1, i2 * $dim + j2)
@ -98,27 +102,24 @@ macro_rules! indexable_impl(
macro_rules! column_impl( macro_rules! column_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N: Clone, V: Zero + Iterable<N> + IterableMut<N>> Column<V> for $t<N> impl<N: Clone, V: Zero + Iterable<N> + IterableMut<N>> Column<V> for $t<N> {
{ fn set_column(&mut self, col: uint, v: V) {
fn set_column(&mut self, col: uint, v: V) for (i, e) in v.iter().enumerate() {
{ if i == Dim::dim::<$t<N>>() {
for (i, e) in v.iter().enumerate() break
{ }
if i == Dim::dim::<$t<N>>()
{ break }
self.set((i, col), e.clone()); self.set((i, col), e.clone());
} }
} }
fn column(&self, col: uint) -> V fn column(&self, col: uint) -> V {
{
let mut res = Zero::zero::<V>(); let mut res = Zero::zero::<V>();
for (i, e) in res.mut_iter().enumerate() for (i, e) in res.mut_iter().enumerate() {
{ if i >= Dim::dim::<$t<N>>() {
if i >= Dim::dim::<$t<N>>() break
{ break } }
*e = self.at((i, col)); *e = self.at((i, col));
} }
@ -131,20 +132,17 @@ macro_rules! column_impl(
macro_rules! mul_impl( macro_rules! mul_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N: Clone + Ring> Mul<$t<N>, $t<N>> for $t<N> impl<N: Clone + Ring> Mul<$t<N>, $t<N>> for $t<N> {
{ fn mul(&self, other: &$t<N>) -> $t<N> {
fn mul(&self, other: &$t<N>) -> $t<N>
{
let mut res: $t<N> = Zero::zero(); let mut res: $t<N> = Zero::zero();
for i in range(0u, $dim) for i in range(0u, $dim) {
{ for j in range(0u, $dim) {
for j in range(0u, $dim)
{
let mut acc = Zero::zero::<N>(); let mut acc = Zero::zero::<N>();
for k in range(0u, $dim) for k in range(0u, $dim) {
{ acc = acc + self.at((i, k)) * other.at((k, j)); } acc = acc + self.at((i, k)) * other.at((k, j));
}
res.set((i, j), acc); res.set((i, j), acc);
} }
@ -158,16 +156,12 @@ macro_rules! mul_impl(
macro_rules! rmul_impl( macro_rules! rmul_impl(
($t: ident, $v: ident, $dim: expr) => ( ($t: ident, $v: ident, $dim: expr) => (
impl<N: Clone + Ring> RMul<$v<N>> for $t<N> impl<N: Clone + Ring> RMul<$v<N>> for $t<N> {
{ fn rmul(&self, other: &$v<N>) -> $v<N> {
fn rmul(&self, other: &$v<N>) -> $v<N>
{
let mut res : $v<N> = Zero::zero(); let mut res : $v<N> = Zero::zero();
for i in range(0u, $dim) for i in range(0u, $dim) {
{ for j in range(0u, $dim) {
for j in range(0u, $dim)
{
let val = res.at(i) + other.at(j) * self.at((i, j)); let val = res.at(i) + other.at(j) * self.at((i, j));
res.set(i, val) res.set(i, val)
} }
@ -181,16 +175,12 @@ macro_rules! rmul_impl(
macro_rules! lmul_impl( macro_rules! lmul_impl(
($t: ident, $v: ident, $dim: expr) => ( ($t: ident, $v: ident, $dim: expr) => (
impl<N: Clone + Ring> LMul<$v<N>> for $t<N> impl<N: Clone + Ring> LMul<$v<N>> for $t<N> {
{ fn lmul(&self, other: &$v<N>) -> $v<N> {
fn lmul(&self, other: &$v<N>) -> $v<N>
{
let mut res : $v<N> = Zero::zero(); let mut res : $v<N> = Zero::zero();
for i in range(0u, $dim) for i in range(0u, $dim) {
{ for j in range(0u, $dim) {
for j in range(0u, $dim)
{
let val = res.at(i) + other.at(j) * self.at((j, i)); let val = res.at(i) + other.at(j) * self.at((j, i));
res.set(i, val) res.set(i, val)
} }
@ -205,17 +195,15 @@ macro_rules! lmul_impl(
macro_rules! transform_impl( macro_rules! transform_impl(
($t: ident, $v: ident) => ( ($t: ident, $v: ident) => (
impl<N: Clone + DivisionRing + Eq> impl<N: Clone + DivisionRing + Eq>
Transform<$v<N>> for $t<N> Transform<$v<N>> for $t<N> {
{
#[inline] #[inline]
fn transform_vec(&self, v: &$v<N>) -> $v<N> fn transform_vec(&self, v: &$v<N>) -> $v<N> {
{ self.rmul(v) } self.rmul(v)
}
#[inline] #[inline]
fn inv_transform(&self, v: &$v<N>) -> $v<N> fn inv_transform(&self, v: &$v<N>) -> $v<N> {
{ match self.inverse() {
match self.inverse()
{
Some(t) => t.transform_vec(v), Some(t) => t.transform_vec(v),
None => fail!("Cannot use inv_transform on a non-inversible matrix.") None => fail!("Cannot use inv_transform on a non-inversible matrix.")
} }
@ -227,49 +215,46 @@ macro_rules! transform_impl(
macro_rules! inv_impl( macro_rules! inv_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N: Clone + Eq + DivisionRing> impl<N: Clone + Eq + DivisionRing>
Inv for $t<N> Inv for $t<N> {
{
#[inline] #[inline]
fn inverse(&self) -> Option<$t<N>> fn inverse(&self) -> Option<$t<N>> {
{
let mut res : $t<N> = self.clone(); let mut res : $t<N> = self.clone();
if res.inplace_inverse() if res.inplace_inverse() {
{ Some(res) } Some(res)
else }
{ None } else {
None
}
} }
fn inplace_inverse(&mut self) -> bool fn inplace_inverse(&mut self) -> bool {
{
let mut res: $t<N> = One::one(); let mut res: $t<N> = One::one();
let _0N: N = Zero::zero(); let _0N: N = Zero::zero();
// inversion using Gauss-Jordan elimination // inversion using Gauss-Jordan elimination
for k in range(0u, $dim) for k in range(0u, $dim) {
{
// search a non-zero value on the k-th column // search a non-zero value on the k-th column
// FIXME: would it be worth it to spend some more time searching for the // FIXME: would it be worth it to spend some more time searching for the
// max instead? // max instead?
let mut n0 = k; // index of a non-zero entry let mut n0 = k; // index of a non-zero entry
while (n0 != $dim) while (n0 != $dim) {
{ if self.at((n0, k)) != _0N {
if self.at((n0, k)) != _0N break;
{ break; } }
n0 = n0 + 1; n0 = n0 + 1;
} }
if n0 == $dim if n0 == $dim {
{ return false } return false
}
// swap pivot line // swap pivot line
if n0 != k if n0 != k {
{ for j in range(0u, $dim) {
for j in range(0u, $dim)
{
self.swap((n0, j), (k, j)); self.swap((n0, j), (k, j));
res.swap((n0, j), (k, j)); res.swap((n0, j), (k, j));
} }
@ -277,32 +262,26 @@ macro_rules! inv_impl(
let pivot = self.at((k, k)); let pivot = self.at((k, k));
for j in range(k, $dim) for j in range(k, $dim) {
{
let selfval = self.at((k, j)) / pivot; let selfval = self.at((k, j)) / pivot;
self.set((k, j), selfval); self.set((k, j), selfval);
} }
for j in range(0u, $dim) for j in range(0u, $dim) {
{
let resval = res.at((k, j)) / pivot; let resval = res.at((k, j)) / pivot;
res.set((k, j), resval); res.set((k, j), resval);
} }
for l in range(0u, $dim) for l in range(0u, $dim) {
{ if l != k {
if l != k
{
let normalizer = self.at((l, k)); let normalizer = self.at((l, k));
for j in range(k, $dim) for j in range(k, $dim) {
{
let selfval = self.at((l, j)) - self.at((k, j)) * normalizer; let selfval = self.at((l, j)) - self.at((k, j)) * normalizer;
self.set((l, j), selfval); self.set((l, j), selfval);
} }
for j in range(0u, $dim) for j in range(0u, $dim) {
{
let resval = res.at((l, j)) - res.at((k, j)) * normalizer; let resval = res.at((l, j)) - res.at((k, j)) * normalizer;
res.set((l, j), resval); res.set((l, j), resval);
} }
@ -320,11 +299,9 @@ macro_rules! inv_impl(
macro_rules! transpose_impl( macro_rules! transpose_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N: Clone> Transpose for $t<N> impl<N: Clone> Transpose for $t<N> {
{
#[inline] #[inline]
fn transposed(&self) -> $t<N> fn transposed(&self) -> $t<N> {
{
let mut res = self.clone(); let mut res = self.clone();
res.transpose(); res.transpose();
@ -332,12 +309,11 @@ macro_rules! transpose_impl(
res res
} }
fn transpose(&mut self) fn transpose(&mut self) {
{ for i in range(1u, $dim) {
for i in range(1u, $dim) for j in range(0u, i) {
{ self.swap((i, j), (j, i))
for j in range(0u, i) }
{ self.swap((i, j), (j, i)) }
} }
} }
} }
@ -346,26 +322,28 @@ macro_rules! transpose_impl(
macro_rules! approx_eq_impl( macro_rules! approx_eq_impl(
($t: ident) => ( ($t: ident) => (
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
{
#[inline] #[inline]
fn approx_epsilon() -> N fn approx_epsilon() -> N {
{ ApproxEq::approx_epsilon::<N, N>() } ApproxEq::approx_epsilon::<N, N>()
#[inline]
fn approx_eq(&self, other: &$t<N>) -> bool
{
let mut zip = self.iter().zip(other.iter());
do zip.all |(a, b)| { a.approx_eq(b) }
} }
#[inline] #[inline]
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N) -> bool fn approx_eq(&self, other: &$t<N>) -> bool {
{
let mut zip = self.iter().zip(other.iter()); let mut zip = self.iter().zip(other.iter());
do zip.all |(a, b)| { a.approx_eq_eps(b, epsilon) } 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.iter().zip(other.iter());
do zip.all |(a, b)| {
a.approx_eq_eps(b, epsilon)
}
} }
} }
) )
@ -373,16 +351,14 @@ macro_rules! approx_eq_impl(
macro_rules! to_homogeneous_impl( macro_rules! to_homogeneous_impl(
($t: ident, $t2: ident, $dim: expr, $dim2: expr) => ( ($t: ident, $t2: ident, $dim: expr, $dim2: expr) => (
impl<N: One + Zero + Clone> ToHomogeneous<$t2<N>> for $t<N> impl<N: One + Zero + Clone> ToHomogeneous<$t2<N>> for $t<N> {
{ fn to_homogeneous(&self) -> $t2<N> {
fn to_homogeneous(&self) -> $t2<N>
{
let mut res: $t2<N> = One::one(); let mut res: $t2<N> = One::one();
for i in range(0u, $dim) for i in range(0u, $dim) {
{ for j in range(0u, $dim) {
for j in range(0u, $dim) res.set((i, j), self.at((i, j)))
{ res.set((i, j), self.at((i, j))) } }
} }
res res
@ -393,16 +369,14 @@ macro_rules! to_homogeneous_impl(
macro_rules! from_homogeneous_impl( macro_rules! from_homogeneous_impl(
($t: ident, $t2: ident, $dim: expr, $dim2: expr) => ( ($t: ident, $t2: ident, $dim: expr, $dim2: expr) => (
impl<N: One + Zero + Clone> FromHomogeneous<$t2<N>> for $t<N> impl<N: One + Zero + Clone> FromHomogeneous<$t2<N>> for $t<N> {
{ fn from(m: &$t2<N>) -> $t<N> {
fn from(m: &$t2<N>) -> $t<N>
{
let mut res: $t<N> = One::one(); let mut res: $t<N> = One::one();
for i in range(0u, $dim2) for i in range(0u, $dim2) {
{ for j in range(0u, $dim2) {
for j in range(0u, $dim2) res.set((i, j), m.at((i, j)))
{ res.set((i, j), m.at((i, j))) } }
} }
// FIXME: do we have to deal the lost components // FIXME: do we have to deal the lost components

View File

@ -5,26 +5,25 @@ use traits::inv::Inv;
// some specializations: // some specializations:
impl<N: DivisionRing + Clone> impl<N: DivisionRing + Clone>
Inv for Mat1<N> Inv for Mat1<N> {
{
#[inline] #[inline]
fn inverse(&self) -> Option<Mat1<N>> fn inverse(&self) -> Option<Mat1<N>> {
{
let mut res : Mat1<N> = self.clone(); let mut res : Mat1<N> = self.clone();
if res.inplace_inverse() if res.inplace_inverse() {
{ Some(res) } Some(res)
else }
{ None } else {
None
}
} }
#[inline] #[inline]
fn inplace_inverse(&mut self) -> bool fn inplace_inverse(&mut self) -> bool {
{ if self.m11.is_zero() {
if self.m11.is_zero() false
{ false } }
else else {
{
self.m11 = One::one::<N>() / self.m11; self.m11 = One::one::<N>() / self.m11;
true true
} }
@ -32,28 +31,27 @@ Inv for Mat1<N>
} }
impl<N: DivisionRing + Clone> impl<N: DivisionRing + Clone>
Inv for Mat2<N> Inv for Mat2<N> {
{
#[inline] #[inline]
fn inverse(&self) -> Option<Mat2<N>> fn inverse(&self) -> Option<Mat2<N>> {
{
let mut res : Mat2<N> = self.clone(); let mut res : Mat2<N> = self.clone();
if res.inplace_inverse() if res.inplace_inverse() {
{ Some(res) } Some(res)
else }
{ None } else {
None
}
} }
#[inline] #[inline]
fn inplace_inverse(&mut self) -> bool fn inplace_inverse(&mut self) -> bool {
{
let det = self.m11 * self.m22 - self.m21 * self.m12; let det = self.m11 * self.m22 - self.m21 * self.m12;
if det.is_zero() if det.is_zero() {
{ false } false
else }
{ else {
*self = Mat2::new(self.m22 / det , -self.m12 / det, *self = Mat2::new(self.m22 / det , -self.m12 / det,
-self.m21 / det, self.m11 / det); -self.m21 / det, self.m11 / det);
@ -63,22 +61,21 @@ Inv for Mat2<N>
} }
impl<N: DivisionRing + Clone> impl<N: DivisionRing + Clone>
Inv for Mat3<N> Inv for Mat3<N> {
{
#[inline] #[inline]
fn inverse(&self) -> Option<Mat3<N>> fn inverse(&self) -> Option<Mat3<N>> {
{
let mut res = self.clone(); let mut res = self.clone();
if res.inplace_inverse() if res.inplace_inverse() {
{ Some(res) } Some(res)
else }
{ None } else {
None
}
} }
#[inline] #[inline]
fn inplace_inverse(&mut self) -> bool fn inplace_inverse(&mut self) -> bool {
{
let minor_m12_m23 = self.m22 * self.m33 - self.m32 * self.m23; let minor_m12_m23 = self.m22 * self.m33 - self.m32 * self.m23;
let minor_m11_m23 = self.m21 * self.m33 - self.m31 * self.m23; let minor_m11_m23 = self.m21 * self.m33 - self.m31 * self.m23;
let minor_m11_m22 = self.m21 * self.m32 - self.m31 * self.m22; let minor_m11_m22 = self.m21 * self.m32 - self.m31 * self.m22;
@ -87,10 +84,10 @@ Inv for Mat3<N>
- self.m12 * minor_m11_m23 - self.m12 * minor_m11_m23
+ self.m13 * minor_m11_m22; + self.m13 * minor_m11_m22;
if det.is_zero() if det.is_zero() {
{ false } false
else }
{ else {
*self = Mat3::new( *self = Mat3::new(
(minor_m12_m23 / det), (minor_m12_m23 / det),
((self.m13 * self.m32 - self.m33 * self.m12) / det), ((self.m13 * self.m32 - self.m33 * self.m12) / det),

View File

@ -25,8 +25,7 @@ use adaptors::rotmat::Rotmat;
macro_rules! test_inv_mat_impl( macro_rules! test_inv_mat_impl(
($t: ty) => ( ($t: ty) => (
do 10000.times do 10000.times {
{
let randmat : $t = random(); let randmat : $t = random();
assert!((randmat.inverse().unwrap() * randmat).approx_eq(&One::one())); assert!((randmat.inverse().unwrap() * randmat).approx_eq(&One::one()));
@ -36,8 +35,7 @@ macro_rules! test_inv_mat_impl(
macro_rules! test_transpose_mat_impl( macro_rules! test_transpose_mat_impl(
($t: ty) => ( ($t: ty) => (
do 10000.times do 10000.times {
{
let randmat : $t = random(); let randmat : $t = random();
assert!(randmat.transposed().transposed().eq(&randmat)); assert!(randmat.transposed().transposed().eq(&randmat));
@ -46,58 +44,68 @@ macro_rules! test_transpose_mat_impl(
) )
#[test] #[test]
fn test_transpose_mat1() fn test_transpose_mat1() {
{ test_transpose_mat_impl!(Mat1<f64>); } test_transpose_mat_impl!(Mat1<f64>);
}
#[test] #[test]
fn test_transpose_mat2() fn test_transpose_mat2() {
{ test_transpose_mat_impl!(Mat2<f64>); } test_transpose_mat_impl!(Mat2<f64>);
}
#[test] #[test]
fn test_transpose_mat3() fn test_transpose_mat3() {
{ test_transpose_mat_impl!(Mat3<f64>); } test_transpose_mat_impl!(Mat3<f64>);
}
#[test] #[test]
fn test_transpose_mat4() fn test_transpose_mat4() {
{ test_transpose_mat_impl!(Mat4<f64>); } test_transpose_mat_impl!(Mat4<f64>);
}
#[test] #[test]
fn test_transpose_mat5() fn test_transpose_mat5() {
{ test_transpose_mat_impl!(Mat5<f64>); } test_transpose_mat_impl!(Mat5<f64>);
}
#[test] #[test]
fn test_transpose_mat6() fn test_transpose_mat6() {
{ test_transpose_mat_impl!(Mat6<f64>); } test_transpose_mat_impl!(Mat6<f64>);
}
#[test] #[test]
fn test_inv_mat1() fn test_inv_mat1() {
{ test_inv_mat_impl!(Mat1<f64>); } test_inv_mat_impl!(Mat1<f64>);
}
#[test] #[test]
fn test_inv_mat2() fn test_inv_mat2() {
{ test_inv_mat_impl!(Mat2<f64>); } test_inv_mat_impl!(Mat2<f64>);
}
#[test] #[test]
fn test_inv_mat3() fn test_inv_mat3() {
{ test_inv_mat_impl!(Mat3<f64>); } test_inv_mat_impl!(Mat3<f64>);
}
#[test] #[test]
fn test_inv_mat4() fn test_inv_mat4() {
{ test_inv_mat_impl!(Mat4<f64>); } test_inv_mat_impl!(Mat4<f64>);
}
#[test] #[test]
fn test_inv_mat5() fn test_inv_mat5() {
{ test_inv_mat_impl!(Mat5<f64>); } test_inv_mat_impl!(Mat5<f64>);
}
#[test] #[test]
fn test_inv_mat6() fn test_inv_mat6() {
{ test_inv_mat_impl!(Mat6<f64>); } test_inv_mat_impl!(Mat6<f64>);
}
#[test] #[test]
fn test_rotation2() fn test_rotation2() {
{ do 10000.times {
do 10000.times
{
let randmat = One::one::<Rotmat<Mat2<f64>>>(); 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());
@ -106,18 +114,15 @@ fn test_rotation2()
} }
#[test] #[test]
fn test_index_mat2() fn test_index_mat2() {
{
let mat: Mat2<f64> = random(); let mat: Mat2<f64> = random();
assert!(mat.at((0, 1)) == mat.transposed().at((1, 0))); assert!(mat.at((0, 1)) == mat.transposed().at((1, 0)));
} }
#[test] #[test]
fn test_inv_rotation3() fn test_inv_rotation3() {
{ do 10000.times {
do 10000.times
{
let randmat = One::one::<Rotmat<Mat3<f64>>>(); let randmat = One::one::<Rotmat<Mat3<f64>>>();
let dir: Vec3<f64> = random(); let dir: Vec3<f64> = random();
let ang = &dir.normalized().scalar_mul(&(abs::<f64>(random()) % Real::pi())); let ang = &dir.normalized().scalar_mul(&(abs::<f64>(random()) % Real::pi()));

View File

@ -23,16 +23,16 @@ use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
macro_rules! test_iterator_impl( macro_rules! test_iterator_impl(
($t: ty, $n: ty) => ( ($t: ty, $n: ty) => (
do 10000.times do 10000.times {
{
let v: $t = random(); let v: $t = random();
let mut mv: $t = v.clone(); let mut mv: $t = v.clone();
let n: $n = random(); let n: $n = random();
let nv: $t = v.iter().transform(|e| e * n).collect(); let nv: $t = v.iter().transform(|e| e * n).collect();
for e in mv.mut_iter() for e in mv.mut_iter() {
{ *e = *e * n } *e = *e * n
}
assert!(nv == mv && nv == v.scalar_mul(&n)); assert!(nv == mv && nv == v.scalar_mul(&n));
} }
@ -41,8 +41,7 @@ macro_rules! test_iterator_impl(
macro_rules! test_commut_dot_impl( macro_rules! test_commut_dot_impl(
($t: ty) => ( ($t: ty) => (
do 10000.times do 10000.times {
{
let v1 : $t = random(); let v1 : $t = random();
let v2 : $t = random(); let v2 : $t = random();
@ -53,8 +52,7 @@ macro_rules! test_commut_dot_impl(
macro_rules! test_scalar_op_impl( macro_rules! test_scalar_op_impl(
($t: ty, $n: ty) => ( ($t: ty, $n: ty) => (
do 10000.times do 10000.times {
{
let v1 : $t = random(); let v1 : $t = random();
let n : $n = random(); let n : $n = random();
@ -77,12 +75,11 @@ macro_rules! test_scalar_op_impl(
macro_rules! test_basis_impl( macro_rules! test_basis_impl(
($t: ty) => ( ($t: ty) => (
do 10000.times do 10000.times {
{ do Basis::canonical_basis::<$t> |e1| {
do Basis::canonical_basis::<$t> |e1| do Basis::canonical_basis::<$t> |e2| {
{ assert!(e1 == e2 || e1.dot(&e2).approx_eq(&Zero::zero()))
do Basis::canonical_basis::<$t> |e2| }
{ assert!(e1 == e2 || e1.dot(&e2).approx_eq(&Zero::zero())) }
assert!(e1.norm().approx_eq(&One::one())); assert!(e1.norm().approx_eq(&One::one()));
} }
@ -92,30 +89,27 @@ macro_rules! test_basis_impl(
macro_rules! test_subspace_basis_impl( macro_rules! test_subspace_basis_impl(
($t: ty) => ( ($t: ty) => (
do 10000.times do 10000.times {
{
let v : $t = random(); let v : $t = random();
let v1 = v.normalized(); let v1 = v.normalized();
do v1.orthonormal_subspace_basis() |e1| do v1.orthonormal_subspace_basis() |e1| {
{
// check vectors are orthogonal to v1 // check vectors are orthogonal to v1
assert!(v1.dot(&e1).approx_eq(&Zero::zero())); assert!(v1.dot(&e1).approx_eq(&Zero::zero()));
// check vectors form an orthonormal basis // check vectors form an orthonormal basis
assert!(e1.norm().approx_eq(&One::one())); assert!(e1.norm().approx_eq(&One::one()));
// check vectors form an ortogonal basis // check vectors form an ortogonal basis
do v1.orthonormal_subspace_basis() |e2| do v1.orthonormal_subspace_basis() |e2| {
{ assert!(e1 == e2 || e1.dot(&e2).approx_eq(&Zero::zero())) } assert!(e1 == e2 || e1.dot(&e2).approx_eq(&Zero::zero()))
}
} }
} }
); );
) )
#[test] #[test]
fn test_cross_vec3() fn test_cross_vec3() {
{ do 10000.times {
do 10000.times
{
let v1 : Vec3<f64> = random(); let v1 : Vec3<f64> = random();
let v2 : Vec3<f64> = random(); let v2 : Vec3<f64> = random();
let v3 : Vec3<f64> = v1.cross(&v2); let v3 : Vec3<f64> = v1.cross(&v2);
@ -126,148 +120,182 @@ fn test_cross_vec3()
} }
#[test] #[test]
fn test_commut_dot_vec0() fn test_commut_dot_vec0() {
{ test_commut_dot_impl!(Vec0<f64>); } test_commut_dot_impl!(Vec0<f64>);
}
#[test] #[test]
fn test_commut_dot_vec1() fn test_commut_dot_vec1() {
{ test_commut_dot_impl!(Vec1<f64>); } test_commut_dot_impl!(Vec1<f64>);
}
#[test] #[test]
fn test_commut_dot_vec2() fn test_commut_dot_vec2() {
{ test_commut_dot_impl!(Vec2<f64>); } test_commut_dot_impl!(Vec2<f64>);
}
#[test] #[test]
fn test_commut_dot_vec3() fn test_commut_dot_vec3() {
{ test_commut_dot_impl!(Vec3<f64>); } test_commut_dot_impl!(Vec3<f64>);
}
#[test] #[test]
fn test_commut_dot_vec4() fn test_commut_dot_vec4() {
{ test_commut_dot_impl!(Vec4<f64>); } test_commut_dot_impl!(Vec4<f64>);
}
#[test] #[test]
fn test_commut_dot_vec5() fn test_commut_dot_vec5() {
{ test_commut_dot_impl!(Vec5<f64>); } test_commut_dot_impl!(Vec5<f64>);
}
#[test] #[test]
fn test_commut_dot_vec6() fn test_commut_dot_vec6() {
{ test_commut_dot_impl!(Vec6<f64>); } test_commut_dot_impl!(Vec6<f64>);
}
#[test] #[test]
fn test_basis_vec0() fn test_basis_vec0() {
{ test_basis_impl!(Vec0<f64>); } test_basis_impl!(Vec0<f64>);
}
#[test] #[test]
fn test_basis_vec1() fn test_basis_vec1() {
{ test_basis_impl!(Vec1<f64>); } test_basis_impl!(Vec1<f64>);
}
#[test] #[test]
fn test_basis_vec2() fn test_basis_vec2() {
{ test_basis_impl!(Vec2<f64>); } test_basis_impl!(Vec2<f64>);
}
#[test] #[test]
fn test_basis_vec3() fn test_basis_vec3() {
{ test_basis_impl!(Vec3<f64>); } test_basis_impl!(Vec3<f64>);
}
#[test] #[test]
fn test_basis_vec4() fn test_basis_vec4() {
{ test_basis_impl!(Vec4<f64>); } test_basis_impl!(Vec4<f64>);
}
#[test] #[test]
fn test_basis_vec5() fn test_basis_vec5() {
{ test_basis_impl!(Vec5<f64>); } test_basis_impl!(Vec5<f64>);
}
#[test] #[test]
fn test_basis_vec6() fn test_basis_vec6() {
{ test_basis_impl!(Vec6<f64>); } test_basis_impl!(Vec6<f64>);
}
#[test] #[test]
fn test_subspace_basis_vec0() fn test_subspace_basis_vec0() {
{ test_subspace_basis_impl!(Vec0<f64>); } test_subspace_basis_impl!(Vec0<f64>);
}
#[test] #[test]
fn test_subspace_basis_vec1() fn test_subspace_basis_vec1() {
{ test_subspace_basis_impl!(Vec1<f64>); } test_subspace_basis_impl!(Vec1<f64>);
}
#[test] #[test]
fn test_subspace_basis_vec2() fn test_subspace_basis_vec2() {
{ test_subspace_basis_impl!(Vec2<f64>); } test_subspace_basis_impl!(Vec2<f64>);
}
#[test] #[test]
fn test_subspace_basis_vec3() fn test_subspace_basis_vec3() {
{ test_subspace_basis_impl!(Vec3<f64>); } test_subspace_basis_impl!(Vec3<f64>);
}
#[test] #[test]
fn test_subspace_basis_vec4() fn test_subspace_basis_vec4() {
{ test_subspace_basis_impl!(Vec4<f64>); } test_subspace_basis_impl!(Vec4<f64>);
}
#[test] #[test]
fn test_subspace_basis_vec5() fn test_subspace_basis_vec5() {
{ test_subspace_basis_impl!(Vec5<f64>); } test_subspace_basis_impl!(Vec5<f64>);
}
#[test] #[test]
fn test_subspace_basis_vec6() fn test_subspace_basis_vec6() {
{ test_subspace_basis_impl!(Vec6<f64>); } test_subspace_basis_impl!(Vec6<f64>);
}
#[test] #[test]
fn test_scalar_op_vec0() fn test_scalar_op_vec0() {
{ test_scalar_op_impl!(Vec0<f64>, f64); } test_scalar_op_impl!(Vec0<f64>, f64);
}
#[test] #[test]
fn test_scalar_op_vec1() fn test_scalar_op_vec1() {
{ test_scalar_op_impl!(Vec1<f64>, f64); } test_scalar_op_impl!(Vec1<f64>, f64);
}
#[test] #[test]
fn test_scalar_op_vec2() fn test_scalar_op_vec2() {
{ test_scalar_op_impl!(Vec2<f64>, f64); } test_scalar_op_impl!(Vec2<f64>, f64);
}
#[test] #[test]
fn test_scalar_op_vec3() fn test_scalar_op_vec3() {
{ test_scalar_op_impl!(Vec3<f64>, f64); } test_scalar_op_impl!(Vec3<f64>, f64);
}
#[test] #[test]
fn test_scalar_op_vec4() fn test_scalar_op_vec4() {
{ test_scalar_op_impl!(Vec4<f64>, f64); } test_scalar_op_impl!(Vec4<f64>, f64);
}
#[test] #[test]
fn test_scalar_op_vec5() fn test_scalar_op_vec5() {
{ test_scalar_op_impl!(Vec5<f64>, f64); } test_scalar_op_impl!(Vec5<f64>, f64);
}
#[test] #[test]
fn test_scalar_op_vec6() fn test_scalar_op_vec6() {
{ test_scalar_op_impl!(Vec6<f64>, f64); } test_scalar_op_impl!(Vec6<f64>, f64);
}
#[test] #[test]
fn test_iterator_vec0() fn test_iterator_vec0() {
{ test_iterator_impl!(Vec0<f64>, f64); } test_iterator_impl!(Vec0<f64>, f64);
}
#[test] #[test]
fn test_iterator_vec1() fn test_iterator_vec1() {
{ test_iterator_impl!(Vec1<f64>, f64); } test_iterator_impl!(Vec1<f64>, f64);
}
#[test] #[test]
fn test_iterator_vec2() fn test_iterator_vec2() {
{ test_iterator_impl!(Vec2<f64>, f64); } test_iterator_impl!(Vec2<f64>, f64);
}
#[test] #[test]
fn test_iterator_vec3() fn test_iterator_vec3() {
{ test_iterator_impl!(Vec3<f64>, f64); } test_iterator_impl!(Vec3<f64>, f64);
}
#[test] #[test]
fn test_iterator_vec4() fn test_iterator_vec4() {
{ test_iterator_impl!(Vec4<f64>, f64); } test_iterator_impl!(Vec4<f64>, f64);
}
#[test] #[test]
fn test_iterator_vec5() fn test_iterator_vec5() {
{ test_iterator_impl!(Vec5<f64>, f64); } test_iterator_impl!(Vec5<f64>, f64);
}
#[test] #[test]
fn test_iterator_vec6() fn test_iterator_vec6() {
{ test_iterator_impl!(Vec6<f64>, f64); } test_iterator_impl!(Vec6<f64>, f64);
}
#[test] #[test]
fn test_ord_vec3() fn test_ord_vec3() {
{
// equality // equality
assert!(Vec3::new(0.5, 0.5, 0.5) == Vec3::new(0.5, 0.5, 0.5)); assert!(Vec3::new(0.5, 0.5, 0.5) == Vec3::new(0.5, 0.5, 0.5));
assert!(!(Vec3::new(1.5, 0.5, 0.5) == Vec3::new(0.5, 0.5, 0.5))); assert!(!(Vec3::new(1.5, 0.5, 0.5) == Vec3::new(0.5, 0.5, 0.5)));
@ -287,8 +315,7 @@ fn test_ord_vec3()
} }
#[test] #[test]
fn test_min_max_vec3() fn test_min_max_vec3() {
{
assert_eq!(Vec3::new(1, 2, 3).max(&Vec3::new(3, 2, 1)), Vec3::new(3, 2, 3)); assert_eq!(Vec3::new(1, 2, 3).max(&Vec3::new(3, 2, 1)), Vec3::new(3, 2, 3));
assert_eq!(Vec3::new(1, 2, 3).min(&Vec3::new(3, 2, 1)), Vec3::new(1, 2, 1)); assert_eq!(Vec3::new(1, 2, 3).min(&Vec3::new(3, 2, 1)), Vec3::new(1, 2, 1));
assert_eq!( assert_eq!(

View File

@ -1,6 +1,5 @@
/// Traits of objecs which can form a basis. /// Traits of objecs which can form a basis.
pub trait Basis pub trait Basis {
{
/// Iterate through the canonical basis of the space in which this object lives. /// Iterate through the canonical basis of the space in which this object lives.
fn canonical_basis(&fn(Self)); fn canonical_basis(&fn(Self));
@ -8,23 +7,23 @@ pub trait Basis
fn orthonormal_subspace_basis(&self, &fn(Self)); fn orthonormal_subspace_basis(&self, &fn(Self));
/// Creates the canonical basis of the space in which this object lives. /// Creates the canonical basis of the space in which this object lives.
fn canonical_basis_list() -> ~[Self] fn canonical_basis_list() -> ~[Self] {
{
let mut res = ~[]; let mut res = ~[];
do Basis::canonical_basis::<Self> |elem| do Basis::canonical_basis::<Self> |elem| {
{ res.push(elem) } res.push(elem)
}
res res
} }
/// Creates a basis of the subspace orthogonal to `self`. /// Creates a basis of the subspace orthogonal to `self`.
fn orthonormal_subspace_basis_list(&self) -> ~[Self] fn orthonormal_subspace_basis_list(&self) -> ~[Self] {
{
let mut res = ~[]; let mut res = ~[];
do self.orthonormal_subspace_basis |elem| do self.orthonormal_subspace_basis |elem| {
{ res.push(elem) } res.push(elem)
}
res res
} }

View File

@ -1,6 +1,5 @@
/// Traits to access columns of a matrix. /// Traits to access columns of a matrix.
pub trait Column<C> pub trait Column<C> {
{
/// Reads the `i`-th column of `self`. /// Reads the `i`-th column of `self`.
fn column(&self, i: uint) -> C; fn column(&self, i: uint) -> C;
/// Writes the `i`-th column of `self`. /// Writes the `i`-th column of `self`.

View File

@ -1,13 +1,11 @@
/// Traits of objects which can be put in homogeneous coordinates. /// Traits of objects which can be put in homogeneous coordinates.
pub trait ToHomogeneous<U> pub trait ToHomogeneous<U> {
{
/// Gets the homogeneous coordinates version of this object. /// Gets the homogeneous coordinates version of this object.
fn to_homogeneous(&self) -> U; fn to_homogeneous(&self) -> U;
} }
/// Traits of objects which can be build from an homogeneous coordinate representation. /// Traits of objects which can be build from an homogeneous coordinate representation.
pub trait FromHomogeneous<U> pub trait FromHomogeneous<U> {
{
/// Builds an object with its homogeneous coordinate version. Note this it is not required for /// Builds an object with its homogeneous coordinate version. Note this it is not required for
/// `from` to be the iverse of `to_homogeneous`. Typically, `from` will remove some informations /// `from` to be the iverse of `to_homogeneous`. Typically, `from` will remove some informations
/// unrecoverable by `to_homogeneous`. /// unrecoverable by `to_homogeneous`.

View File

@ -7,8 +7,7 @@
/// It exists because the `Index` trait cannot be used to express write access. /// It exists because the `Index` trait cannot be used to express write access.
/// Thus, this is the same as the `Index` trait but without the syntactic sugar and with a method /// Thus, this is the same as the `Index` trait but without the syntactic sugar and with a method
/// to write to a specific index. /// to write to a specific index.
pub trait Indexable<Index, Res> pub trait Indexable<Index, Res> {
{
/// Reads the `i`-th element of `self`. /// Reads the `i`-th element of `self`.
fn at(&self, i: Index) -> Res; fn at(&self, i: Index) -> Res;
/// Writes to the `i`-th element of `self`. /// Writes to the `i`-th element of `self`.

View File

@ -1,8 +1,7 @@
/** /**
* Trait of inversible objects. Typically used to implement matrix inverse. * Trait of inversible objects. Typically used to implement matrix inverse.
*/ */
pub trait Inv pub trait Inv {
{
/// Returns the inverse of an element. /// Returns the inverse of an element.
fn inverse(&self) -> Option<Self>; fn inverse(&self) -> Option<Self>;
/// Inplace version of `inverse`. /// Inplace version of `inverse`.

View File

@ -1,15 +1,13 @@
use std::vec; use std::vec;
/// Traits of objects which can be iterated through like a vector. /// Traits of objects which can be iterated through like a vector.
pub trait Iterable<N> pub trait Iterable<N> {
{
/// Gets a vector-like read-only iterator. /// Gets a vector-like read-only iterator.
fn iter<'l>(&'l self) -> vec::VecIterator<'l, N>; fn iter<'l>(&'l self) -> vec::VecIterator<'l, N>;
} }
/// Traits of mutable objects which can be iterated through like a vector. /// Traits of mutable objects which can be iterated through like a vector.
pub trait IterableMut<N> pub trait IterableMut<N> {
{
/// Gets a vector-like read-write iterator. /// Gets a vector-like read-write iterator.
fn mut_iter<'l>(&'l mut self) -> vec::VecMutIterator<'l, N>; fn mut_iter<'l>(&'l mut self) -> vec::VecMutIterator<'l, N>;
} }
@ -18,13 +16,11 @@ pub trait IterableMut<N>
* FIXME: the prevous traits are only workarounds. * FIXME: the prevous traits are only workarounds.
* It should be something like: * It should be something like:
pub trait Iterable<'self, N, I: Iterator<N>> pub trait Iterable<'self, N, I: Iterator<N>> {
{
fn iter(&'self self) -> I; fn iter(&'self self) -> I;
} }
pub trait IterableMut<'self, N, I: Iterator<N>> pub trait IterableMut<'self, N, I: Iterator<N>> {
{
fn mut_iter(&'self self) -> I; fn mut_iter(&'self self) -> I;
} }

View File

@ -1,7 +1,6 @@
/// Trait of matrices which can be converted to another matrix. Used to change the type of a matrix /// Trait of matrices which can be converted to another matrix. Used to change the type of a matrix
/// components. /// components.
pub trait MatCast<M> pub trait MatCast<M> {
{
/// Converts `m` to have the type `M`. /// Converts `m` to have the type `M`.
fn from(m: Self) -> M; fn from(m: Self) -> M;
} }

View File

@ -1,8 +1,7 @@
/** /**
* Trait of objects having a L² norm and which can be normalized. * Trait of objects having a L² norm and which can be normalized.
*/ */
pub trait Norm<N> pub trait Norm<N> {
{
/// Computes the norm a an object. /// Computes the norm a an object.
fn norm(&self) -> N; fn norm(&self) -> N;

View File

@ -7,8 +7,7 @@ use std::num::{One, Zero};
* `Zero`) respectively neutral and absorbant wrt the multiplication. * `Zero`) respectively neutral and absorbant wrt the multiplication.
*/ */
pub trait Ring : pub trait Ring :
Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Mul<Self, Self> + One + Zero Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Mul<Self, Self> + One + Zero { }
{ }
impl<N: Sub<N, N> + Add<N, N> + Neg<N> + Mul<N, N> + One + Zero> impl<N: Sub<N, N> + Add<N, N> + Neg<N> + Mul<N, N> + One + Zero>
Ring for N; Ring for N;

View File

@ -1,8 +1,7 @@
/** /**
* Trait of objects having a right multiplication with another element. * Trait of objects having a right multiplication with another element.
*/ */
pub trait RMul<V> pub trait RMul<V> {
{
/// Computes self * v /// Computes self * v
fn rmul(&self, v : &V) -> V; fn rmul(&self, v : &V) -> V;
} }
@ -10,8 +9,7 @@ pub trait RMul<V>
/** /**
* Trait of objects having a left multiplication with another element. * Trait of objects having a left multiplication with another element.
*/ */
pub trait LMul<V> pub trait LMul<V> {
{
/// Computes v * self /// Computes v * self
fn lmul(&self, &V) -> V; fn lmul(&self, &V) -> V;
} }

View File

@ -3,8 +3,7 @@ use traits::translation::{Translation, Translatable};
/// Trait of object which represent a rotation, and to wich new rotations can /// Trait of object which represent a rotation, and to wich new rotations can
/// be appended. A rotation is assumed to be an isomitry without translation /// be appended. A rotation is assumed to be an isomitry without translation
/// and without reflexion. /// and without reflexion.
pub trait Rotation<V> pub trait Rotation<V> {
{
/// Gets the rotation associated with this object. /// Gets the rotation associated with this object.
fn rotation(&self) -> V; fn rotation(&self) -> V;
@ -18,8 +17,7 @@ pub trait Rotation<V>
/// Trait of objects which can be put on an alternate form which represent a rotation. This is /// Trait of objects which can be put on an alternate form which represent a rotation. This is
/// typically implemented by structures requiring an internal restructuration to be able to /// typically implemented by structures requiring an internal restructuration to be able to
/// represent a rotation. /// represent a rotation.
pub trait Rotatable<V, Res: Rotation<V>> pub trait Rotatable<V, Res: Rotation<V>> {
{
/// Appends a rotation from an alternative representation. Such /// Appends a rotation from an alternative representation. Such
/// representation has the same format as the one returned by `rotation`. /// representation has the same format as the one returned by `rotation`.
fn rotated(&self, &V) -> Res; fn rotated(&self, &V) -> Res;
@ -27,8 +25,7 @@ pub trait Rotatable<V, Res: Rotation<V>>
/// Trait of objects able to rotate other objects. This is typically implemented by matrices which /// Trait of objects able to rotate other objects. This is typically implemented by matrices which
/// rotate vectors. /// rotate vectors.
pub trait Rotate<V> pub trait Rotate<V> {
{
/// Apply a rotation to an object. /// Apply a rotation to an object.
fn rotate(&self, &V) -> V; fn rotate(&self, &V) -> V;
/// Apply an inverse rotation to an object. /// Apply an inverse rotation to an object.
@ -50,8 +47,7 @@ pub fn rotated_wrt_point<M: Translatable<LV, M2>,
m: &M, m: &M,
ammount: &AV, ammount: &AV,
center: &LV) center: &LV)
-> M2 -> M2 {
{
let mut res = m.translated(&-center); let mut res = m.translated(&-center);
res.rotate_by(ammount); res.rotate_by(ammount);
@ -72,8 +68,7 @@ pub fn rotate_wrt_point<M: Rotation<AV> + Translation<LV>,
AV>( AV>(
m: &mut M, m: &mut M,
ammount: &AV, ammount: &AV,
center: &LV) center: &LV) {
{
m.translate_by(&-center); m.translate_by(&-center);
m.rotate_by(ammount); m.rotate_by(ammount);
m.translate_by(center); m.translate_by(center);
@ -93,8 +88,9 @@ pub fn rotated_wrt_center<M: Translatable<LV, M2> + Translation<LV>,
AV>( AV>(
m: &M, m: &M,
ammount: &AV) ammount: &AV)
-> M2 -> M2 {
{ rotated_wrt_point(m, ammount, &m.translation()) } rotated_wrt_point(m, ammount, &m.translation())
}
/** /**
* Applies a rotation centered on the input translation. * Applies a rotation centered on the input translation.
@ -108,8 +104,7 @@ pub fn rotate_wrt_center<M: Translatable<LV, M> + Translation<LV> + Rotation<AV>
LV: Neg<LV>, LV: Neg<LV>,
AV>( AV>(
m: &mut M, m: &mut M,
ammount: &AV) ammount: &AV) {
{
let t = m.translation(); let t = m.translation();
rotate_wrt_point(m, ammount, &t) rotate_wrt_point(m, ammount, &t)

View File

@ -1,17 +1,16 @@
/// Traits of vectors able to sample a sphere. The number of sample must be sufficient to /// Traits of vectors able to sample a sphere. The number of sample must be sufficient to
/// approximate a sphere using support mapping functions. /// approximate a sphere using support mapping functions.
pub trait UniformSphereSample pub trait UniformSphereSample {
{
/// Iterate throught the samples. /// Iterate throught the samples.
pub fn sample(&fn(&'static Self)); pub fn sample(&fn(&'static Self));
/// Gets the list of all samples. /// Gets the list of all samples.
pub fn sample_list() -> ~[&'static Self] pub fn sample_list() -> ~[&'static Self] {
{
let mut res = ~[]; let mut res = ~[];
do UniformSphereSample::sample::<Self> |s| do UniformSphereSample::sample::<Self> |s| {
{ res.push(s) } res.push(s)
}
res res
} }

View File

@ -1,8 +1,7 @@
/** /**
* Trait of objects having a multiplication with a scalar. * Trait of objects having a multiplication with a scalar.
*/ */
pub trait ScalarMul<N> pub trait ScalarMul<N> {
{
/// Gets the result of a multiplication by a scalar. /// Gets the result of a multiplication by a scalar.
fn scalar_mul(&self, &N) -> Self; fn scalar_mul(&self, &N) -> Self;
@ -13,8 +12,7 @@ pub trait ScalarMul<N>
/** /**
* Trait of objects having a division with a scalar. * Trait of objects having a division with a scalar.
*/ */
pub trait ScalarDiv<N> pub trait ScalarDiv<N> {
{
/// Gets the result of a division by a scalar. /// Gets the result of a division by a scalar.
fn scalar_div(&self, &N) -> Self; fn scalar_div(&self, &N) -> Self;
@ -25,8 +23,7 @@ pub trait ScalarDiv<N>
/** /**
* Trait of objects having an addition with a scalar. * Trait of objects having an addition with a scalar.
*/ */
pub trait ScalarAdd<N> pub trait ScalarAdd<N> {
{
/// Gets the result of an addition by a scalar. /// Gets the result of an addition by a scalar.
fn scalar_add(&self, &N) -> Self; fn scalar_add(&self, &N) -> Self;
@ -37,8 +34,7 @@ pub trait ScalarAdd<N>
/** /**
* Trait of objects having a subtraction with a scalar. * Trait of objects having a subtraction with a scalar.
*/ */
pub trait ScalarSub<N> pub trait ScalarSub<N> {
{
/// Gets the result of a subtraction by a scalar. /// Gets the result of a subtraction by a scalar.
fn scalar_sub(&self, &N) -> Self; fn scalar_sub(&self, &N) -> Self;

View File

@ -1,8 +1,7 @@
use traits::dot::Dot; use traits::dot::Dot;
/// Traits of objects with a subtract and a dot product. Exists only for optimization purpose. /// Traits of objects with a subtract and a dot product. Exists only for optimization purpose.
pub trait SubDot<N> : Sub<Self, Self> + Dot<N> pub trait SubDot<N> : Sub<Self, Self> + Dot<N> {
{
/** /**
* Short-cut to compute the projection of a point on a vector, but without * Short-cut to compute the projection of a point on a vector, but without
* computing intermediate vectors. * computing intermediate vectors.

View File

@ -1,8 +1,7 @@
/// Trait of object which represent a transformation, and to wich new transformations can /// Trait of object which represent a transformation, and to wich new transformations can
/// be appended. A transformation is assumed to be an isomitry without translation /// be appended. A transformation is assumed to be an isomitry without translation
/// and without reflexion. /// and without reflexion.
pub trait Transformation<M> pub trait Transformation<M> {
{
/// Gets the transformation associated with this object. /// Gets the transformation associated with this object.
fn transformation(&self) -> M; fn transformation(&self) -> M;
@ -15,8 +14,7 @@ pub trait Transformation<M>
/// Trait of objects able to transform other objects. This is typically implemented by matrices which /// Trait of objects able to transform other objects. This is typically implemented by matrices which
/// transform vectors. /// transform vectors.
pub trait Transform<V> pub trait Transform<V> {
{
// XXX: sadly we cannot call this `transform` as it conflicts with the // XXX: sadly we cannot call this `transform` as it conflicts with the
// iterators' `transform` function (which seems always exist). // iterators' `transform` function (which seems always exist).
/// Apply a transformation to an object. /// Apply a transformation to an object.
@ -28,8 +26,7 @@ pub trait Transform<V>
/// Trait of objects which can be put on an alternate form which represent a transformation. This is /// Trait of objects which can be put on an alternate form which represent a transformation. This is
/// typically implemented by structures requiring an internal restructuration to be able to /// typically implemented by structures requiring an internal restructuration to be able to
/// represent a transformation. /// represent a transformation.
pub trait Transformable<M, Res: Transformation<M>> pub trait Transformable<M, Res: Transformation<M>> {
{
/// Appends a transformation from an alternative representation. Such /// Appends a transformation from an alternative representation. Such
/// representation has the same format as the one returned by `transformation`. /// representation has the same format as the one returned by `transformation`.
fn transformed(&self, &M) -> Res; fn transformed(&self, &M) -> Res;

View File

@ -1,7 +1,6 @@
/// Trait of object which represent a translation, and to wich new translation /// Trait of object which represent a translation, and to wich new translation
/// can be appended. /// can be appended.
pub trait Translation<V> pub trait Translation<V> {
{
// FIXME: add a "from translation: translantion(V) -> Self ? // FIXME: add a "from translation: translantion(V) -> Self ?
/// Gets the translation associated with this object. /// Gets the translation associated with this object.
fn translation(&self) -> V; fn translation(&self) -> V;
@ -15,8 +14,7 @@ pub trait Translation<V>
/// Trait of objects able to rotate other objects. This is typically implemented by matrices which /// Trait of objects able to rotate other objects. This is typically implemented by matrices which
/// rotate vectors. /// rotate vectors.
pub trait Translate<V> pub trait Translate<V> {
{
/// Apply a translation to an object. /// Apply a translation to an object.
fn translate(&self, &V) -> V; fn translate(&self, &V) -> V;
/// Apply an inverse translation to an object. /// Apply an inverse translation to an object.
@ -26,8 +24,7 @@ pub trait Translate<V>
/// Trait of objects which can be put on an alternate form which represent a translation. This is /// Trait of objects which can be put on an alternate form which represent a translation. This is
/// typically implemented by structures requiring an internal restructuration to be able to /// typically implemented by structures requiring an internal restructuration to be able to
/// represent a translation. /// represent a translation.
pub trait Translatable<V, Res: Translation<V>> pub trait Translatable<V, Res: Translation<V>> {
{
/// Appends a translation from an alternative representation. Such /// Appends a translation from an alternative representation. Such
/// representation has the same format as the one returned by `translation`. /// representation has the same format as the one returned by `translation`.
fn translated(&self, &V) -> Res; fn translated(&self, &V) -> Res;

View File

@ -2,8 +2,7 @@
/// Trait of objects which can be transposed. Note that, for the moment, this /// Trait of objects which can be transposed. Note that, for the moment, this
/// does not allow the implementation by non-square matrix (or anything which /// does not allow the implementation by non-square matrix (or anything which
/// is not stable by transposition). /// is not stable by transposition).
pub trait Transpose pub trait Transpose {
{
/// Computes the transpose of a matrix. /// Computes the transpose of a matrix.
fn transposed(&self) -> Self; fn transposed(&self) -> Self;

View File

@ -1,7 +1,6 @@
/// Trait of vectors which can be converted to another matrix. Used to change the type of a vector /// Trait of vectors which can be converted to another matrix. Used to change the type of a vector
/// components. /// components.
pub trait VecCast<V> pub trait VecCast<V> {
{
/// Converts `v` to have the type `V`. /// Converts `v` to have the type `V`.
fn from(v: Self) -> V; fn from(v: Self) -> V;
} }

View File

@ -8,8 +8,7 @@ use traits::scalar_op::{ScalarMul, ScalarDiv};
/// has a distinct element (`Zero`) neutral wrt the addition. /// has a distinct element (`Zero`) neutral wrt the addition.
pub trait VectorSpace<N> pub trait VectorSpace<N>
: Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Zero + : Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Zero +
ScalarMul<N> + ScalarDiv<N> ScalarMul<N> + ScalarDiv<N> { }
{ }
impl<V: Sub<V, V> + Add<V, V> + Neg<V> + Zero + ScalarMul<N> + ScalarDiv<N>, impl<V: Sub<V, V> + Add<V, V> + Neg<V> + Zero + ScalarMul<N> + ScalarDiv<N>,
N: DivisionRing> VectorSpace<N> for V; N: DivisionRing> VectorSpace<N> for V;

View File

@ -32,8 +32,7 @@ pub struct Vec0<N>;
/// Vector of dimension 1. /// Vector of dimension 1.
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] #[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
pub struct Vec1<N> pub struct Vec1<N> {
{
/// First component of the vector. /// First component of the vector.
x: N x: N
} }
@ -70,8 +69,7 @@ from_homogeneous_impl!(Vec1, Vec2, y, x)
/// Vector of dimension 2. /// Vector of dimension 2.
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] #[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
pub struct Vec2<N> pub struct Vec2<N> {
{
/// First component of the vector. /// First component of the vector.
x: N, x: N,
/// Second component of the vector. /// Second component of the vector.
@ -110,8 +108,7 @@ from_homogeneous_impl!(Vec2, Vec3, z, x, y)
/// Vector of dimension 3. /// Vector of dimension 3.
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] #[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
pub struct Vec3<N> pub struct Vec3<N> {
{
/// First component of the vector. /// First component of the vector.
x: N, x: N,
/// Second component of the vector. /// Second component of the vector.
@ -152,8 +149,7 @@ from_homogeneous_impl!(Vec3, Vec4, w, x, y, z)
/// Vector of dimension 4. /// Vector of dimension 4.
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] #[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
pub struct Vec4<N> pub struct Vec4<N> {
{
/// First component of the vector. /// First component of the vector.
x: N, x: N,
/// Second component of the vector. /// Second component of the vector.
@ -196,8 +192,7 @@ from_homogeneous_impl!(Vec4, Vec5, a, x, y, z, w)
/// Vector of dimension 5. /// Vector of dimension 5.
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] #[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
pub struct Vec5<N> pub struct Vec5<N> {
{
/// First component of the vector. /// First component of the vector.
x: N, x: N,
/// Second component of the vector. /// Second component of the vector.
@ -242,8 +237,7 @@ from_homogeneous_impl!(Vec5, Vec6, b, x, y, z, w, a)
/// Vector of dimension 6. /// Vector of dimension 6.
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] #[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
pub struct Vec6<N> pub struct Vec6<N> {
{
/// First component of the vector. /// First component of the vector.
x: N, x: N,
/// Second component of the vector. /// Second component of the vector.

View File

@ -16,179 +16,176 @@ use traits::division_ring::DivisionRing;
use traits::indexable::Indexable; use traits::indexable::Indexable;
use vec; use vec;
impl<N> vec::Vec0<N> impl<N> vec::Vec0<N> {
{
/// Creates a new vector. /// Creates a new vector.
#[inline] #[inline]
pub fn new() -> vec::Vec0<N> pub fn new() -> vec::Vec0<N> {
{ vec::Vec0 } vec::Vec0
}
} }
impl<N: Clone> Indexable<uint, N> for vec::Vec0<N> impl<N: Clone> Indexable<uint, N> for vec::Vec0<N> {
{
#[inline] #[inline]
pub fn at(&self, _: uint) -> N pub fn at(&self, _: uint) -> N {
{ fail!("Cannot index a Vec0.") } fail!("Cannot index a Vec0.")
}
#[inline] #[inline]
pub fn set(&mut self, _: uint, _: N) pub fn set(&mut self, _: uint, _: N) {
{ }
}
#[inline] #[inline]
pub fn swap(&mut self, _: uint, _: uint) pub fn swap(&mut self, _: uint, _: uint) {
{ }
}
} }
impl<N: Clone> vec::Vec0<N> impl<N: Clone> vec::Vec0<N> {
{
/// Creates a new vector. The parameter is not taken in account. /// Creates a new vector. The parameter is not taken in account.
#[inline] #[inline]
pub fn new_repeat(_: N) -> vec::Vec0<N> pub fn new_repeat(_: N) -> vec::Vec0<N> {
{ vec::Vec0 } vec::Vec0
}
} }
impl<N> Iterable<N> for vec::Vec0<N> impl<N> Iterable<N> for vec::Vec0<N> {
{ fn iter<'l>(&'l self) -> VecIterator<'l, N> {
fn iter<'l>(&'l self) -> VecIterator<'l, N> unsafe { cast::transmute::<&'l vec::Vec0<N>, &'l [N, ..0]>(self).iter() }
{ unsafe { cast::transmute::<&'l vec::Vec0<N>, &'l [N, ..0]>(self).iter() } } }
} }
impl<N> IterableMut<N> for vec::Vec0<N> impl<N> IterableMut<N> for vec::Vec0<N> {
{ fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> {
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> unsafe { cast::transmute::<&'l mut vec::Vec0<N>, &'l mut [N, ..0]>(self).mut_iter() }
{ unsafe { cast::transmute::<&'l mut vec::Vec0<N>, &'l mut [N, ..0]>(self).mut_iter() } } }
} }
impl<N> Dim for vec::Vec0<N> impl<N> Dim for vec::Vec0<N> {
{
#[inline] #[inline]
fn dim() -> uint fn dim() -> uint {
{ 0 } 0
}
} }
impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> Basis for vec::Vec0<N> impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> Basis for vec::Vec0<N> {
{ pub fn canonical_basis(_: &fn(vec::Vec0<N>)) { }
pub fn canonical_basis(_: &fn(vec::Vec0<N>))
{ }
pub fn orthonormal_subspace_basis(&self, _: &fn(vec::Vec0<N>)) pub fn orthonormal_subspace_basis(&self, _: &fn(vec::Vec0<N>)) { }
{ }
} }
impl<N: Clone + Add<N,N>> Add<vec::Vec0<N>, vec::Vec0<N>> for vec::Vec0<N> impl<N: Clone + Add<N,N>> Add<vec::Vec0<N>, vec::Vec0<N>> for vec::Vec0<N> {
{
#[inline] #[inline]
fn add(&self, _: &vec::Vec0<N>) -> vec::Vec0<N> fn add(&self, _: &vec::Vec0<N>) -> vec::Vec0<N> {
{ vec::Vec0 } vec::Vec0
}
} }
impl<N: Clone + Sub<N,N>> Sub<vec::Vec0<N>, vec::Vec0<N>> for vec::Vec0<N> impl<N: Clone + Sub<N,N>> Sub<vec::Vec0<N>, vec::Vec0<N>> for vec::Vec0<N> {
{
#[inline] #[inline]
fn sub(&self, _: &vec::Vec0<N>) -> vec::Vec0<N> fn sub(&self, _: &vec::Vec0<N>) -> vec::Vec0<N> {
{ vec::Vec0 } vec::Vec0
}
} }
impl<N: Neg<N>> Neg<vec::Vec0<N>> for vec::Vec0<N> impl<N: Neg<N>> Neg<vec::Vec0<N>> for vec::Vec0<N> {
{
#[inline] #[inline]
fn neg(&self) -> vec::Vec0<N> fn neg(&self) -> vec::Vec0<N> {
{ vec::Vec0 } vec::Vec0
}
} }
impl<N: Ring> Dot<N> for vec::Vec0<N> impl<N: Ring> Dot<N> for vec::Vec0<N> {
{
#[inline] #[inline]
fn dot(&self, _: &vec::Vec0<N>) -> N fn dot(&self, _: &vec::Vec0<N>) -> N {
{ Zero::zero() } Zero::zero()
}
} }
impl<N: Clone + Ring> SubDot<N> for vec::Vec0<N> impl<N: Clone + Ring> SubDot<N> for vec::Vec0<N> {
{
#[inline] #[inline]
fn sub_dot(&self, _: &vec::Vec0<N>, _: &vec::Vec0<N>) -> N fn sub_dot(&self, _: &vec::Vec0<N>, _: &vec::Vec0<N>) -> N {
{ Zero::zero() } Zero::zero()
}
} }
impl<N: Mul<N, N>> ScalarMul<N> for vec::Vec0<N> impl<N: Mul<N, N>> ScalarMul<N> for vec::Vec0<N> {
{
#[inline] #[inline]
fn scalar_mul(&self, _: &N) -> vec::Vec0<N> fn scalar_mul(&self, _: &N) -> vec::Vec0<N> {
{ vec::Vec0 } vec::Vec0
}
#[inline] #[inline]
fn scalar_mul_inplace(&mut self, _: &N) fn scalar_mul_inplace(&mut self, _: &N) { }
{ }
} }
impl<N: Div<N, N>> ScalarDiv<N> for vec::Vec0<N> impl<N: Div<N, N>> ScalarDiv<N> for vec::Vec0<N> {
{
#[inline] #[inline]
fn scalar_div(&self, _: &N) -> vec::Vec0<N> fn scalar_div(&self, _: &N) -> vec::Vec0<N> {
{ vec::Vec0 } vec::Vec0
}
#[inline] #[inline]
fn scalar_div_inplace(&mut self, _: &N) fn scalar_div_inplace(&mut self, _: &N) { }
{ }
} }
impl<N: Add<N, N>> ScalarAdd<N> for vec::Vec0<N> impl<N: Add<N, N>> ScalarAdd<N> for vec::Vec0<N> {
{
#[inline] #[inline]
fn scalar_add(&self, _: &N) -> vec::Vec0<N> fn scalar_add(&self, _: &N) -> vec::Vec0<N> {
{ vec::Vec0 } vec::Vec0
}
#[inline] #[inline]
fn scalar_add_inplace(&mut self, _: &N) fn scalar_add_inplace(&mut self, _: &N) { }
{ }
} }
impl<N: Sub<N, N>> ScalarSub<N> for vec::Vec0<N> impl<N: Sub<N, N>> ScalarSub<N> for vec::Vec0<N> {
{
#[inline] #[inline]
fn scalar_sub(&self, _: &N) -> vec::Vec0<N> fn scalar_sub(&self, _: &N) -> vec::Vec0<N> {
{ vec::Vec0 } vec::Vec0
}
#[inline] #[inline]
fn scalar_sub_inplace(&mut self, _: &N) fn scalar_sub_inplace(&mut self, _: &N) { }
{ }
} }
impl<N: Clone + Add<N, N> + Neg<N>> Translation<vec::Vec0<N>> for vec::Vec0<N> impl<N: Clone + Add<N, N> + Neg<N>> Translation<vec::Vec0<N>> for vec::Vec0<N> {
{
#[inline] #[inline]
fn translation(&self) -> vec::Vec0<N> fn translation(&self) -> vec::Vec0<N> {
{ self.clone() } self.clone()
}
#[inline] #[inline]
fn inv_translation(&self) -> vec::Vec0<N> fn inv_translation(&self) -> vec::Vec0<N> {
{ -self } -self
}
#[inline] #[inline]
fn translate_by(&mut self, t: &vec::Vec0<N>) fn translate_by(&mut self, t: &vec::Vec0<N>) {
{ *self = *self + *t; } *self = *self + *t;
}
} }
impl<N: Add<N, N> + Neg<N> + Clone> Translatable<vec::Vec0<N>, vec::Vec0<N>> for vec::Vec0<N> impl<N: Add<N, N> + Neg<N> + Clone> Translatable<vec::Vec0<N>, vec::Vec0<N>> for vec::Vec0<N> {
{
#[inline] #[inline]
fn translated(&self, t: &vec::Vec0<N>) -> vec::Vec0<N> fn translated(&self, t: &vec::Vec0<N>) -> vec::Vec0<N> {
{ self + *t } self + *t
}
} }
impl<N: Clone + DivisionRing + Algebraic> Norm<N> for vec::Vec0<N> impl<N: Clone + DivisionRing + Algebraic> Norm<N> for vec::Vec0<N> {
{
#[inline] #[inline]
fn sqnorm(&self) -> N fn sqnorm(&self) -> N {
{ self.dot(self) } self.dot(self)
}
#[inline] #[inline]
fn norm(&self) -> N fn norm(&self) -> N {
{ self.sqnorm().sqrt() } self.sqnorm().sqrt()
}
#[inline] #[inline]
fn normalized(&self) -> vec::Vec0<N> fn normalized(&self) -> vec::Vec0<N> {
{
let mut res : vec::Vec0<N> = self.clone(); let mut res : vec::Vec0<N> = self.clone();
res.normalize(); res.normalize();
@ -197,8 +194,7 @@ impl<N: Clone + DivisionRing + Algebraic> Norm<N> for vec::Vec0<N>
} }
#[inline] #[inline]
fn normalize(&mut self) -> N fn normalize(&mut self) -> N {
{
let l = self.norm(); let l = self.norm();
self.scalar_div_inplace(&l); self.scalar_div_inplace(&l);
@ -207,41 +203,44 @@ impl<N: Clone + DivisionRing + Algebraic> Norm<N> for vec::Vec0<N>
} }
} }
impl<N: ApproxEq<N>> ApproxEq<N> for vec::Vec0<N> impl<N: ApproxEq<N>> ApproxEq<N> for vec::Vec0<N> {
{
#[inline] #[inline]
fn approx_epsilon() -> N fn approx_epsilon() -> N {
{ ApproxEq::approx_epsilon::<N, N>() } ApproxEq::approx_epsilon::<N, N>()
}
#[inline] #[inline]
fn approx_eq(&self, _: &vec::Vec0<N>) -> bool fn approx_eq(&self, _: &vec::Vec0<N>) -> bool {
{ true } true
}
#[inline] #[inline]
fn approx_eq_eps(&self, _: &vec::Vec0<N>, _: &N) -> bool fn approx_eq_eps(&self, _: &vec::Vec0<N>, _: &N) -> bool {
{ true } true
}
} }
impl<N: Clone + One> One for vec::Vec0<N> impl<N: Clone + One> One for vec::Vec0<N> {
{
#[inline] #[inline]
fn one() -> vec::Vec0<N> fn one() -> vec::Vec0<N> {
{ vec::Vec0 } vec::Vec0
}
} }
impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for vec::Vec0<N> impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for vec::Vec0<N> {
{ fn from_iterator(_: &mut Iter) -> vec::Vec0<N> {
fn from_iterator(_: &mut Iter) -> vec::Vec0<N> vec::Vec0
{ vec::Vec0 } }
} }
impl<N: Bounded + Clone> Bounded for vec::Vec0<N> impl<N: Bounded + Clone> Bounded for vec::Vec0<N> {
{
#[inline] #[inline]
fn max_value() -> vec::Vec0<N> fn max_value() -> vec::Vec0<N> {
{ vec::Vec0 } vec::Vec0
}
#[inline] #[inline]
fn min_value() -> vec::Vec0<N> fn min_value() -> vec::Vec0<N> {
{ vec::Vec0 } vec::Vec0
}
} }

View File

@ -2,12 +2,10 @@
macro_rules! new_impl( macro_rules! new_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N> $t<N> impl<N> $t<N> {
{
/// Creates a new vector. /// Creates a new vector.
#[inline] #[inline]
pub fn new($comp0: N $( , $compN: N )*) -> $t<N> pub fn new($comp0: N $( , $compN: N )*) -> $t<N> {
{
$t { $t {
$comp0: $comp0 $comp0: $comp0
$(, $compN: $compN )* $(, $compN: $compN )*
@ -19,42 +17,45 @@ macro_rules! new_impl(
macro_rules! ord_impl( macro_rules! ord_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Ord> Ord for $t<N> impl<N: Ord> Ord for $t<N> {
{
#[inline] #[inline]
fn lt(&self, other: &$t<N>) -> bool fn lt(&self, other: &$t<N>) -> bool {
{ self.$comp0 < other.$comp0 $(&& self.$compN < other.$compN)* } self.$comp0 < other.$comp0 $(&& self.$compN < other.$compN)*
}
#[inline] #[inline]
fn le(&self, other: &$t<N>) -> bool fn le(&self, other: &$t<N>) -> bool {
{ self.$comp0 <= other.$comp0 $(&& self.$compN <= other.$compN)* } self.$comp0 <= other.$comp0 $(&& self.$compN <= other.$compN)*
}
#[inline] #[inline]
fn gt(&self, other: &$t<N>) -> bool fn gt(&self, other: &$t<N>) -> bool {
{ self.$comp0 > other.$comp0 $(&& self.$compN > other.$compN)* } self.$comp0 > other.$comp0 $(&& self.$compN > other.$compN)*
}
#[inline] #[inline]
fn ge(&self, other: &$t<N>) -> bool fn ge(&self, other: &$t<N>) -> bool {
{ self.$comp0 >= other.$comp0 $(&& self.$compN >= other.$compN)* } self.$comp0 >= other.$comp0 $(&& self.$compN >= other.$compN)*
}
} }
) )
) )
macro_rules! orderable_impl( macro_rules! orderable_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Orderable> Orderable for $t<N> impl<N: Orderable> Orderable for $t<N> {
{
#[inline] #[inline]
fn max(&self, other: &$t<N>) -> $t<N> fn max(&self, other: &$t<N>) -> $t<N> {
{ $t::new(self.$comp0.max(&other.$comp0) $(, self.$compN.max(&other.$compN))*) } $t::new(self.$comp0.max(&other.$comp0) $(, self.$compN.max(&other.$compN))*)
}
#[inline] #[inline]
fn min(&self, other: &$t<N>) -> $t<N> fn min(&self, other: &$t<N>) -> $t<N> {
{ $t::new(self.$comp0.min(&other.$comp0) $(, self.$compN.min(&other.$compN))*) } $t::new(self.$comp0.min(&other.$comp0) $(, self.$compN.min(&other.$compN))*)
}
#[inline] #[inline]
fn clamp(&self, min: &$t<N>, max: &$t<N>) -> $t<N> fn clamp(&self, min: &$t<N>, max: &$t<N>) -> $t<N> {
{
$t::new(self.$comp0.clamp(&min.$comp0, &max.$comp0) $t::new(self.$comp0.clamp(&min.$comp0, &max.$comp0)
$(, self.$compN.clamp(&min.$comp0, &max.$comp0))*) $(, self.$compN.clamp(&min.$comp0, &max.$comp0))*)
} }
@ -64,12 +65,10 @@ macro_rules! orderable_impl(
macro_rules! vec_axis_impl( macro_rules! vec_axis_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Zero + One> $t<N> impl<N: Zero + One> $t<N> {
{
/// Create a unit vector with its `$comp0` component equal to 1.0. /// Create a unit vector with its `$comp0` component equal to 1.0.
#[inline] #[inline]
pub fn $comp0() -> $t<N> pub fn $comp0() -> $t<N> {
{
let mut res: $t<N> = Zero::zero(); let mut res: $t<N> = Zero::zero();
res.$comp0 = One::one(); res.$comp0 = One::one();
@ -80,8 +79,7 @@ macro_rules! vec_axis_impl(
$( $(
/// Create a unit vector with its `$compN` component equal to 1.0. /// Create a unit vector with its `$compN` component equal to 1.0.
#[inline] #[inline]
pub fn $compN() -> $t<N> pub fn $compN() -> $t<N> {
{
let mut res: $t<N> = Zero::zero(); let mut res: $t<N> = Zero::zero();
res.$compN = One::one(); res.$compN = One::one();
@ -95,42 +93,48 @@ macro_rules! vec_axis_impl(
macro_rules! vec_cast_impl( macro_rules! vec_cast_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<Nin: NumCast + Clone, Nout: NumCast> VecCast<$t<Nout>> for $t<Nin> impl<Nin: NumCast + Clone, Nout: NumCast> VecCast<$t<Nout>> for $t<Nin> {
{
#[inline] #[inline]
pub fn from(v: $t<Nin>) -> $t<Nout> pub fn from(v: $t<Nin>) -> $t<Nout> {
{ $t::new(NumCast::from(v.$comp0.clone()) $(, NumCast::from(v.$compN.clone()))*) } $t::new(NumCast::from(v.$comp0.clone()) $(, NumCast::from(v.$compN.clone()))*)
}
} }
) )
) )
macro_rules! indexable_impl( macro_rules! indexable_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N: Clone> Indexable<uint, N> for $t<N> impl<N: Clone> Indexable<uint, N> for $t<N> {
{
#[inline] #[inline]
pub fn at(&self, i: uint) -> N pub fn at(&self, i: uint) -> N {
{ unsafe { cast::transmute::<&$t<N>, &[N, ..$dim]>(self)[i].clone() } } unsafe {
cast::transmute::<&$t<N>, &[N, ..$dim]>(self)[i].clone()
}
}
#[inline] #[inline]
pub fn set(&mut self, i: uint, val: N) pub fn set(&mut self, i: uint, val: N) {
{ unsafe { cast::transmute::<&mut $t<N>, &mut [N, ..$dim]>(self)[i] = val } } unsafe {
cast::transmute::<&mut $t<N>, &mut [N, ..$dim]>(self)[i] = val
}
}
#[inline] #[inline]
pub fn swap(&mut self, i1: uint, i2: uint) pub fn swap(&mut self, i1: uint, i2: uint) {
{ unsafe { cast::transmute::<&mut $t<N>, &mut [N, ..$dim]>(self).swap(i1, i2) } } unsafe {
cast::transmute::<&mut $t<N>, &mut [N, ..$dim]>(self).swap(i1, i2)
}
}
} }
) )
) )
macro_rules! new_repeat_impl( macro_rules! new_repeat_impl(
($t: ident, $param: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $param: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone> $t<N> impl<N: Clone> $t<N> {
{
/// Creates a new vector with all its components equal to a given value. /// Creates a new vector with all its components equal to a given value.
#[inline] #[inline]
pub fn new_repeat($param: N) -> $t<N> pub fn new_repeat($param: N) -> $t<N> {
{
$t{ $t{
$comp0: $param.clone() $comp0: $param.clone()
$(, $compN: $param.clone() )* $(, $compN: $param.clone() )*
@ -142,43 +146,44 @@ macro_rules! new_repeat_impl(
macro_rules! iterable_impl( macro_rules! iterable_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N> Iterable<N> for $t<N> impl<N> Iterable<N> for $t<N> {
{ fn iter<'l>(&'l self) -> VecIterator<'l, N> {
fn iter<'l>(&'l self) -> VecIterator<'l, N> unsafe {
{ unsafe { cast::transmute::<&'l $t<N>, &'l [N, ..$dim]>(self).iter() } } cast::transmute::<&'l $t<N>, &'l [N, ..$dim]>(self).iter()
}
}
} }
) )
) )
macro_rules! iterable_mut_impl( macro_rules! iterable_mut_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N> IterableMut<N> for $t<N> impl<N> IterableMut<N> for $t<N> {
{ fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> {
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> unsafe {
{ unsafe { cast::transmute::<&'l mut $t<N>, &'l mut [N, ..$dim]>(self).mut_iter() } } cast::transmute::<&'l mut $t<N>, &'l mut [N, ..$dim]>(self).mut_iter()
}
}
} }
) )
) )
macro_rules! dim_impl( macro_rules! dim_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N> Dim for $t<N> impl<N> Dim for $t<N> {
{
#[inline] #[inline]
fn dim() -> uint fn dim() -> uint {
{ $dim } $dim
}
} }
) )
) )
macro_rules! basis_impl( macro_rules! basis_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> Basis for $t<N> impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> Basis for $t<N> {
{ pub fn canonical_basis(f: &fn($t<N>)) {
pub fn canonical_basis(f: &fn($t<N>)) for i in range(0u, $dim) {
{
for i in range(0u, $dim)
{
let mut basis_element : $t<N> = Zero::zero(); let mut basis_element : $t<N> = Zero::zero();
basis_element.set(i, One::one()); basis_element.set(i, One::one());
@ -187,30 +192,29 @@ macro_rules! basis_impl(
} }
} }
pub fn orthonormal_subspace_basis(&self, f: &fn($t<N>)) pub fn orthonormal_subspace_basis(&self, f: &fn($t<N>)) {
{
// compute the basis of the orthogonal subspace using Gram-Schmidt // compute the basis of the orthogonal subspace using Gram-Schmidt
// orthogonalization algorithm // orthogonalization algorithm
let mut basis: ~[$t<N>] = ~[]; let mut basis: ~[$t<N>] = ~[];
for i in range(0u, $dim) for i in range(0u, $dim) {
{
let mut basis_element : $t<N> = Zero::zero(); let mut basis_element : $t<N> = Zero::zero();
basis_element.set(i, One::one()); basis_element.set(i, One::one());
if basis.len() == $dim - 1 if basis.len() == $dim - 1 {
{ break; } break;
}
let mut elt = basis_element.clone(); let mut elt = basis_element.clone();
elt = elt - self.scalar_mul(&basis_element.dot(self)); elt = elt - self.scalar_mul(&basis_element.dot(self));
for v in basis.iter() for v in basis.iter() {
{ elt = elt - v.scalar_mul(&elt.dot(v)) }; elt = elt - v.scalar_mul(&elt.dot(v))
};
if !elt.sqnorm().approx_eq(&Zero::zero()) if !elt.sqnorm().approx_eq(&Zero::zero()) {
{
let new_element = elt.normalized(); let new_element = elt.normalized();
f(new_element.clone()); f(new_element.clone());
@ -225,70 +229,69 @@ macro_rules! basis_impl(
macro_rules! add_impl( macro_rules! add_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + Add<N, N>> Add<$t<N>, $t<N>> for $t<N> impl<N: Clone + Add<N, N>> Add<$t<N>, $t<N>> for $t<N> {
{
#[inline] #[inline]
fn add(&self, other: &$t<N>) -> $t<N> fn add(&self, other: &$t<N>) -> $t<N> {
{ $t::new(self.$comp0 + other.$comp0 $(, self.$compN + other.$compN)*) } $t::new(self.$comp0 + other.$comp0 $(, self.$compN + other.$compN)*)
}
} }
) )
) )
macro_rules! sub_impl( macro_rules! sub_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + Sub<N, N>> Sub<$t<N>, $t<N>> for $t<N> impl<N: Clone + Sub<N, N>> Sub<$t<N>, $t<N>> for $t<N> {
{
#[inline] #[inline]
fn sub(&self, other: &$t<N>) -> $t<N> fn sub(&self, other: &$t<N>) -> $t<N> {
{ $t::new(self.$comp0 - other.$comp0 $(, self.$compN - other.$compN)*) } $t::new(self.$comp0 - other.$comp0 $(, self.$compN - other.$compN)*)
}
} }
) )
) )
macro_rules! neg_impl( macro_rules! neg_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Neg<N>> Neg<$t<N>> for $t<N> impl<N: Neg<N>> Neg<$t<N>> for $t<N> {
{
#[inline] #[inline]
fn neg(&self) -> $t<N> fn neg(&self) -> $t<N> {
{ $t::new(-self.$comp0 $(, -self.$compN )*) } $t::new(-self.$comp0 $(, -self.$compN )*)
}
} }
) )
) )
macro_rules! dot_impl( macro_rules! dot_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Ring> Dot<N> for $t<N> impl<N: Ring> Dot<N> for $t<N> {
{
#[inline] #[inline]
fn dot(&self, other: &$t<N>) -> N fn dot(&self, other: &$t<N>) -> N {
{ self.$comp0 * other.$comp0 $(+ self.$compN * other.$compN )* } self.$comp0 * other.$comp0 $(+ self.$compN * other.$compN )*
}
} }
) )
) )
macro_rules! sub_dot_impl( macro_rules! sub_dot_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + Ring> SubDot<N> for $t<N> impl<N: Clone + Ring> SubDot<N> for $t<N> {
{
#[inline] #[inline]
fn sub_dot(&self, a: &$t<N>, b: &$t<N>) -> N fn sub_dot(&self, a: &$t<N>, b: &$t<N>) -> N {
{ (self.$comp0 - a.$comp0) * b.$comp0 $(+ (self.$compN - a.$compN) * b.$compN )* } (self.$comp0 - a.$comp0) * b.$comp0 $(+ (self.$compN - a.$compN) * b.$compN )*
}
} }
) )
) )
macro_rules! scalar_mul_impl( macro_rules! scalar_mul_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Mul<N, N>> ScalarMul<N> for $t<N> impl<N: Mul<N, N>> ScalarMul<N> for $t<N> {
{
#[inline] #[inline]
fn scalar_mul(&self, s: &N) -> $t<N> fn scalar_mul(&self, s: &N) -> $t<N> {
{ $t::new(self.$comp0 * *s $(, self.$compN * *s)*) } $t::new(self.$comp0 * *s $(, self.$compN * *s)*)
}
#[inline] #[inline]
fn scalar_mul_inplace(&mut self, s: &N) fn scalar_mul_inplace(&mut self, s: &N) {
{
self.$comp0 = self.$comp0 * *s; self.$comp0 = self.$comp0 * *s;
$(self.$compN = self.$compN * *s;)* $(self.$compN = self.$compN * *s;)*
} }
@ -298,15 +301,14 @@ macro_rules! scalar_mul_impl(
macro_rules! scalar_div_impl( macro_rules! scalar_div_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Div<N, N>> ScalarDiv<N> for $t<N> impl<N: Div<N, N>> ScalarDiv<N> for $t<N> {
{
#[inline] #[inline]
fn scalar_div(&self, s: &N) -> $t<N> fn scalar_div(&self, s: &N) -> $t<N> {
{ $t::new(self.$comp0 / *s $(, self.$compN / *s)*) } $t::new(self.$comp0 / *s $(, self.$compN / *s)*)
}
#[inline] #[inline]
fn scalar_div_inplace(&mut self, s: &N) fn scalar_div_inplace(&mut self, s: &N) {
{
self.$comp0 = self.$comp0 / *s; self.$comp0 = self.$comp0 / *s;
$(self.$compN = self.$compN / *s;)* $(self.$compN = self.$compN / *s;)*
} }
@ -316,15 +318,14 @@ macro_rules! scalar_div_impl(
macro_rules! scalar_add_impl( macro_rules! scalar_add_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Add<N, N>> ScalarAdd<N> for $t<N> impl<N: Add<N, N>> ScalarAdd<N> for $t<N> {
{
#[inline] #[inline]
fn scalar_add(&self, s: &N) -> $t<N> fn scalar_add(&self, s: &N) -> $t<N> {
{ $t::new(self.$comp0 + *s $(, self.$compN + *s)*) } $t::new(self.$comp0 + *s $(, self.$compN + *s)*)
}
#[inline] #[inline]
fn scalar_add_inplace(&mut self, s: &N) fn scalar_add_inplace(&mut self, s: &N) {
{
self.$comp0 = self.$comp0 + *s; self.$comp0 = self.$comp0 + *s;
$(self.$compN = self.$compN + *s;)* $(self.$compN = self.$compN + *s;)*
} }
@ -334,15 +335,14 @@ macro_rules! scalar_add_impl(
macro_rules! scalar_sub_impl( macro_rules! scalar_sub_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Sub<N, N>> ScalarSub<N> for $t<N> impl<N: Sub<N, N>> ScalarSub<N> for $t<N> {
{
#[inline] #[inline]
fn scalar_sub(&self, s: &N) -> $t<N> fn scalar_sub(&self, s: &N) -> $t<N> {
{ $t::new(self.$comp0 - *s $(, self.$compN - *s)*) } $t::new(self.$comp0 - *s $(, self.$compN - *s)*)
}
#[inline] #[inline]
fn scalar_sub_inplace(&mut self, s: &N) fn scalar_sub_inplace(&mut self, s: &N) {
{
self.$comp0 = self.$comp0 - *s; self.$comp0 = self.$comp0 - *s;
$(self.$compN = self.$compN - *s;)* $(self.$compN = self.$compN - *s;)*
} }
@ -352,49 +352,51 @@ macro_rules! scalar_sub_impl(
macro_rules! translation_impl( macro_rules! translation_impl(
($t: ident) => ( ($t: ident) => (
impl<N: Clone + Add<N, N> + Neg<N>> Translation<$t<N>> for $t<N> impl<N: Clone + Add<N, N> + Neg<N>> Translation<$t<N>> for $t<N> {
{
#[inline] #[inline]
fn translation(&self) -> $t<N> fn translation(&self) -> $t<N> {
{ self.clone() } self.clone()
}
#[inline] #[inline]
fn inv_translation(&self) -> $t<N> fn inv_translation(&self) -> $t<N> {
{ -self } -self
}
#[inline] #[inline]
fn translate_by(&mut self, t: &$t<N>) fn translate_by(&mut self, t: &$t<N>) {
{ *self = *self + *t; } *self = *self + *t;
}
} }
) )
) )
macro_rules! translatable_impl( macro_rules! translatable_impl(
($t: ident) => ( ($t: ident) => (
impl<N: Add<N, N> + Neg<N> + Clone> Translatable<$t<N>, $t<N>> for $t<N> impl<N: Add<N, N> + Neg<N> + Clone> Translatable<$t<N>, $t<N>> for $t<N> {
{
#[inline] #[inline]
fn translated(&self, t: &$t<N>) -> $t<N> fn translated(&self, t: &$t<N>) -> $t<N> {
{ self + *t } self + *t
}
} }
) )
) )
macro_rules! norm_impl( macro_rules! norm_impl(
($t: ident) => ( ($t: ident) => (
impl<N: Clone + DivisionRing + Algebraic> Norm<N> for $t<N> impl<N: Clone + DivisionRing + Algebraic> Norm<N> for $t<N> {
{
#[inline] #[inline]
fn sqnorm(&self) -> N fn sqnorm(&self) -> N {
{ self.dot(self) } self.dot(self)
}
#[inline] #[inline]
fn norm(&self) -> N fn norm(&self) -> N {
{ self.sqnorm().sqrt() } self.sqnorm().sqrt()
}
#[inline] #[inline]
fn normalized(&self) -> $t<N> fn normalized(&self) -> $t<N> {
{
let mut res : $t<N> = self.clone(); let mut res : $t<N> = self.clone();
res.normalize(); res.normalize();
@ -403,8 +405,7 @@ macro_rules! norm_impl(
} }
#[inline] #[inline]
fn normalize(&mut self) -> N fn normalize(&mut self) -> N {
{
let l = self.norm(); let l = self.norm();
self.scalar_div_inplace(&l); self.scalar_div_inplace(&l);
@ -417,65 +418,66 @@ macro_rules! norm_impl(
macro_rules! approx_eq_impl( macro_rules! approx_eq_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
{
#[inline] #[inline]
fn approx_epsilon() -> N fn approx_epsilon() -> N {
{ ApproxEq::approx_epsilon::<N, N>() } ApproxEq::approx_epsilon::<N, N>()
}
#[inline] #[inline]
fn approx_eq(&self, other: &$t<N>) -> bool fn approx_eq(&self, other: &$t<N>) -> bool {
{ self.$comp0.approx_eq(&other.$comp0) $(&& self.$compN.approx_eq(&other.$compN))* } self.$comp0.approx_eq(&other.$comp0) $(&& self.$compN.approx_eq(&other.$compN))*
}
#[inline] #[inline]
fn approx_eq_eps(&self, other: &$t<N>, eps: &N) -> bool fn approx_eq_eps(&self, other: &$t<N>, eps: &N) -> bool {
{ self.$comp0.approx_eq_eps(&other.$comp0, eps) $(&& self.$compN.approx_eq_eps(&other.$compN, eps))* } self.$comp0.approx_eq_eps(&other.$comp0, eps) $(&& self.$compN.approx_eq_eps(&other.$compN, eps))*
}
} }
) )
) )
macro_rules! one_impl( macro_rules! one_impl(
($t: ident) => ( ($t: ident) => (
impl<N: Clone + One> One for $t<N> impl<N: Clone + One> One for $t<N> {
{
#[inline] #[inline]
fn one() -> $t<N> fn one() -> $t<N> {
{ $t::new_repeat(One::one()) } $t::new_repeat(One::one())
}
} }
) )
) )
macro_rules! from_iterator_impl( macro_rules! from_iterator_impl(
($t: ident, $param0: ident $(, $paramN: ident)*) => ( ($t: ident, $param0: ident $(, $paramN: ident)*) => (
impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for $t<N> impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for $t<N> {
{ fn from_iterator($param0: &mut Iter) -> $t<N> {
fn from_iterator($param0: &mut Iter) -> $t<N> $t::new($param0.next().unwrap() $(, $paramN.next().unwrap())*)
{ $t::new($param0.next().unwrap() $(, $paramN.next().unwrap())*) } }
} }
) )
) )
macro_rules! bounded_impl( macro_rules! bounded_impl(
($t: ident) => ( ($t: ident) => (
impl<N: Bounded + Clone> Bounded for $t<N> impl<N: Bounded + Clone> Bounded for $t<N> {
{
#[inline] #[inline]
fn max_value() -> $t<N> fn max_value() -> $t<N> {
{ $t::new_repeat(Bounded::max_value()) } $t::new_repeat(Bounded::max_value())
}
#[inline] #[inline]
fn min_value() -> $t<N> fn min_value() -> $t<N> {
{ $t::new_repeat(Bounded::min_value()) } $t::new_repeat(Bounded::min_value())
}
} }
) )
) )
macro_rules! to_homogeneous_impl( macro_rules! to_homogeneous_impl(
($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + One + Zero> ToHomogeneous<$t2<N>> for $t<N> impl<N: Clone + One + Zero> ToHomogeneous<$t2<N>> for $t<N> {
{ fn to_homogeneous(&self) -> $t2<N> {
fn to_homogeneous(&self) -> $t2<N>
{
let mut res: $t2<N> = One::one(); let mut res: $t2<N> = One::one();
res.$comp0 = self.$comp0.clone(); res.$comp0 = self.$comp0.clone();
@ -489,10 +491,8 @@ macro_rules! to_homogeneous_impl(
macro_rules! from_homogeneous_impl( macro_rules! from_homogeneous_impl(
($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + Div<N, N> + One + Zero> FromHomogeneous<$t2<N>> for $t<N> impl<N: Clone + Div<N, N> + One + Zero> FromHomogeneous<$t2<N>> for $t<N> {
{ fn from(v: &$t2<N>) -> $t<N> {
fn from(v: &$t2<N>) -> $t<N>
{
let mut res: $t<N> = Zero::zero(); let mut res: $t<N> = Zero::zero();
res.$comp0 = v.$comp0.clone(); res.$comp0 = v.$comp0.clone();

View File

@ -6,18 +6,16 @@ use traits::norm::Norm;
use traits::sample::UniformSphereSample; use traits::sample::UniformSphereSample;
use vec::{Vec1, Vec2, Vec3}; use vec::{Vec1, Vec2, Vec3};
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec1<N>> for Vec2<N> impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec1<N>> for Vec2<N> {
{
#[inline] #[inline]
fn cross(&self, other : &Vec2<N>) -> Vec1<N> fn cross(&self, other : &Vec2<N>) -> Vec1<N> {
{ Vec1::new(self.x * other.y - self.y * other.x) } Vec1::new(self.x * other.y - self.y * other.x)
}
} }
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec3<N>> for Vec3<N> impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec3<N>> for Vec3<N> {
{
#[inline] #[inline]
fn cross(&self, other : &Vec3<N>) -> Vec3<N> fn cross(&self, other : &Vec3<N>) -> Vec3<N> {
{
Vec3::new( Vec3::new(
self.y * other.z - self.z * other.y, self.y * other.z - self.z * other.y,
self.z * other.x - self.x * other.z, self.z * other.x - self.x * other.z,
@ -26,50 +24,47 @@ impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec3<N>> for Vec3<N>
} }
} }
impl<N: One> Basis for Vec1<N> impl<N: One> Basis for Vec1<N> {
{
#[inline(always)] #[inline(always)]
fn canonical_basis(f: &fn(Vec1<N>)) fn canonical_basis(f: &fn(Vec1<N>)) {
{ f(Vec1::new(One::one())) } f(Vec1::new(One::one()))
}
#[inline(always)] #[inline(always)]
fn orthonormal_subspace_basis(&self, _: &fn(Vec1<N>)) fn orthonormal_subspace_basis(&self, _: &fn(Vec1<N>)) { }
{ }
} }
impl<N: Clone + One + Zero + Neg<N>> Basis for Vec2<N> impl<N: Clone + One + Zero + Neg<N>> Basis for Vec2<N> {
{
#[inline] #[inline]
fn canonical_basis(f: &fn(Vec2<N>)) fn canonical_basis(f: &fn(Vec2<N>)) {
{
f(Vec2::new(One::one(), Zero::zero())); f(Vec2::new(One::one(), Zero::zero()));
f(Vec2::new(Zero::zero(), One::one())); f(Vec2::new(Zero::zero(), One::one()));
} }
#[inline] #[inline]
fn orthonormal_subspace_basis(&self, f: &fn(Vec2<N>)) fn orthonormal_subspace_basis(&self, f: &fn(Vec2<N>)) {
{ f(Vec2::new(-self.y, self.x.clone())) } f(Vec2::new(-self.y, self.x.clone()))
}
} }
impl<N: Clone + DivisionRing + Ord + Algebraic + Signed> impl<N: Clone + DivisionRing + Ord + Algebraic + Signed>
Basis for Vec3<N> Basis for Vec3<N> {
{
#[inline(always)] #[inline(always)]
fn canonical_basis(f: &fn(Vec3<N>)) fn canonical_basis(f: &fn(Vec3<N>)) {
{
f(Vec3::new(One::one(), Zero::zero(), Zero::zero())); f(Vec3::new(One::one(), Zero::zero(), Zero::zero()));
f(Vec3::new(Zero::zero(), One::one(), Zero::zero())); f(Vec3::new(Zero::zero(), One::one(), Zero::zero()));
f(Vec3::new(Zero::zero(), Zero::zero(), One::one())); f(Vec3::new(Zero::zero(), Zero::zero(), One::one()));
} }
#[inline(always)] #[inline(always)]
fn orthonormal_subspace_basis(&self, f: &fn(Vec3<N>)) fn orthonormal_subspace_basis(&self, f: &fn(Vec3<N>)) {
{
let a = let a =
if self.x.clone().abs() > self.y.clone().abs() if self.x.clone().abs() > self.y.clone().abs() {
{ Vec3::new(self.z.clone(), Zero::zero(), -self.x).normalized() } Vec3::new(self.z.clone(), Zero::zero(), -self.x).normalized()
else }
{ Vec3::new(Zero::zero(), -self.z, self.y.clone()).normalized() }; else {
Vec3::new(Zero::zero(), -self.z, self.y.clone()).normalized()
};
f(a.cross(self)); f(a.cross(self));
f(a); f(a);
@ -147,20 +142,18 @@ static SAMPLES_3_F64: [Vec3<f64>, ..42] = [
Vec3 { x: 0.162456 , y: 0.499995 , z: 0.850654 } Vec3 { x: 0.162456 , y: 0.499995 , z: 0.850654 }
]; ];
impl UniformSphereSample for Vec2<f64> impl UniformSphereSample for Vec2<f64> {
{ pub fn sample(f: &fn(&'static Vec2<f64>)) {
pub fn sample(f: &fn(&'static Vec2<f64>)) for sample in SAMPLES_2_F64.iter() {
{ f(sample)
for sample in SAMPLES_2_F64.iter() }
{ f(sample) }
} }
} }
impl UniformSphereSample for Vec3<f64> impl UniformSphereSample for Vec3<f64> {
{ pub fn sample(f: &fn(&'static Vec3<f64>)) {
pub fn sample(f: &fn(&'static Vec3<f64>)) for sample in SAMPLES_3_F64.iter() {
{ f(sample)
for sample in SAMPLES_3_F64.iter() }
{ f(sample) }
} }
} }