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
/// properties useful for performances, like the fact that the inversion is simply a transposition.
#[deriving(Eq, ToStr, Clone)]
pub struct Rotmat<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() }
pub struct Rotmat<M> {
priv submat: M
}
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<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 + 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.
///
/// # Arguments
/// * `axisangle` - A vector representing the rotation. Its magnitude is the amount of rotation
/// in radian. Its direction is the axis of rotation.
pub fn from_axis_angle(axisangle: Vec3<N>) -> Rotmat<Mat3<N>>
{
if axisangle.sqnorm().is_zero()
{ One::one() }
else
{
pub fn from_axis_angle(axisangle: Vec3<N>) -> Rotmat<Mat3<N>> {
if axisangle.sqnorm().is_zero() {
One::one()
}
else {
let mut axis = axisangle;
let angle = axis.normalize();
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
/// usually known `look_at` function does the same thing but with the `z` axis. See `look_at_z`
/// for that.
@ -95,8 +93,7 @@ impl<N: Clone + DivisionRing + Algebraic> Rotmat<Mat3<N>>
/// with
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
/// 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 zaxis = up.cross(&xaxis).normalized();
let yaxis = zaxis.cross(&xaxis);
@ -113,8 +110,7 @@ impl<N: Clone + DivisionRing + Algebraic> Rotmat<Mat3<N>>
/// with
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
/// 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 xaxis = up.cross(&zaxis).normalized();
let yaxis = zaxis.cross(&xaxis);
@ -126,171 +122,179 @@ impl<N: Clone + DivisionRing + Algebraic> Rotmat<Mat3<N>>
}
impl<N: Trigonometric + DivisionRing + Clone>
Rotation<Vec1<N>> for Rotmat<Mat2<N>>
{
Rotation<Vec1<N>> for Rotmat<Mat2<N>> {
#[inline]
fn rotation(&self) -> Vec1<N>
{ Vec1::new((-self.submat.at((0, 1))).atan2(&self.submat.at((0, 0)))) }
fn rotation(&self) -> Vec1<N> {
Vec1::new((-self.submat.at((0, 1))).atan2(&self.submat.at((0, 0))))
}
#[inline]
fn inv_rotation(&self) -> Vec1<N>
{ -self.rotation() }
fn inv_rotation(&self) -> Vec1<N> {
-self.rotation()
}
#[inline]
fn rotate_by(&mut self, rot: &Vec1<N>)
{ *self = self.rotated(rot) }
fn rotate_by(&mut self, rot: &Vec1<N>) {
*self = self.rotated(rot)
}
}
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]
fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>>
{ Rotmat::from_angle(rot.x.clone()) * *self }
fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>> {
Rotmat::from_angle(rot.x.clone()) * *self
}
}
impl<N: Clone + Trigonometric + DivisionRing + Algebraic>
Rotation<Vec3<N>> for Rotmat<Mat3<N>>
{
#[inline]
fn rotation(&self) -> Vec3<N>
{ fail!("Not yet implemented.") }
Rotation<Vec3<N>> for Rotmat<Mat3<N>> {
#[inline]
fn rotation(&self) -> Vec3<N> {
fail!("Not yet implemented.")
}
fn inv_rotation(&self) -> Vec3<N>
{ fail!("Not yet implemented.") }
#[inline]
fn inv_rotation(&self) -> Vec3<N> {
fail!("Not yet implemented.")
}
#[inline]
fn rotate_by(&mut self, rot: &Vec3<N>)
{ *self = self.rotated(rot) }
fn rotate_by(&mut self, rot: &Vec3<N>) {
*self = self.rotated(rot)
}
}
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]
fn rotated(&self, axisangle: &Vec3<N>) -> Rotmat<Mat3<N>>
{ Rotmat::from_axis_angle(axisangle.clone()) * *self }
fn rotated(&self, axisangle: &Vec3<N>) -> Rotmat<Mat3<N>> {
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]
fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat2<N>>
{ Rotmat::from_angle(rng.gen()) }
fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat2<N>> {
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]
fn rotate(&self, v: &V) -> V
{ self.rmul(v) }
fn rotate(&self, v: &V) -> V {
self.rmul(v)
}
#[inline]
fn inv_rotate(&self, v: &V) -> V
{ self.lmul(v) }
fn inv_rotate(&self, v: &V) -> 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]
fn transform_vec(&self, v: &V) -> V
{ self.rotate(v) }
fn transform_vec(&self, v: &V) -> V {
self.rotate(v)
}
#[inline]
fn inv_transform(&self, v: &V) -> V
{ self.inv_rotate(v) }
fn inv_transform(&self, v: &V) -> V {
self.inv_rotate(v)
}
}
impl<N: Clone + Rand + Trigonometric + DivisionRing + Algebraic>
Rand for Rotmat<Mat3<N>>
{
Rand for Rotmat<Mat3<N>> {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat3<N>>
{ Rotmat::from_axis_angle(rng.gen()) }
fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat3<N>> {
Rotmat::from_axis_angle(rng.gen())
}
}
impl<M: Dim> Dim for Rotmat<M>
{
impl<M: Dim> Dim for Rotmat<M> {
#[inline]
fn dim() -> uint
{ Dim::dim::<M>() }
fn dim() -> uint {
Dim::dim::<M>()
}
}
impl<M: One + Zero> One for Rotmat<M>
{
impl<M: One + Zero> One for Rotmat<M> {
#[inline]
fn one() -> Rotmat<M>
{ Rotmat { submat: One::one() } }
fn one() -> Rotmat<M> {
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]
fn mul(&self, other: &Rotmat<M>) -> Rotmat<M>
{ Rotmat { submat: self.submat.mul(&other.submat) } }
fn mul(&self, other: &Rotmat<M>) -> Rotmat<M> {
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]
fn rmul(&self, other: &V) -> V
{ self.submat.rmul(other) }
fn rmul(&self, other: &V) -> V {
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]
fn lmul(&self, other: &V) -> V
{ self.submat.lmul(other) }
fn lmul(&self, other: &V) -> V {
self.submat.lmul(other)
}
}
impl<M: Transpose> Inv for Rotmat<M>
{
impl<M: Transpose> Inv for Rotmat<M> {
#[inline]
fn inplace_inverse(&mut self) -> bool
{
fn inplace_inverse(&mut self) -> bool {
self.transpose();
true
}
#[inline]
fn inverse(&self) -> Option<Rotmat<M>>
{ Some(self.transposed()) }
fn inverse(&self) -> Option<Rotmat<M>> {
Some(self.transposed())
}
}
impl<M: Transpose>
Transpose for Rotmat<M>
{
Transpose for Rotmat<M> {
#[inline]
fn transposed(&self) -> Rotmat<M>
{ Rotmat { submat: self.submat.transposed() } }
fn transposed(&self) -> Rotmat<M> {
Rotmat { submat: self.submat.transposed() }
}
#[inline]
fn transpose(&mut self)
{ self.submat.transpose() }
fn transpose(&mut self) {
self.submat.transpose()
}
}
// we loose the info that we are a rotation matrix
impl<M: ToHomogeneous<M2>, M2> ToHomogeneous<M2> for Rotmat<M>
{
fn to_homogeneous(&self) -> M2
{ self.submat.to_homogeneous() }
impl<M: ToHomogeneous<M2>, M2> ToHomogeneous<M2> for Rotmat<M> {
fn to_homogeneous(&self) -> M2 {
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]
fn approx_epsilon() -> N
{ ApproxEq::approx_epsilon::<N, N>() }
fn approx_epsilon() -> N {
ApproxEq::approx_epsilon::<N, N>()
}
#[inline]
fn approx_eq(&self, other: &Rotmat<M>) -> bool
{ self.submat.approx_eq(&other.submat) }
fn approx_eq(&self, other: &Rotmat<M>) -> bool {
self.submat.approx_eq(&other.submat)
}
#[inline]
fn approx_eq_eps(&self, other: &Rotmat<M>, epsilon: &N) -> bool
{ self.submat.approx_eq_eps(&other.submat, epsilon) }
fn approx_eq_eps(&self, other: &Rotmat<M>, epsilon: &N) -> bool {
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
/// inverting the homogeneous matrix itself.
#[deriving(Eq, ToStr, Clone)]
pub struct Transform<M, V>
{
pub struct Transform<M, V> {
priv submat : M,
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.
#[inline]
pub fn new(mat: M, trans: V) -> Transform<M, V>
{ Transform { submat: mat, subtrans: trans } }
pub fn new(mat: M, trans: V) -> Transform<M, V> {
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.
#[inline]
pub fn submat(&self) -> M
{ self.submat.clone() }
pub fn submat(&self) -> M {
self.submat.clone()
}
/// Gets a copy of the internal translation.
#[inline]
pub fn subtrans(&self) -> V
{ self.subtrans.clone() }
pub fn subtrans(&self) -> V {
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
/// direction. Note that the usually known `look_at` function does the same thing but with the
/// `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
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
/// 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.subtrans = eye.clone();
}
@ -77,112 +78,119 @@ impl<N: Clone + DivisionRing + Algebraic> Transform<Rotmat<Mat3<N>>, Vec3<N>>
/// aligned with
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
/// 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.subtrans = eye.clone();
}
}
impl<M: Dim, V> Dim for Transform<M, V>
{
impl<M: Dim, V> Dim for Transform<M, V> {
#[inline]
fn dim() -> uint
{ 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) }
fn dim() -> uint {
Dim::dim::<M>()
}
}
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]
fn rmul(&self, other: &V) -> V
{ self.submat.rmul(other) + self.subtrans }
fn one() -> Transform<M, V> {
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]
fn lmul(&self, other: &V) -> V
{ self.submat.lmul(other) + self.subtrans }
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, 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]
fn translation(&self) -> V
{ self.subtrans.translation() }
#[inline]
fn inv_translation(&self) -> V
{ self.subtrans.inv_translation() }
#[inline]
fn translate_by(&mut self, t: &V)
{ self.subtrans.translate_by(t) }
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: 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]
fn translate(&self, v: &V) -> V
{ self.submat.translate(v) }
fn rmul(&self, other: &V) -> 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]
fn inv_translate(&self, v: &V) -> V
{ self.submat.inv_translate(v) }
fn inv_translation(&self) -> V {
self.subtrans.inv_translation()
}
#[inline]
fn translate_by(&mut self, t: &V) {
self.subtrans.translate_by(t)
}
}
impl<M: Translate<V>, V, _0> Translate<V> for Transform<M, _0> {
#[inline]
fn translate(&self, v: &V) -> V {
self.submat.translate(v)
}
#[inline]
fn inv_translate(&self, v: &V) -> V {
self.submat.inv_translate(v)
}
}
impl<M: 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]
fn translated(&self, t: &V) -> Transform<M, V>
{ Transform::new(self.submat.clone(), self.subtrans.translated(t)) }
fn translated(&self, t: &V) -> Transform<M, V> {
Transform::new(self.submat.clone(), self.subtrans.translated(t))
}
}
impl<M: Rotation<AV> + RMul<V> + One, V, AV>
Rotation<AV> for Transform<M, V>
{
Rotation<AV> for Transform<M, V> {
#[inline]
fn rotation(&self) -> AV
{ self.submat.rotation() }
fn rotation(&self) -> AV {
self.submat.rotation()
}
#[inline]
fn inv_rotation(&self) -> AV
{ self.submat.inv_rotation() }
fn inv_rotation(&self) -> AV {
self.submat.inv_rotation()
}
#[inline]
fn rotate_by(&mut self, rot: &AV)
{
fn rotate_by(&mut self, rot: &AV) {
// FIXME: this does not seem opitmal
let mut delta = One::one::<M>();
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]
fn rotate(&self, v: &V) -> V
{ self.submat.rotate(v) }
fn rotate(&self, v: &V) -> V {
self.submat.rotate(v)
}
#[inline]
fn inv_rotate(&self, v: &V) -> V
{ self.submat.inv_rotate(v) }
fn inv_rotate(&self, v: &V) -> V {
self.submat.inv_rotate(v)
}
}
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]
fn rotated(&self, rot: &AV) -> Transform<Res, V>
{
fn rotated(&self, rot: &AV) -> Transform<Res, V> {
// FIXME: this does not seem opitmal
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>
Transformation<Transform<M, V>> for Transform<M, V>
{
fn transformation(&self) -> Transform<M, V>
{ self.clone() }
Transformation<Transform<M, V>> for Transform<M, V> {
fn transformation(&self) -> Transform<M, V> {
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>> ?
match self.inverse()
{
match self.inverse() {
Some(t) => t,
None => fail!("This transformation was not inversible.")
}
}
fn transform_by(&mut self, other: &Transform<M, V>)
{ *self = other * *self; }
fn transform_by(&mut self, other: &Transform<M, V>) {
*self = other * *self
}
}
impl<M: Ts<V>, V: Add<V, V> + Sub<V, V>>
Ts<V> for Transform<M, V>
{
Ts<V> for Transform<M, V> {
#[inline]
fn transform_vec(&self, v: &V) -> V
{ self.submat.transform_vec(v) + self.subtrans }
fn transform_vec(&self, v: &V) -> V {
self.submat.transform_vec(v) + self.subtrans
}
#[inline]
fn inv_transform(&self, v: &V) -> V
{ self.submat.inv_transform(&(v - self.subtrans)) }
fn inv_transform(&self, v: &V) -> V {
self.submat.inv_transform(&(v - self.subtrans))
}
}
// FIXME: constraints are too restrictive.
// Should be: Transformable<M2, // Transform<Res, V> ...
impl<M: RMul<V> + Mul<M, M> + Inv + Clone, V: Add<V, V> + Neg<V> + Clone>
Transformable<Transform<M, V>, Transform<M, V>> for Transform<M, V>
{
fn transformed(&self, t: &Transform<M, V>) -> Transform<M, V>
{ t * *self }
Transformable<Transform<M, V>, Transform<M, V>> for Transform<M, V> {
fn transformed(&self, t: &Transform<M, V>) -> Transform<M, V> {
t * *self
}
}
impl<M: Inv + RMul<V> + Clone, V: Neg<V> + Clone>
Inv for Transform<M, V>
{
Inv for Transform<M, V> {
#[inline]
fn inplace_inverse(&mut self) -> bool
{
if !self.submat.inplace_inverse()
{ false }
else
{
fn inplace_inverse(&mut self) -> bool {
if !self.submat.inplace_inverse() {
false
}
else {
self.subtrans = self.submat.rmul(&-self.subtrans);
true
}
}
#[inline]
fn inverse(&self) -> Option<Transform<M, V>>
{
fn inverse(&self) -> Option<Transform<M, V>> {
let mut res = self.clone();
if res.inplace_inverse()
{ Some(res) }
else
{ None }
if res.inplace_inverse() {
Some(res)
}
else {
None
}
}
}
impl<M: ToHomogeneous<M2>, M2: Dim + Column<V>, V: Clone>
ToHomogeneous<M2> for Transform<M, V>
{
fn to_homogeneous(&self) -> M2
{
ToHomogeneous<M2> for Transform<M, V> {
fn to_homogeneous(&self) -> M2 {
let mut res = self.submat.to_homogeneous();
// copy the translation
@ -301,39 +305,35 @@ ToHomogeneous<M2> for Transform<M, V>
}
impl<M: Column<V> + Dim, M2: FromHomogeneous<M>, V>
FromHomogeneous<M> for Transform<M2, V>
{
fn from(m: &M) -> Transform<M2, V>
{
FromHomogeneous<M> for Transform<M2, V> {
fn from(m: &M) -> Transform<M2, V> {
Transform::new(FromHomogeneous::from(m), m.column(Dim::dim::<M>() - 1))
}
}
impl<N: ApproxEq<N>, M:ApproxEq<N>, V:ApproxEq<N>>
ApproxEq<N> for Transform<M, V>
{
ApproxEq<N> for Transform<M, V> {
#[inline]
fn approx_epsilon() -> N
{ ApproxEq::approx_epsilon::<N, N>() }
fn approx_epsilon() -> N {
ApproxEq::approx_epsilon::<N, N>()
}
#[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.subtrans.approx_eq(&other.subtrans)
}
#[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.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]
fn rand<R: Rng>(rng: &mut R) -> Transform<M, V>
{ Transform::new(rng.gen(), rng.gen()) }
fn rand<R: Rng>(rng: &mut R) -> Transform<M, V> {
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.
#[deriving(Eq, ToStr, Clone)]
pub struct DMat<N>
{
pub struct DMat<N> {
priv dim: uint, // FIXME: handle more than just square matrices
priv mij: ~[N]
}
@ -22,13 +21,15 @@ pub struct DMat<N>
/// * `dim` - The dimension of the matrix. A `dim`-dimensional matrix contains `dim * dim`
/// components.
#[inline]
pub fn zero_mat_with_dim<N: Zero + Clone>(dim: uint) -> DMat<N>
{ DMat { dim: dim, mij: from_elem(dim * dim, Zero::zero()) } }
pub fn zero_mat_with_dim<N: Zero + Clone>(dim: uint) -> DMat<N> {
DMat { dim: dim, mij: from_elem(dim * dim, Zero::zero()) }
}
/// Tests if all components of the matrix are zeroes.
#[inline]
pub fn is_zero_mat<N: Zero>(mat: &DMat<N>) -> bool
{ mat.mij.iter().all(|e| e.is_zero()) }
pub fn is_zero_mat<N: Zero>(mat: &DMat<N>) -> bool {
mat.mij.iter().all(|e| e.is_zero())
}
/// 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`
/// components.
#[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 _1 = One::one::<N>();
for i in range(0u, dim)
{ res.set(i, i, &_1); }
for i in range(0u, dim) {
res.set(i, i, &_1);
}
res
}
impl<N: Clone> DMat<N>
{
impl<N: Clone> DMat<N> {
#[inline]
fn offset(&self, i: uint, j: uint) -> uint
{ i * self.dim + j }
fn offset(&self, i: uint, j: uint) -> uint {
i * self.dim + j
}
/// 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
/// * `j` - 0-based index of the column to be changed
#[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!(j < self.dim);
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
/// * `j` - 0-based index of the column to be read
#[inline]
pub fn at(&self, i: uint, j: uint) -> N
{
pub fn at(&self, i: uint, j: uint) -> N {
assert!(i < self.dim);
assert!(j < self.dim);
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]
fn index(&self, &(i, j): &(uint, uint)) -> N
{ self.at(i, j) }
fn index(&self, &(i, j): &(uint, uint)) -> N {
self.at(i, j)
}
}
impl<N: Clone + Mul<N, N> + Add<N, N> + Zero>
Mul<DMat<N>, DMat<N>> for DMat<N>
{
fn mul(&self, other: &DMat<N>) -> DMat<N>
{
Mul<DMat<N>, DMat<N>> for DMat<N> {
fn mul(&self, other: &DMat<N>) -> DMat<N> {
assert!(self.dim == other.dim);
let dim = self.dim;
let mut res = zero_mat_with_dim(dim);
for i in range(0u, dim)
{
for j in range(0u, dim)
{
for i in range(0u, dim) {
for j in range(0u, dim) {
let mut acc = Zero::zero::<N>();
for k in range(0u, dim)
{ acc = acc + self.at(i, k) * other.at(k, j); }
for k in range(0u, dim) {
acc = acc + self.at(i, k) * other.at(k, j);
}
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>
RMul<DVec<N>> for DMat<N>
{
fn rmul(&self, other: &DVec<N>) -> DVec<N>
{
RMul<DVec<N>> for DMat<N> {
fn rmul(&self, other: &DVec<N>) -> DVec<N> {
assert!(self.dim == other.at.len());
let dim = self.dim;
let mut res : DVec<N> = zero_vec_with_dim(dim);
for i in range(0u, dim)
{
for j in range(0u, dim)
{ res.at[i] = res.at[i] + other.at[j] * self.at(i, j); }
for i in range(0u, dim) {
for j in range(0u, dim) {
res.at[i] = res.at[i] + other.at[j] * self.at(i, j);
}
}
res
@ -135,19 +129,17 @@ RMul<DVec<N>> for DMat<N>
}
impl<N: Clone + Add<N, N> + Mul<N, N> + Zero>
LMul<DVec<N>> for DMat<N>
{
fn lmul(&self, other: &DVec<N>) -> DVec<N>
{
LMul<DVec<N>> for DMat<N> {
fn lmul(&self, other: &DVec<N>) -> DVec<N> {
assert!(self.dim == other.at.len());
let dim = self.dim;
let mut res : DVec<N> = zero_vec_with_dim(dim);
for i in range(0u, dim)
{
for j in range(0u, dim)
{ res.at[i] = res.at[i] + other.at[j] * self.at(j, i); }
for i in range(0u, dim) {
for j in range(0u, dim) {
res.at[i] = res.at[i] + other.at[j] * self.at(j, i);
}
}
res
@ -155,50 +147,47 @@ LMul<DVec<N>> for DMat<N>
}
impl<N: Clone + Eq + DivisionRing>
Inv for DMat<N>
{
Inv for DMat<N> {
#[inline]
fn inverse(&self) -> Option<DMat<N>>
{
fn inverse(&self) -> Option<DMat<N>> {
let mut res : DMat<N> = self.clone();
if res.inplace_inverse()
{ Some(res) }
else
{ None }
if res.inplace_inverse() {
Some(res)
}
else {
None
}
}
fn inplace_inverse(&mut self) -> bool
{
fn inplace_inverse(&mut self) -> bool {
let dim = self.dim;
let mut res = one_mat_with_dim::<N>(dim);
let _0T = Zero::zero::<N>();
// 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
// FIXME: would it be worth it to spend some more time searching for the
// max instead?
let mut n0 = k; // index of a non-zero entry
while (n0 != dim)
{
if self.at(n0, k) != _0T
{ break; }
while (n0 != dim) {
if self.at(n0, k) != _0T {
break;
}
n0 = n0 + 1;
}
if n0 == dim
{ return false }
if n0 == dim {
return false
}
// swap pivot line
if n0 != k
{
for j in range(0u, dim)
{
if n0 != k {
for j in range(0u, dim) {
let off_n0_j = self.offset(n0, j);
let off_k_j = self.offset(k, j);
@ -209,32 +198,26 @@ Inv for DMat<N>
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);
self.set(k, j, selfval);
}
for j in range(0u, dim)
{
for j in range(0u, dim) {
let resval = &(res.at(k, j) / pivot);
res.set(k, j, resval);
}
for l in range(0u, dim)
{
if l != k
{
for l in range(0u, dim) {
if 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);
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);
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]
fn transposed(&self) -> DMat<N>
{
fn transposed(&self) -> DMat<N> {
let mut res = self.clone();
res.transpose();
@ -260,14 +241,11 @@ impl<N: Clone> Transpose for DMat<N>
res
}
fn transpose(&mut self)
{
fn transpose(&mut self) {
let dim = self.dim;
for i in range(1u, dim)
{
for j in range(0u, dim - 1)
{
for i in range(1u, dim) {
for j in range(0u, dim - 1) {
let off_i_j = self.offset(i, j);
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]
fn approx_epsilon() -> 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) }
fn approx_epsilon() -> N {
ApproxEq::approx_epsilon::<N, N>()
}
#[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());
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.
#[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.
at: ~[N]
}
@ -25,50 +24,48 @@ pub struct DVec<N>
/// # Arguments
/// * `dim` - The dimension of the vector.
#[inline]
pub fn zero_vec_with_dim<N: Zero + Clone>(dim: uint) -> DVec<N>
{ DVec { at: from_elem(dim, Zero::zero::<N>()) } }
pub fn zero_vec_with_dim<N: Zero + Clone>(dim: uint) -> DVec<N> {
DVec { at: from_elem(dim, Zero::zero::<N>()) }
}
/// Tests if all components of the vector are zeroes.
#[inline]
pub fn is_zero_vec<N: Zero>(vec: &DVec<N>) -> bool
{ vec.at.iter().all(|e| e.is_zero()) }
impl<N> Iterable<N> for DVec<N>
{
fn iter<'l>(&'l self) -> VecIterator<'l, N>
{ self.at.iter() }
pub fn is_zero_vec<N: Zero>(vec: &DVec<N>) -> bool {
vec.at.iter().all(|e| e.is_zero())
}
impl<N> IterableMut<N> for DVec<N>
{
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N>
{ self.at.mut_iter() }
impl<N> Iterable<N> for DVec<N> {
fn iter<'l>(&'l self) -> VecIterator<'l, N> {
self.at.iter()
}
}
impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for DVec<N>
{
fn from_iterator(mut param: &mut Iter) -> DVec<N>
{
impl<N> IterableMut<N> for DVec<N> {
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> {
self.at.mut_iter()
}
}
impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for DVec<N> {
fn from_iterator(mut param: &mut Iter) -> DVec<N> {
let mut res = DVec { at: ~[] };
for e in param
{ res.at.push(e) }
for e in param {
res.at.push(e)
}
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
/// vectors, mutually orthogonal, with all its component equal to 0.0 exept one which is equal
/// 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>] = ~[];
for i in range(0u, dim)
{
for i in range(0u, dim) {
let mut basis_element : DVec<N> = zero_vec_with_dim(dim);
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
/// `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
// orthogonalization algorithm
let dim = self.at.len();
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());
basis_element.at[i] = One::one();
if res.len() == dim - 1
{ break; }
if res.len() == dim - 1 {
break;
}
let mut elt = basis_element.clone();
elt = elt - self.scalar_mul(&basis_element.dot(self));
for v in res.iter()
{ elt = elt - v.scalar_mul(&elt.dot(v)) };
for v in res.iter() {
elt = elt - v.scalar_mul(&elt.dot(v))
};
if !elt.sqnorm().approx_eq(&Zero::zero())
{ res.push(elt.normalized()); }
if !elt.sqnorm().approx_eq(&Zero::zero()) {
res.push(elt.normalized());
}
}
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]
fn add(&self, other: &DVec<N>) -> DVec<N>
{
fn add(&self, other: &DVec<N>) -> DVec<N> {
assert!(self.at.len() == other.at.len());
DVec {
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]
fn sub(&self, other: &DVec<N>) -> DVec<N>
{
fn sub(&self, other: &DVec<N>) -> DVec<N> {
assert!(self.at.len() == other.at.len());
DVec {
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]
fn neg(&self) -> DVec<N>
{ DVec { at: self.at.iter().transform(|a| -a).collect() } }
fn neg(&self) -> DVec<N> {
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]
fn dot(&self, other: &DVec<N>) -> N
{
fn dot(&self, other: &DVec<N>) -> N {
assert!(self.at.len() == other.at.len());
let mut res = Zero::zero::<N>();
for i in range(0u, self.at.len())
{ res = res + self.at[i] * other.at[i]; }
for i in range(0u, self.at.len()) {
res = res + self.at[i] * other.at[i];
}
res
}
}
impl<N: Ring> SubDot<N> for DVec<N>
{
impl<N: Ring> SubDot<N> for DVec<N> {
#[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>();
for i in range(0u, self.at.len())
{ res = res + (self.at[i] - a.at[i]) * b.at[i]; }
for i in range(0u, self.at.len()) {
res = res + (self.at[i] - a.at[i]) * b.at[i];
}
res
}
}
impl<N: Mul<N, N>> ScalarMul<N> for DVec<N>
{
impl<N: Mul<N, N>> ScalarMul<N> for DVec<N> {
#[inline]
fn scalar_mul(&self, s: &N) -> DVec<N>
{ DVec { at: self.at.iter().transform(|a| a * *s).collect() } }
fn scalar_mul(&self, s: &N) -> DVec<N> {
DVec { at: self.at.iter().transform(|a| a * *s).collect() }
}
#[inline]
fn scalar_mul_inplace(&mut self, s: &N)
{
for i in range(0u, self.at.len())
{ self.at[i] = self.at[i] * *s; }
fn scalar_mul_inplace(&mut self, s: &N) {
for i in range(0u, self.at.len()) {
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]
fn scalar_div(&self, s: &N) -> DVec<N>
{ DVec { at: self.at.iter().transform(|a| a / *s).collect() } }
fn scalar_div(&self, s: &N) -> DVec<N> {
DVec { at: self.at.iter().transform(|a| a / *s).collect() }
}
#[inline]
fn scalar_div_inplace(&mut self, s: &N)
{
for i in range(0u, self.at.len())
{ self.at[i] = self.at[i] / *s; }
fn scalar_div_inplace(&mut self, s: &N) {
for i in range(0u, self.at.len()) {
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]
fn scalar_add(&self, s: &N) -> DVec<N>
{ DVec { at: self.at.iter().transform(|a| a + *s).collect() } }
fn scalar_add(&self, s: &N) -> DVec<N> {
DVec { at: self.at.iter().transform(|a| a + *s).collect() }
}
#[inline]
fn scalar_add_inplace(&mut self, s: &N)
{
for i in range(0u, self.at.len())
{ self.at[i] = self.at[i] + *s; }
fn scalar_add_inplace(&mut self, s: &N) {
for i in range(0u, self.at.len()) {
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]
fn scalar_sub(&self, s: &N) -> DVec<N>
{ DVec { at: self.at.iter().transform(|a| a - *s).collect() } }
fn scalar_sub(&self, s: &N) -> DVec<N> {
DVec { at: self.at.iter().transform(|a| a - *s).collect() }
}
#[inline]
fn scalar_sub_inplace(&mut self, s: &N)
{
for i in range(0u, self.at.len())
{ self.at[i] = self.at[i] - *s; }
fn scalar_sub_inplace(&mut self, s: &N) {
for i in range(0u, self.at.len()) {
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]
fn translation(&self) -> DVec<N>
{ self.clone() }
fn translation(&self) -> DVec<N> {
self.clone()
}
#[inline]
fn inv_translation(&self) -> DVec<N>
{ -self }
fn inv_translation(&self) -> DVec<N> {
-self
}
#[inline]
fn translate_by(&mut self, t: &DVec<N>)
{ *self = *self + *t; }
fn translate_by(&mut self, t: &DVec<N>) {
*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]
fn translated(&self, t: &DVec<N>) -> DVec<N>
{ self + *t }
fn translated(&self, t: &DVec<N>) -> DVec<N> {
self + *t
}
}
impl<N: DivisionRing + Algebraic + Clone> Norm<N> for DVec<N>
{
impl<N: DivisionRing + Algebraic + Clone> Norm<N> for DVec<N> {
#[inline]
fn sqnorm(&self) -> N
{ self.dot(self) }
fn sqnorm(&self) -> N {
self.dot(self)
}
#[inline]
fn norm(&self) -> N
{ self.sqnorm().sqrt() }
fn norm(&self) -> N {
self.sqnorm().sqrt()
}
#[inline]
fn normalized(&self) -> DVec<N>
{
fn normalized(&self) -> DVec<N> {
let mut res : DVec<N> = self.clone();
res.normalize();
@ -275,36 +269,38 @@ impl<N: DivisionRing + Algebraic + Clone> Norm<N> for DVec<N>
}
#[inline]
fn normalize(&mut self) -> N
{
fn normalize(&mut self) -> N {
let l = self.norm();
for i in range(0u, self.at.len())
{ self.at[i] = self.at[i] / l; }
for i in range(0u, self.at.len()) {
self.at[i] = self.at[i] / l;
}
l
}
}
impl<N: ApproxEq<N>> ApproxEq<N> for DVec<N>
{
impl<N: ApproxEq<N>> ApproxEq<N> for DVec<N> {
#[inline]
fn approx_epsilon() -> 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) }
fn approx_epsilon() -> N {
ApproxEq::approx_epsilon::<N, N>()
}
#[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());
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.
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
pub struct Mat1<N>
{
pub struct Mat1<N> {
m11: N
}
@ -56,8 +55,7 @@ from_homogeneous_impl!(Mat1, Mat2, 1, 2)
/// Square matrix of dimension 2.
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
pub struct Mat2<N>
{
pub struct Mat2<N> {
m11: N, m12: N,
m21: N, m22: N
}
@ -85,8 +83,7 @@ from_homogeneous_impl!(Mat2, Mat3, 2, 3)
/// Square matrix of dimension 3.
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
pub struct Mat3<N>
{
pub struct Mat3<N> {
m11: N, m12: N, m13: N,
m21: N, m22: N, m23: N,
m31: N, m32: N, m33: N
@ -118,8 +115,7 @@ from_homogeneous_impl!(Mat3, Mat4, 3, 4)
/// Square matrix of dimension 4.
#[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,
m21: N, m22: N, m23: N, m24: 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.
#[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,
m21: N, m22: N, m23: N, m24: N, m25: 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.
#[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,
m21: N, m22: N, m23: N, m24: N, m25: N, m26: N,
m31: N, m32: N, m33: N, m34: N, m35: N, m36: N,

View File

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

View File

@ -5,26 +5,25 @@ use traits::inv::Inv;
// some specializations:
impl<N: DivisionRing + Clone>
Inv for Mat1<N>
{
Inv for Mat1<N> {
#[inline]
fn inverse(&self) -> Option<Mat1<N>>
{
fn inverse(&self) -> Option<Mat1<N>> {
let mut res : Mat1<N> = self.clone();
if res.inplace_inverse()
{ Some(res) }
else
{ None }
if res.inplace_inverse() {
Some(res)
}
else {
None
}
}
#[inline]
fn inplace_inverse(&mut self) -> bool
{
if self.m11.is_zero()
{ false }
else
{
fn inplace_inverse(&mut self) -> bool {
if self.m11.is_zero() {
false
}
else {
self.m11 = One::one::<N>() / self.m11;
true
}
@ -32,28 +31,27 @@ Inv for Mat1<N>
}
impl<N: DivisionRing + Clone>
Inv for Mat2<N>
{
Inv for Mat2<N> {
#[inline]
fn inverse(&self) -> Option<Mat2<N>>
{
fn inverse(&self) -> Option<Mat2<N>> {
let mut res : Mat2<N> = self.clone();
if res.inplace_inverse()
{ Some(res) }
else
{ None }
if res.inplace_inverse() {
Some(res)
}
else {
None
}
}
#[inline]
fn inplace_inverse(&mut self) -> bool
{
fn inplace_inverse(&mut self) -> bool {
let det = self.m11 * self.m22 - self.m21 * self.m12;
if det.is_zero()
{ false }
else
{
if det.is_zero() {
false
}
else {
*self = Mat2::new(self.m22 / det , -self.m12 / det,
-self.m21 / det, self.m11 / det);
@ -63,22 +61,21 @@ Inv for Mat2<N>
}
impl<N: DivisionRing + Clone>
Inv for Mat3<N>
{
Inv for Mat3<N> {
#[inline]
fn inverse(&self) -> Option<Mat3<N>>
{
fn inverse(&self) -> Option<Mat3<N>> {
let mut res = self.clone();
if res.inplace_inverse()
{ Some(res) }
else
{ None }
if res.inplace_inverse() {
Some(res)
}
else {
None
}
}
#[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_m11_m23 = self.m21 * self.m33 - self.m31 * self.m23;
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.m13 * minor_m11_m22;
if det.is_zero()
{ false }
else
{
if det.is_zero() {
false
}
else {
*self = Mat3::new(
(minor_m12_m23 / 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(
($t: ty) => (
do 10000.times
{
do 10000.times {
let randmat : $t = random();
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(
($t: ty) => (
do 10000.times
{
do 10000.times {
let randmat : $t = random();
assert!(randmat.transposed().transposed().eq(&randmat));
@ -46,58 +44,68 @@ macro_rules! test_transpose_mat_impl(
)
#[test]
fn test_transpose_mat1()
{ test_transpose_mat_impl!(Mat1<f64>); }
fn test_transpose_mat1() {
test_transpose_mat_impl!(Mat1<f64>);
}
#[test]
fn test_transpose_mat2()
{ test_transpose_mat_impl!(Mat2<f64>); }
fn test_transpose_mat2() {
test_transpose_mat_impl!(Mat2<f64>);
}
#[test]
fn test_transpose_mat3()
{ test_transpose_mat_impl!(Mat3<f64>); }
fn test_transpose_mat3() {
test_transpose_mat_impl!(Mat3<f64>);
}
#[test]
fn test_transpose_mat4()
{ test_transpose_mat_impl!(Mat4<f64>); }
fn test_transpose_mat4() {
test_transpose_mat_impl!(Mat4<f64>);
}
#[test]
fn test_transpose_mat5()
{ test_transpose_mat_impl!(Mat5<f64>); }
fn test_transpose_mat5() {
test_transpose_mat_impl!(Mat5<f64>);
}
#[test]
fn test_transpose_mat6()
{ test_transpose_mat_impl!(Mat6<f64>); }
fn test_transpose_mat6() {
test_transpose_mat_impl!(Mat6<f64>);
}
#[test]
fn test_inv_mat1()
{ test_inv_mat_impl!(Mat1<f64>); }
fn test_inv_mat1() {
test_inv_mat_impl!(Mat1<f64>);
}
#[test]
fn test_inv_mat2()
{ test_inv_mat_impl!(Mat2<f64>); }
fn test_inv_mat2() {
test_inv_mat_impl!(Mat2<f64>);
}
#[test]
fn test_inv_mat3()
{ test_inv_mat_impl!(Mat3<f64>); }
fn test_inv_mat3() {
test_inv_mat_impl!(Mat3<f64>);
}
#[test]
fn test_inv_mat4()
{ test_inv_mat_impl!(Mat4<f64>); }
fn test_inv_mat4() {
test_inv_mat_impl!(Mat4<f64>);
}
#[test]
fn test_inv_mat5()
{ test_inv_mat_impl!(Mat5<f64>); }
fn test_inv_mat5() {
test_inv_mat_impl!(Mat5<f64>);
}
#[test]
fn test_inv_mat6()
{ test_inv_mat_impl!(Mat6<f64>); }
fn test_inv_mat6() {
test_inv_mat_impl!(Mat6<f64>);
}
#[test]
fn test_rotation2()
{
do 10000.times
{
fn test_rotation2() {
do 10000.times {
let randmat = One::one::<Rotmat<Mat2<f64>>>();
let ang = &Vec1::new(abs::<f64>(random()) % Real::pi());
@ -106,18 +114,15 @@ fn test_rotation2()
}
#[test]
fn test_index_mat2()
{
fn test_index_mat2() {
let mat: Mat2<f64> = random();
assert!(mat.at((0, 1)) == mat.transposed().at((1, 0)));
}
#[test]
fn test_inv_rotation3()
{
do 10000.times
{
fn test_inv_rotation3() {
do 10000.times {
let randmat = One::one::<Rotmat<Mat3<f64>>>();
let dir: Vec3<f64> = random();
let ang = &dir.normalized().scalar_mul(&(abs::<f64>(random()) % Real::pi()));

View File

@ -22,252 +22,280 @@ use traits::iterable::{Iterable, IterableMut};
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
macro_rules! test_iterator_impl(
($t: ty, $n: ty) => (
do 10000.times
{
let v: $t = random();
let mut mv: $t = v.clone();
let n: $n = random();
($t: ty, $n: ty) => (
do 10000.times {
let v: $t = random();
let mut mv: $t = v.clone();
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()
{ *e = *e * n }
for e in mv.mut_iter() {
*e = *e * n
}
assert!(nv == mv && nv == v.scalar_mul(&n));
}
)
assert!(nv == mv && nv == v.scalar_mul(&n));
}
)
)
macro_rules! test_commut_dot_impl(
($t: ty) => (
do 10000.times
{
let v1 : $t = random();
let v2 : $t = random();
assert!(v1.dot(&v2).approx_eq(&v2.dot(&v1)));
}
);
($t: ty) => (
do 10000.times {
let v1 : $t = random();
let v2 : $t = random();
assert!(v1.dot(&v2).approx_eq(&v2.dot(&v1)));
}
);
)
macro_rules! test_scalar_op_impl(
($t: ty, $n: ty) => (
do 10000.times
{
let v1 : $t = random();
let n : $n = random();
assert!(v1.scalar_mul(&n).scalar_div(&n).approx_eq(&v1));
assert!(v1.scalar_div(&n).scalar_mul(&n).approx_eq(&v1));
assert!(v1.scalar_sub(&n).scalar_add(&n).approx_eq(&v1));
assert!(v1.scalar_add(&n).scalar_sub(&n).approx_eq(&v1));
($t: ty, $n: ty) => (
do 10000.times {
let v1 : $t = random();
let n : $n = random();
assert!(v1.scalar_mul(&n).scalar_div(&n).approx_eq(&v1));
assert!(v1.scalar_div(&n).scalar_mul(&n).approx_eq(&v1));
assert!(v1.scalar_sub(&n).scalar_add(&n).approx_eq(&v1));
assert!(v1.scalar_add(&n).scalar_sub(&n).approx_eq(&v1));
let mut v1 : $t = random();
let v0 : $t = v1.clone();
let n : $n = random();
let mut v1 : $t = random();
let v0 : $t = v1.clone();
let n : $n = random();
v1.scalar_mul_inplace(&n);
v1.scalar_div_inplace(&n);
assert!(v1.approx_eq(&v0));
}
);
v1.scalar_mul_inplace(&n);
v1.scalar_div_inplace(&n);
assert!(v1.approx_eq(&v0));
}
);
)
macro_rules! test_basis_impl(
($t: ty) => (
do 10000.times
{
do Basis::canonical_basis::<$t> |e1|
{
do Basis::canonical_basis::<$t> |e2|
{ assert!(e1 == e2 || e1.dot(&e2).approx_eq(&Zero::zero())) }
($t: ty) => (
do 10000.times {
do Basis::canonical_basis::<$t> |e1| {
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()));
}
}
);
)
macro_rules! test_subspace_basis_impl(
($t: ty) => (
do 10000.times
{
let v : $t = random();
let v1 = v.normalized();
($t: ty) => (
do 10000.times {
let v : $t = random();
let v1 = v.normalized();
do v1.orthonormal_subspace_basis() |e1|
{
// check vectors are orthogonal to v1
assert!(v1.dot(&e1).approx_eq(&Zero::zero()));
// check vectors form an orthonormal basis
assert!(e1.norm().approx_eq(&One::one()));
// check vectors form an ortogonal basis
do v1.orthonormal_subspace_basis() |e2|
{ assert!(e1 == e2 || e1.dot(&e2).approx_eq(&Zero::zero())) }
}
}
);
do v1.orthonormal_subspace_basis() |e1| {
// check vectors are orthogonal to v1
assert!(v1.dot(&e1).approx_eq(&Zero::zero()));
// check vectors form an orthonormal basis
assert!(e1.norm().approx_eq(&One::one()));
// check vectors form an ortogonal basis
do v1.orthonormal_subspace_basis() |e2| {
assert!(e1 == e2 || e1.dot(&e2).approx_eq(&Zero::zero()))
}
}
}
);
)
#[test]
fn test_cross_vec3()
{
do 10000.times
{
let v1 : Vec3<f64> = random();
let v2 : Vec3<f64> = random();
let v3 : Vec3<f64> = v1.cross(&v2);
fn test_cross_vec3() {
do 10000.times {
let v1 : Vec3<f64> = random();
let v2 : Vec3<f64> = random();
let v3 : Vec3<f64> = v1.cross(&v2);
assert!(v3.dot(&v2).approx_eq(&Zero::zero()));
assert!(v3.dot(&v1).approx_eq(&Zero::zero()));
}
assert!(v3.dot(&v2).approx_eq(&Zero::zero()));
assert!(v3.dot(&v1).approx_eq(&Zero::zero()));
}
}
#[test]
fn test_commut_dot_vec0()
{ test_commut_dot_impl!(Vec0<f64>); }
fn test_commut_dot_vec0() {
test_commut_dot_impl!(Vec0<f64>);
}
#[test]
fn test_commut_dot_vec1()
{ test_commut_dot_impl!(Vec1<f64>); }
fn test_commut_dot_vec1() {
test_commut_dot_impl!(Vec1<f64>);
}
#[test]
fn test_commut_dot_vec2()
{ test_commut_dot_impl!(Vec2<f64>); }
fn test_commut_dot_vec2() {
test_commut_dot_impl!(Vec2<f64>);
}
#[test]
fn test_commut_dot_vec3()
{ test_commut_dot_impl!(Vec3<f64>); }
fn test_commut_dot_vec3() {
test_commut_dot_impl!(Vec3<f64>);
}
#[test]
fn test_commut_dot_vec4()
{ test_commut_dot_impl!(Vec4<f64>); }
fn test_commut_dot_vec4() {
test_commut_dot_impl!(Vec4<f64>);
}
#[test]
fn test_commut_dot_vec5()
{ test_commut_dot_impl!(Vec5<f64>); }
fn test_commut_dot_vec5() {
test_commut_dot_impl!(Vec5<f64>);
}
#[test]
fn test_commut_dot_vec6()
{ test_commut_dot_impl!(Vec6<f64>); }
fn test_commut_dot_vec6() {
test_commut_dot_impl!(Vec6<f64>);
}
#[test]
fn test_basis_vec0()
{ test_basis_impl!(Vec0<f64>); }
fn test_basis_vec0() {
test_basis_impl!(Vec0<f64>);
}
#[test]
fn test_basis_vec1()
{ test_basis_impl!(Vec1<f64>); }
fn test_basis_vec1() {
test_basis_impl!(Vec1<f64>);
}
#[test]
fn test_basis_vec2()
{ test_basis_impl!(Vec2<f64>); }
fn test_basis_vec2() {
test_basis_impl!(Vec2<f64>);
}
#[test]
fn test_basis_vec3()
{ test_basis_impl!(Vec3<f64>); }
fn test_basis_vec3() {
test_basis_impl!(Vec3<f64>);
}
#[test]
fn test_basis_vec4()
{ test_basis_impl!(Vec4<f64>); }
fn test_basis_vec4() {
test_basis_impl!(Vec4<f64>);
}
#[test]
fn test_basis_vec5()
{ test_basis_impl!(Vec5<f64>); }
fn test_basis_vec5() {
test_basis_impl!(Vec5<f64>);
}
#[test]
fn test_basis_vec6()
{ test_basis_impl!(Vec6<f64>); }
fn test_basis_vec6() {
test_basis_impl!(Vec6<f64>);
}
#[test]
fn test_subspace_basis_vec0()
{ test_subspace_basis_impl!(Vec0<f64>); }
fn test_subspace_basis_vec0() {
test_subspace_basis_impl!(Vec0<f64>);
}
#[test]
fn test_subspace_basis_vec1()
{ test_subspace_basis_impl!(Vec1<f64>); }
fn test_subspace_basis_vec1() {
test_subspace_basis_impl!(Vec1<f64>);
}
#[test]
fn test_subspace_basis_vec2()
{ test_subspace_basis_impl!(Vec2<f64>); }
fn test_subspace_basis_vec2() {
test_subspace_basis_impl!(Vec2<f64>);
}
#[test]
fn test_subspace_basis_vec3()
{ test_subspace_basis_impl!(Vec3<f64>); }
fn test_subspace_basis_vec3() {
test_subspace_basis_impl!(Vec3<f64>);
}
#[test]
fn test_subspace_basis_vec4()
{ test_subspace_basis_impl!(Vec4<f64>); }
fn test_subspace_basis_vec4() {
test_subspace_basis_impl!(Vec4<f64>);
}
#[test]
fn test_subspace_basis_vec5()
{ test_subspace_basis_impl!(Vec5<f64>); }
fn test_subspace_basis_vec5() {
test_subspace_basis_impl!(Vec5<f64>);
}
#[test]
fn test_subspace_basis_vec6()
{ test_subspace_basis_impl!(Vec6<f64>); }
fn test_subspace_basis_vec6() {
test_subspace_basis_impl!(Vec6<f64>);
}
#[test]
fn test_scalar_op_vec0()
{ test_scalar_op_impl!(Vec0<f64>, f64); }
fn test_scalar_op_vec0() {
test_scalar_op_impl!(Vec0<f64>, f64);
}
#[test]
fn test_scalar_op_vec1()
{ test_scalar_op_impl!(Vec1<f64>, f64); }
fn test_scalar_op_vec1() {
test_scalar_op_impl!(Vec1<f64>, f64);
}
#[test]
fn test_scalar_op_vec2()
{ test_scalar_op_impl!(Vec2<f64>, f64); }
fn test_scalar_op_vec2() {
test_scalar_op_impl!(Vec2<f64>, f64);
}
#[test]
fn test_scalar_op_vec3()
{ test_scalar_op_impl!(Vec3<f64>, f64); }
fn test_scalar_op_vec3() {
test_scalar_op_impl!(Vec3<f64>, f64);
}
#[test]
fn test_scalar_op_vec4()
{ test_scalar_op_impl!(Vec4<f64>, f64); }
fn test_scalar_op_vec4() {
test_scalar_op_impl!(Vec4<f64>, f64);
}
#[test]
fn test_scalar_op_vec5()
{ test_scalar_op_impl!(Vec5<f64>, f64); }
fn test_scalar_op_vec5() {
test_scalar_op_impl!(Vec5<f64>, f64);
}
#[test]
fn test_scalar_op_vec6()
{ test_scalar_op_impl!(Vec6<f64>, f64); }
fn test_scalar_op_vec6() {
test_scalar_op_impl!(Vec6<f64>, f64);
}
#[test]
fn test_iterator_vec0()
{ test_iterator_impl!(Vec0<f64>, f64); }
fn test_iterator_vec0() {
test_iterator_impl!(Vec0<f64>, f64);
}
#[test]
fn test_iterator_vec1()
{ test_iterator_impl!(Vec1<f64>, f64); }
fn test_iterator_vec1() {
test_iterator_impl!(Vec1<f64>, f64);
}
#[test]
fn test_iterator_vec2()
{ test_iterator_impl!(Vec2<f64>, f64); }
fn test_iterator_vec2() {
test_iterator_impl!(Vec2<f64>, f64);
}
#[test]
fn test_iterator_vec3()
{ test_iterator_impl!(Vec3<f64>, f64); }
fn test_iterator_vec3() {
test_iterator_impl!(Vec3<f64>, f64);
}
#[test]
fn test_iterator_vec4()
{ test_iterator_impl!(Vec4<f64>, f64); }
fn test_iterator_vec4() {
test_iterator_impl!(Vec4<f64>, f64);
}
#[test]
fn test_iterator_vec5()
{ test_iterator_impl!(Vec5<f64>, f64); }
fn test_iterator_vec5() {
test_iterator_impl!(Vec5<f64>, f64);
}
#[test]
fn test_iterator_vec6()
{ test_iterator_impl!(Vec6<f64>, f64); }
fn test_iterator_vec6() {
test_iterator_impl!(Vec6<f64>, f64);
}
#[test]
fn test_ord_vec3()
{
fn test_ord_vec3() {
// equality
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)));
@ -287,8 +315,7 @@ fn test_ord_vec3()
}
#[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).min(&Vec3::new(3, 2, 1)), Vec3::new(1, 2, 1));
assert_eq!(

View File

@ -1,6 +1,5 @@
/// 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.
fn canonical_basis(&fn(Self));
@ -8,23 +7,23 @@ pub trait Basis
fn orthonormal_subspace_basis(&self, &fn(Self));
/// 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 = ~[];
do Basis::canonical_basis::<Self> |elem|
{ res.push(elem) }
do Basis::canonical_basis::<Self> |elem| {
res.push(elem)
}
res
}
/// 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 = ~[];
do self.orthonormal_subspace_basis |elem|
{ res.push(elem) }
do self.orthonormal_subspace_basis |elem| {
res.push(elem)
}
res
}

View File

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

View File

@ -1,13 +1,11 @@
/// 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.
fn to_homogeneous(&self) -> U;
}
/// 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
/// `from` to be the iverse of `to_homogeneous`. Typically, `from` will remove some informations
/// unrecoverable by `to_homogeneous`.

View File

@ -7,8 +7,7 @@
/// 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
/// to write to a specific index.
pub trait Indexable<Index, Res>
{
pub trait Indexable<Index, Res> {
/// Reads the `i`-th element of `self`.
fn at(&self, i: Index) -> Res;
/// Writes to the `i`-th element of `self`.

View File

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

View File

@ -1,15 +1,13 @@
use std::vec;
/// 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.
fn iter<'l>(&'l self) -> vec::VecIterator<'l, N>;
}
/// 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.
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.
* 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;
}
pub trait IterableMut<'self, N, I: Iterator<N>>
{
pub trait IterableMut<'self, N, I: Iterator<N>> {
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
/// components.
pub trait MatCast<M>
{
pub trait MatCast<M> {
/// Converts `m` to have the type `M`.
fn from(m: Self) -> M;
}

View File

@ -1,8 +1,7 @@
/**
* 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.
fn norm(&self) -> N;

View File

@ -7,8 +7,7 @@ use std::num::{One, Zero};
* `Zero`) respectively neutral and absorbant wrt the multiplication.
*/
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>
Ring for N;

View File

@ -1,8 +1,7 @@
/**
* Trait of objects having a right multiplication with another element.
*/
pub trait RMul<V>
{
pub trait RMul<V> {
/// Computes self * 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.
*/
pub trait LMul<V>
{
pub trait LMul<V> {
/// Computes v * self
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
/// be appended. A rotation is assumed to be an isomitry without translation
/// and without reflexion.
pub trait Rotation<V>
{
pub trait Rotation<V> {
/// Gets the rotation associated with this object.
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
/// typically implemented by structures requiring an internal restructuration to be able to
/// 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
/// representation has the same format as the one returned by `rotation`.
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
/// rotate vectors.
pub trait Rotate<V>
{
pub trait Rotate<V> {
/// Apply a rotation to an object.
fn rotate(&self, &V) -> V;
/// Apply an inverse rotation to an object.
@ -50,8 +47,7 @@ pub fn rotated_wrt_point<M: Translatable<LV, M2>,
m: &M,
ammount: &AV,
center: &LV)
-> M2
{
-> M2 {
let mut res = m.translated(&-center);
res.rotate_by(ammount);
@ -72,8 +68,7 @@ pub fn rotate_wrt_point<M: Rotation<AV> + Translation<LV>,
AV>(
m: &mut M,
ammount: &AV,
center: &LV)
{
center: &LV) {
m.translate_by(&-center);
m.rotate_by(ammount);
m.translate_by(center);
@ -93,8 +88,9 @@ pub fn rotated_wrt_center<M: Translatable<LV, M2> + Translation<LV>,
AV>(
m: &M,
ammount: &AV)
-> M2
{ rotated_wrt_point(m, ammount, &m.translation()) }
-> M2 {
rotated_wrt_point(m, ammount, &m.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>,
AV>(
m: &mut M,
ammount: &AV)
{
ammount: &AV) {
let t = m.translation();
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
/// approximate a sphere using support mapping functions.
pub trait UniformSphereSample
{
pub trait UniformSphereSample {
/// Iterate throught the samples.
pub fn sample(&fn(&'static Self));
/// Gets the list of all samples.
pub fn sample_list() -> ~[&'static Self]
{
pub fn sample_list() -> ~[&'static Self] {
let mut res = ~[];
do UniformSphereSample::sample::<Self> |s|
{ res.push(s) }
do UniformSphereSample::sample::<Self> |s| {
res.push(s)
}
res
}

View File

@ -1,8 +1,7 @@
/**
* 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.
fn scalar_mul(&self, &N) -> Self;
@ -13,8 +12,7 @@ pub trait ScalarMul<N>
/**
* 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.
fn scalar_div(&self, &N) -> Self;
@ -25,8 +23,7 @@ pub trait ScalarDiv<N>
/**
* 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.
fn scalar_add(&self, &N) -> Self;
@ -37,8 +34,7 @@ pub trait ScalarAdd<N>
/**
* 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.
fn scalar_sub(&self, &N) -> Self;

View File

@ -1,8 +1,7 @@
use traits::dot::Dot;
/// 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
* computing intermediate vectors.

View File

@ -1,8 +1,7 @@
/// 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
/// and without reflexion.
pub trait Transformation<M>
{
pub trait Transformation<M> {
/// Gets the transformation associated with this object.
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
/// transform vectors.
pub trait Transform<V>
{
pub trait Transform<V> {
// XXX: sadly we cannot call this `transform` as it conflicts with the
// iterators' `transform` function (which seems always exist).
/// 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
/// typically implemented by structures requiring an internal restructuration to be able to
/// 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
/// representation has the same format as the one returned by `transformation`.
fn transformed(&self, &M) -> Res;

View File

@ -1,7 +1,6 @@
/// Trait of object which represent a translation, and to wich new translation
/// can be appended.
pub trait Translation<V>
{
pub trait Translation<V> {
// FIXME: add a "from translation: translantion(V) -> Self ?
/// Gets the translation associated with this object.
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
/// rotate vectors.
pub trait Translate<V>
{
pub trait Translate<V> {
/// Apply a translation to an object.
fn translate(&self, &V) -> V;
/// 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
/// typically implemented by structures requiring an internal restructuration to be able to
/// 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
/// representation has the same format as the one returned by `translation`.
fn translated(&self, &V) -> Res;

View File

@ -2,8 +2,7 @@
/// 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
/// is not stable by transposition).
pub trait Transpose
{
pub trait Transpose {
/// Computes the transpose of a matrix.
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
/// components.
pub trait VecCast<V>
{
pub trait VecCast<V> {
/// Converts `v` to have the type `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.
pub trait VectorSpace<N>
: 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>,
N: DivisionRing> VectorSpace<N> for V;

View File

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

View File

@ -16,179 +16,176 @@ use traits::division_ring::DivisionRing;
use traits::indexable::Indexable;
use vec;
impl<N> vec::Vec0<N>
{
impl<N> vec::Vec0<N> {
/// Creates a new vector.
#[inline]
pub fn new() -> vec::Vec0<N>
{ vec::Vec0 }
pub fn new() -> vec::Vec0<N> {
vec::Vec0
}
}
impl<N: Clone> Indexable<uint, N> for vec::Vec0<N>
{
impl<N: Clone> Indexable<uint, N> for vec::Vec0<N> {
#[inline]
pub fn at(&self, _: uint) -> N
{ fail!("Cannot index a Vec0.") }
pub fn at(&self, _: uint) -> N {
fail!("Cannot index a Vec0.")
}
#[inline]
pub fn set(&mut self, _: uint, _: N)
{ }
pub fn set(&mut self, _: uint, _: N) {
}
#[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.
#[inline]
pub fn new_repeat(_: N) -> vec::Vec0<N>
{ vec::Vec0 }
pub fn new_repeat(_: N) -> vec::Vec0<N> {
vec::Vec0
}
}
impl<N> Iterable<N> for vec::Vec0<N>
{
fn iter<'l>(&'l self) -> VecIterator<'l, N>
{ unsafe { cast::transmute::<&'l vec::Vec0<N>, &'l [N, ..0]>(self).iter() } }
impl<N> Iterable<N> for vec::Vec0<N> {
fn iter<'l>(&'l self) -> VecIterator<'l, N> {
unsafe { cast::transmute::<&'l vec::Vec0<N>, &'l [N, ..0]>(self).iter() }
}
}
impl<N> IterableMut<N> for vec::Vec0<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() } }
impl<N> IterableMut<N> for vec::Vec0<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() }
}
}
impl<N> Dim for vec::Vec0<N>
{
impl<N> Dim for vec::Vec0<N> {
#[inline]
fn dim() -> uint
{ 0 }
fn dim() -> uint {
0
}
}
impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> Basis for vec::Vec0<N>
{
pub fn canonical_basis(_: &fn(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 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]
fn add(&self, _: &vec::Vec0<N>) -> vec::Vec0<N>
{ vec::Vec0 }
fn add(&self, _: &vec::Vec0<N>) -> vec::Vec0<N> {
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]
fn sub(&self, _: &vec::Vec0<N>) -> vec::Vec0<N>
{ vec::Vec0 }
fn sub(&self, _: &vec::Vec0<N>) -> vec::Vec0<N> {
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]
fn neg(&self) -> vec::Vec0<N>
{ vec::Vec0 }
fn neg(&self) -> vec::Vec0<N> {
vec::Vec0
}
}
impl<N: Ring> Dot<N> for vec::Vec0<N>
{
impl<N: Ring> Dot<N> for vec::Vec0<N> {
#[inline]
fn dot(&self, _: &vec::Vec0<N>) -> N
{ Zero::zero() }
fn dot(&self, _: &vec::Vec0<N>) -> N {
Zero::zero()
}
}
impl<N: Clone + Ring> SubDot<N> for vec::Vec0<N>
{
impl<N: Clone + Ring> SubDot<N> for vec::Vec0<N> {
#[inline]
fn sub_dot(&self, _: &vec::Vec0<N>, _: &vec::Vec0<N>) -> N
{ Zero::zero() }
fn sub_dot(&self, _: &vec::Vec0<N>, _: &vec::Vec0<N>) -> N {
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]
fn scalar_mul(&self, _: &N) -> vec::Vec0<N>
{ vec::Vec0 }
fn scalar_mul(&self, _: &N) -> vec::Vec0<N> {
vec::Vec0
}
#[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]
fn scalar_div(&self, _: &N) -> vec::Vec0<N>
{ vec::Vec0 }
fn scalar_div(&self, _: &N) -> vec::Vec0<N> {
vec::Vec0
}
#[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]
fn scalar_add(&self, _: &N) -> vec::Vec0<N>
{ vec::Vec0 }
fn scalar_add(&self, _: &N) -> vec::Vec0<N> {
vec::Vec0
}
#[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]
fn scalar_sub(&self, _: &N) -> vec::Vec0<N>
{ vec::Vec0 }
fn scalar_sub(&self, _: &N) -> vec::Vec0<N> {
vec::Vec0
}
#[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]
fn translation(&self) -> vec::Vec0<N>
{ self.clone() }
fn translation(&self) -> vec::Vec0<N> {
self.clone()
}
#[inline]
fn inv_translation(&self) -> vec::Vec0<N>
{ -self }
fn inv_translation(&self) -> vec::Vec0<N> {
-self
}
#[inline]
fn translate_by(&mut self, t: &vec::Vec0<N>)
{ *self = *self + *t; }
fn translate_by(&mut self, t: &vec::Vec0<N>) {
*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]
fn translated(&self, t: &vec::Vec0<N>) -> vec::Vec0<N>
{ self + *t }
fn translated(&self, t: &vec::Vec0<N>) -> vec::Vec0<N> {
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]
fn sqnorm(&self) -> N
{ self.dot(self) }
fn sqnorm(&self) -> N {
self.dot(self)
}
#[inline]
fn norm(&self) -> N
{ self.sqnorm().sqrt() }
fn norm(&self) -> N {
self.sqnorm().sqrt()
}
#[inline]
fn normalized(&self) -> vec::Vec0<N>
{
fn normalized(&self) -> vec::Vec0<N> {
let mut res : vec::Vec0<N> = self.clone();
res.normalize();
@ -197,8 +194,7 @@ impl<N: Clone + DivisionRing + Algebraic> Norm<N> for vec::Vec0<N>
}
#[inline]
fn normalize(&mut self) -> N
{
fn normalize(&mut self) -> N {
let l = self.norm();
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]
fn approx_epsilon() -> N
{ ApproxEq::approx_epsilon::<N, N>() }
fn approx_epsilon() -> N {
ApproxEq::approx_epsilon::<N, N>()
}
#[inline]
fn approx_eq(&self, _: &vec::Vec0<N>) -> bool
{ true }
fn approx_eq(&self, _: &vec::Vec0<N>) -> bool {
true
}
#[inline]
fn approx_eq_eps(&self, _: &vec::Vec0<N>, _: &N) -> bool
{ true }
fn approx_eq_eps(&self, _: &vec::Vec0<N>, _: &N) -> bool {
true
}
}
impl<N: Clone + One> One for vec::Vec0<N>
{
impl<N: Clone + One> One for vec::Vec0<N> {
#[inline]
fn one() -> vec::Vec0<N>
{ vec::Vec0 }
fn one() -> vec::Vec0<N> {
vec::Vec0
}
}
impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for vec::Vec0<N>
{
fn from_iterator(_: &mut Iter) -> vec::Vec0<N>
{ vec::Vec0 }
impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for vec::Vec0<N> {
fn from_iterator(_: &mut Iter) -> vec::Vec0<N> {
vec::Vec0
}
}
impl<N: Bounded + Clone> Bounded for vec::Vec0<N>
{
impl<N: Bounded + Clone> Bounded for vec::Vec0<N> {
#[inline]
fn max_value() -> vec::Vec0<N>
{ vec::Vec0 }
fn max_value() -> vec::Vec0<N> {
vec::Vec0
}
#[inline]
fn min_value() -> vec::Vec0<N>
{ vec::Vec0 }
fn min_value() -> vec::Vec0<N> {
vec::Vec0
}
}

View File

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

View File

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