Flattened the `traits` submodules.
This commit is contained in:
parent
e548e1fa5e
commit
ff24f70332
209
src/mat.rs
209
src/mat.rs
|
@ -1,209 +0,0 @@
|
||||||
use std::cast;
|
|
||||||
use std::uint::iterate;
|
|
||||||
use std::num::{One, Zero};
|
|
||||||
use std::cmp::ApproxEq;
|
|
||||||
use std::iterator::IteratorUtil;
|
|
||||||
use std::vec::{VecIterator, VecMutIterator};
|
|
||||||
use vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6};
|
|
||||||
use traits::dim::Dim;
|
|
||||||
use traits::ring::Ring;
|
|
||||||
use traits::inv::Inv;
|
|
||||||
use traits::division_ring::DivisionRing;
|
|
||||||
use traits::transpose::Transpose;
|
|
||||||
use traits::rlmul::{RMul, LMul};
|
|
||||||
use traits::transformation::Transform;
|
|
||||||
use traits::homogeneous::{FromHomogeneous, ToHomogeneous};
|
|
||||||
use traits::indexable::Indexable;
|
|
||||||
use traits::column::Column;
|
|
||||||
use traits::iterable::{Iterable, IterableMut};
|
|
||||||
|
|
||||||
mod mat_impl;
|
|
||||||
|
|
||||||
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
|
||||||
pub struct Mat1<N>
|
|
||||||
{ m11: N }
|
|
||||||
|
|
||||||
mat_impl!(Mat1, 1, m11)
|
|
||||||
one_impl!(Mat1, _1)
|
|
||||||
iterable_impl!(Mat1, 1)
|
|
||||||
iterable_mut_impl!(Mat1, 1)
|
|
||||||
dim_impl!(Mat1, 1)
|
|
||||||
indexable_impl!(Mat1, 1)
|
|
||||||
mul_impl!(Mat1, 1)
|
|
||||||
rmul_impl!(Mat1, Vec1, 1)
|
|
||||||
lmul_impl!(Mat1, Vec1, 1)
|
|
||||||
transform_impl!(Mat1, Vec1)
|
|
||||||
// (specialized) inv_impl!(Mat1, 1)
|
|
||||||
transpose_impl!(Mat1, 1)
|
|
||||||
approx_eq_impl!(Mat1)
|
|
||||||
column_impl!(Mat1, 1)
|
|
||||||
to_homogeneous_impl!(Mat1, Mat2, 1, 2)
|
|
||||||
from_homogeneous_impl!(Mat1, Mat2, 1, 2)
|
|
||||||
|
|
||||||
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
|
||||||
pub struct Mat2<N>
|
|
||||||
{
|
|
||||||
m11: N, m12: N,
|
|
||||||
m21: N, m22: N
|
|
||||||
}
|
|
||||||
|
|
||||||
mat_impl!(Mat2, 2, m11, m12,
|
|
||||||
m21, m22)
|
|
||||||
one_impl!(Mat2, _1, _0,
|
|
||||||
_0, _1)
|
|
||||||
iterable_impl!(Mat2, 2)
|
|
||||||
iterable_mut_impl!(Mat2, 2)
|
|
||||||
dim_impl!(Mat2, 2)
|
|
||||||
indexable_impl!(Mat2, 2)
|
|
||||||
mul_impl!(Mat2, 2)
|
|
||||||
rmul_impl!(Mat2, Vec2, 2)
|
|
||||||
lmul_impl!(Mat2, Vec2, 2)
|
|
||||||
transform_impl!(Mat2, Vec2)
|
|
||||||
// (specialized) inv_impl!(Mat2, 2)
|
|
||||||
transpose_impl!(Mat2, 2)
|
|
||||||
approx_eq_impl!(Mat2)
|
|
||||||
column_impl!(Mat2, 2)
|
|
||||||
to_homogeneous_impl!(Mat2, Mat3, 2, 3)
|
|
||||||
from_homogeneous_impl!(Mat2, Mat3, 2, 3)
|
|
||||||
|
|
||||||
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
|
||||||
pub struct Mat3<N>
|
|
||||||
{
|
|
||||||
m11: N, m12: N, m13: N,
|
|
||||||
m21: N, m22: N, m23: N,
|
|
||||||
m31: N, m32: N, m33: N
|
|
||||||
}
|
|
||||||
|
|
||||||
mat_impl!(Mat3, 3, m11, m12, m13,
|
|
||||||
m21, m22, m23,
|
|
||||||
m31, m32, m33)
|
|
||||||
one_impl!(Mat3, _1, _0, _0,
|
|
||||||
_0, _1, _0,
|
|
||||||
_0, _0, _1)
|
|
||||||
iterable_impl!(Mat3, 3)
|
|
||||||
iterable_mut_impl!(Mat3, 3)
|
|
||||||
dim_impl!(Mat3, 3)
|
|
||||||
indexable_impl!(Mat3, 3)
|
|
||||||
mul_impl!(Mat3, 3)
|
|
||||||
rmul_impl!(Mat3, Vec3, 3)
|
|
||||||
lmul_impl!(Mat3, Vec3, 3)
|
|
||||||
transform_impl!(Mat3, Vec3)
|
|
||||||
// (specialized) inv_impl!(Mat3, 3)
|
|
||||||
transpose_impl!(Mat3, 3)
|
|
||||||
approx_eq_impl!(Mat3)
|
|
||||||
column_impl!(Mat3, 3)
|
|
||||||
to_homogeneous_impl!(Mat3, Mat4, 3, 4)
|
|
||||||
from_homogeneous_impl!(Mat3, Mat4, 3, 4)
|
|
||||||
|
|
||||||
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
|
||||||
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,
|
|
||||||
m41: N, m42: N, m43: N, m44: N
|
|
||||||
}
|
|
||||||
|
|
||||||
mat_impl!(Mat4, 4,
|
|
||||||
m11, m12, m13, m14,
|
|
||||||
m21, m22, m23, m24,
|
|
||||||
m31, m32, m33, m34,
|
|
||||||
m41, m42, m43, m44
|
|
||||||
)
|
|
||||||
one_impl!(Mat4, _1, _0, _0, _0,
|
|
||||||
_0, _1, _0, _0,
|
|
||||||
_0, _0, _1, _0,
|
|
||||||
_0, _0, _0, _1)
|
|
||||||
iterable_impl!(Mat4, 4)
|
|
||||||
iterable_mut_impl!(Mat4, 4)
|
|
||||||
dim_impl!(Mat4, 4)
|
|
||||||
indexable_impl!(Mat4, 4)
|
|
||||||
mul_impl!(Mat4, 4)
|
|
||||||
rmul_impl!(Mat4, Vec4, 4)
|
|
||||||
lmul_impl!(Mat4, Vec4, 4)
|
|
||||||
transform_impl!(Mat4, Vec4)
|
|
||||||
inv_impl!(Mat4, 4)
|
|
||||||
transpose_impl!(Mat4, 4)
|
|
||||||
approx_eq_impl!(Mat4)
|
|
||||||
column_impl!(Mat4, 4)
|
|
||||||
to_homogeneous_impl!(Mat4, Mat5, 4, 5)
|
|
||||||
from_homogeneous_impl!(Mat4, Mat5, 4, 5)
|
|
||||||
|
|
||||||
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
|
||||||
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,
|
|
||||||
m41: N, m42: N, m43: N, m44: N, m45: N,
|
|
||||||
m51: N, m52: N, m53: N, m54: N, m55: N
|
|
||||||
}
|
|
||||||
|
|
||||||
mat_impl!(Mat5, 5,
|
|
||||||
m11, m12, m13, m14, m15,
|
|
||||||
m21, m22, m23, m24, m25,
|
|
||||||
m31, m32, m33, m34, m35,
|
|
||||||
m41, m42, m43, m44, m45,
|
|
||||||
m51, m52, m53, m54, m55
|
|
||||||
)
|
|
||||||
one_impl!(Mat5,
|
|
||||||
_1, _0, _0, _0, _0,
|
|
||||||
_0, _1, _0, _0, _0,
|
|
||||||
_0, _0, _1, _0, _0,
|
|
||||||
_0, _0, _0, _1, _0,
|
|
||||||
_0, _0, _0, _0, _1
|
|
||||||
)
|
|
||||||
iterable_impl!(Mat5, 5)
|
|
||||||
iterable_mut_impl!(Mat5, 5)
|
|
||||||
dim_impl!(Mat5, 5)
|
|
||||||
indexable_impl!(Mat5, 5)
|
|
||||||
mul_impl!(Mat5, 5)
|
|
||||||
rmul_impl!(Mat5, Vec5, 5)
|
|
||||||
lmul_impl!(Mat5, Vec5, 5)
|
|
||||||
transform_impl!(Mat5, Vec5)
|
|
||||||
inv_impl!(Mat5, 5)
|
|
||||||
transpose_impl!(Mat5, 5)
|
|
||||||
approx_eq_impl!(Mat5)
|
|
||||||
column_impl!(Mat5, 5)
|
|
||||||
to_homogeneous_impl!(Mat5, Mat6, 5, 6)
|
|
||||||
from_homogeneous_impl!(Mat5, Mat6, 5, 6)
|
|
||||||
|
|
||||||
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
|
||||||
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,
|
|
||||||
m41: N, m42: N, m43: N, m44: N, m45: N, m46: N,
|
|
||||||
m51: N, m52: N, m53: N, m54: N, m55: N, m56: N,
|
|
||||||
m61: N, m62: N, m63: N, m64: N, m65: N, m66: N
|
|
||||||
}
|
|
||||||
|
|
||||||
mat_impl!(Mat6, 6,
|
|
||||||
m11, m12, m13, m14, m15, m16,
|
|
||||||
m21, m22, m23, m24, m25, m26,
|
|
||||||
m31, m32, m33, m34, m35, m36,
|
|
||||||
m41, m42, m43, m44, m45, m46,
|
|
||||||
m51, m52, m53, m54, m55, m56,
|
|
||||||
m61, m62, m63, m64, m65, m66
|
|
||||||
)
|
|
||||||
one_impl!(Mat6,
|
|
||||||
_1, _0, _0, _0, _0, _0,
|
|
||||||
_0, _1, _0, _0, _0, _0,
|
|
||||||
_0, _0, _1, _0, _0, _0,
|
|
||||||
_0, _0, _0, _1, _0, _0,
|
|
||||||
_0, _0, _0, _0, _1, _0,
|
|
||||||
_0, _0, _0, _0, _0, _1
|
|
||||||
)
|
|
||||||
iterable_impl!(Mat6, 6)
|
|
||||||
iterable_mut_impl!(Mat6, 6)
|
|
||||||
dim_impl!(Mat6, 6)
|
|
||||||
indexable_impl!(Mat6, 6)
|
|
||||||
mul_impl!(Mat6, 6)
|
|
||||||
rmul_impl!(Mat6, Vec6, 6)
|
|
||||||
lmul_impl!(Mat6, Vec6, 6)
|
|
||||||
transform_impl!(Mat6, Vec6)
|
|
||||||
inv_impl!(Mat6, 6)
|
|
||||||
transpose_impl!(Mat6, 6)
|
|
||||||
approx_eq_impl!(Mat6)
|
|
||||||
column_impl!(Mat6, 6)
|
|
601
src/mat_impl.rs
601
src/mat_impl.rs
|
@ -1,408 +1,209 @@
|
||||||
#[macro_escape];
|
use std::cast;
|
||||||
|
use std::uint::iterate;
|
||||||
|
use std::num::{One, Zero};
|
||||||
|
use std::cmp::ApproxEq;
|
||||||
|
use std::iterator::IteratorUtil;
|
||||||
|
use std::vec::{VecIterator, VecMutIterator};
|
||||||
|
use vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6};
|
||||||
|
use traits::dim::Dim;
|
||||||
|
use traits::ring::Ring;
|
||||||
|
use traits::inv::Inv;
|
||||||
|
use traits::division_ring::DivisionRing;
|
||||||
|
use traits::transpose::Transpose;
|
||||||
|
use traits::rlmul::{RMul, LMul};
|
||||||
|
use traits::transformation::Transform;
|
||||||
|
use traits::homogeneous::{FromHomogeneous, ToHomogeneous};
|
||||||
|
use traits::indexable::Indexable;
|
||||||
|
use traits::column::Column;
|
||||||
|
use traits::iterable::{Iterable, IterableMut};
|
||||||
|
|
||||||
macro_rules! mat_impl(
|
mod mat_macros;
|
||||||
($t: ident, $dim: expr, $comp0: ident $(,$compN: ident)*) => (
|
|
||||||
impl<N> $t<N>
|
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
{
|
pub struct Mat1<N>
|
||||||
#[inline]
|
{ m11: N }
|
||||||
pub fn new($comp0: N $(, $compN: N )*) -> $t<N>
|
|
||||||
{
|
mat_impl!(Mat1, 1, m11)
|
||||||
$t {
|
one_impl!(Mat1, _1)
|
||||||
$comp0: $comp0
|
iterable_impl!(Mat1, 1)
|
||||||
$(, $compN: $compN )*
|
iterable_mut_impl!(Mat1, 1)
|
||||||
}
|
dim_impl!(Mat1, 1)
|
||||||
}
|
indexable_impl!(Mat1, 1)
|
||||||
}
|
mul_impl!(Mat1, 1)
|
||||||
)
|
rmul_impl!(Mat1, Vec1, 1)
|
||||||
|
lmul_impl!(Mat1, Vec1, 1)
|
||||||
|
transform_impl!(Mat1, Vec1)
|
||||||
|
// (specialized) inv_impl!(Mat1, 1)
|
||||||
|
transpose_impl!(Mat1, 1)
|
||||||
|
approx_eq_impl!(Mat1)
|
||||||
|
column_impl!(Mat1, 1)
|
||||||
|
to_homogeneous_impl!(Mat1, Mat2, 1, 2)
|
||||||
|
from_homogeneous_impl!(Mat1, Mat2, 1, 2)
|
||||||
|
|
||||||
|
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
|
pub struct Mat2<N>
|
||||||
|
{
|
||||||
|
m11: N, m12: N,
|
||||||
|
m21: N, m22: N
|
||||||
|
}
|
||||||
|
|
||||||
|
mat_impl!(Mat2, 2, m11, m12,
|
||||||
|
m21, m22)
|
||||||
|
one_impl!(Mat2, _1, _0,
|
||||||
|
_0, _1)
|
||||||
|
iterable_impl!(Mat2, 2)
|
||||||
|
iterable_mut_impl!(Mat2, 2)
|
||||||
|
dim_impl!(Mat2, 2)
|
||||||
|
indexable_impl!(Mat2, 2)
|
||||||
|
mul_impl!(Mat2, 2)
|
||||||
|
rmul_impl!(Mat2, Vec2, 2)
|
||||||
|
lmul_impl!(Mat2, Vec2, 2)
|
||||||
|
transform_impl!(Mat2, Vec2)
|
||||||
|
// (specialized) inv_impl!(Mat2, 2)
|
||||||
|
transpose_impl!(Mat2, 2)
|
||||||
|
approx_eq_impl!(Mat2)
|
||||||
|
column_impl!(Mat2, 2)
|
||||||
|
to_homogeneous_impl!(Mat2, Mat3, 2, 3)
|
||||||
|
from_homogeneous_impl!(Mat2, Mat3, 2, 3)
|
||||||
|
|
||||||
|
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
|
pub struct Mat3<N>
|
||||||
|
{
|
||||||
|
m11: N, m12: N, m13: N,
|
||||||
|
m21: N, m22: N, m23: N,
|
||||||
|
m31: N, m32: N, m33: N
|
||||||
|
}
|
||||||
|
|
||||||
|
mat_impl!(Mat3, 3, m11, m12, m13,
|
||||||
|
m21, m22, m23,
|
||||||
|
m31, m32, m33)
|
||||||
|
one_impl!(Mat3, _1, _0, _0,
|
||||||
|
_0, _1, _0,
|
||||||
|
_0, _0, _1)
|
||||||
|
iterable_impl!(Mat3, 3)
|
||||||
|
iterable_mut_impl!(Mat3, 3)
|
||||||
|
dim_impl!(Mat3, 3)
|
||||||
|
indexable_impl!(Mat3, 3)
|
||||||
|
mul_impl!(Mat3, 3)
|
||||||
|
rmul_impl!(Mat3, Vec3, 3)
|
||||||
|
lmul_impl!(Mat3, Vec3, 3)
|
||||||
|
transform_impl!(Mat3, Vec3)
|
||||||
|
// (specialized) inv_impl!(Mat3, 3)
|
||||||
|
transpose_impl!(Mat3, 3)
|
||||||
|
approx_eq_impl!(Mat3)
|
||||||
|
column_impl!(Mat3, 3)
|
||||||
|
to_homogeneous_impl!(Mat3, Mat4, 3, 4)
|
||||||
|
from_homogeneous_impl!(Mat3, Mat4, 3, 4)
|
||||||
|
|
||||||
|
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
|
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,
|
||||||
|
m41: N, m42: N, m43: N, m44: N
|
||||||
|
}
|
||||||
|
|
||||||
|
mat_impl!(Mat4, 4,
|
||||||
|
m11, m12, m13, m14,
|
||||||
|
m21, m22, m23, m24,
|
||||||
|
m31, m32, m33, m34,
|
||||||
|
m41, m42, m43, m44
|
||||||
)
|
)
|
||||||
|
one_impl!(Mat4, _1, _0, _0, _0,
|
||||||
|
_0, _1, _0, _0,
|
||||||
|
_0, _0, _1, _0,
|
||||||
|
_0, _0, _0, _1)
|
||||||
|
iterable_impl!(Mat4, 4)
|
||||||
|
iterable_mut_impl!(Mat4, 4)
|
||||||
|
dim_impl!(Mat4, 4)
|
||||||
|
indexable_impl!(Mat4, 4)
|
||||||
|
mul_impl!(Mat4, 4)
|
||||||
|
rmul_impl!(Mat4, Vec4, 4)
|
||||||
|
lmul_impl!(Mat4, Vec4, 4)
|
||||||
|
transform_impl!(Mat4, Vec4)
|
||||||
|
inv_impl!(Mat4, 4)
|
||||||
|
transpose_impl!(Mat4, 4)
|
||||||
|
approx_eq_impl!(Mat4)
|
||||||
|
column_impl!(Mat4, 4)
|
||||||
|
to_homogeneous_impl!(Mat4, Mat5, 4, 5)
|
||||||
|
from_homogeneous_impl!(Mat4, Mat5, 4, 5)
|
||||||
|
|
||||||
macro_rules! iterable_impl(
|
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
($t: ident, $dim: expr) => (
|
pub struct Mat5<N>
|
||||||
impl<N> Iterable<N> for $t<N>
|
{
|
||||||
{
|
m11: N, m12: N, m13: N, m14: N, m15: N,
|
||||||
fn iter<'l>(&'l self) -> VecIterator<'l, N>
|
m21: N, m22: N, m23: N, m24: N, m25: N,
|
||||||
{ unsafe { cast::transmute::<&'l $t<N>, &'l [N, ..$dim * $dim]>(self).iter() } }
|
m31: N, m32: N, m33: N, m34: N, m35: N,
|
||||||
}
|
m41: N, m42: N, m43: N, m44: N, m45: N,
|
||||||
)
|
m51: N, m52: N, m53: N, m54: N, m55: N
|
||||||
|
}
|
||||||
|
|
||||||
|
mat_impl!(Mat5, 5,
|
||||||
|
m11, m12, m13, m14, m15,
|
||||||
|
m21, m22, m23, m24, m25,
|
||||||
|
m31, m32, m33, m34, m35,
|
||||||
|
m41, m42, m43, m44, m45,
|
||||||
|
m51, m52, m53, m54, m55
|
||||||
)
|
)
|
||||||
|
one_impl!(Mat5,
|
||||||
macro_rules! iterable_mut_impl(
|
_1, _0, _0, _0, _0,
|
||||||
($t: ident, $dim: expr) => (
|
_0, _1, _0, _0, _0,
|
||||||
impl<N> IterableMut<N> for $t<N>
|
_0, _0, _1, _0, _0,
|
||||||
{
|
_0, _0, _0, _1, _0,
|
||||||
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N>
|
_0, _0, _0, _0, _1
|
||||||
{ unsafe { cast::transmute::<&'l mut $t<N>, &'l mut [N, ..$dim * $dim]>(self).mut_iter() } }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
iterable_impl!(Mat5, 5)
|
||||||
|
iterable_mut_impl!(Mat5, 5)
|
||||||
|
dim_impl!(Mat5, 5)
|
||||||
|
indexable_impl!(Mat5, 5)
|
||||||
|
mul_impl!(Mat5, 5)
|
||||||
|
rmul_impl!(Mat5, Vec5, 5)
|
||||||
|
lmul_impl!(Mat5, Vec5, 5)
|
||||||
|
transform_impl!(Mat5, Vec5)
|
||||||
|
inv_impl!(Mat5, 5)
|
||||||
|
transpose_impl!(Mat5, 5)
|
||||||
|
approx_eq_impl!(Mat5)
|
||||||
|
column_impl!(Mat5, 5)
|
||||||
|
to_homogeneous_impl!(Mat5, Mat6, 5, 6)
|
||||||
|
from_homogeneous_impl!(Mat5, Mat6, 5, 6)
|
||||||
|
|
||||||
macro_rules! one_impl(
|
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
($t: ident, $value0: ident $(, $valueN: ident)* ) => (
|
pub struct Mat6<N>
|
||||||
impl<N: Clone + One + Zero> One for $t<N>
|
{
|
||||||
{
|
m11: N, m12: N, m13: N, m14: N, m15: N, m16: N,
|
||||||
#[inline]
|
m21: N, m22: N, m23: N, m24: N, m25: N, m26: N,
|
||||||
fn one() -> $t<N>
|
m31: N, m32: N, m33: N, m34: N, m35: N, m36: N,
|
||||||
{
|
m41: N, m42: N, m43: N, m44: N, m45: N, m46: N,
|
||||||
let (_0, _1) = (Zero::zero::<N>(), One::one::<N>());
|
m51: N, m52: N, m53: N, m54: N, m55: N, m56: N,
|
||||||
return $t::new($value0.clone() $(, $valueN.clone() )*)
|
m61: N, m62: N, m63: N, m64: N, m65: N, m66: N
|
||||||
}
|
}
|
||||||
}
|
|
||||||
)
|
mat_impl!(Mat6, 6,
|
||||||
|
m11, m12, m13, m14, m15, m16,
|
||||||
|
m21, m22, m23, m24, m25, m26,
|
||||||
|
m31, m32, m33, m34, m35, m36,
|
||||||
|
m41, m42, m43, m44, m45, m46,
|
||||||
|
m51, m52, m53, m54, m55, m56,
|
||||||
|
m61, m62, m63, m64, m65, m66
|
||||||
)
|
)
|
||||||
|
one_impl!(Mat6,
|
||||||
macro_rules! dim_impl(
|
_1, _0, _0, _0, _0, _0,
|
||||||
($t: ident, $dim: expr) => (
|
_0, _1, _0, _0, _0, _0,
|
||||||
impl<N> Dim for $t<N>
|
_0, _0, _1, _0, _0, _0,
|
||||||
{
|
_0, _0, _0, _1, _0, _0,
|
||||||
#[inline]
|
_0, _0, _0, _0, _1, _0,
|
||||||
fn dim() -> uint
|
_0, _0, _0, _0, _0, _1
|
||||||
{ $dim }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! indexable_impl(
|
|
||||||
($t: ident, $dim: expr) => (
|
|
||||||
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() } }
|
|
||||||
|
|
||||||
#[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 } }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
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 v.iter().enumerate().advance |(i, e)|
|
|
||||||
{
|
|
||||||
if i == Dim::dim::<$t<N>>()
|
|
||||||
{ break }
|
|
||||||
|
|
||||||
self.set((i, col), e.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn column(&self, col: uint) -> V
|
|
||||||
{
|
|
||||||
let mut res = Zero::zero::<V>();
|
|
||||||
|
|
||||||
for res.mut_iter().enumerate().advance |(i, e)|
|
|
||||||
{
|
|
||||||
if i >= Dim::dim::<$t<N>>()
|
|
||||||
{ break }
|
|
||||||
|
|
||||||
*e = self.at((i, col));
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
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>
|
|
||||||
{
|
|
||||||
let mut res: $t<N> = Zero::zero();
|
|
||||||
|
|
||||||
for iterate(0u, $dim) |i|
|
|
||||||
{
|
|
||||||
for iterate(0u, $dim) |j|
|
|
||||||
{
|
|
||||||
let mut acc = Zero::zero::<N>();
|
|
||||||
|
|
||||||
for iterate(0u, $dim) |k|
|
|
||||||
{ acc = acc + self.at((i, k)) * other.at((k, j)); }
|
|
||||||
|
|
||||||
res.set((i, j), acc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
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>
|
|
||||||
{
|
|
||||||
let mut res : $v<N> = Zero::zero();
|
|
||||||
|
|
||||||
for iterate(0u, $dim) |i|
|
|
||||||
{
|
|
||||||
for iterate(0u, $dim) |j|
|
|
||||||
{
|
|
||||||
let val = res.at(i) + other.at(j) * self.at((i, j));
|
|
||||||
res.set(i, val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
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>
|
|
||||||
{
|
|
||||||
|
|
||||||
let mut res : $v<N> = Zero::zero();
|
|
||||||
|
|
||||||
for iterate(0u, $dim) |i|
|
|
||||||
{
|
|
||||||
for iterate(0u, $dim) |j|
|
|
||||||
{
|
|
||||||
let val = res.at(i) + other.at(j) * self.at((j, i));
|
|
||||||
res.set(i, val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! transform_impl(
|
|
||||||
($t: ident, $v: ident) => (
|
|
||||||
impl<N: Clone + DivisionRing + Eq>
|
|
||||||
Transform<$v<N>> for $t<N>
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
Some(t) => t.transform_vec(v),
|
|
||||||
None => fail!("Cannot use inv_transform on a non-inversible matrix.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! inv_impl(
|
|
||||||
($t: ident, $dim: expr) => (
|
|
||||||
impl<N: Clone + Eq + DivisionRing>
|
|
||||||
Inv for $t<N>
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn inverse(&self) -> Option<$t<N>>
|
|
||||||
{
|
|
||||||
let mut res : $t<N> = self.clone();
|
|
||||||
|
|
||||||
if res.inplace_inverse()
|
|
||||||
{ Some(res) }
|
|
||||||
else
|
|
||||||
{ None }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inplace_inverse(&mut self) -> bool
|
|
||||||
{
|
|
||||||
let mut res: $t<N> = One::one();
|
|
||||||
let _0N: N = Zero::zero();
|
|
||||||
|
|
||||||
// inversion using Gauss-Jordan elimination
|
|
||||||
for iterate(0u, $dim) |k|
|
|
||||||
{
|
|
||||||
// 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; }
|
|
||||||
|
|
||||||
n0 = n0 + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if n0 == $dim
|
|
||||||
{ return false }
|
|
||||||
|
|
||||||
// swap pivot line
|
|
||||||
if n0 != k
|
|
||||||
{
|
|
||||||
for iterate(0u, $dim) |j|
|
|
||||||
{
|
|
||||||
self.swap((n0, j), (k, j));
|
|
||||||
res.swap((n0, j), (k, j));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let pivot = self.at((k, k));
|
|
||||||
|
|
||||||
for iterate(k, $dim) |j|
|
|
||||||
{
|
|
||||||
let selfval = self.at((k, j)) / pivot;
|
|
||||||
self.set((k, j), selfval);
|
|
||||||
}
|
|
||||||
|
|
||||||
for iterate(0u, $dim) |j|
|
|
||||||
{
|
|
||||||
let resval = res.at((k, j)) / pivot;
|
|
||||||
res.set((k, j), resval);
|
|
||||||
}
|
|
||||||
|
|
||||||
for iterate(0u, $dim) |l|
|
|
||||||
{
|
|
||||||
if l != k
|
|
||||||
{
|
|
||||||
let normalizer = self.at((l, k));
|
|
||||||
|
|
||||||
for iterate(k, $dim) |j|
|
|
||||||
{
|
|
||||||
let selfval = self.at((l, j)) - self.at((k, j)) * normalizer;
|
|
||||||
self.set((l, j), selfval);
|
|
||||||
}
|
|
||||||
|
|
||||||
for iterate(0u, $dim) |j|
|
|
||||||
{
|
|
||||||
let resval = res.at((l, j)) - res.at((k, j)) * normalizer;
|
|
||||||
res.set((l, j), resval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*self = res;
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! transpose_impl(
|
|
||||||
($t: ident, $dim: expr) => (
|
|
||||||
impl<N: Clone> Transpose for $t<N>
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn transposed(&self) -> $t<N>
|
|
||||||
{
|
|
||||||
let mut res = self.clone();
|
|
||||||
|
|
||||||
res.transpose();
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transpose(&mut self)
|
|
||||||
{
|
|
||||||
for iterate(1u, $dim) |i|
|
|
||||||
{
|
|
||||||
for iterate(0u, $dim - 1) |j|
|
|
||||||
{ self.swap((i, j), (j, i)) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! approx_eq_impl(
|
|
||||||
($t: ident) => (
|
|
||||||
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N>
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn approx_epsilon() -> N
|
|
||||||
{ ApproxEq::approx_epsilon::<N, N>() }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq(&self, other: &$t<N>) -> bool
|
|
||||||
{
|
|
||||||
let mut zip = self.iter().zip(other.iter());
|
|
||||||
|
|
||||||
do zip.all |(a, b)| { a.approx_eq(b) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N) -> bool
|
|
||||||
{
|
|
||||||
let mut zip = self.iter().zip(other.iter());
|
|
||||||
|
|
||||||
do zip.all |(a, b)| { a.approx_eq_eps(b, epsilon) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
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>
|
|
||||||
{
|
|
||||||
let mut res: $t2<N> = One::one();
|
|
||||||
|
|
||||||
for iterate(0, $dim) |i|
|
|
||||||
{
|
|
||||||
for iterate(0, $dim) |j|
|
|
||||||
{ res.set((i, j), self.at((i, j))) }
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
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_homogeneous(m: &$t2<N>) -> $t<N>
|
|
||||||
{
|
|
||||||
let mut res: $t<N> = One::one();
|
|
||||||
|
|
||||||
for iterate(0, $dim2) |i|
|
|
||||||
{
|
|
||||||
for iterate(0, $dim2) |j|
|
|
||||||
{ res.set((i, j), m.at((i, j))) }
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: do we have to deal the lost components
|
|
||||||
// (like if the 1 is not a 1… do we have to divide?)
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
iterable_impl!(Mat6, 6)
|
||||||
|
iterable_mut_impl!(Mat6, 6)
|
||||||
|
dim_impl!(Mat6, 6)
|
||||||
|
indexable_impl!(Mat6, 6)
|
||||||
|
mul_impl!(Mat6, 6)
|
||||||
|
rmul_impl!(Mat6, Vec6, 6)
|
||||||
|
lmul_impl!(Mat6, Vec6, 6)
|
||||||
|
transform_impl!(Mat6, Vec6)
|
||||||
|
inv_impl!(Mat6, 6)
|
||||||
|
transpose_impl!(Mat6, 6)
|
||||||
|
approx_eq_impl!(Mat6)
|
||||||
|
column_impl!(Mat6, 6)
|
||||||
|
|
|
@ -0,0 +1,408 @@
|
||||||
|
#[macro_escape];
|
||||||
|
|
||||||
|
macro_rules! mat_impl(
|
||||||
|
($t: ident, $dim: expr, $comp0: ident $(,$compN: ident)*) => (
|
||||||
|
impl<N> $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
pub fn new($comp0: N $(, $compN: N )*) -> $t<N>
|
||||||
|
{
|
||||||
|
$t {
|
||||||
|
$comp0: $comp0
|
||||||
|
$(, $compN: $compN )*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
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() } }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
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() } }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! one_impl(
|
||||||
|
($t: ident, $value0: ident $(, $valueN: ident)* ) => (
|
||||||
|
impl<N: Clone + One + Zero> One for $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn one() -> $t<N>
|
||||||
|
{
|
||||||
|
let (_0, _1) = (Zero::zero::<N>(), One::one::<N>());
|
||||||
|
return $t::new($value0.clone() $(, $valueN.clone() )*)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! dim_impl(
|
||||||
|
($t: ident, $dim: expr) => (
|
||||||
|
impl<N> Dim for $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn dim() -> uint
|
||||||
|
{ $dim }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! indexable_impl(
|
||||||
|
($t: ident, $dim: expr) => (
|
||||||
|
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() } }
|
||||||
|
|
||||||
|
#[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 } }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
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 v.iter().enumerate().advance |(i, e)|
|
||||||
|
{
|
||||||
|
if i == Dim::dim::<$t<N>>()
|
||||||
|
{ break }
|
||||||
|
|
||||||
|
self.set((i, col), e.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn column(&self, col: uint) -> V
|
||||||
|
{
|
||||||
|
let mut res = Zero::zero::<V>();
|
||||||
|
|
||||||
|
for res.mut_iter().enumerate().advance |(i, e)|
|
||||||
|
{
|
||||||
|
if i >= Dim::dim::<$t<N>>()
|
||||||
|
{ break }
|
||||||
|
|
||||||
|
*e = self.at((i, col));
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
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>
|
||||||
|
{
|
||||||
|
let mut res: $t<N> = Zero::zero();
|
||||||
|
|
||||||
|
for iterate(0u, $dim) |i|
|
||||||
|
{
|
||||||
|
for iterate(0u, $dim) |j|
|
||||||
|
{
|
||||||
|
let mut acc = Zero::zero::<N>();
|
||||||
|
|
||||||
|
for iterate(0u, $dim) |k|
|
||||||
|
{ acc = acc + self.at((i, k)) * other.at((k, j)); }
|
||||||
|
|
||||||
|
res.set((i, j), acc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
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>
|
||||||
|
{
|
||||||
|
let mut res : $v<N> = Zero::zero();
|
||||||
|
|
||||||
|
for iterate(0u, $dim) |i|
|
||||||
|
{
|
||||||
|
for iterate(0u, $dim) |j|
|
||||||
|
{
|
||||||
|
let val = res.at(i) + other.at(j) * self.at((i, j));
|
||||||
|
res.set(i, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
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>
|
||||||
|
{
|
||||||
|
|
||||||
|
let mut res : $v<N> = Zero::zero();
|
||||||
|
|
||||||
|
for iterate(0u, $dim) |i|
|
||||||
|
{
|
||||||
|
for iterate(0u, $dim) |j|
|
||||||
|
{
|
||||||
|
let val = res.at(i) + other.at(j) * self.at((j, i));
|
||||||
|
res.set(i, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! transform_impl(
|
||||||
|
($t: ident, $v: ident) => (
|
||||||
|
impl<N: Clone + DivisionRing + Eq>
|
||||||
|
Transform<$v<N>> for $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
Some(t) => t.transform_vec(v),
|
||||||
|
None => fail!("Cannot use inv_transform on a non-inversible matrix.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! inv_impl(
|
||||||
|
($t: ident, $dim: expr) => (
|
||||||
|
impl<N: Clone + Eq + DivisionRing>
|
||||||
|
Inv for $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn inverse(&self) -> Option<$t<N>>
|
||||||
|
{
|
||||||
|
let mut res : $t<N> = self.clone();
|
||||||
|
|
||||||
|
if res.inplace_inverse()
|
||||||
|
{ Some(res) }
|
||||||
|
else
|
||||||
|
{ None }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inplace_inverse(&mut self) -> bool
|
||||||
|
{
|
||||||
|
let mut res: $t<N> = One::one();
|
||||||
|
let _0N: N = Zero::zero();
|
||||||
|
|
||||||
|
// inversion using Gauss-Jordan elimination
|
||||||
|
for iterate(0u, $dim) |k|
|
||||||
|
{
|
||||||
|
// 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; }
|
||||||
|
|
||||||
|
n0 = n0 + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if n0 == $dim
|
||||||
|
{ return false }
|
||||||
|
|
||||||
|
// swap pivot line
|
||||||
|
if n0 != k
|
||||||
|
{
|
||||||
|
for iterate(0u, $dim) |j|
|
||||||
|
{
|
||||||
|
self.swap((n0, j), (k, j));
|
||||||
|
res.swap((n0, j), (k, j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let pivot = self.at((k, k));
|
||||||
|
|
||||||
|
for iterate(k, $dim) |j|
|
||||||
|
{
|
||||||
|
let selfval = self.at((k, j)) / pivot;
|
||||||
|
self.set((k, j), selfval);
|
||||||
|
}
|
||||||
|
|
||||||
|
for iterate(0u, $dim) |j|
|
||||||
|
{
|
||||||
|
let resval = res.at((k, j)) / pivot;
|
||||||
|
res.set((k, j), resval);
|
||||||
|
}
|
||||||
|
|
||||||
|
for iterate(0u, $dim) |l|
|
||||||
|
{
|
||||||
|
if l != k
|
||||||
|
{
|
||||||
|
let normalizer = self.at((l, k));
|
||||||
|
|
||||||
|
for iterate(k, $dim) |j|
|
||||||
|
{
|
||||||
|
let selfval = self.at((l, j)) - self.at((k, j)) * normalizer;
|
||||||
|
self.set((l, j), selfval);
|
||||||
|
}
|
||||||
|
|
||||||
|
for iterate(0u, $dim) |j|
|
||||||
|
{
|
||||||
|
let resval = res.at((l, j)) - res.at((k, j)) * normalizer;
|
||||||
|
res.set((l, j), resval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*self = res;
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! transpose_impl(
|
||||||
|
($t: ident, $dim: expr) => (
|
||||||
|
impl<N: Clone> Transpose for $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn transposed(&self) -> $t<N>
|
||||||
|
{
|
||||||
|
let mut res = self.clone();
|
||||||
|
|
||||||
|
res.transpose();
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transpose(&mut self)
|
||||||
|
{
|
||||||
|
for iterate(1u, $dim) |i|
|
||||||
|
{
|
||||||
|
for iterate(0u, $dim - 1) |j|
|
||||||
|
{ self.swap((i, j), (j, i)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! approx_eq_impl(
|
||||||
|
($t: ident) => (
|
||||||
|
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn approx_epsilon() -> N
|
||||||
|
{ ApproxEq::approx_epsilon::<N, N>() }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn approx_eq(&self, other: &$t<N>) -> bool
|
||||||
|
{
|
||||||
|
let mut zip = self.iter().zip(other.iter());
|
||||||
|
|
||||||
|
do zip.all |(a, b)| { a.approx_eq(b) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N) -> bool
|
||||||
|
{
|
||||||
|
let mut zip = self.iter().zip(other.iter());
|
||||||
|
|
||||||
|
do zip.all |(a, b)| { a.approx_eq_eps(b, epsilon) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
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>
|
||||||
|
{
|
||||||
|
let mut res: $t2<N> = One::one();
|
||||||
|
|
||||||
|
for iterate(0, $dim) |i|
|
||||||
|
{
|
||||||
|
for iterate(0, $dim) |j|
|
||||||
|
{ res.set((i, j), self.at((i, j))) }
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
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_homogeneous(m: &$t2<N>) -> $t<N>
|
||||||
|
{
|
||||||
|
let mut res: $t<N> = One::one();
|
||||||
|
|
||||||
|
for iterate(0, $dim2) |i|
|
||||||
|
{
|
||||||
|
for iterate(0, $dim2) |j|
|
||||||
|
{ res.set((i, j), m.at((i, j))) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: do we have to deal the lost components
|
||||||
|
// (like if the 1 is not a 1… do we have to divide?)
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
|
@ -13,10 +13,10 @@
|
||||||
extern mod std;
|
extern mod std;
|
||||||
extern mod extra;
|
extern mod extra;
|
||||||
|
|
||||||
pub mod vec;
|
mod dmat;
|
||||||
pub mod mat;
|
mod dvec;
|
||||||
pub mod dmat;
|
mod vec_impl;
|
||||||
pub mod dvec;
|
mod mat_impl;
|
||||||
|
|
||||||
// specialization for some 1d, 2d and 3d operations
|
// specialization for some 1d, 2d and 3d operations
|
||||||
pub mod mat_spec;
|
pub mod mat_spec;
|
||||||
|
@ -30,9 +30,43 @@ pub mod adaptors
|
||||||
pub mod transform;
|
pub mod transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod vec
|
||||||
|
{
|
||||||
|
pub use vec_impl::*;
|
||||||
|
pub use dvec::*;
|
||||||
|
pub use traits::sample::*;
|
||||||
|
pub use traits::dot::*;
|
||||||
|
pub use traits::cross::*;
|
||||||
|
pub use traits::basis::*;
|
||||||
|
pub use traits::norm::*;
|
||||||
|
pub use traits::vector_space::*;
|
||||||
|
pub use traits::sub_dot::*;
|
||||||
|
pub use traits::scalar_op::*;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod mat
|
||||||
|
{
|
||||||
|
pub use mat_impl::*;
|
||||||
|
pub use dmat::*;
|
||||||
|
pub use traits::column::*;
|
||||||
|
pub use traits::inv::*;
|
||||||
|
pub use traits::transpose::*;
|
||||||
|
pub use traits::rotation::*;
|
||||||
|
pub use traits::translation::*;
|
||||||
|
pub use traits::transformation::*;
|
||||||
|
}
|
||||||
|
|
||||||
/// Useful linear-algebra related traits.
|
/// Useful linear-algebra related traits.
|
||||||
pub mod traits
|
pub mod traits
|
||||||
{
|
{
|
||||||
|
pub use traits::indexable::*;
|
||||||
|
pub use traits::iterable::*;
|
||||||
|
pub use traits::dim::*;
|
||||||
|
pub use traits::ring::*;
|
||||||
|
pub use traits::division_ring::*;
|
||||||
|
pub use traits::rlmul::*;
|
||||||
|
pub use traits::homogeneous::*;
|
||||||
|
|
||||||
pub mod sample;
|
pub mod sample;
|
||||||
pub mod indexable;
|
pub mod indexable;
|
||||||
pub mod column;
|
pub mod column;
|
||||||
|
|
227
src/vec.rs
227
src/vec.rs
|
@ -1,227 +0,0 @@
|
||||||
use std::cast;
|
|
||||||
use std::num::{Zero, One, Algebraic, Bounded};
|
|
||||||
use std::rand::Rng;
|
|
||||||
use std::vec::{VecIterator, VecMutIterator};
|
|
||||||
use std::iterator::{Iterator, IteratorUtil, FromIterator};
|
|
||||||
use std::cmp::ApproxEq;
|
|
||||||
use std::uint::iterate;
|
|
||||||
use traits::iterable::{Iterable, IterableMut};
|
|
||||||
use traits::basis::Basis;
|
|
||||||
use traits::dim::Dim;
|
|
||||||
use traits::dot::Dot;
|
|
||||||
use traits::sub_dot::SubDot;
|
|
||||||
use traits::norm::Norm;
|
|
||||||
use traits::translation::{Translation, Translatable};
|
|
||||||
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
|
||||||
use traits::ring::Ring;
|
|
||||||
use traits::division_ring::DivisionRing;
|
|
||||||
use traits::homogeneous::{FromHomogeneous, ToHomogeneous};
|
|
||||||
use traits::indexable::Indexable;
|
|
||||||
|
|
||||||
mod vec_impl;
|
|
||||||
|
|
||||||
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, Rand, Zero, ToStr)]
|
|
||||||
pub struct Vec0<N>;
|
|
||||||
|
|
||||||
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
|
||||||
pub struct Vec1<N>
|
|
||||||
{ x: N }
|
|
||||||
|
|
||||||
new_impl!(Vec1, x)
|
|
||||||
indexable_impl!(Vec1, 1)
|
|
||||||
new_repeat_impl!(Vec1, val, x)
|
|
||||||
dim_impl!(Vec1, 1)
|
|
||||||
// (specialized) basis_impl!(Vec1, 1)
|
|
||||||
add_impl!(Vec1, x)
|
|
||||||
sub_impl!(Vec1, x)
|
|
||||||
neg_impl!(Vec1, x)
|
|
||||||
dot_impl!(Vec1, x)
|
|
||||||
sub_dot_impl!(Vec1, x)
|
|
||||||
scalar_mul_impl!(Vec1, x)
|
|
||||||
scalar_div_impl!(Vec1, x)
|
|
||||||
scalar_add_impl!(Vec1, x)
|
|
||||||
scalar_sub_impl!(Vec1, x)
|
|
||||||
translation_impl!(Vec1)
|
|
||||||
translatable_impl!(Vec1)
|
|
||||||
norm_impl!(Vec1)
|
|
||||||
approx_eq_impl!(Vec1, x)
|
|
||||||
one_impl!(Vec1)
|
|
||||||
from_iterator_impl!(Vec1, iterator)
|
|
||||||
bounded_impl!(Vec1)
|
|
||||||
iterable_impl!(Vec1, 1)
|
|
||||||
iterable_mut_impl!(Vec1, 1)
|
|
||||||
to_homogeneous_impl!(Vec1, Vec2, y, x)
|
|
||||||
from_homogeneous_impl!(Vec1, Vec2, y, x)
|
|
||||||
|
|
||||||
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
|
||||||
pub struct Vec2<N>
|
|
||||||
{
|
|
||||||
x: N,
|
|
||||||
y: N
|
|
||||||
}
|
|
||||||
|
|
||||||
new_impl!(Vec2, x, y)
|
|
||||||
indexable_impl!(Vec2, 2)
|
|
||||||
new_repeat_impl!(Vec2, val, x, y)
|
|
||||||
dim_impl!(Vec2, 2)
|
|
||||||
// (specialized) basis_impl!(Vec2, 1)
|
|
||||||
add_impl!(Vec2, x, y)
|
|
||||||
sub_impl!(Vec2, x, y)
|
|
||||||
neg_impl!(Vec2, x, y)
|
|
||||||
dot_impl!(Vec2, x, y)
|
|
||||||
sub_dot_impl!(Vec2, x, y)
|
|
||||||
scalar_mul_impl!(Vec2, x, y)
|
|
||||||
scalar_div_impl!(Vec2, x, y)
|
|
||||||
scalar_add_impl!(Vec2, x, y)
|
|
||||||
scalar_sub_impl!(Vec2, x, y)
|
|
||||||
translation_impl!(Vec2)
|
|
||||||
translatable_impl!(Vec2)
|
|
||||||
norm_impl!(Vec2)
|
|
||||||
approx_eq_impl!(Vec2, x, y)
|
|
||||||
one_impl!(Vec2)
|
|
||||||
from_iterator_impl!(Vec2, iterator, iterator)
|
|
||||||
bounded_impl!(Vec2)
|
|
||||||
iterable_impl!(Vec2, 2)
|
|
||||||
iterable_mut_impl!(Vec2, 2)
|
|
||||||
to_homogeneous_impl!(Vec2, Vec3, z, x, y)
|
|
||||||
from_homogeneous_impl!(Vec2, Vec3, z, x, y)
|
|
||||||
|
|
||||||
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
|
||||||
pub struct Vec3<N>
|
|
||||||
{
|
|
||||||
x: N,
|
|
||||||
y: N,
|
|
||||||
z: N
|
|
||||||
}
|
|
||||||
|
|
||||||
new_impl!(Vec3, x, y, z)
|
|
||||||
indexable_impl!(Vec3, 3)
|
|
||||||
new_repeat_impl!(Vec3, val, x, y, z)
|
|
||||||
dim_impl!(Vec3, 3)
|
|
||||||
// (specialized) basis_impl!(Vec3, 1)
|
|
||||||
add_impl!(Vec3, x, y, z)
|
|
||||||
sub_impl!(Vec3, x, y, z)
|
|
||||||
neg_impl!(Vec3, x, y, z)
|
|
||||||
dot_impl!(Vec3, x, y, z)
|
|
||||||
sub_dot_impl!(Vec3, x, y, z)
|
|
||||||
scalar_mul_impl!(Vec3, x, y, z)
|
|
||||||
scalar_div_impl!(Vec3, x, y, z)
|
|
||||||
scalar_add_impl!(Vec3, x, y, z)
|
|
||||||
scalar_sub_impl!(Vec3, x, y, z)
|
|
||||||
translation_impl!(Vec3)
|
|
||||||
translatable_impl!(Vec3)
|
|
||||||
norm_impl!(Vec3)
|
|
||||||
approx_eq_impl!(Vec3, x, y, z)
|
|
||||||
one_impl!(Vec3)
|
|
||||||
from_iterator_impl!(Vec3, iterator, iterator, iterator)
|
|
||||||
bounded_impl!(Vec3)
|
|
||||||
iterable_impl!(Vec3, 3)
|
|
||||||
iterable_mut_impl!(Vec3, 3)
|
|
||||||
to_homogeneous_impl!(Vec3, Vec4, w, x, y, z)
|
|
||||||
from_homogeneous_impl!(Vec3, Vec4, w, x, y, z)
|
|
||||||
|
|
||||||
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
|
||||||
pub struct Vec4<N>
|
|
||||||
{
|
|
||||||
x: N,
|
|
||||||
y: N,
|
|
||||||
z: N,
|
|
||||||
w: N
|
|
||||||
}
|
|
||||||
|
|
||||||
new_impl!(Vec4, x, y, z, w)
|
|
||||||
indexable_impl!(Vec4, 4)
|
|
||||||
new_repeat_impl!(Vec4, val, x, y, z, w)
|
|
||||||
dim_impl!(Vec4, 4)
|
|
||||||
basis_impl!(Vec4, 4)
|
|
||||||
add_impl!(Vec4, x, y, z, w)
|
|
||||||
sub_impl!(Vec4, x, y, z, w)
|
|
||||||
neg_impl!(Vec4, x, y, z, w)
|
|
||||||
dot_impl!(Vec4, x, y, z, w)
|
|
||||||
sub_dot_impl!(Vec4, x, y, z, w)
|
|
||||||
scalar_mul_impl!(Vec4, x, y, z, w)
|
|
||||||
scalar_div_impl!(Vec4, x, y, z, w)
|
|
||||||
scalar_add_impl!(Vec4, x, y, z, w)
|
|
||||||
scalar_sub_impl!(Vec4, x, y, z, w)
|
|
||||||
translation_impl!(Vec4)
|
|
||||||
translatable_impl!(Vec4)
|
|
||||||
norm_impl!(Vec4)
|
|
||||||
approx_eq_impl!(Vec4, x, y, z, w)
|
|
||||||
one_impl!(Vec4)
|
|
||||||
from_iterator_impl!(Vec4, iterator, iterator, iterator, iterator)
|
|
||||||
bounded_impl!(Vec4)
|
|
||||||
iterable_impl!(Vec4, 4)
|
|
||||||
iterable_mut_impl!(Vec4, 4)
|
|
||||||
to_homogeneous_impl!(Vec4, Vec5, a, x, y, z, w)
|
|
||||||
from_homogeneous_impl!(Vec4, Vec5, a, x, y, z, w)
|
|
||||||
|
|
||||||
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
|
||||||
pub struct Vec5<N>
|
|
||||||
{
|
|
||||||
x: N,
|
|
||||||
y: N,
|
|
||||||
z: N,
|
|
||||||
w: N,
|
|
||||||
a: N,
|
|
||||||
}
|
|
||||||
|
|
||||||
new_impl!(Vec5, x, y, z, w, a)
|
|
||||||
indexable_impl!(Vec5, 5)
|
|
||||||
new_repeat_impl!(Vec5, val, x, y, z, w, a)
|
|
||||||
dim_impl!(Vec5, 5)
|
|
||||||
basis_impl!(Vec5, 5)
|
|
||||||
add_impl!(Vec5, x, y, z, w, a)
|
|
||||||
sub_impl!(Vec5, x, y, z, w, a)
|
|
||||||
neg_impl!(Vec5, x, y, z, w, a)
|
|
||||||
dot_impl!(Vec5, x, y, z, w, a)
|
|
||||||
sub_dot_impl!(Vec5, x, y, z, w, a)
|
|
||||||
scalar_mul_impl!(Vec5, x, y, z, w, a)
|
|
||||||
scalar_div_impl!(Vec5, x, y, z, w, a)
|
|
||||||
scalar_add_impl!(Vec5, x, y, z, w, a)
|
|
||||||
scalar_sub_impl!(Vec5, x, y, z, w, a)
|
|
||||||
translation_impl!(Vec5)
|
|
||||||
translatable_impl!(Vec5)
|
|
||||||
norm_impl!(Vec5)
|
|
||||||
approx_eq_impl!(Vec5, x, y, z, w, a)
|
|
||||||
one_impl!(Vec5)
|
|
||||||
from_iterator_impl!(Vec5, iterator, iterator, iterator, iterator, iterator)
|
|
||||||
bounded_impl!(Vec5)
|
|
||||||
iterable_impl!(Vec5, 5)
|
|
||||||
iterable_mut_impl!(Vec5, 5)
|
|
||||||
to_homogeneous_impl!(Vec5, Vec6, b, x, y, z, w, a)
|
|
||||||
from_homogeneous_impl!(Vec5, Vec6, b, x, y, z, w, a)
|
|
||||||
|
|
||||||
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
|
||||||
pub struct Vec6<N>
|
|
||||||
{
|
|
||||||
x: N,
|
|
||||||
y: N,
|
|
||||||
z: N,
|
|
||||||
w: N,
|
|
||||||
a: N,
|
|
||||||
b: N
|
|
||||||
}
|
|
||||||
|
|
||||||
new_impl!(Vec6, x, y, z, w, a, b)
|
|
||||||
indexable_impl!(Vec6, 6)
|
|
||||||
new_repeat_impl!(Vec6, val, x, y, z, w, a, b)
|
|
||||||
dim_impl!(Vec6, 6)
|
|
||||||
basis_impl!(Vec6, 6)
|
|
||||||
add_impl!(Vec6, x, y, z, w, a, b)
|
|
||||||
sub_impl!(Vec6, x, y, z, w, a, b)
|
|
||||||
neg_impl!(Vec6, x, y, z, w, a, b)
|
|
||||||
dot_impl!(Vec6, x, y, z, w, a, b)
|
|
||||||
sub_dot_impl!(Vec6, x, y, z, w, a, b)
|
|
||||||
scalar_mul_impl!(Vec6, x, y, z, w, a, b)
|
|
||||||
scalar_div_impl!(Vec6, x, y, z, w, a, b)
|
|
||||||
scalar_add_impl!(Vec6, x, y, z, w, a, b)
|
|
||||||
scalar_sub_impl!(Vec6, x, y, z, w, a, b)
|
|
||||||
translation_impl!(Vec6)
|
|
||||||
translatable_impl!(Vec6)
|
|
||||||
norm_impl!(Vec6)
|
|
||||||
approx_eq_impl!(Vec6, x, y, z, w, a, b)
|
|
||||||
one_impl!(Vec6)
|
|
||||||
from_iterator_impl!(Vec6, iterator, iterator, iterator, iterator, iterator, iterator)
|
|
||||||
bounded_impl!(Vec6)
|
|
||||||
iterable_impl!(Vec6, 6)
|
|
||||||
iterable_mut_impl!(Vec6, 6)
|
|
617
src/vec_impl.rs
617
src/vec_impl.rs
|
@ -1,418 +1,227 @@
|
||||||
#[macro_escape];
|
use std::cast;
|
||||||
|
use std::num::{Zero, One, Algebraic, Bounded};
|
||||||
|
use std::rand::Rng;
|
||||||
|
use std::vec::{VecIterator, VecMutIterator};
|
||||||
|
use std::iterator::{Iterator, IteratorUtil, FromIterator};
|
||||||
|
use std::cmp::ApproxEq;
|
||||||
|
use std::uint::iterate;
|
||||||
|
use traits::iterable::{Iterable, IterableMut};
|
||||||
|
use traits::basis::Basis;
|
||||||
|
use traits::dim::Dim;
|
||||||
|
use traits::dot::Dot;
|
||||||
|
use traits::sub_dot::SubDot;
|
||||||
|
use traits::norm::Norm;
|
||||||
|
use traits::translation::{Translation, Translatable};
|
||||||
|
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||||
|
use traits::ring::Ring;
|
||||||
|
use traits::division_ring::DivisionRing;
|
||||||
|
use traits::homogeneous::{FromHomogeneous, ToHomogeneous};
|
||||||
|
use traits::indexable::Indexable;
|
||||||
|
|
||||||
macro_rules! new_impl(
|
mod vec_macros;
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
|
||||||
impl<N> $t<N>
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
pub fn new($comp0: N $( , $compN: N )*) -> $t<N>
|
|
||||||
{
|
|
||||||
$t {
|
|
||||||
$comp0: $comp0
|
|
||||||
$(, $compN: $compN )*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! indexable_impl(
|
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, Rand, Zero, ToStr)]
|
||||||
($t: ident, $dim: expr) => (
|
pub struct Vec0<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() } }
|
|
||||||
|
|
||||||
#[inline]
|
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
pub fn set(&mut self, i: uint, val: N)
|
pub struct Vec1<N>
|
||||||
{ unsafe { cast::transmute::<&mut $t<N>, &mut [N, ..$dim]>(self)[i] = val } }
|
{ x: N }
|
||||||
|
|
||||||
#[inline]
|
new_impl!(Vec1, x)
|
||||||
pub fn swap(&mut self, i1: uint, i2: uint)
|
indexable_impl!(Vec1, 1)
|
||||||
{ unsafe { cast::transmute::<&mut $t<N>, &mut [N, ..$dim]>(self).swap(i1, i2) } }
|
new_repeat_impl!(Vec1, val, x)
|
||||||
}
|
dim_impl!(Vec1, 1)
|
||||||
)
|
// (specialized) basis_impl!(Vec1, 1)
|
||||||
)
|
add_impl!(Vec1, x)
|
||||||
|
sub_impl!(Vec1, x)
|
||||||
|
neg_impl!(Vec1, x)
|
||||||
|
dot_impl!(Vec1, x)
|
||||||
|
sub_dot_impl!(Vec1, x)
|
||||||
|
scalar_mul_impl!(Vec1, x)
|
||||||
|
scalar_div_impl!(Vec1, x)
|
||||||
|
scalar_add_impl!(Vec1, x)
|
||||||
|
scalar_sub_impl!(Vec1, x)
|
||||||
|
translation_impl!(Vec1)
|
||||||
|
translatable_impl!(Vec1)
|
||||||
|
norm_impl!(Vec1)
|
||||||
|
approx_eq_impl!(Vec1, x)
|
||||||
|
one_impl!(Vec1)
|
||||||
|
from_iterator_impl!(Vec1, iterator)
|
||||||
|
bounded_impl!(Vec1)
|
||||||
|
iterable_impl!(Vec1, 1)
|
||||||
|
iterable_mut_impl!(Vec1, 1)
|
||||||
|
to_homogeneous_impl!(Vec1, Vec2, y, x)
|
||||||
|
from_homogeneous_impl!(Vec1, Vec2, y, x)
|
||||||
|
|
||||||
macro_rules! new_repeat_impl(
|
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
($t: ident, $param: ident, $comp0: ident $(,$compN: ident)*) => (
|
pub struct Vec2<N>
|
||||||
impl<N: Clone> $t<N>
|
{
|
||||||
{
|
x: N,
|
||||||
#[inline]
|
y: N
|
||||||
pub fn new_repeat($param: N) -> $t<N>
|
}
|
||||||
{
|
|
||||||
$t{
|
|
||||||
$comp0: $param.clone()
|
|
||||||
$(, $compN: $param.clone() )*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! iterable_impl(
|
new_impl!(Vec2, x, y)
|
||||||
($t: ident, $dim: expr) => (
|
indexable_impl!(Vec2, 2)
|
||||||
impl<N> Iterable<N> for $t<N>
|
new_repeat_impl!(Vec2, val, x, y)
|
||||||
{
|
dim_impl!(Vec2, 2)
|
||||||
fn iter<'l>(&'l self) -> VecIterator<'l, N>
|
// (specialized) basis_impl!(Vec2, 1)
|
||||||
{ unsafe { cast::transmute::<&'l $t<N>, &'l [N, ..$dim]>(self).iter() } }
|
add_impl!(Vec2, x, y)
|
||||||
}
|
sub_impl!(Vec2, x, y)
|
||||||
)
|
neg_impl!(Vec2, x, y)
|
||||||
)
|
dot_impl!(Vec2, x, y)
|
||||||
|
sub_dot_impl!(Vec2, x, y)
|
||||||
|
scalar_mul_impl!(Vec2, x, y)
|
||||||
|
scalar_div_impl!(Vec2, x, y)
|
||||||
|
scalar_add_impl!(Vec2, x, y)
|
||||||
|
scalar_sub_impl!(Vec2, x, y)
|
||||||
|
translation_impl!(Vec2)
|
||||||
|
translatable_impl!(Vec2)
|
||||||
|
norm_impl!(Vec2)
|
||||||
|
approx_eq_impl!(Vec2, x, y)
|
||||||
|
one_impl!(Vec2)
|
||||||
|
from_iterator_impl!(Vec2, iterator, iterator)
|
||||||
|
bounded_impl!(Vec2)
|
||||||
|
iterable_impl!(Vec2, 2)
|
||||||
|
iterable_mut_impl!(Vec2, 2)
|
||||||
|
to_homogeneous_impl!(Vec2, Vec3, z, x, y)
|
||||||
|
from_homogeneous_impl!(Vec2, Vec3, z, x, y)
|
||||||
|
|
||||||
macro_rules! iterable_mut_impl(
|
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
($t: ident, $dim: expr) => (
|
pub struct Vec3<N>
|
||||||
impl<N> IterableMut<N> for $t<N>
|
{
|
||||||
{
|
x: N,
|
||||||
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N>
|
y: N,
|
||||||
{ unsafe { cast::transmute::<&'l mut $t<N>, &'l mut [N, ..$dim]>(self).mut_iter() } }
|
z: N
|
||||||
}
|
}
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! dim_impl(
|
new_impl!(Vec3, x, y, z)
|
||||||
($t: ident, $dim: expr) => (
|
indexable_impl!(Vec3, 3)
|
||||||
impl<N> Dim for $t<N>
|
new_repeat_impl!(Vec3, val, x, y, z)
|
||||||
{
|
dim_impl!(Vec3, 3)
|
||||||
#[inline]
|
// (specialized) basis_impl!(Vec3, 1)
|
||||||
fn dim() -> uint
|
add_impl!(Vec3, x, y, z)
|
||||||
{ $dim }
|
sub_impl!(Vec3, x, y, z)
|
||||||
}
|
neg_impl!(Vec3, x, y, z)
|
||||||
)
|
dot_impl!(Vec3, x, y, z)
|
||||||
)
|
sub_dot_impl!(Vec3, x, y, z)
|
||||||
|
scalar_mul_impl!(Vec3, x, y, z)
|
||||||
|
scalar_div_impl!(Vec3, x, y, z)
|
||||||
|
scalar_add_impl!(Vec3, x, y, z)
|
||||||
|
scalar_sub_impl!(Vec3, x, y, z)
|
||||||
|
translation_impl!(Vec3)
|
||||||
|
translatable_impl!(Vec3)
|
||||||
|
norm_impl!(Vec3)
|
||||||
|
approx_eq_impl!(Vec3, x, y, z)
|
||||||
|
one_impl!(Vec3)
|
||||||
|
from_iterator_impl!(Vec3, iterator, iterator, iterator)
|
||||||
|
bounded_impl!(Vec3)
|
||||||
|
iterable_impl!(Vec3, 3)
|
||||||
|
iterable_mut_impl!(Vec3, 3)
|
||||||
|
to_homogeneous_impl!(Vec3, Vec4, w, x, y, z)
|
||||||
|
from_homogeneous_impl!(Vec3, Vec4, w, x, y, z)
|
||||||
|
|
||||||
macro_rules! basis_impl(
|
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
($t: ident, $dim: expr) => (
|
pub struct Vec4<N>
|
||||||
impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> Basis for $t<N>
|
{
|
||||||
{
|
x: N,
|
||||||
pub fn canonical_basis(f: &fn($t<N>))
|
y: N,
|
||||||
{
|
z: N,
|
||||||
for iterate(0u, $dim) |i|
|
w: N
|
||||||
{
|
}
|
||||||
let mut basis_element : $t<N> = Zero::zero();
|
|
||||||
|
|
||||||
basis_element.set(i, One::one());
|
|
||||||
|
|
||||||
f(basis_element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 iterate(0u, $dim) |i|
|
|
||||||
{
|
|
||||||
let mut basis_element : $t<N> = Zero::zero();
|
|
||||||
|
|
||||||
basis_element.set(i, One::one());
|
|
||||||
|
|
||||||
if basis.len() == $dim - 1
|
|
||||||
{ break; }
|
|
||||||
|
|
||||||
let mut elt = basis_element.clone();
|
|
||||||
|
|
||||||
elt = elt - self.scalar_mul(&basis_element.dot(self));
|
|
||||||
|
|
||||||
for basis.iter().advance |v|
|
|
||||||
{ elt = elt - v.scalar_mul(&elt.dot(v)) };
|
|
||||||
|
|
||||||
if !elt.sqnorm().approx_eq(&Zero::zero())
|
|
||||||
{
|
|
||||||
let new_element = elt.normalized();
|
|
||||||
|
|
||||||
f(new_element.clone());
|
new_impl!(Vec4, x, y, z, w)
|
||||||
|
indexable_impl!(Vec4, 4)
|
||||||
|
new_repeat_impl!(Vec4, val, x, y, z, w)
|
||||||
|
dim_impl!(Vec4, 4)
|
||||||
|
basis_impl!(Vec4, 4)
|
||||||
|
add_impl!(Vec4, x, y, z, w)
|
||||||
|
sub_impl!(Vec4, x, y, z, w)
|
||||||
|
neg_impl!(Vec4, x, y, z, w)
|
||||||
|
dot_impl!(Vec4, x, y, z, w)
|
||||||
|
sub_dot_impl!(Vec4, x, y, z, w)
|
||||||
|
scalar_mul_impl!(Vec4, x, y, z, w)
|
||||||
|
scalar_div_impl!(Vec4, x, y, z, w)
|
||||||
|
scalar_add_impl!(Vec4, x, y, z, w)
|
||||||
|
scalar_sub_impl!(Vec4, x, y, z, w)
|
||||||
|
translation_impl!(Vec4)
|
||||||
|
translatable_impl!(Vec4)
|
||||||
|
norm_impl!(Vec4)
|
||||||
|
approx_eq_impl!(Vec4, x, y, z, w)
|
||||||
|
one_impl!(Vec4)
|
||||||
|
from_iterator_impl!(Vec4, iterator, iterator, iterator, iterator)
|
||||||
|
bounded_impl!(Vec4)
|
||||||
|
iterable_impl!(Vec4, 4)
|
||||||
|
iterable_mut_impl!(Vec4, 4)
|
||||||
|
to_homogeneous_impl!(Vec4, Vec5, a, x, y, z, w)
|
||||||
|
from_homogeneous_impl!(Vec4, Vec5, a, x, y, z, w)
|
||||||
|
|
||||||
basis.push(new_element);
|
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
}
|
pub struct Vec5<N>
|
||||||
}
|
{
|
||||||
}
|
x: N,
|
||||||
}
|
y: N,
|
||||||
)
|
z: N,
|
||||||
)
|
w: N,
|
||||||
|
a: N,
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! add_impl(
|
new_impl!(Vec5, x, y, z, w, a)
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
indexable_impl!(Vec5, 5)
|
||||||
impl<N: Clone + Add<N,N>> Add<$t<N>, $t<N>> for $t<N>
|
new_repeat_impl!(Vec5, val, x, y, z, w, a)
|
||||||
{
|
dim_impl!(Vec5, 5)
|
||||||
#[inline]
|
basis_impl!(Vec5, 5)
|
||||||
fn add(&self, other: &$t<N>) -> $t<N>
|
add_impl!(Vec5, x, y, z, w, a)
|
||||||
{ $t::new(self.$comp0 + other.$comp0 $(, self.$compN + other.$compN)*) }
|
sub_impl!(Vec5, x, y, z, w, a)
|
||||||
}
|
neg_impl!(Vec5, x, y, z, w, a)
|
||||||
)
|
dot_impl!(Vec5, x, y, z, w, a)
|
||||||
)
|
sub_dot_impl!(Vec5, x, y, z, w, a)
|
||||||
|
scalar_mul_impl!(Vec5, x, y, z, w, a)
|
||||||
|
scalar_div_impl!(Vec5, x, y, z, w, a)
|
||||||
|
scalar_add_impl!(Vec5, x, y, z, w, a)
|
||||||
|
scalar_sub_impl!(Vec5, x, y, z, w, a)
|
||||||
|
translation_impl!(Vec5)
|
||||||
|
translatable_impl!(Vec5)
|
||||||
|
norm_impl!(Vec5)
|
||||||
|
approx_eq_impl!(Vec5, x, y, z, w, a)
|
||||||
|
one_impl!(Vec5)
|
||||||
|
from_iterator_impl!(Vec5, iterator, iterator, iterator, iterator, iterator)
|
||||||
|
bounded_impl!(Vec5)
|
||||||
|
iterable_impl!(Vec5, 5)
|
||||||
|
iterable_mut_impl!(Vec5, 5)
|
||||||
|
to_homogeneous_impl!(Vec5, Vec6, b, x, y, z, w, a)
|
||||||
|
from_homogeneous_impl!(Vec5, Vec6, b, x, y, z, w, a)
|
||||||
|
|
||||||
macro_rules! sub_impl(
|
#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
pub struct Vec6<N>
|
||||||
impl<N: Clone + Sub<N,N>> Sub<$t<N>, $t<N>> for $t<N>
|
{
|
||||||
{
|
x: N,
|
||||||
#[inline]
|
y: N,
|
||||||
fn sub(&self, other: &$t<N>) -> $t<N>
|
z: N,
|
||||||
{ $t::new(self.$comp0 - other.$comp0 $(, self.$compN - other.$compN)*) }
|
w: N,
|
||||||
}
|
a: N,
|
||||||
)
|
b: N
|
||||||
)
|
}
|
||||||
|
|
||||||
macro_rules! neg_impl(
|
new_impl!(Vec6, x, y, z, w, a, b)
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
indexable_impl!(Vec6, 6)
|
||||||
impl<N: Neg<N>> Neg<$t<N>> for $t<N>
|
new_repeat_impl!(Vec6, val, x, y, z, w, a, b)
|
||||||
{
|
dim_impl!(Vec6, 6)
|
||||||
#[inline]
|
basis_impl!(Vec6, 6)
|
||||||
fn neg(&self) -> $t<N>
|
add_impl!(Vec6, x, y, z, w, a, b)
|
||||||
{ $t::new(-self.$comp0 $(, -self.$compN )*) }
|
sub_impl!(Vec6, x, y, z, w, a, b)
|
||||||
}
|
neg_impl!(Vec6, x, y, z, w, a, b)
|
||||||
)
|
dot_impl!(Vec6, x, y, z, w, a, b)
|
||||||
)
|
sub_dot_impl!(Vec6, x, y, z, w, a, b)
|
||||||
|
scalar_mul_impl!(Vec6, x, y, z, w, a, b)
|
||||||
macro_rules! dot_impl(
|
scalar_div_impl!(Vec6, x, y, z, w, a, b)
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
scalar_add_impl!(Vec6, x, y, z, w, a, b)
|
||||||
impl<N: Ring> Dot<N> for $t<N>
|
scalar_sub_impl!(Vec6, x, y, z, w, a, b)
|
||||||
{
|
translation_impl!(Vec6)
|
||||||
#[inline]
|
translatable_impl!(Vec6)
|
||||||
fn dot(&self, other: &$t<N>) -> N
|
norm_impl!(Vec6)
|
||||||
{ self.$comp0 * other.$comp0 $(+ self.$compN * other.$compN )* }
|
approx_eq_impl!(Vec6, x, y, z, w, a, b)
|
||||||
}
|
one_impl!(Vec6)
|
||||||
)
|
from_iterator_impl!(Vec6, iterator, iterator, iterator, iterator, iterator, iterator)
|
||||||
)
|
bounded_impl!(Vec6)
|
||||||
|
iterable_impl!(Vec6, 6)
|
||||||
macro_rules! sub_dot_impl(
|
iterable_mut_impl!(Vec6, 6)
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
|
||||||
impl<N: 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 )* }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! scalar_mul_impl(
|
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
|
||||||
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)*) }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn scalar_mul_inplace(&mut self, s: &N)
|
|
||||||
{
|
|
||||||
self.$comp0 = self.$comp0 * *s;
|
|
||||||
$(self.$compN = self.$compN * *s;)*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! scalar_div_impl(
|
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
|
||||||
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)*) }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn scalar_div_inplace(&mut self, s: &N)
|
|
||||||
{
|
|
||||||
self.$comp0 = self.$comp0 / *s;
|
|
||||||
$(self.$compN = self.$compN / *s;)*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! scalar_add_impl(
|
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
|
||||||
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)*) }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn scalar_add_inplace(&mut self, s: &N)
|
|
||||||
{
|
|
||||||
self.$comp0 = self.$comp0 + *s;
|
|
||||||
$(self.$compN = self.$compN + *s;)*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! scalar_sub_impl(
|
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
|
||||||
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)*) }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn scalar_sub_inplace(&mut self, s: &N)
|
|
||||||
{
|
|
||||||
self.$comp0 = self.$comp0 - *s;
|
|
||||||
$(self.$compN = self.$compN - *s;)*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! translation_impl(
|
|
||||||
($t: ident) => (
|
|
||||||
impl<N: Clone + Add<N, N> + Neg<N>> Translation<$t<N>> for $t<N>
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn translation(&self) -> $t<N>
|
|
||||||
{ self.clone() }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn inv_translation(&self) -> $t<N>
|
|
||||||
{ -self }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn translate_by(&mut self, t: &$t<N>)
|
|
||||||
{ *self = *self + *t; }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! translatable_impl(
|
|
||||||
($t: ident) => (
|
|
||||||
impl<N: Add<N, N> + Neg<N> + Clone> Translatable<$t<N>, $t<N>> for $t<N>
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn translated(&self, t: &$t<N>) -> $t<N>
|
|
||||||
{ self + *t }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! norm_impl(
|
|
||||||
($t: ident) => (
|
|
||||||
impl<N: Clone + DivisionRing + Algebraic> Norm<N> for $t<N>
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn sqnorm(&self) -> N
|
|
||||||
{ self.dot(self) }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn norm(&self) -> N
|
|
||||||
{ self.sqnorm().sqrt() }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn normalized(&self) -> $t<N>
|
|
||||||
{
|
|
||||||
let mut res : $t<N> = self.clone();
|
|
||||||
|
|
||||||
res.normalize();
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn normalize(&mut self) -> N
|
|
||||||
{
|
|
||||||
let l = self.norm();
|
|
||||||
|
|
||||||
self.scalar_div_inplace(&l);
|
|
||||||
|
|
||||||
l
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! approx_eq_impl(
|
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
|
||||||
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N>
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn approx_epsilon() -> N
|
|
||||||
{ ApproxEq::approx_epsilon::<N, N>() }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq(&self, other: &$t<N>) -> bool
|
|
||||||
{ 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))* }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! one_impl(
|
|
||||||
($t: ident) => (
|
|
||||||
impl<N: Clone + One> One for $t<N>
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
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())*) }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! bounded_impl(
|
|
||||||
($t: ident) => (
|
|
||||||
impl<N: Bounded + Clone> Bounded for $t<N>
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn max_value() -> $t<N>
|
|
||||||
{ $t::new_repeat(Bounded::max_value()) }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn min_value() -> $t<N>
|
|
||||||
{ $t::new_repeat(Bounded::min_value()) }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
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>
|
|
||||||
{
|
|
||||||
let mut res: $t2<N> = One::one();
|
|
||||||
|
|
||||||
res.$comp0 = self.$comp0.clone();
|
|
||||||
$( res.$compN = self.$compN.clone(); )*
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
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_homogeneous(v: &$t2<N>) -> $t<N>
|
|
||||||
{
|
|
||||||
let mut res: $t<N> = Zero::zero();
|
|
||||||
|
|
||||||
res.$comp0 = v.$comp0.clone();
|
|
||||||
$( res.$compN = v.$compN.clone(); )*
|
|
||||||
|
|
||||||
res.scalar_div(&v.$extra);
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
|
@ -0,0 +1,418 @@
|
||||||
|
#[macro_escape];
|
||||||
|
|
||||||
|
macro_rules! new_impl(
|
||||||
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
|
impl<N> $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
pub fn new($comp0: N $( , $compN: N )*) -> $t<N>
|
||||||
|
{
|
||||||
|
$t {
|
||||||
|
$comp0: $comp0
|
||||||
|
$(, $compN: $compN )*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! indexable_impl(
|
||||||
|
($t: ident, $dim: expr) => (
|
||||||
|
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() } }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
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) } }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! new_repeat_impl(
|
||||||
|
($t: ident, $param: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
|
impl<N: Clone> $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
pub fn new_repeat($param: N) -> $t<N>
|
||||||
|
{
|
||||||
|
$t{
|
||||||
|
$comp0: $param.clone()
|
||||||
|
$(, $compN: $param.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]>(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() } }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! dim_impl(
|
||||||
|
($t: ident, $dim: expr) => (
|
||||||
|
impl<N> Dim for $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
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 iterate(0u, $dim) |i|
|
||||||
|
{
|
||||||
|
let mut basis_element : $t<N> = Zero::zero();
|
||||||
|
|
||||||
|
basis_element.set(i, One::one());
|
||||||
|
|
||||||
|
f(basis_element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 iterate(0u, $dim) |i|
|
||||||
|
{
|
||||||
|
let mut basis_element : $t<N> = Zero::zero();
|
||||||
|
|
||||||
|
basis_element.set(i, One::one());
|
||||||
|
|
||||||
|
if basis.len() == $dim - 1
|
||||||
|
{ break; }
|
||||||
|
|
||||||
|
let mut elt = basis_element.clone();
|
||||||
|
|
||||||
|
elt = elt - self.scalar_mul(&basis_element.dot(self));
|
||||||
|
|
||||||
|
for basis.iter().advance |v|
|
||||||
|
{ elt = elt - v.scalar_mul(&elt.dot(v)) };
|
||||||
|
|
||||||
|
if !elt.sqnorm().approx_eq(&Zero::zero())
|
||||||
|
{
|
||||||
|
let new_element = elt.normalized();
|
||||||
|
|
||||||
|
f(new_element.clone());
|
||||||
|
|
||||||
|
basis.push(new_element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! add_impl(
|
||||||
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
|
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)*) }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! sub_impl(
|
||||||
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
|
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)*) }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! neg_impl(
|
||||||
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
|
impl<N: Neg<N>> Neg<$t<N>> for $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
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>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
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: 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 )* }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! scalar_mul_impl(
|
||||||
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
|
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)*) }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn scalar_mul_inplace(&mut self, s: &N)
|
||||||
|
{
|
||||||
|
self.$comp0 = self.$comp0 * *s;
|
||||||
|
$(self.$compN = self.$compN * *s;)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! scalar_div_impl(
|
||||||
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
|
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)*) }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn scalar_div_inplace(&mut self, s: &N)
|
||||||
|
{
|
||||||
|
self.$comp0 = self.$comp0 / *s;
|
||||||
|
$(self.$compN = self.$compN / *s;)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! scalar_add_impl(
|
||||||
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
|
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)*) }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn scalar_add_inplace(&mut self, s: &N)
|
||||||
|
{
|
||||||
|
self.$comp0 = self.$comp0 + *s;
|
||||||
|
$(self.$compN = self.$compN + *s;)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! scalar_sub_impl(
|
||||||
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
|
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)*) }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn scalar_sub_inplace(&mut self, s: &N)
|
||||||
|
{
|
||||||
|
self.$comp0 = self.$comp0 - *s;
|
||||||
|
$(self.$compN = self.$compN - *s;)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! translation_impl(
|
||||||
|
($t: ident) => (
|
||||||
|
impl<N: Clone + Add<N, N> + Neg<N>> Translation<$t<N>> for $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn translation(&self) -> $t<N>
|
||||||
|
{ self.clone() }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn inv_translation(&self) -> $t<N>
|
||||||
|
{ -self }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn translate_by(&mut self, t: &$t<N>)
|
||||||
|
{ *self = *self + *t; }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! translatable_impl(
|
||||||
|
($t: ident) => (
|
||||||
|
impl<N: Add<N, N> + Neg<N> + Clone> Translatable<$t<N>, $t<N>> for $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn translated(&self, t: &$t<N>) -> $t<N>
|
||||||
|
{ self + *t }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! norm_impl(
|
||||||
|
($t: ident) => (
|
||||||
|
impl<N: Clone + DivisionRing + Algebraic> Norm<N> for $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn sqnorm(&self) -> N
|
||||||
|
{ self.dot(self) }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn norm(&self) -> N
|
||||||
|
{ self.sqnorm().sqrt() }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn normalized(&self) -> $t<N>
|
||||||
|
{
|
||||||
|
let mut res : $t<N> = self.clone();
|
||||||
|
|
||||||
|
res.normalize();
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn normalize(&mut self) -> N
|
||||||
|
{
|
||||||
|
let l = self.norm();
|
||||||
|
|
||||||
|
self.scalar_div_inplace(&l);
|
||||||
|
|
||||||
|
l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! approx_eq_impl(
|
||||||
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
|
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn approx_epsilon() -> N
|
||||||
|
{ ApproxEq::approx_epsilon::<N, N>() }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn approx_eq(&self, other: &$t<N>) -> bool
|
||||||
|
{ 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))* }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! one_impl(
|
||||||
|
($t: ident) => (
|
||||||
|
impl<N: Clone + One> One for $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
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())*) }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! bounded_impl(
|
||||||
|
($t: ident) => (
|
||||||
|
impl<N: Bounded + Clone> Bounded for $t<N>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn max_value() -> $t<N>
|
||||||
|
{ $t::new_repeat(Bounded::max_value()) }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn min_value() -> $t<N>
|
||||||
|
{ $t::new_repeat(Bounded::min_value()) }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
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>
|
||||||
|
{
|
||||||
|
let mut res: $t2<N> = One::one();
|
||||||
|
|
||||||
|
res.$comp0 = self.$comp0.clone();
|
||||||
|
$( res.$compN = self.$compN.clone(); )*
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
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_homogeneous(v: &$t2<N>) -> $t<N>
|
||||||
|
{
|
||||||
|
let mut res: $t<N> = Zero::zero();
|
||||||
|
|
||||||
|
res.$comp0 = v.$comp0.clone();
|
||||||
|
$( res.$compN = v.$compN.clone(); )*
|
||||||
|
|
||||||
|
res.scalar_div(&v.$extra);
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
Loading…
Reference in New Issue