Fix curly braces.
This commit is contained in:
parent
a810bf6008
commit
c59911168e
|
@ -20,40 +20,39 @@ use vec::Vec3;
|
||||||
/// the type-level) that it will always represent a rotation. Rotation matrices have some
|
/// the type-level) that it will always represent a rotation. Rotation matrices have some
|
||||||
/// properties useful for performances, like the fact that the inversion is simply a transposition.
|
/// properties useful for performances, like the fact that the inversion is simply a transposition.
|
||||||
#[deriving(Eq, ToStr, Clone)]
|
#[deriving(Eq, ToStr, Clone)]
|
||||||
pub struct Rotmat<M>
|
pub struct Rotmat<M> {
|
||||||
{ priv submat: M }
|
priv submat: M
|
||||||
|
|
||||||
impl<M: Clone> Rotmat<M>
|
|
||||||
{
|
|
||||||
/// Gets a copy of the internal representation of the rotation.
|
|
||||||
pub fn submat(&self) -> M
|
|
||||||
{ self.submat.clone() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Trigonometric + Neg<N>> Rotmat<Mat2<N>>
|
impl<M: Clone> Rotmat<M> {
|
||||||
{
|
/// Gets a copy of the internal representation of the rotation.
|
||||||
|
pub fn submat(&self) -> M {
|
||||||
|
self.submat.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Clone + Trigonometric + Neg<N>> Rotmat<Mat2<N>> {
|
||||||
/// Builds a 2 dimensional rotation matrix from an angle in radian.
|
/// Builds a 2 dimensional rotation matrix from an angle in radian.
|
||||||
pub fn from_angle(angle: N) -> Rotmat<Mat2<N>>
|
pub fn from_angle(angle: N) -> Rotmat<Mat2<N>> {
|
||||||
{
|
|
||||||
let (sia, coa) = angle.sin_cos();
|
let (sia, coa) = angle.sin_cos();
|
||||||
|
|
||||||
Rotmat { submat: Mat2::new(coa.clone(), -sia, sia.clone(), coa) }
|
Rotmat {
|
||||||
|
submat: Mat2::new(coa.clone(), -sia, sia.clone(), coa)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Trigonometric + DivisionRing + Algebraic> Rotmat<Mat3<N>>
|
impl<N: Clone + Trigonometric + DivisionRing + Algebraic> Rotmat<Mat3<N>> {
|
||||||
{
|
|
||||||
/// Builds a 3 dimensional rotation matrix from an axis and an angle.
|
/// Builds a 3 dimensional rotation matrix from an axis and an angle.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
/// * `axisangle` - A vector representing the rotation. Its magnitude is the amount of rotation
|
/// * `axisangle` - A vector representing the rotation. Its magnitude is the amount of rotation
|
||||||
/// in radian. Its direction is the axis of rotation.
|
/// in radian. Its direction is the axis of rotation.
|
||||||
pub fn from_axis_angle(axisangle: Vec3<N>) -> Rotmat<Mat3<N>>
|
pub fn from_axis_angle(axisangle: Vec3<N>) -> Rotmat<Mat3<N>> {
|
||||||
{
|
if axisangle.sqnorm().is_zero() {
|
||||||
if axisangle.sqnorm().is_zero()
|
One::one()
|
||||||
{ One::one() }
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
let mut axis = axisangle;
|
let mut axis = axisangle;
|
||||||
let angle = axis.normalize();
|
let angle = axis.normalize();
|
||||||
let _1 = One::one::<N>();
|
let _1 = One::one::<N>();
|
||||||
|
@ -84,8 +83,7 @@ impl<N: Clone + Trigonometric + DivisionRing + Algebraic> Rotmat<Mat3<N>>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + DivisionRing + Algebraic> Rotmat<Mat3<N>>
|
impl<N: Clone + DivisionRing + Algebraic> Rotmat<Mat3<N>> {
|
||||||
{
|
|
||||||
/// Reorient this matrix such that its local `x` axis points to a given point. Note that the
|
/// Reorient this matrix such that its local `x` axis points to a given point. Note that the
|
||||||
/// usually known `look_at` function does the same thing but with the `z` axis. See `look_at_z`
|
/// usually known `look_at` function does the same thing but with the `z` axis. See `look_at_z`
|
||||||
/// for that.
|
/// for that.
|
||||||
|
@ -95,8 +93,7 @@ impl<N: Clone + DivisionRing + Algebraic> Rotmat<Mat3<N>>
|
||||||
/// with
|
/// with
|
||||||
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
|
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
|
||||||
/// with `at`. Non-colinearity is not checked.
|
/// with `at`. Non-colinearity is not checked.
|
||||||
pub fn look_at(&mut self, at: &Vec3<N>, up: &Vec3<N>)
|
pub fn look_at(&mut self, at: &Vec3<N>, up: &Vec3<N>) {
|
||||||
{
|
|
||||||
let xaxis = at.normalized();
|
let xaxis = at.normalized();
|
||||||
let zaxis = up.cross(&xaxis).normalized();
|
let zaxis = up.cross(&xaxis).normalized();
|
||||||
let yaxis = zaxis.cross(&xaxis);
|
let yaxis = zaxis.cross(&xaxis);
|
||||||
|
@ -113,8 +110,7 @@ impl<N: Clone + DivisionRing + Algebraic> Rotmat<Mat3<N>>
|
||||||
/// with
|
/// with
|
||||||
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
|
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
|
||||||
/// with `at`. Non-colinearity is not checked.
|
/// with `at`. Non-colinearity is not checked.
|
||||||
pub fn look_at_z(&mut self, at: &Vec3<N>, up: &Vec3<N>)
|
pub fn look_at_z(&mut self, at: &Vec3<N>, up: &Vec3<N>) {
|
||||||
{
|
|
||||||
let zaxis = at.normalized();
|
let zaxis = at.normalized();
|
||||||
let xaxis = up.cross(&zaxis).normalized();
|
let xaxis = up.cross(&zaxis).normalized();
|
||||||
let yaxis = zaxis.cross(&xaxis);
|
let yaxis = zaxis.cross(&xaxis);
|
||||||
|
@ -126,171 +122,179 @@ impl<N: Clone + DivisionRing + Algebraic> Rotmat<Mat3<N>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Trigonometric + DivisionRing + Clone>
|
impl<N: Trigonometric + DivisionRing + Clone>
|
||||||
Rotation<Vec1<N>> for Rotmat<Mat2<N>>
|
Rotation<Vec1<N>> for Rotmat<Mat2<N>> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotation(&self) -> Vec1<N>
|
fn rotation(&self) -> Vec1<N> {
|
||||||
{ Vec1::new((-self.submat.at((0, 1))).atan2(&self.submat.at((0, 0)))) }
|
Vec1::new((-self.submat.at((0, 1))).atan2(&self.submat.at((0, 0))))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inv_rotation(&self) -> Vec1<N>
|
fn inv_rotation(&self) -> Vec1<N> {
|
||||||
{ -self.rotation() }
|
-self.rotation()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate_by(&mut self, rot: &Vec1<N>)
|
fn rotate_by(&mut self, rot: &Vec1<N>) {
|
||||||
{ *self = self.rotated(rot) }
|
*self = self.rotated(rot)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Trigonometric + DivisionRing + Clone>
|
impl<N: Trigonometric + DivisionRing + Clone>
|
||||||
Rotatable<Vec1<N>, Rotmat<Mat2<N>>> for Rotmat<Mat2<N>>
|
Rotatable<Vec1<N>, Rotmat<Mat2<N>>> for Rotmat<Mat2<N>> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>>
|
fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>> {
|
||||||
{ Rotmat::from_angle(rot.x.clone()) * *self }
|
Rotmat::from_angle(rot.x.clone()) * *self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Trigonometric + DivisionRing + Algebraic>
|
impl<N: Clone + Trigonometric + DivisionRing + Algebraic>
|
||||||
Rotation<Vec3<N>> for Rotmat<Mat3<N>>
|
Rotation<Vec3<N>> for Rotmat<Mat3<N>> {
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn rotation(&self) -> Vec3<N>
|
|
||||||
{ fail!("Not yet implemented.") }
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
fn rotation(&self) -> Vec3<N> {
|
||||||
|
fail!("Not yet implemented.")
|
||||||
|
}
|
||||||
|
|
||||||
fn inv_rotation(&self) -> Vec3<N>
|
#[inline]
|
||||||
{ fail!("Not yet implemented.") }
|
fn inv_rotation(&self) -> Vec3<N> {
|
||||||
|
fail!("Not yet implemented.")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate_by(&mut self, rot: &Vec3<N>)
|
fn rotate_by(&mut self, rot: &Vec3<N>) {
|
||||||
{ *self = self.rotated(rot) }
|
*self = self.rotated(rot)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Trigonometric + DivisionRing + Algebraic>
|
impl<N: Clone + Trigonometric + DivisionRing + Algebraic>
|
||||||
Rotatable<Vec3<N>, Rotmat<Mat3<N>>> for Rotmat<Mat3<N>>
|
Rotatable<Vec3<N>, Rotmat<Mat3<N>>> for Rotmat<Mat3<N>> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotated(&self, axisangle: &Vec3<N>) -> Rotmat<Mat3<N>>
|
fn rotated(&self, axisangle: &Vec3<N>) -> Rotmat<Mat3<N>> {
|
||||||
{ Rotmat::from_axis_angle(axisangle.clone()) * *self }
|
Rotmat::from_axis_angle(axisangle.clone()) * *self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Rand + Trigonometric + Neg<N>> Rand for Rotmat<Mat2<N>>
|
impl<N: Clone + Rand + Trigonometric + Neg<N>> Rand for Rotmat<Mat2<N>> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat2<N>>
|
fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat2<N>> {
|
||||||
{ Rotmat::from_angle(rng.gen()) }
|
Rotmat::from_angle(rng.gen())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: RMul<V> + LMul<V>, V> Rotate<V> for Rotmat<M>
|
impl<M: RMul<V> + LMul<V>, V> Rotate<V> for Rotmat<M> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate(&self, v: &V) -> V
|
fn rotate(&self, v: &V) -> V {
|
||||||
{ self.rmul(v) }
|
self.rmul(v)
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn inv_rotate(&self, v: &V) -> V
|
|
||||||
{ self.lmul(v) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: RMul<V> + LMul<V>, V> Transform<V> for Rotmat<M>
|
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transform_vec(&self, v: &V) -> V
|
fn inv_rotate(&self, v: &V) -> V {
|
||||||
{ self.rotate(v) }
|
self.lmul(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M: RMul<V> + LMul<V>, V> Transform<V> for Rotmat<M> {
|
||||||
|
#[inline]
|
||||||
|
fn transform_vec(&self, v: &V) -> V {
|
||||||
|
self.rotate(v)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inv_transform(&self, v: &V) -> V
|
fn inv_transform(&self, v: &V) -> V {
|
||||||
{ self.inv_rotate(v) }
|
self.inv_rotate(v)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Rand + Trigonometric + DivisionRing + Algebraic>
|
impl<N: Clone + Rand + Trigonometric + DivisionRing + Algebraic>
|
||||||
Rand for Rotmat<Mat3<N>>
|
Rand for Rotmat<Mat3<N>> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat3<N>>
|
fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat3<N>> {
|
||||||
{ Rotmat::from_axis_angle(rng.gen()) }
|
Rotmat::from_axis_angle(rng.gen())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Dim> Dim for Rotmat<M>
|
impl<M: Dim> Dim for Rotmat<M> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn dim() -> uint
|
fn dim() -> uint {
|
||||||
{ Dim::dim::<M>() }
|
Dim::dim::<M>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: One + Zero> One for Rotmat<M>
|
impl<M: One + Zero> One for Rotmat<M> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn one() -> Rotmat<M>
|
fn one() -> Rotmat<M> {
|
||||||
{ Rotmat { submat: One::one() } }
|
Rotmat { submat: One::one() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Mul<M, M>> Mul<Rotmat<M>, Rotmat<M>> for Rotmat<M>
|
impl<M: Mul<M, M>> Mul<Rotmat<M>, Rotmat<M>> for Rotmat<M> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul(&self, other: &Rotmat<M>) -> Rotmat<M>
|
fn mul(&self, other: &Rotmat<M>) -> Rotmat<M> {
|
||||||
{ Rotmat { submat: self.submat.mul(&other.submat) } }
|
Rotmat { submat: self.submat.mul(&other.submat) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V, M: RMul<V>> RMul<V> for Rotmat<M>
|
impl<V, M: RMul<V>> RMul<V> for Rotmat<M> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rmul(&self, other: &V) -> V
|
fn rmul(&self, other: &V) -> V {
|
||||||
{ self.submat.rmul(other) }
|
self.submat.rmul(other)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V, M: LMul<V>> LMul<V> for Rotmat<M>
|
impl<V, M: LMul<V>> LMul<V> for Rotmat<M> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn lmul(&self, other: &V) -> V
|
fn lmul(&self, other: &V) -> V {
|
||||||
{ self.submat.lmul(other) }
|
self.submat.lmul(other)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Transpose> Inv for Rotmat<M>
|
impl<M: Transpose> Inv for Rotmat<M> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inplace_inverse(&mut self) -> bool
|
fn inplace_inverse(&mut self) -> bool {
|
||||||
{
|
|
||||||
self.transpose();
|
self.transpose();
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse(&self) -> Option<Rotmat<M>>
|
fn inverse(&self) -> Option<Rotmat<M>> {
|
||||||
{ Some(self.transposed()) }
|
Some(self.transposed())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Transpose>
|
impl<M: Transpose>
|
||||||
Transpose for Rotmat<M>
|
Transpose for Rotmat<M> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transposed(&self) -> Rotmat<M>
|
fn transposed(&self) -> Rotmat<M> {
|
||||||
{ Rotmat { submat: self.submat.transposed() } }
|
Rotmat { submat: self.submat.transposed() }
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transpose(&mut self)
|
fn transpose(&mut self) {
|
||||||
{ self.submat.transpose() }
|
self.submat.transpose()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we loose the info that we are a rotation matrix
|
// we loose the info that we are a rotation matrix
|
||||||
impl<M: ToHomogeneous<M2>, M2> ToHomogeneous<M2> for Rotmat<M>
|
impl<M: ToHomogeneous<M2>, M2> ToHomogeneous<M2> for Rotmat<M> {
|
||||||
{
|
fn to_homogeneous(&self) -> M2 {
|
||||||
fn to_homogeneous(&self) -> M2
|
self.submat.to_homogeneous()
|
||||||
{ self.submat.to_homogeneous() }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: ApproxEq<N>, M: ApproxEq<N>> ApproxEq<N> for Rotmat<M>
|
impl<N: ApproxEq<N>, M: ApproxEq<N>> ApproxEq<N> for Rotmat<M> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_epsilon() -> N
|
fn approx_epsilon() -> N {
|
||||||
{ ApproxEq::approx_epsilon::<N, N>() }
|
ApproxEq::approx_epsilon::<N, N>()
|
||||||
|
}
|
||||||
#[inline]
|
|
||||||
fn approx_eq(&self, other: &Rotmat<M>) -> bool
|
#[inline]
|
||||||
{ 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) }
|
#[inline]
|
||||||
|
fn approx_eq_eps(&self, other: &Rotmat<M>, epsilon: &N) -> bool {
|
||||||
|
self.submat.approx_eq_eps(&other.submat, epsilon)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,35 +23,37 @@ use mat::Mat3;
|
||||||
/// underlying transform is a rotation (see `Rotmat`): this makes inversion much faster than
|
/// underlying transform is a rotation (see `Rotmat`): this makes inversion much faster than
|
||||||
/// inverting the homogeneous matrix itself.
|
/// inverting the homogeneous matrix itself.
|
||||||
#[deriving(Eq, ToStr, Clone)]
|
#[deriving(Eq, ToStr, Clone)]
|
||||||
pub struct Transform<M, V>
|
pub struct Transform<M, V> {
|
||||||
{
|
|
||||||
priv submat : M,
|
priv submat : M,
|
||||||
priv subtrans : V
|
priv subtrans : V
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M, V> Transform<M, V>
|
impl<M, V> Transform<M, V> {
|
||||||
{
|
|
||||||
/// Builds a new transform from a matrix and a vector.
|
/// Builds a new transform from a matrix and a vector.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(mat: M, trans: V) -> Transform<M, V>
|
pub fn new(mat: M, trans: V) -> Transform<M, V> {
|
||||||
{ Transform { submat: mat, subtrans: trans } }
|
Transform {
|
||||||
|
submat: mat,
|
||||||
|
subtrans: trans
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Clone, V: Clone> Transform<M, V>
|
impl<M: Clone, V: Clone> Transform<M, V> {
|
||||||
{
|
|
||||||
/// Gets a copy of the internal matrix.
|
/// Gets a copy of the internal matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn submat(&self) -> M
|
pub fn submat(&self) -> M {
|
||||||
{ self.submat.clone() }
|
self.submat.clone()
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets a copy of the internal translation.
|
/// Gets a copy of the internal translation.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn subtrans(&self) -> V
|
pub fn subtrans(&self) -> V {
|
||||||
{ self.subtrans.clone() }
|
self.subtrans.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + DivisionRing + Algebraic> Transform<Rotmat<Mat3<N>>, Vec3<N>>
|
impl<N: Clone + DivisionRing + Algebraic> Transform<Rotmat<Mat3<N>>, Vec3<N>> {
|
||||||
{
|
|
||||||
/// Reorient and translate this transformation such that its local `x` axis points to a given
|
/// Reorient and translate this transformation such that its local `x` axis points to a given
|
||||||
/// direction. Note that the usually known `look_at` function does the same thing but with the
|
/// direction. Note that the usually known `look_at` function does the same thing but with the
|
||||||
/// `z` axis. See `look_at_z` for that.
|
/// `z` axis. See `look_at_z` for that.
|
||||||
|
@ -62,8 +64,7 @@ impl<N: Clone + DivisionRing + Algebraic> Transform<Rotmat<Mat3<N>>, Vec3<N>>
|
||||||
/// aligned with
|
/// aligned with
|
||||||
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
|
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
|
||||||
/// with `at`. Non-colinearity is not checked.
|
/// with `at`. Non-colinearity is not checked.
|
||||||
pub fn look_at(&mut self, eye: &Vec3<N>, at: &Vec3<N>, up: &Vec3<N>)
|
pub fn look_at(&mut self, eye: &Vec3<N>, at: &Vec3<N>, up: &Vec3<N>) {
|
||||||
{
|
|
||||||
self.submat.look_at(&(*at - *eye), up);
|
self.submat.look_at(&(*at - *eye), up);
|
||||||
self.subtrans = eye.clone();
|
self.subtrans = eye.clone();
|
||||||
}
|
}
|
||||||
|
@ -77,112 +78,119 @@ impl<N: Clone + DivisionRing + Algebraic> Transform<Rotmat<Mat3<N>>, Vec3<N>>
|
||||||
/// aligned with
|
/// aligned with
|
||||||
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
|
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
|
||||||
/// with `at`. Non-colinearity is not checked.
|
/// with `at`. Non-colinearity is not checked.
|
||||||
pub fn look_at_z(&mut self, eye: &Vec3<N>, at: &Vec3<N>, up: &Vec3<N>)
|
pub fn look_at_z(&mut self, eye: &Vec3<N>, at: &Vec3<N>, up: &Vec3<N>) {
|
||||||
{
|
|
||||||
self.submat.look_at_z(&(*at - *eye), up);
|
self.submat.look_at_z(&(*at - *eye), up);
|
||||||
self.subtrans = eye.clone();
|
self.subtrans = eye.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Dim, V> Dim for Transform<M, V>
|
impl<M: Dim, V> Dim for Transform<M, V> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn dim() -> uint
|
fn dim() -> uint {
|
||||||
{ Dim::dim::<M>() }
|
Dim::dim::<M>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: One, V: Zero> One for Transform<M, V>
|
impl<M: One, V: Zero> One for Transform<M, V> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn one() -> Transform<M, V>
|
fn one() -> Transform<M, V> {
|
||||||
{ Transform { submat: One::one(), subtrans: Zero::zero() } }
|
Transform {
|
||||||
|
submat: One::one(), subtrans: Zero::zero()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Zero, V: Zero> Zero for Transform<M, V>
|
impl<M: Zero, V: Zero> Zero for Transform<M, V> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn zero() -> Transform<M, V>
|
fn zero() -> Transform<M, V> {
|
||||||
{ Transform { submat: Zero::zero(), subtrans: Zero::zero() } }
|
Transform {
|
||||||
|
submat: Zero::zero(), subtrans: Zero::zero()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_zero(&self) -> bool
|
fn is_zero(&self) -> bool {
|
||||||
{ self.submat.is_zero() && self.subtrans.is_zero() }
|
self.submat.is_zero() && self.subtrans.is_zero()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: RMul<V> + Mul<M, M>, V: Add<V, V>>
|
impl<M: RMul<V> + Mul<M, M>, V: Add<V, V>>
|
||||||
Mul<Transform<M, V>, Transform<M, V>> for Transform<M, V>
|
Mul<Transform<M, V>, Transform<M, V>> for Transform<M, V> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul(&self, other: &Transform<M, V>) -> Transform<M, V>
|
fn mul(&self, other: &Transform<M, V>) -> Transform<M, V> {
|
||||||
{
|
Transform {
|
||||||
Transform { submat: self.submat * other.submat,
|
submat: self.submat * other.submat,
|
||||||
subtrans: self.subtrans + self.submat.rmul(&other.subtrans) }
|
subtrans: self.subtrans + self.submat.rmul(&other.subtrans)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: RMul<V>, V: Add<V, V>> RMul<V> for Transform<M, V>
|
impl<M: RMul<V>, V: Add<V, V>> RMul<V> for Transform<M, V> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rmul(&self, other: &V) -> V
|
fn rmul(&self, other: &V) -> V {
|
||||||
{ self.submat.rmul(other) + self.subtrans }
|
self.submat.rmul(other) + self.subtrans
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: LMul<V>, V: Add<V, V>> LMul<V> for Transform<M, V>
|
impl<M: LMul<V>, V: Add<V, V>> LMul<V> for Transform<M, V> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn lmul(&self, other: &V) -> V
|
fn lmul(&self, other: &V) -> V {
|
||||||
{ self.submat.lmul(other) + self.subtrans }
|
self.submat.lmul(other) + self.subtrans
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M, V: Translation<V>> Translation<V> for Transform<M, V>
|
impl<M, V: Translation<V>> Translation<V> for Transform<M, V> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn translation(&self) -> V
|
fn translation(&self) -> V {
|
||||||
{ self.subtrans.translation() }
|
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) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Translate<V>, V, _0> Translate<V> for Transform<M, _0>
|
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn translate(&self, v: &V) -> V
|
fn inv_translation(&self) -> V {
|
||||||
{ self.submat.translate(v) }
|
self.subtrans.inv_translation()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inv_translate(&self, v: &V) -> V
|
fn translate_by(&mut self, t: &V) {
|
||||||
{ self.submat.inv_translate(v) }
|
self.subtrans.translate_by(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M: Translate<V>, V, _0> Translate<V> for Transform<M, _0> {
|
||||||
|
#[inline]
|
||||||
|
fn translate(&self, v: &V) -> V {
|
||||||
|
self.submat.translate(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn inv_translate(&self, v: &V) -> V {
|
||||||
|
self.submat.inv_translate(v)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Clone, V: Translatable<V, V> + Translation<V>>
|
impl<M: Clone, V: Translatable<V, V> + Translation<V>>
|
||||||
Translatable<V, Transform<M, V>> for Transform<M, V>
|
Translatable<V, Transform<M, V>> for Transform<M, V> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn translated(&self, t: &V) -> Transform<M, V>
|
fn translated(&self, t: &V) -> Transform<M, V> {
|
||||||
{ Transform::new(self.submat.clone(), self.subtrans.translated(t)) }
|
Transform::new(self.submat.clone(), self.subtrans.translated(t))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Rotation<AV> + RMul<V> + One, V, AV>
|
impl<M: Rotation<AV> + RMul<V> + One, V, AV>
|
||||||
Rotation<AV> for Transform<M, V>
|
Rotation<AV> for Transform<M, V> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotation(&self) -> AV
|
fn rotation(&self) -> AV {
|
||||||
{ self.submat.rotation() }
|
self.submat.rotation()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inv_rotation(&self) -> AV
|
fn inv_rotation(&self) -> AV {
|
||||||
{ self.submat.inv_rotation() }
|
self.submat.inv_rotation()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate_by(&mut self, rot: &AV)
|
fn rotate_by(&mut self, rot: &AV) {
|
||||||
{
|
|
||||||
// FIXME: this does not seem opitmal
|
// FIXME: this does not seem opitmal
|
||||||
let mut delta = One::one::<M>();
|
let mut delta = One::one::<M>();
|
||||||
delta.rotate_by(rot);
|
delta.rotate_by(rot);
|
||||||
|
@ -191,23 +199,22 @@ Rotation<AV> for Transform<M, V>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Rotate<V>, V, _0> Rotate<V> for Transform<M, _0>
|
impl<M: Rotate<V>, V, _0> Rotate<V> for Transform<M, _0> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate(&self, v: &V) -> V
|
fn rotate(&self, v: &V) -> V {
|
||||||
{ self.submat.rotate(v) }
|
self.submat.rotate(v)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inv_rotate(&self, v: &V) -> V
|
fn inv_rotate(&self, v: &V) -> V {
|
||||||
{ self.submat.inv_rotate(v) }
|
self.submat.inv_rotate(v)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Rotatable<AV, Res> + One, Res: Rotation<AV> + RMul<V> + One, V, AV>
|
impl<M: Rotatable<AV, Res> + One, Res: Rotation<AV> + RMul<V> + One, V, AV>
|
||||||
Rotatable<AV, Transform<Res, V>> for Transform<M, V>
|
Rotatable<AV, Transform<Res, V>> for Transform<M, V> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotated(&self, rot: &AV) -> Transform<Res, V>
|
fn rotated(&self, rot: &AV) -> Transform<Res, V> {
|
||||||
{
|
|
||||||
// FIXME: this does not seem opitmal
|
// FIXME: this does not seem opitmal
|
||||||
let delta = One::one::<M>().rotated(rot);
|
let delta = One::one::<M>().rotated(rot);
|
||||||
|
|
||||||
|
@ -216,79 +223,76 @@ Rotatable<AV, Transform<Res, V>> for Transform<M, V>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Inv + RMul<V> + Mul<M, M> + Clone, V: Add<V, V> + Neg<V> + Clone>
|
impl<M: Inv + RMul<V> + Mul<M, M> + Clone, V: Add<V, V> + Neg<V> + Clone>
|
||||||
Transformation<Transform<M, V>> for Transform<M, V>
|
Transformation<Transform<M, V>> for Transform<M, V> {
|
||||||
{
|
fn transformation(&self) -> Transform<M, V> {
|
||||||
fn transformation(&self) -> Transform<M, V>
|
self.clone()
|
||||||
{ self.clone() }
|
}
|
||||||
|
|
||||||
fn inv_transformation(&self) -> Transform<M, V>
|
fn inv_transformation(&self) -> Transform<M, V> {
|
||||||
{
|
|
||||||
// FIXME: fail or return a Some<Transform<M, V>> ?
|
// FIXME: fail or return a Some<Transform<M, V>> ?
|
||||||
match self.inverse()
|
match self.inverse() {
|
||||||
{
|
|
||||||
Some(t) => t,
|
Some(t) => t,
|
||||||
None => fail!("This transformation was not inversible.")
|
None => fail!("This transformation was not inversible.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transform_by(&mut self, other: &Transform<M, V>)
|
fn transform_by(&mut self, other: &Transform<M, V>) {
|
||||||
{ *self = other * *self; }
|
*self = other * *self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Ts<V>, V: Add<V, V> + Sub<V, V>>
|
impl<M: Ts<V>, V: Add<V, V> + Sub<V, V>>
|
||||||
Ts<V> for Transform<M, V>
|
Ts<V> for Transform<M, V> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transform_vec(&self, v: &V) -> V
|
fn transform_vec(&self, v: &V) -> V {
|
||||||
{ self.submat.transform_vec(v) + self.subtrans }
|
self.submat.transform_vec(v) + self.subtrans
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inv_transform(&self, v: &V) -> V
|
fn inv_transform(&self, v: &V) -> V {
|
||||||
{ self.submat.inv_transform(&(v - self.subtrans)) }
|
self.submat.inv_transform(&(v - self.subtrans))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FIXME: constraints are too restrictive.
|
// FIXME: constraints are too restrictive.
|
||||||
// Should be: Transformable<M2, // Transform<Res, V> ...
|
// Should be: Transformable<M2, // Transform<Res, V> ...
|
||||||
impl<M: RMul<V> + Mul<M, M> + Inv + Clone, V: Add<V, V> + Neg<V> + Clone>
|
impl<M: RMul<V> + Mul<M, M> + Inv + Clone, V: Add<V, V> + Neg<V> + Clone>
|
||||||
Transformable<Transform<M, V>, Transform<M, V>> for Transform<M, V>
|
Transformable<Transform<M, V>, Transform<M, V>> for Transform<M, V> {
|
||||||
{
|
fn transformed(&self, t: &Transform<M, V>) -> Transform<M, V> {
|
||||||
fn transformed(&self, t: &Transform<M, V>) -> Transform<M, V>
|
t * *self
|
||||||
{ t * *self }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Inv + RMul<V> + Clone, V: Neg<V> + Clone>
|
impl<M: Inv + RMul<V> + Clone, V: Neg<V> + Clone>
|
||||||
Inv for Transform<M, V>
|
Inv for Transform<M, V> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inplace_inverse(&mut self) -> bool
|
fn inplace_inverse(&mut self) -> bool {
|
||||||
{
|
if !self.submat.inplace_inverse() {
|
||||||
if !self.submat.inplace_inverse()
|
false
|
||||||
{ false }
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
self.subtrans = self.submat.rmul(&-self.subtrans);
|
self.subtrans = self.submat.rmul(&-self.subtrans);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse(&self) -> Option<Transform<M, V>>
|
fn inverse(&self) -> Option<Transform<M, V>> {
|
||||||
{
|
|
||||||
let mut res = self.clone();
|
let mut res = self.clone();
|
||||||
|
|
||||||
if res.inplace_inverse()
|
if res.inplace_inverse() {
|
||||||
{ Some(res) }
|
Some(res)
|
||||||
else
|
}
|
||||||
{ None }
|
else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: ToHomogeneous<M2>, M2: Dim + Column<V>, V: Clone>
|
impl<M: ToHomogeneous<M2>, M2: Dim + Column<V>, V: Clone>
|
||||||
ToHomogeneous<M2> for Transform<M, V>
|
ToHomogeneous<M2> for Transform<M, V> {
|
||||||
{
|
fn to_homogeneous(&self) -> M2 {
|
||||||
fn to_homogeneous(&self) -> M2
|
|
||||||
{
|
|
||||||
let mut res = self.submat.to_homogeneous();
|
let mut res = self.submat.to_homogeneous();
|
||||||
|
|
||||||
// copy the translation
|
// copy the translation
|
||||||
|
@ -301,39 +305,35 @@ ToHomogeneous<M2> for Transform<M, V>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Column<V> + Dim, M2: FromHomogeneous<M>, V>
|
impl<M: Column<V> + Dim, M2: FromHomogeneous<M>, V>
|
||||||
FromHomogeneous<M> for Transform<M2, V>
|
FromHomogeneous<M> for Transform<M2, V> {
|
||||||
{
|
fn from(m: &M) -> Transform<M2, V> {
|
||||||
fn from(m: &M) -> Transform<M2, V>
|
|
||||||
{
|
|
||||||
Transform::new(FromHomogeneous::from(m), m.column(Dim::dim::<M>() - 1))
|
Transform::new(FromHomogeneous::from(m), m.column(Dim::dim::<M>() - 1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: ApproxEq<N>, M:ApproxEq<N>, V:ApproxEq<N>>
|
impl<N: ApproxEq<N>, M:ApproxEq<N>, V:ApproxEq<N>>
|
||||||
ApproxEq<N> for Transform<M, V>
|
ApproxEq<N> for Transform<M, V> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_epsilon() -> N
|
fn approx_epsilon() -> N {
|
||||||
{ ApproxEq::approx_epsilon::<N, N>() }
|
ApproxEq::approx_epsilon::<N, N>()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_eq(&self, other: &Transform<M, V>) -> bool
|
fn approx_eq(&self, other: &Transform<M, V>) -> bool {
|
||||||
{
|
|
||||||
self.submat.approx_eq(&other.submat) &&
|
self.submat.approx_eq(&other.submat) &&
|
||||||
self.subtrans.approx_eq(&other.subtrans)
|
self.subtrans.approx_eq(&other.subtrans)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_eq_eps(&self, other: &Transform<M, V>, epsilon: &N) -> bool
|
fn approx_eq_eps(&self, other: &Transform<M, V>, epsilon: &N) -> bool {
|
||||||
{
|
|
||||||
self.submat.approx_eq_eps(&other.submat, epsilon) &&
|
self.submat.approx_eq_eps(&other.submat, epsilon) &&
|
||||||
self.subtrans.approx_eq_eps(&other.subtrans, epsilon)
|
self.subtrans.approx_eq_eps(&other.subtrans, epsilon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Rand, V: Rand> Rand for Transform<M, V>
|
impl<M: Rand, V: Rand> Rand for Transform<M, V> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rand<R: Rng>(rng: &mut R) -> Transform<M, V>
|
fn rand<R: Rng>(rng: &mut R) -> Transform<M, V> {
|
||||||
{ Transform::new(rng.gen(), rng.gen()) }
|
Transform::new(rng.gen(), rng.gen())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
184
src/dmat.rs
184
src/dmat.rs
|
@ -10,8 +10,7 @@ use dvec::{DVec, zero_vec_with_dim};
|
||||||
|
|
||||||
/// Square matrix with a dimension unknown at compile-time.
|
/// Square matrix with a dimension unknown at compile-time.
|
||||||
#[deriving(Eq, ToStr, Clone)]
|
#[deriving(Eq, ToStr, Clone)]
|
||||||
pub struct DMat<N>
|
pub struct DMat<N> {
|
||||||
{
|
|
||||||
priv dim: uint, // FIXME: handle more than just square matrices
|
priv dim: uint, // FIXME: handle more than just square matrices
|
||||||
priv mij: ~[N]
|
priv mij: ~[N]
|
||||||
}
|
}
|
||||||
|
@ -22,13 +21,15 @@ pub struct DMat<N>
|
||||||
/// * `dim` - The dimension of the matrix. A `dim`-dimensional matrix contains `dim * dim`
|
/// * `dim` - The dimension of the matrix. A `dim`-dimensional matrix contains `dim * dim`
|
||||||
/// components.
|
/// components.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn zero_mat_with_dim<N: Zero + Clone>(dim: uint) -> DMat<N>
|
pub fn zero_mat_with_dim<N: Zero + Clone>(dim: uint) -> DMat<N> {
|
||||||
{ DMat { dim: dim, mij: from_elem(dim * dim, Zero::zero()) } }
|
DMat { dim: dim, mij: from_elem(dim * dim, Zero::zero()) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Tests if all components of the matrix are zeroes.
|
/// Tests if all components of the matrix are zeroes.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_zero_mat<N: Zero>(mat: &DMat<N>) -> bool
|
pub fn is_zero_mat<N: Zero>(mat: &DMat<N>) -> bool {
|
||||||
{ mat.mij.iter().all(|e| e.is_zero()) }
|
mat.mij.iter().all(|e| e.is_zero())
|
||||||
|
}
|
||||||
|
|
||||||
/// Builds an identity matrix.
|
/// Builds an identity matrix.
|
||||||
///
|
///
|
||||||
|
@ -36,22 +37,22 @@ pub fn is_zero_mat<N: Zero>(mat: &DMat<N>) -> bool
|
||||||
/// * `dim` - The dimension of the matrix. A `dim`-dimensional matrix contains `dim * dim`
|
/// * `dim` - The dimension of the matrix. A `dim`-dimensional matrix contains `dim * dim`
|
||||||
/// components.
|
/// components.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn one_mat_with_dim<N: Clone + One + Zero>(dim: uint) -> DMat<N>
|
pub fn one_mat_with_dim<N: Clone + One + Zero>(dim: uint) -> DMat<N> {
|
||||||
{
|
|
||||||
let mut res = zero_mat_with_dim(dim);
|
let mut res = zero_mat_with_dim(dim);
|
||||||
let _1 = One::one::<N>();
|
let _1 = One::one::<N>();
|
||||||
|
|
||||||
for i in range(0u, dim)
|
for i in range(0u, dim) {
|
||||||
{ res.set(i, i, &_1); }
|
res.set(i, i, &_1);
|
||||||
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone> DMat<N>
|
impl<N: Clone> DMat<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn offset(&self, i: uint, j: uint) -> uint
|
fn offset(&self, i: uint, j: uint) -> uint {
|
||||||
{ i * self.dim + j }
|
i * self.dim + j
|
||||||
|
}
|
||||||
|
|
||||||
/// Changes the value of a component of the matrix.
|
/// Changes the value of a component of the matrix.
|
||||||
///
|
///
|
||||||
|
@ -59,8 +60,7 @@ impl<N: Clone> DMat<N>
|
||||||
/// * `i` - 0-based index of the line to be changed
|
/// * `i` - 0-based index of the line to be changed
|
||||||
/// * `j` - 0-based index of the column to be changed
|
/// * `j` - 0-based index of the column to be changed
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set(&mut self, i: uint, j: uint, t: &N)
|
pub fn set(&mut self, i: uint, j: uint, t: &N) {
|
||||||
{
|
|
||||||
assert!(i < self.dim);
|
assert!(i < self.dim);
|
||||||
assert!(j < self.dim);
|
assert!(j < self.dim);
|
||||||
self.mij[self.offset(i, j)] = t.clone()
|
self.mij[self.offset(i, j)] = t.clone()
|
||||||
|
@ -72,39 +72,35 @@ impl<N: Clone> DMat<N>
|
||||||
/// * `i` - 0-based index of the line to be read
|
/// * `i` - 0-based index of the line to be read
|
||||||
/// * `j` - 0-based index of the column to be read
|
/// * `j` - 0-based index of the column to be read
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn at(&self, i: uint, j: uint) -> N
|
pub fn at(&self, i: uint, j: uint) -> N {
|
||||||
{
|
|
||||||
assert!(i < self.dim);
|
assert!(i < self.dim);
|
||||||
assert!(j < self.dim);
|
assert!(j < self.dim);
|
||||||
self.mij[self.offset(i, j)].clone()
|
self.mij[self.offset(i, j)].clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone> Index<(uint, uint), N> for DMat<N>
|
impl<N: Clone> Index<(uint, uint), N> for DMat<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index(&self, &(i, j): &(uint, uint)) -> N
|
fn index(&self, &(i, j): &(uint, uint)) -> N {
|
||||||
{ self.at(i, j) }
|
self.at(i, j)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Mul<N, N> + Add<N, N> + Zero>
|
impl<N: Clone + Mul<N, N> + Add<N, N> + Zero>
|
||||||
Mul<DMat<N>, DMat<N>> for DMat<N>
|
Mul<DMat<N>, DMat<N>> for DMat<N> {
|
||||||
{
|
fn mul(&self, other: &DMat<N>) -> DMat<N> {
|
||||||
fn mul(&self, other: &DMat<N>) -> DMat<N>
|
|
||||||
{
|
|
||||||
assert!(self.dim == other.dim);
|
assert!(self.dim == other.dim);
|
||||||
|
|
||||||
let dim = self.dim;
|
let dim = self.dim;
|
||||||
let mut res = zero_mat_with_dim(dim);
|
let mut res = zero_mat_with_dim(dim);
|
||||||
|
|
||||||
for i in range(0u, dim)
|
for i in range(0u, dim) {
|
||||||
{
|
for j in range(0u, dim) {
|
||||||
for j in range(0u, dim)
|
|
||||||
{
|
|
||||||
let mut acc = Zero::zero::<N>();
|
let mut acc = Zero::zero::<N>();
|
||||||
|
|
||||||
for k in range(0u, dim)
|
for k in range(0u, dim) {
|
||||||
{ acc = acc + self.at(i, k) * other.at(k, j); }
|
acc = acc + self.at(i, k) * other.at(k, j);
|
||||||
|
}
|
||||||
|
|
||||||
res.set(i, j, &acc);
|
res.set(i, j, &acc);
|
||||||
}
|
}
|
||||||
|
@ -115,19 +111,17 @@ Mul<DMat<N>, DMat<N>> for DMat<N>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Add<N, N> + Mul<N, N> + Zero>
|
impl<N: Clone + Add<N, N> + Mul<N, N> + Zero>
|
||||||
RMul<DVec<N>> for DMat<N>
|
RMul<DVec<N>> for DMat<N> {
|
||||||
{
|
fn rmul(&self, other: &DVec<N>) -> DVec<N> {
|
||||||
fn rmul(&self, other: &DVec<N>) -> DVec<N>
|
|
||||||
{
|
|
||||||
assert!(self.dim == other.at.len());
|
assert!(self.dim == other.at.len());
|
||||||
|
|
||||||
let dim = self.dim;
|
let dim = self.dim;
|
||||||
let mut res : DVec<N> = zero_vec_with_dim(dim);
|
let mut res : DVec<N> = zero_vec_with_dim(dim);
|
||||||
|
|
||||||
for i in range(0u, dim)
|
for i in range(0u, dim) {
|
||||||
{
|
for j in range(0u, dim) {
|
||||||
for j in range(0u, dim)
|
res.at[i] = res.at[i] + other.at[j] * self.at(i, j);
|
||||||
{ res.at[i] = res.at[i] + other.at[j] * self.at(i, j); }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -135,19 +129,17 @@ RMul<DVec<N>> for DMat<N>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Add<N, N> + Mul<N, N> + Zero>
|
impl<N: Clone + Add<N, N> + Mul<N, N> + Zero>
|
||||||
LMul<DVec<N>> for DMat<N>
|
LMul<DVec<N>> for DMat<N> {
|
||||||
{
|
fn lmul(&self, other: &DVec<N>) -> DVec<N> {
|
||||||
fn lmul(&self, other: &DVec<N>) -> DVec<N>
|
|
||||||
{
|
|
||||||
assert!(self.dim == other.at.len());
|
assert!(self.dim == other.at.len());
|
||||||
|
|
||||||
let dim = self.dim;
|
let dim = self.dim;
|
||||||
let mut res : DVec<N> = zero_vec_with_dim(dim);
|
let mut res : DVec<N> = zero_vec_with_dim(dim);
|
||||||
|
|
||||||
for i in range(0u, dim)
|
for i in range(0u, dim) {
|
||||||
{
|
for j in range(0u, dim) {
|
||||||
for j in range(0u, dim)
|
res.at[i] = res.at[i] + other.at[j] * self.at(j, i);
|
||||||
{ res.at[i] = res.at[i] + other.at[j] * self.at(j, i); }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -155,50 +147,47 @@ LMul<DVec<N>> for DMat<N>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Eq + DivisionRing>
|
impl<N: Clone + Eq + DivisionRing>
|
||||||
Inv for DMat<N>
|
Inv for DMat<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse(&self) -> Option<DMat<N>>
|
fn inverse(&self) -> Option<DMat<N>> {
|
||||||
{
|
|
||||||
let mut res : DMat<N> = self.clone();
|
let mut res : DMat<N> = self.clone();
|
||||||
|
|
||||||
if res.inplace_inverse()
|
if res.inplace_inverse() {
|
||||||
{ Some(res) }
|
Some(res)
|
||||||
else
|
}
|
||||||
{ None }
|
else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inplace_inverse(&mut self) -> bool
|
fn inplace_inverse(&mut self) -> bool {
|
||||||
{
|
|
||||||
let dim = self.dim;
|
let dim = self.dim;
|
||||||
let mut res = one_mat_with_dim::<N>(dim);
|
let mut res = one_mat_with_dim::<N>(dim);
|
||||||
let _0T = Zero::zero::<N>();
|
let _0T = Zero::zero::<N>();
|
||||||
|
|
||||||
// inversion using Gauss-Jordan elimination
|
// inversion using Gauss-Jordan elimination
|
||||||
for k in range(0u, dim)
|
for k in range(0u, dim) {
|
||||||
{
|
|
||||||
// search a non-zero value on the k-th column
|
// search a non-zero value on the k-th column
|
||||||
// FIXME: would it be worth it to spend some more time searching for the
|
// FIXME: would it be worth it to spend some more time searching for the
|
||||||
// max instead?
|
// max instead?
|
||||||
|
|
||||||
let mut n0 = k; // index of a non-zero entry
|
let mut n0 = k; // index of a non-zero entry
|
||||||
|
|
||||||
while (n0 != dim)
|
while (n0 != dim) {
|
||||||
{
|
if self.at(n0, k) != _0T {
|
||||||
if self.at(n0, k) != _0T
|
break;
|
||||||
{ break; }
|
}
|
||||||
|
|
||||||
n0 = n0 + 1;
|
n0 = n0 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if n0 == dim
|
if n0 == dim {
|
||||||
{ return false }
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// swap pivot line
|
// swap pivot line
|
||||||
if n0 != k
|
if n0 != k {
|
||||||
{
|
for j in range(0u, dim) {
|
||||||
for j in range(0u, dim)
|
|
||||||
{
|
|
||||||
let off_n0_j = self.offset(n0, j);
|
let off_n0_j = self.offset(n0, j);
|
||||||
let off_k_j = self.offset(k, j);
|
let off_k_j = self.offset(k, j);
|
||||||
|
|
||||||
|
@ -209,32 +198,26 @@ Inv for DMat<N>
|
||||||
|
|
||||||
let pivot = self.at(k, k);
|
let pivot = self.at(k, k);
|
||||||
|
|
||||||
for j in range(k, dim)
|
for j in range(k, dim) {
|
||||||
{
|
|
||||||
let selfval = &(self.at(k, j) / pivot);
|
let selfval = &(self.at(k, j) / pivot);
|
||||||
self.set(k, j, selfval);
|
self.set(k, j, selfval);
|
||||||
}
|
}
|
||||||
|
|
||||||
for j in range(0u, dim)
|
for j in range(0u, dim) {
|
||||||
{
|
|
||||||
let resval = &(res.at(k, j) / pivot);
|
let resval = &(res.at(k, j) / pivot);
|
||||||
res.set(k, j, resval);
|
res.set(k, j, resval);
|
||||||
}
|
}
|
||||||
|
|
||||||
for l in range(0u, dim)
|
for l in range(0u, dim) {
|
||||||
{
|
if l != k {
|
||||||
if l != k
|
|
||||||
{
|
|
||||||
let normalizer = self.at(l, k);
|
let normalizer = self.at(l, k);
|
||||||
|
|
||||||
for j in range(k, dim)
|
for j in range(k, dim) {
|
||||||
{
|
|
||||||
let selfval = &(self.at(l, j) - self.at(k, j) * normalizer);
|
let selfval = &(self.at(l, j) - self.at(k, j) * normalizer);
|
||||||
self.set(l, j, selfval);
|
self.set(l, j, selfval);
|
||||||
}
|
}
|
||||||
|
|
||||||
for j in range(0u, dim)
|
for j in range(0u, dim) {
|
||||||
{
|
|
||||||
let resval = &(res.at(l, j) - res.at(k, j) * normalizer);
|
let resval = &(res.at(l, j) - res.at(k, j) * normalizer);
|
||||||
res.set(l, j, resval);
|
res.set(l, j, resval);
|
||||||
}
|
}
|
||||||
|
@ -248,11 +231,9 @@ Inv for DMat<N>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone> Transpose for DMat<N>
|
impl<N: Clone> Transpose for DMat<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transposed(&self) -> DMat<N>
|
fn transposed(&self) -> DMat<N> {
|
||||||
{
|
|
||||||
let mut res = self.clone();
|
let mut res = self.clone();
|
||||||
|
|
||||||
res.transpose();
|
res.transpose();
|
||||||
|
@ -260,14 +241,11 @@ impl<N: Clone> Transpose for DMat<N>
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transpose(&mut self)
|
fn transpose(&mut self) {
|
||||||
{
|
|
||||||
let dim = self.dim;
|
let dim = self.dim;
|
||||||
|
|
||||||
for i in range(1u, dim)
|
for i in range(1u, dim) {
|
||||||
{
|
for j in range(0u, dim - 1) {
|
||||||
for j in range(0u, dim - 1)
|
|
||||||
{
|
|
||||||
let off_i_j = self.offset(i, j);
|
let off_i_j = self.offset(i, j);
|
||||||
let off_j_i = self.offset(j, i);
|
let off_j_i = self.offset(j, i);
|
||||||
|
|
||||||
|
@ -277,25 +255,27 @@ impl<N: Clone> Transpose for DMat<N>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: ApproxEq<N>> ApproxEq<N> for DMat<N>
|
impl<N: ApproxEq<N>> ApproxEq<N> for DMat<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_epsilon() -> N
|
fn approx_epsilon() -> N {
|
||||||
{ ApproxEq::approx_epsilon::<N, N>() }
|
ApproxEq::approx_epsilon::<N, N>()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_eq(&self, other: &DMat<N>) -> bool
|
fn approx_eq(&self, other: &DMat<N>) -> bool {
|
||||||
{
|
|
||||||
let mut zip = self.mij.iter().zip(other.mij.iter());
|
let mut zip = self.mij.iter().zip(other.mij.iter());
|
||||||
|
|
||||||
do zip.all |(a, b)| { a.approx_eq(b) }
|
do zip.all |(a, b)| {
|
||||||
|
a.approx_eq(b)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_eq_eps(&self, other: &DMat<N>, epsilon: &N) -> bool
|
fn approx_eq_eps(&self, other: &DMat<N>, epsilon: &N) -> bool {
|
||||||
{
|
|
||||||
let mut zip = self.mij.iter().zip(other.mij.iter());
|
let mut zip = self.mij.iter().zip(other.mij.iter());
|
||||||
|
|
||||||
do zip.all |(a, b)| { a.approx_eq_eps(b, epsilon) }
|
do zip.all |(a, b)| {
|
||||||
|
a.approx_eq_eps(b, epsilon)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
258
src/dvec.rs
258
src/dvec.rs
|
@ -14,8 +14,7 @@ use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||||
|
|
||||||
/// Vector with a dimension unknown at compile-time.
|
/// Vector with a dimension unknown at compile-time.
|
||||||
#[deriving(Eq, Ord, ToStr, Clone)]
|
#[deriving(Eq, Ord, ToStr, Clone)]
|
||||||
pub struct DVec<N>
|
pub struct DVec<N> {
|
||||||
{
|
|
||||||
/// Components of the vector. Contains as much elements as the vector dimension.
|
/// Components of the vector. Contains as much elements as the vector dimension.
|
||||||
at: ~[N]
|
at: ~[N]
|
||||||
}
|
}
|
||||||
|
@ -25,50 +24,48 @@ pub struct DVec<N>
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
/// * `dim` - The dimension of the vector.
|
/// * `dim` - The dimension of the vector.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn zero_vec_with_dim<N: Zero + Clone>(dim: uint) -> DVec<N>
|
pub fn zero_vec_with_dim<N: Zero + Clone>(dim: uint) -> DVec<N> {
|
||||||
{ DVec { at: from_elem(dim, Zero::zero::<N>()) } }
|
DVec { at: from_elem(dim, Zero::zero::<N>()) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Tests if all components of the vector are zeroes.
|
/// Tests if all components of the vector are zeroes.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_zero_vec<N: Zero>(vec: &DVec<N>) -> bool
|
pub fn is_zero_vec<N: Zero>(vec: &DVec<N>) -> bool {
|
||||||
{ vec.at.iter().all(|e| e.is_zero()) }
|
vec.at.iter().all(|e| e.is_zero())
|
||||||
|
|
||||||
impl<N> Iterable<N> for DVec<N>
|
|
||||||
{
|
|
||||||
fn iter<'l>(&'l self) -> VecIterator<'l, N>
|
|
||||||
{ self.at.iter() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N> IterableMut<N> for DVec<N>
|
impl<N> Iterable<N> for DVec<N> {
|
||||||
{
|
fn iter<'l>(&'l self) -> VecIterator<'l, N> {
|
||||||
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N>
|
self.at.iter()
|
||||||
{ self.at.mut_iter() }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for DVec<N>
|
impl<N> IterableMut<N> for DVec<N> {
|
||||||
{
|
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> {
|
||||||
fn from_iterator(mut param: &mut Iter) -> DVec<N>
|
self.at.mut_iter()
|
||||||
{
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for DVec<N> {
|
||||||
|
fn from_iterator(mut param: &mut Iter) -> DVec<N> {
|
||||||
let mut res = DVec { at: ~[] };
|
let mut res = DVec { at: ~[] };
|
||||||
|
|
||||||
for e in param
|
for e in param {
|
||||||
{ res.at.push(e) }
|
res.at.push(e)
|
||||||
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> DVec<N>
|
impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> DVec<N> {
|
||||||
{
|
|
||||||
/// Computes the canonical basis for the given dimension. A canonical basis is a set of
|
/// Computes the canonical basis for the given dimension. A canonical basis is a set of
|
||||||
/// vectors, mutually orthogonal, with all its component equal to 0.0 exept one which is equal
|
/// vectors, mutually orthogonal, with all its component equal to 0.0 exept one which is equal
|
||||||
/// to 1.0.
|
/// to 1.0.
|
||||||
pub fn canonical_basis_with_dim(dim: uint) -> ~[DVec<N>]
|
pub fn canonical_basis_with_dim(dim: uint) -> ~[DVec<N>] {
|
||||||
{
|
|
||||||
let mut res : ~[DVec<N>] = ~[];
|
let mut res : ~[DVec<N>] = ~[];
|
||||||
|
|
||||||
for i in range(0u, dim)
|
for i in range(0u, dim) {
|
||||||
{
|
|
||||||
let mut basis_element : DVec<N> = zero_vec_with_dim(dim);
|
let mut basis_element : DVec<N> = zero_vec_with_dim(dim);
|
||||||
|
|
||||||
basis_element.at[i] = One::one();
|
basis_element.at[i] = One::one();
|
||||||
|
@ -81,31 +78,32 @@ impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> DVec<N>
|
||||||
|
|
||||||
/// Computes a basis of the space orthogonal to the vector. If the input vector is of dimension
|
/// Computes a basis of the space orthogonal to the vector. If the input vector is of dimension
|
||||||
/// `n`, this will return `n - 1` vectors.
|
/// `n`, this will return `n - 1` vectors.
|
||||||
pub fn orthogonal_subspace_basis(&self) -> ~[DVec<N>]
|
pub fn orthogonal_subspace_basis(&self) -> ~[DVec<N>] {
|
||||||
{
|
|
||||||
// compute the basis of the orthogonal subspace using Gram-Schmidt
|
// compute the basis of the orthogonal subspace using Gram-Schmidt
|
||||||
// orthogonalization algorithm
|
// orthogonalization algorithm
|
||||||
let dim = self.at.len();
|
let dim = self.at.len();
|
||||||
let mut res : ~[DVec<N>] = ~[];
|
let mut res : ~[DVec<N>] = ~[];
|
||||||
|
|
||||||
for i in range(0u, dim)
|
for i in range(0u, dim) {
|
||||||
{
|
|
||||||
let mut basis_element : DVec<N> = zero_vec_with_dim(self.at.len());
|
let mut basis_element : DVec<N> = zero_vec_with_dim(self.at.len());
|
||||||
|
|
||||||
basis_element.at[i] = One::one();
|
basis_element.at[i] = One::one();
|
||||||
|
|
||||||
if res.len() == dim - 1
|
if res.len() == dim - 1 {
|
||||||
{ break; }
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
let mut elt = basis_element.clone();
|
let mut elt = basis_element.clone();
|
||||||
|
|
||||||
elt = elt - self.scalar_mul(&basis_element.dot(self));
|
elt = elt - self.scalar_mul(&basis_element.dot(self));
|
||||||
|
|
||||||
for v in res.iter()
|
for v in res.iter() {
|
||||||
{ elt = elt - v.scalar_mul(&elt.dot(v)) };
|
elt = elt - v.scalar_mul(&elt.dot(v))
|
||||||
|
};
|
||||||
|
|
||||||
if !elt.sqnorm().approx_eq(&Zero::zero())
|
if !elt.sqnorm().approx_eq(&Zero::zero()) {
|
||||||
{ res.push(elt.normalized()); }
|
res.push(elt.normalized());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(res.len() == dim - 1);
|
assert!(res.len() == dim - 1);
|
||||||
|
@ -114,11 +112,9 @@ impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> DVec<N>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Add<N,N>> Add<DVec<N>, DVec<N>> for DVec<N>
|
impl<N: Add<N,N>> Add<DVec<N>, DVec<N>> for DVec<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add(&self, other: &DVec<N>) -> DVec<N>
|
fn add(&self, other: &DVec<N>) -> DVec<N> {
|
||||||
{
|
|
||||||
assert!(self.at.len() == other.at.len());
|
assert!(self.at.len() == other.at.len());
|
||||||
DVec {
|
DVec {
|
||||||
at: self.at.iter().zip(other.at.iter()).transform(|(a, b)| *a + *b).collect()
|
at: self.at.iter().zip(other.at.iter()).transform(|(a, b)| *a + *b).collect()
|
||||||
|
@ -126,11 +122,9 @@ impl<N: Add<N,N>> Add<DVec<N>, DVec<N>> for DVec<N>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Sub<N,N>> Sub<DVec<N>, DVec<N>> for DVec<N>
|
impl<N: Sub<N,N>> Sub<DVec<N>, DVec<N>> for DVec<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sub(&self, other: &DVec<N>) -> DVec<N>
|
fn sub(&self, other: &DVec<N>) -> DVec<N> {
|
||||||
{
|
|
||||||
assert!(self.at.len() == other.at.len());
|
assert!(self.at.len() == other.at.len());
|
||||||
DVec {
|
DVec {
|
||||||
at: self.at.iter().zip(other.at.iter()).transform(|(a, b)| *a - *b).collect()
|
at: self.at.iter().zip(other.at.iter()).transform(|(a, b)| *a - *b).collect()
|
||||||
|
@ -138,135 +132,135 @@ impl<N: Sub<N,N>> Sub<DVec<N>, DVec<N>> for DVec<N>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Neg<N>> Neg<DVec<N>> for DVec<N>
|
impl<N: Neg<N>> Neg<DVec<N>> for DVec<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn neg(&self) -> DVec<N>
|
fn neg(&self) -> DVec<N> {
|
||||||
{ DVec { at: self.at.iter().transform(|a| -a).collect() } }
|
DVec { at: self.at.iter().transform(|a| -a).collect() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Ring> Dot<N> for DVec<N>
|
impl<N: Ring> Dot<N> for DVec<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn dot(&self, other: &DVec<N>) -> N
|
fn dot(&self, other: &DVec<N>) -> N {
|
||||||
{
|
|
||||||
assert!(self.at.len() == other.at.len());
|
assert!(self.at.len() == other.at.len());
|
||||||
|
|
||||||
let mut res = Zero::zero::<N>();
|
let mut res = Zero::zero::<N>();
|
||||||
|
|
||||||
for i in range(0u, self.at.len())
|
for i in range(0u, self.at.len()) {
|
||||||
{ res = res + self.at[i] * other.at[i]; }
|
res = res + self.at[i] * other.at[i];
|
||||||
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Ring> SubDot<N> for DVec<N>
|
impl<N: Ring> SubDot<N> for DVec<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sub_dot(&self, a: &DVec<N>, b: &DVec<N>) -> N
|
fn sub_dot(&self, a: &DVec<N>, b: &DVec<N>) -> N {
|
||||||
{
|
|
||||||
let mut res = Zero::zero::<N>();
|
let mut res = Zero::zero::<N>();
|
||||||
|
|
||||||
for i in range(0u, self.at.len())
|
for i in range(0u, self.at.len()) {
|
||||||
{ res = res + (self.at[i] - a.at[i]) * b.at[i]; }
|
res = res + (self.at[i] - a.at[i]) * b.at[i];
|
||||||
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Mul<N, N>> ScalarMul<N> for DVec<N>
|
impl<N: Mul<N, N>> ScalarMul<N> for DVec<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_mul(&self, s: &N) -> DVec<N>
|
fn scalar_mul(&self, s: &N) -> DVec<N> {
|
||||||
{ DVec { at: self.at.iter().transform(|a| a * *s).collect() } }
|
DVec { at: self.at.iter().transform(|a| a * *s).collect() }
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_mul_inplace(&mut self, s: &N)
|
fn scalar_mul_inplace(&mut self, s: &N) {
|
||||||
{
|
for i in range(0u, self.at.len()) {
|
||||||
for i in range(0u, self.at.len())
|
self.at[i] = self.at[i] * *s;
|
||||||
{ self.at[i] = self.at[i] * *s; }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<N: Div<N, N>> ScalarDiv<N> for DVec<N>
|
impl<N: Div<N, N>> ScalarDiv<N> for DVec<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_div(&self, s: &N) -> DVec<N>
|
fn scalar_div(&self, s: &N) -> DVec<N> {
|
||||||
{ DVec { at: self.at.iter().transform(|a| a / *s).collect() } }
|
DVec { at: self.at.iter().transform(|a| a / *s).collect() }
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_div_inplace(&mut self, s: &N)
|
fn scalar_div_inplace(&mut self, s: &N) {
|
||||||
{
|
for i in range(0u, self.at.len()) {
|
||||||
for i in range(0u, self.at.len())
|
self.at[i] = self.at[i] / *s;
|
||||||
{ self.at[i] = self.at[i] / *s; }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Add<N, N>> ScalarAdd<N> for DVec<N>
|
impl<N: Add<N, N>> ScalarAdd<N> for DVec<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_add(&self, s: &N) -> DVec<N>
|
fn scalar_add(&self, s: &N) -> DVec<N> {
|
||||||
{ DVec { at: self.at.iter().transform(|a| a + *s).collect() } }
|
DVec { at: self.at.iter().transform(|a| a + *s).collect() }
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_add_inplace(&mut self, s: &N)
|
fn scalar_add_inplace(&mut self, s: &N) {
|
||||||
{
|
for i in range(0u, self.at.len()) {
|
||||||
for i in range(0u, self.at.len())
|
self.at[i] = self.at[i] + *s;
|
||||||
{ self.at[i] = self.at[i] + *s; }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Sub<N, N>> ScalarSub<N> for DVec<N>
|
impl<N: Sub<N, N>> ScalarSub<N> for DVec<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_sub(&self, s: &N) -> DVec<N>
|
fn scalar_sub(&self, s: &N) -> DVec<N> {
|
||||||
{ DVec { at: self.at.iter().transform(|a| a - *s).collect() } }
|
DVec { at: self.at.iter().transform(|a| a - *s).collect() }
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_sub_inplace(&mut self, s: &N)
|
fn scalar_sub_inplace(&mut self, s: &N) {
|
||||||
{
|
for i in range(0u, self.at.len()) {
|
||||||
for i in range(0u, self.at.len())
|
self.at[i] = self.at[i] - *s;
|
||||||
{ self.at[i] = self.at[i] - *s; }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Add<N, N> + Neg<N> + Clone> Translation<DVec<N>> for DVec<N>
|
impl<N: Add<N, N> + Neg<N> + Clone> Translation<DVec<N>> for DVec<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn translation(&self) -> DVec<N>
|
fn translation(&self) -> DVec<N> {
|
||||||
{ self.clone() }
|
self.clone()
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn inv_translation(&self) -> DVec<N>
|
|
||||||
{ -self }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
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>
|
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn translated(&self, t: &DVec<N>) -> DVec<N>
|
fn inv_translation(&self) -> DVec<N> {
|
||||||
{ self + *t }
|
-self
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: DivisionRing + Algebraic + Clone> Norm<N> for DVec<N>
|
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sqnorm(&self) -> N
|
fn translate_by(&mut self, t: &DVec<N>) {
|
||||||
{ self.dot(self) }
|
*self = *self + *t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: DivisionRing + Algebraic + Clone> Norm<N> for DVec<N> {
|
||||||
|
#[inline]
|
||||||
|
fn sqnorm(&self) -> N {
|
||||||
|
self.dot(self)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn norm(&self) -> N
|
fn norm(&self) -> N {
|
||||||
{ self.sqnorm().sqrt() }
|
self.sqnorm().sqrt()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn normalized(&self) -> DVec<N>
|
fn normalized(&self) -> DVec<N> {
|
||||||
{
|
|
||||||
let mut res : DVec<N> = self.clone();
|
let mut res : DVec<N> = self.clone();
|
||||||
|
|
||||||
res.normalize();
|
res.normalize();
|
||||||
|
@ -275,36 +269,38 @@ impl<N: DivisionRing + Algebraic + Clone> Norm<N> for DVec<N>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn normalize(&mut self) -> N
|
fn normalize(&mut self) -> N {
|
||||||
{
|
|
||||||
let l = self.norm();
|
let l = self.norm();
|
||||||
|
|
||||||
for i in range(0u, self.at.len())
|
for i in range(0u, self.at.len()) {
|
||||||
{ self.at[i] = self.at[i] / l; }
|
self.at[i] = self.at[i] / l;
|
||||||
|
}
|
||||||
|
|
||||||
l
|
l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: ApproxEq<N>> ApproxEq<N> for DVec<N>
|
impl<N: ApproxEq<N>> ApproxEq<N> for DVec<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_epsilon() -> N
|
fn approx_epsilon() -> N {
|
||||||
{ ApproxEq::approx_epsilon::<N, N>() }
|
ApproxEq::approx_epsilon::<N, N>()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_eq(&self, other: &DVec<N>) -> bool
|
fn approx_eq(&self, other: &DVec<N>) -> bool {
|
||||||
{
|
|
||||||
let mut zip = self.at.iter().zip(other.at.iter());
|
let mut zip = self.at.iter().zip(other.at.iter());
|
||||||
|
|
||||||
do zip.all |(a, b)| { a.approx_eq(b) }
|
do zip.all |(a, b)| {
|
||||||
|
a.approx_eq(b)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_eq_eps(&self, other: &DVec<N>, epsilon: &N) -> bool
|
fn approx_eq_eps(&self, other: &DVec<N>, epsilon: &N) -> bool {
|
||||||
{
|
|
||||||
let mut zip = self.at.iter().zip(other.at.iter());
|
let mut zip = self.at.iter().zip(other.at.iter());
|
||||||
|
|
||||||
do zip.all |(a, b)| { a.approx_eq_eps(b, epsilon) }
|
do zip.all |(a, b)| {
|
||||||
|
a.approx_eq_eps(b, epsilon)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
18
src/mat.rs
18
src/mat.rs
|
@ -31,8 +31,7 @@ mod mat_macros;
|
||||||
|
|
||||||
/// Square matrix of dimension 1.
|
/// Square matrix of dimension 1.
|
||||||
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
pub struct Mat1<N>
|
pub struct Mat1<N> {
|
||||||
{
|
|
||||||
m11: N
|
m11: N
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,8 +55,7 @@ from_homogeneous_impl!(Mat1, Mat2, 1, 2)
|
||||||
|
|
||||||
/// Square matrix of dimension 2.
|
/// Square matrix of dimension 2.
|
||||||
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
pub struct Mat2<N>
|
pub struct Mat2<N> {
|
||||||
{
|
|
||||||
m11: N, m12: N,
|
m11: N, m12: N,
|
||||||
m21: N, m22: N
|
m21: N, m22: N
|
||||||
}
|
}
|
||||||
|
@ -85,8 +83,7 @@ from_homogeneous_impl!(Mat2, Mat3, 2, 3)
|
||||||
|
|
||||||
/// Square matrix of dimension 3.
|
/// Square matrix of dimension 3.
|
||||||
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
pub struct Mat3<N>
|
pub struct Mat3<N> {
|
||||||
{
|
|
||||||
m11: N, m12: N, m13: N,
|
m11: N, m12: N, m13: N,
|
||||||
m21: N, m22: N, m23: N,
|
m21: N, m22: N, m23: N,
|
||||||
m31: N, m32: N, m33: N
|
m31: N, m32: N, m33: N
|
||||||
|
@ -118,8 +115,7 @@ from_homogeneous_impl!(Mat3, Mat4, 3, 4)
|
||||||
|
|
||||||
/// Square matrix of dimension 4.
|
/// Square matrix of dimension 4.
|
||||||
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
pub struct Mat4<N>
|
pub struct Mat4<N> {
|
||||||
{
|
|
||||||
m11: N, m12: N, m13: N, m14: N,
|
m11: N, m12: N, m13: N, m14: N,
|
||||||
m21: N, m22: N, m23: N, m24: N,
|
m21: N, m22: N, m23: N, m24: N,
|
||||||
m31: N, m32: N, m33: N, m34: N,
|
m31: N, m32: N, m33: N, m34: N,
|
||||||
|
@ -159,8 +155,7 @@ from_homogeneous_impl!(Mat4, Mat5, 4, 5)
|
||||||
|
|
||||||
/// Square matrix of dimension 5.
|
/// Square matrix of dimension 5.
|
||||||
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
pub struct Mat5<N>
|
pub struct Mat5<N> {
|
||||||
{
|
|
||||||
m11: N, m12: N, m13: N, m14: N, m15: N,
|
m11: N, m12: N, m13: N, m14: N, m15: N,
|
||||||
m21: N, m22: N, m23: N, m24: N, m25: N,
|
m21: N, m22: N, m23: N, m24: N, m25: N,
|
||||||
m31: N, m32: N, m33: N, m34: N, m35: N,
|
m31: N, m32: N, m33: N, m34: N, m35: N,
|
||||||
|
@ -206,8 +201,7 @@ from_homogeneous_impl!(Mat5, Mat6, 5, 6)
|
||||||
|
|
||||||
/// Square matrix of dimension 6.
|
/// Square matrix of dimension 6.
|
||||||
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
pub struct Mat6<N>
|
pub struct Mat6<N> {
|
||||||
{
|
|
||||||
m11: N, m12: N, m13: N, m14: N, m15: N, m16: N,
|
m11: N, m12: N, m13: N, m14: N, m15: N, m16: N,
|
||||||
m21: N, m22: N, m23: N, m24: N, m25: N, m26: N,
|
m21: N, m22: N, m23: N, m24: N, m25: N, m26: N,
|
||||||
m31: N, m32: N, m33: N, m34: N, m35: N, m36: N,
|
m31: N, m32: N, m33: N, m34: N, m35: N, m36: N,
|
||||||
|
|
|
@ -2,11 +2,9 @@
|
||||||
|
|
||||||
macro_rules! mat_impl(
|
macro_rules! mat_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N> $t<N>
|
impl<N> $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new($comp0: N $(, $compN: N )*) -> $t<N>
|
pub fn new($comp0: N $(, $compN: N )*) -> $t<N> {
|
||||||
{
|
|
||||||
$t {
|
$t {
|
||||||
$comp0: $comp0
|
$comp0: $comp0
|
||||||
$(, $compN: $compN )*
|
$(, $compN: $compN )*
|
||||||
|
@ -18,42 +16,44 @@ macro_rules! mat_impl(
|
||||||
|
|
||||||
macro_rules! mat_cast_impl(
|
macro_rules! mat_cast_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<Nin: NumCast + Clone, Nout: NumCast> MatCast<$t<Nout>> for $t<Nin>
|
impl<Nin: NumCast + Clone, Nout: NumCast> MatCast<$t<Nout>> for $t<Nin> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from(m: $t<Nin>) -> $t<Nout>
|
pub fn from(m: $t<Nin>) -> $t<Nout> {
|
||||||
{ $t::new(NumCast::from(m.$comp0.clone()) $(, NumCast::from(m.$compN.clone()) )*) }
|
$t::new(NumCast::from(m.$comp0.clone()) $(, NumCast::from(m.$compN.clone()) )*)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! iterable_impl(
|
macro_rules! iterable_impl(
|
||||||
($t: ident, $dim: expr) => (
|
($t: ident, $dim: expr) => (
|
||||||
impl<N> Iterable<N> for $t<N>
|
impl<N> Iterable<N> for $t<N> {
|
||||||
{
|
fn iter<'l>(&'l self) -> VecIterator<'l, N> {
|
||||||
fn iter<'l>(&'l self) -> VecIterator<'l, N>
|
unsafe {
|
||||||
{ unsafe { cast::transmute::<&'l $t<N>, &'l [N, ..$dim * $dim]>(self).iter() } }
|
cast::transmute::<&'l $t<N>, &'l [N, ..$dim * $dim]>(self).iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! iterable_mut_impl(
|
macro_rules! iterable_mut_impl(
|
||||||
($t: ident, $dim: expr) => (
|
($t: ident, $dim: expr) => (
|
||||||
impl<N> IterableMut<N> for $t<N>
|
impl<N> IterableMut<N> for $t<N> {
|
||||||
{
|
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> {
|
||||||
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N>
|
unsafe {
|
||||||
{ unsafe { cast::transmute::<&'l mut $t<N>, &'l mut [N, ..$dim * $dim]>(self).mut_iter() } }
|
cast::transmute::<&'l mut $t<N>, &'l mut [N, ..$dim * $dim]>(self).mut_iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! one_impl(
|
macro_rules! one_impl(
|
||||||
($t: ident, $value0: ident $(, $valueN: ident)* ) => (
|
($t: ident, $value0: ident $(, $valueN: ident)* ) => (
|
||||||
impl<N: Clone + One + Zero> One for $t<N>
|
impl<N: Clone + One + Zero> One for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn one() -> $t<N>
|
fn one() -> $t<N> {
|
||||||
{
|
|
||||||
let (_0, _1) = (Zero::zero::<N>(), One::one::<N>());
|
let (_0, _1) = (Zero::zero::<N>(), One::one::<N>());
|
||||||
return $t::new($value0.clone() $(, $valueN.clone() )*)
|
return $t::new($value0.clone() $(, $valueN.clone() )*)
|
||||||
}
|
}
|
||||||
|
@ -63,30 +63,34 @@ macro_rules! one_impl(
|
||||||
|
|
||||||
macro_rules! dim_impl(
|
macro_rules! dim_impl(
|
||||||
($t: ident, $dim: expr) => (
|
($t: ident, $dim: expr) => (
|
||||||
impl<N> Dim for $t<N>
|
impl<N> Dim for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn dim() -> uint
|
fn dim() -> uint {
|
||||||
{ $dim }
|
$dim
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! indexable_impl(
|
macro_rules! indexable_impl(
|
||||||
($t: ident, $dim: expr) => (
|
($t: ident, $dim: expr) => (
|
||||||
impl<N: Clone> Indexable<(uint, uint), N> for $t<N>
|
impl<N: Clone> Indexable<(uint, uint), N> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn at(&self, (i, j): (uint, uint)) -> N
|
pub fn at(&self, (i, j): (uint, uint)) -> N {
|
||||||
{ unsafe { cast::transmute::<&$t<N>, &[N, ..$dim * $dim]>(self)[i * $dim + j].clone() } }
|
unsafe {
|
||||||
|
cast::transmute::<&$t<N>, &[N, ..$dim * $dim]>(self)[i * $dim + j].clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set(&mut self, (i, j): (uint, uint), val: N)
|
pub fn set(&mut self, (i, j): (uint, uint), val: N) {
|
||||||
{ unsafe { cast::transmute::<&mut $t<N>, &mut [N, ..$dim * $dim]>(self)[i * $dim + j] = val } }
|
unsafe {
|
||||||
|
cast::transmute::<&mut $t<N>, &mut [N, ..$dim * $dim]>(self)[i * $dim + j] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn swap(&mut self, (i1, j1): (uint, uint), (i2, j2): (uint, uint))
|
pub fn swap(&mut self, (i1, j1): (uint, uint), (i2, j2): (uint, uint)) {
|
||||||
{
|
|
||||||
unsafe {
|
unsafe {
|
||||||
cast::transmute::<&mut $t<N>, &mut [N, ..$dim * $dim]>(self)
|
cast::transmute::<&mut $t<N>, &mut [N, ..$dim * $dim]>(self)
|
||||||
.swap(i1 * $dim + j1, i2 * $dim + j2)
|
.swap(i1 * $dim + j1, i2 * $dim + j2)
|
||||||
|
@ -98,27 +102,24 @@ macro_rules! indexable_impl(
|
||||||
|
|
||||||
macro_rules! column_impl(
|
macro_rules! column_impl(
|
||||||
($t: ident, $dim: expr) => (
|
($t: ident, $dim: expr) => (
|
||||||
impl<N: Clone, V: Zero + Iterable<N> + IterableMut<N>> Column<V> for $t<N>
|
impl<N: Clone, V: Zero + Iterable<N> + IterableMut<N>> Column<V> for $t<N> {
|
||||||
{
|
fn set_column(&mut self, col: uint, v: V) {
|
||||||
fn set_column(&mut self, col: uint, v: V)
|
for (i, e) in v.iter().enumerate() {
|
||||||
{
|
if i == Dim::dim::<$t<N>>() {
|
||||||
for (i, e) in v.iter().enumerate()
|
break
|
||||||
{
|
}
|
||||||
if i == Dim::dim::<$t<N>>()
|
|
||||||
{ break }
|
|
||||||
|
|
||||||
self.set((i, col), e.clone());
|
self.set((i, col), e.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn column(&self, col: uint) -> V
|
fn column(&self, col: uint) -> V {
|
||||||
{
|
|
||||||
let mut res = Zero::zero::<V>();
|
let mut res = Zero::zero::<V>();
|
||||||
|
|
||||||
for (i, e) in res.mut_iter().enumerate()
|
for (i, e) in res.mut_iter().enumerate() {
|
||||||
{
|
if i >= Dim::dim::<$t<N>>() {
|
||||||
if i >= Dim::dim::<$t<N>>()
|
break
|
||||||
{ break }
|
}
|
||||||
|
|
||||||
*e = self.at((i, col));
|
*e = self.at((i, col));
|
||||||
}
|
}
|
||||||
|
@ -131,20 +132,17 @@ macro_rules! column_impl(
|
||||||
|
|
||||||
macro_rules! mul_impl(
|
macro_rules! mul_impl(
|
||||||
($t: ident, $dim: expr) => (
|
($t: ident, $dim: expr) => (
|
||||||
impl<N: Clone + Ring> Mul<$t<N>, $t<N>> for $t<N>
|
impl<N: Clone + Ring> Mul<$t<N>, $t<N>> for $t<N> {
|
||||||
{
|
fn mul(&self, other: &$t<N>) -> $t<N> {
|
||||||
fn mul(&self, other: &$t<N>) -> $t<N>
|
|
||||||
{
|
|
||||||
let mut res: $t<N> = Zero::zero();
|
let mut res: $t<N> = Zero::zero();
|
||||||
|
|
||||||
for i in range(0u, $dim)
|
for i in range(0u, $dim) {
|
||||||
{
|
for j in range(0u, $dim) {
|
||||||
for j in range(0u, $dim)
|
|
||||||
{
|
|
||||||
let mut acc = Zero::zero::<N>();
|
let mut acc = Zero::zero::<N>();
|
||||||
|
|
||||||
for k in range(0u, $dim)
|
for k in range(0u, $dim) {
|
||||||
{ acc = acc + self.at((i, k)) * other.at((k, j)); }
|
acc = acc + self.at((i, k)) * other.at((k, j));
|
||||||
|
}
|
||||||
|
|
||||||
res.set((i, j), acc);
|
res.set((i, j), acc);
|
||||||
}
|
}
|
||||||
|
@ -158,16 +156,12 @@ macro_rules! mul_impl(
|
||||||
|
|
||||||
macro_rules! rmul_impl(
|
macro_rules! rmul_impl(
|
||||||
($t: ident, $v: ident, $dim: expr) => (
|
($t: ident, $v: ident, $dim: expr) => (
|
||||||
impl<N: Clone + Ring> RMul<$v<N>> for $t<N>
|
impl<N: Clone + Ring> RMul<$v<N>> for $t<N> {
|
||||||
{
|
fn rmul(&self, other: &$v<N>) -> $v<N> {
|
||||||
fn rmul(&self, other: &$v<N>) -> $v<N>
|
|
||||||
{
|
|
||||||
let mut res : $v<N> = Zero::zero();
|
let mut res : $v<N> = Zero::zero();
|
||||||
|
|
||||||
for i in range(0u, $dim)
|
for i in range(0u, $dim) {
|
||||||
{
|
for j in range(0u, $dim) {
|
||||||
for j in range(0u, $dim)
|
|
||||||
{
|
|
||||||
let val = res.at(i) + other.at(j) * self.at((i, j));
|
let val = res.at(i) + other.at(j) * self.at((i, j));
|
||||||
res.set(i, val)
|
res.set(i, val)
|
||||||
}
|
}
|
||||||
|
@ -181,16 +175,12 @@ macro_rules! rmul_impl(
|
||||||
|
|
||||||
macro_rules! lmul_impl(
|
macro_rules! lmul_impl(
|
||||||
($t: ident, $v: ident, $dim: expr) => (
|
($t: ident, $v: ident, $dim: expr) => (
|
||||||
impl<N: Clone + Ring> LMul<$v<N>> for $t<N>
|
impl<N: Clone + Ring> LMul<$v<N>> for $t<N> {
|
||||||
{
|
fn lmul(&self, other: &$v<N>) -> $v<N> {
|
||||||
fn lmul(&self, other: &$v<N>) -> $v<N>
|
|
||||||
{
|
|
||||||
let mut res : $v<N> = Zero::zero();
|
let mut res : $v<N> = Zero::zero();
|
||||||
|
|
||||||
for i in range(0u, $dim)
|
for i in range(0u, $dim) {
|
||||||
{
|
for j in range(0u, $dim) {
|
||||||
for j in range(0u, $dim)
|
|
||||||
{
|
|
||||||
let val = res.at(i) + other.at(j) * self.at((j, i));
|
let val = res.at(i) + other.at(j) * self.at((j, i));
|
||||||
res.set(i, val)
|
res.set(i, val)
|
||||||
}
|
}
|
||||||
|
@ -205,17 +195,15 @@ macro_rules! lmul_impl(
|
||||||
macro_rules! transform_impl(
|
macro_rules! transform_impl(
|
||||||
($t: ident, $v: ident) => (
|
($t: ident, $v: ident) => (
|
||||||
impl<N: Clone + DivisionRing + Eq>
|
impl<N: Clone + DivisionRing + Eq>
|
||||||
Transform<$v<N>> for $t<N>
|
Transform<$v<N>> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transform_vec(&self, v: &$v<N>) -> $v<N>
|
fn transform_vec(&self, v: &$v<N>) -> $v<N> {
|
||||||
{ self.rmul(v) }
|
self.rmul(v)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inv_transform(&self, v: &$v<N>) -> $v<N>
|
fn inv_transform(&self, v: &$v<N>) -> $v<N> {
|
||||||
{
|
match self.inverse() {
|
||||||
match self.inverse()
|
|
||||||
{
|
|
||||||
Some(t) => t.transform_vec(v),
|
Some(t) => t.transform_vec(v),
|
||||||
None => fail!("Cannot use inv_transform on a non-inversible matrix.")
|
None => fail!("Cannot use inv_transform on a non-inversible matrix.")
|
||||||
}
|
}
|
||||||
|
@ -227,49 +215,46 @@ macro_rules! transform_impl(
|
||||||
macro_rules! inv_impl(
|
macro_rules! inv_impl(
|
||||||
($t: ident, $dim: expr) => (
|
($t: ident, $dim: expr) => (
|
||||||
impl<N: Clone + Eq + DivisionRing>
|
impl<N: Clone + Eq + DivisionRing>
|
||||||
Inv for $t<N>
|
Inv for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse(&self) -> Option<$t<N>>
|
fn inverse(&self) -> Option<$t<N>> {
|
||||||
{
|
|
||||||
let mut res : $t<N> = self.clone();
|
let mut res : $t<N> = self.clone();
|
||||||
|
|
||||||
if res.inplace_inverse()
|
if res.inplace_inverse() {
|
||||||
{ Some(res) }
|
Some(res)
|
||||||
else
|
}
|
||||||
{ None }
|
else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inplace_inverse(&mut self) -> bool
|
fn inplace_inverse(&mut self) -> bool {
|
||||||
{
|
|
||||||
let mut res: $t<N> = One::one();
|
let mut res: $t<N> = One::one();
|
||||||
let _0N: N = Zero::zero();
|
let _0N: N = Zero::zero();
|
||||||
|
|
||||||
// inversion using Gauss-Jordan elimination
|
// inversion using Gauss-Jordan elimination
|
||||||
for k in range(0u, $dim)
|
for k in range(0u, $dim) {
|
||||||
{
|
|
||||||
// search a non-zero value on the k-th column
|
// search a non-zero value on the k-th column
|
||||||
// FIXME: would it be worth it to spend some more time searching for the
|
// FIXME: would it be worth it to spend some more time searching for the
|
||||||
// max instead?
|
// max instead?
|
||||||
|
|
||||||
let mut n0 = k; // index of a non-zero entry
|
let mut n0 = k; // index of a non-zero entry
|
||||||
|
|
||||||
while (n0 != $dim)
|
while (n0 != $dim) {
|
||||||
{
|
if self.at((n0, k)) != _0N {
|
||||||
if self.at((n0, k)) != _0N
|
break;
|
||||||
{ break; }
|
}
|
||||||
|
|
||||||
n0 = n0 + 1;
|
n0 = n0 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if n0 == $dim
|
if n0 == $dim {
|
||||||
{ return false }
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// swap pivot line
|
// swap pivot line
|
||||||
if n0 != k
|
if n0 != k {
|
||||||
{
|
for j in range(0u, $dim) {
|
||||||
for j in range(0u, $dim)
|
|
||||||
{
|
|
||||||
self.swap((n0, j), (k, j));
|
self.swap((n0, j), (k, j));
|
||||||
res.swap((n0, j), (k, j));
|
res.swap((n0, j), (k, j));
|
||||||
}
|
}
|
||||||
|
@ -277,32 +262,26 @@ macro_rules! inv_impl(
|
||||||
|
|
||||||
let pivot = self.at((k, k));
|
let pivot = self.at((k, k));
|
||||||
|
|
||||||
for j in range(k, $dim)
|
for j in range(k, $dim) {
|
||||||
{
|
|
||||||
let selfval = self.at((k, j)) / pivot;
|
let selfval = self.at((k, j)) / pivot;
|
||||||
self.set((k, j), selfval);
|
self.set((k, j), selfval);
|
||||||
}
|
}
|
||||||
|
|
||||||
for j in range(0u, $dim)
|
for j in range(0u, $dim) {
|
||||||
{
|
|
||||||
let resval = res.at((k, j)) / pivot;
|
let resval = res.at((k, j)) / pivot;
|
||||||
res.set((k, j), resval);
|
res.set((k, j), resval);
|
||||||
}
|
}
|
||||||
|
|
||||||
for l in range(0u, $dim)
|
for l in range(0u, $dim) {
|
||||||
{
|
if l != k {
|
||||||
if l != k
|
|
||||||
{
|
|
||||||
let normalizer = self.at((l, k));
|
let normalizer = self.at((l, k));
|
||||||
|
|
||||||
for j in range(k, $dim)
|
for j in range(k, $dim) {
|
||||||
{
|
|
||||||
let selfval = self.at((l, j)) - self.at((k, j)) * normalizer;
|
let selfval = self.at((l, j)) - self.at((k, j)) * normalizer;
|
||||||
self.set((l, j), selfval);
|
self.set((l, j), selfval);
|
||||||
}
|
}
|
||||||
|
|
||||||
for j in range(0u, $dim)
|
for j in range(0u, $dim) {
|
||||||
{
|
|
||||||
let resval = res.at((l, j)) - res.at((k, j)) * normalizer;
|
let resval = res.at((l, j)) - res.at((k, j)) * normalizer;
|
||||||
res.set((l, j), resval);
|
res.set((l, j), resval);
|
||||||
}
|
}
|
||||||
|
@ -320,11 +299,9 @@ macro_rules! inv_impl(
|
||||||
|
|
||||||
macro_rules! transpose_impl(
|
macro_rules! transpose_impl(
|
||||||
($t: ident, $dim: expr) => (
|
($t: ident, $dim: expr) => (
|
||||||
impl<N: Clone> Transpose for $t<N>
|
impl<N: Clone> Transpose for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transposed(&self) -> $t<N>
|
fn transposed(&self) -> $t<N> {
|
||||||
{
|
|
||||||
let mut res = self.clone();
|
let mut res = self.clone();
|
||||||
|
|
||||||
res.transpose();
|
res.transpose();
|
||||||
|
@ -332,12 +309,11 @@ macro_rules! transpose_impl(
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transpose(&mut self)
|
fn transpose(&mut self) {
|
||||||
{
|
for i in range(1u, $dim) {
|
||||||
for i in range(1u, $dim)
|
for j in range(0u, i) {
|
||||||
{
|
self.swap((i, j), (j, i))
|
||||||
for j in range(0u, i)
|
}
|
||||||
{ self.swap((i, j), (j, i)) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -346,26 +322,28 @@ macro_rules! transpose_impl(
|
||||||
|
|
||||||
macro_rules! approx_eq_impl(
|
macro_rules! approx_eq_impl(
|
||||||
($t: ident) => (
|
($t: ident) => (
|
||||||
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N>
|
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_epsilon() -> N
|
fn approx_epsilon() -> N {
|
||||||
{ ApproxEq::approx_epsilon::<N, N>() }
|
ApproxEq::approx_epsilon::<N, N>()
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq(&self, other: &$t<N>) -> bool
|
|
||||||
{
|
|
||||||
let mut zip = self.iter().zip(other.iter());
|
|
||||||
|
|
||||||
do zip.all |(a, b)| { a.approx_eq(b) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N) -> bool
|
fn approx_eq(&self, other: &$t<N>) -> bool {
|
||||||
{
|
|
||||||
let mut zip = self.iter().zip(other.iter());
|
let mut zip = self.iter().zip(other.iter());
|
||||||
|
|
||||||
do zip.all |(a, b)| { a.approx_eq_eps(b, epsilon) }
|
do zip.all |(a, b)| {
|
||||||
|
a.approx_eq(b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N) -> bool {
|
||||||
|
let mut zip = self.iter().zip(other.iter());
|
||||||
|
|
||||||
|
do zip.all |(a, b)| {
|
||||||
|
a.approx_eq_eps(b, epsilon)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -373,16 +351,14 @@ macro_rules! approx_eq_impl(
|
||||||
|
|
||||||
macro_rules! to_homogeneous_impl(
|
macro_rules! to_homogeneous_impl(
|
||||||
($t: ident, $t2: ident, $dim: expr, $dim2: expr) => (
|
($t: ident, $t2: ident, $dim: expr, $dim2: expr) => (
|
||||||
impl<N: One + Zero + Clone> ToHomogeneous<$t2<N>> for $t<N>
|
impl<N: One + Zero + Clone> ToHomogeneous<$t2<N>> for $t<N> {
|
||||||
{
|
fn to_homogeneous(&self) -> $t2<N> {
|
||||||
fn to_homogeneous(&self) -> $t2<N>
|
|
||||||
{
|
|
||||||
let mut res: $t2<N> = One::one();
|
let mut res: $t2<N> = One::one();
|
||||||
|
|
||||||
for i in range(0u, $dim)
|
for i in range(0u, $dim) {
|
||||||
{
|
for j in range(0u, $dim) {
|
||||||
for j in range(0u, $dim)
|
res.set((i, j), self.at((i, j)))
|
||||||
{ res.set((i, j), self.at((i, j))) }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -393,16 +369,14 @@ macro_rules! to_homogeneous_impl(
|
||||||
|
|
||||||
macro_rules! from_homogeneous_impl(
|
macro_rules! from_homogeneous_impl(
|
||||||
($t: ident, $t2: ident, $dim: expr, $dim2: expr) => (
|
($t: ident, $t2: ident, $dim: expr, $dim2: expr) => (
|
||||||
impl<N: One + Zero + Clone> FromHomogeneous<$t2<N>> for $t<N>
|
impl<N: One + Zero + Clone> FromHomogeneous<$t2<N>> for $t<N> {
|
||||||
{
|
fn from(m: &$t2<N>) -> $t<N> {
|
||||||
fn from(m: &$t2<N>) -> $t<N>
|
|
||||||
{
|
|
||||||
let mut res: $t<N> = One::one();
|
let mut res: $t<N> = One::one();
|
||||||
|
|
||||||
for i in range(0u, $dim2)
|
for i in range(0u, $dim2) {
|
||||||
{
|
for j in range(0u, $dim2) {
|
||||||
for j in range(0u, $dim2)
|
res.set((i, j), m.at((i, j)))
|
||||||
{ res.set((i, j), m.at((i, j))) }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: do we have to deal the lost components
|
// FIXME: do we have to deal the lost components
|
||||||
|
|
|
@ -5,26 +5,25 @@ use traits::inv::Inv;
|
||||||
|
|
||||||
// some specializations:
|
// some specializations:
|
||||||
impl<N: DivisionRing + Clone>
|
impl<N: DivisionRing + Clone>
|
||||||
Inv for Mat1<N>
|
Inv for Mat1<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse(&self) -> Option<Mat1<N>>
|
fn inverse(&self) -> Option<Mat1<N>> {
|
||||||
{
|
|
||||||
let mut res : Mat1<N> = self.clone();
|
let mut res : Mat1<N> = self.clone();
|
||||||
|
|
||||||
if res.inplace_inverse()
|
if res.inplace_inverse() {
|
||||||
{ Some(res) }
|
Some(res)
|
||||||
else
|
}
|
||||||
{ None }
|
else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inplace_inverse(&mut self) -> bool
|
fn inplace_inverse(&mut self) -> bool {
|
||||||
{
|
if self.m11.is_zero() {
|
||||||
if self.m11.is_zero()
|
false
|
||||||
{ false }
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
self.m11 = One::one::<N>() / self.m11;
|
self.m11 = One::one::<N>() / self.m11;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -32,28 +31,27 @@ Inv for Mat1<N>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: DivisionRing + Clone>
|
impl<N: DivisionRing + Clone>
|
||||||
Inv for Mat2<N>
|
Inv for Mat2<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse(&self) -> Option<Mat2<N>>
|
fn inverse(&self) -> Option<Mat2<N>> {
|
||||||
{
|
|
||||||
let mut res : Mat2<N> = self.clone();
|
let mut res : Mat2<N> = self.clone();
|
||||||
|
|
||||||
if res.inplace_inverse()
|
if res.inplace_inverse() {
|
||||||
{ Some(res) }
|
Some(res)
|
||||||
else
|
}
|
||||||
{ None }
|
else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inplace_inverse(&mut self) -> bool
|
fn inplace_inverse(&mut self) -> bool {
|
||||||
{
|
|
||||||
let det = self.m11 * self.m22 - self.m21 * self.m12;
|
let det = self.m11 * self.m22 - self.m21 * self.m12;
|
||||||
|
|
||||||
if det.is_zero()
|
if det.is_zero() {
|
||||||
{ false }
|
false
|
||||||
else
|
}
|
||||||
{
|
else {
|
||||||
*self = Mat2::new(self.m22 / det , -self.m12 / det,
|
*self = Mat2::new(self.m22 / det , -self.m12 / det,
|
||||||
-self.m21 / det, self.m11 / det);
|
-self.m21 / det, self.m11 / det);
|
||||||
|
|
||||||
|
@ -63,22 +61,21 @@ Inv for Mat2<N>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: DivisionRing + Clone>
|
impl<N: DivisionRing + Clone>
|
||||||
Inv for Mat3<N>
|
Inv for Mat3<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse(&self) -> Option<Mat3<N>>
|
fn inverse(&self) -> Option<Mat3<N>> {
|
||||||
{
|
|
||||||
let mut res = self.clone();
|
let mut res = self.clone();
|
||||||
|
|
||||||
if res.inplace_inverse()
|
if res.inplace_inverse() {
|
||||||
{ Some(res) }
|
Some(res)
|
||||||
else
|
}
|
||||||
{ None }
|
else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inplace_inverse(&mut self) -> bool
|
fn inplace_inverse(&mut self) -> bool {
|
||||||
{
|
|
||||||
let minor_m12_m23 = self.m22 * self.m33 - self.m32 * self.m23;
|
let minor_m12_m23 = self.m22 * self.m33 - self.m32 * self.m23;
|
||||||
let minor_m11_m23 = self.m21 * self.m33 - self.m31 * self.m23;
|
let minor_m11_m23 = self.m21 * self.m33 - self.m31 * self.m23;
|
||||||
let minor_m11_m22 = self.m21 * self.m32 - self.m31 * self.m22;
|
let minor_m11_m22 = self.m21 * self.m32 - self.m31 * self.m22;
|
||||||
|
@ -87,10 +84,10 @@ Inv for Mat3<N>
|
||||||
- self.m12 * minor_m11_m23
|
- self.m12 * minor_m11_m23
|
||||||
+ self.m13 * minor_m11_m22;
|
+ self.m13 * minor_m11_m22;
|
||||||
|
|
||||||
if det.is_zero()
|
if det.is_zero() {
|
||||||
{ false }
|
false
|
||||||
else
|
}
|
||||||
{
|
else {
|
||||||
*self = Mat3::new(
|
*self = Mat3::new(
|
||||||
(minor_m12_m23 / det),
|
(minor_m12_m23 / det),
|
||||||
((self.m13 * self.m32 - self.m33 * self.m12) / det),
|
((self.m13 * self.m32 - self.m33 * self.m12) / det),
|
||||||
|
|
|
@ -25,8 +25,7 @@ use adaptors::rotmat::Rotmat;
|
||||||
|
|
||||||
macro_rules! test_inv_mat_impl(
|
macro_rules! test_inv_mat_impl(
|
||||||
($t: ty) => (
|
($t: ty) => (
|
||||||
do 10000.times
|
do 10000.times {
|
||||||
{
|
|
||||||
let randmat : $t = random();
|
let randmat : $t = random();
|
||||||
|
|
||||||
assert!((randmat.inverse().unwrap() * randmat).approx_eq(&One::one()));
|
assert!((randmat.inverse().unwrap() * randmat).approx_eq(&One::one()));
|
||||||
|
@ -36,8 +35,7 @@ macro_rules! test_inv_mat_impl(
|
||||||
|
|
||||||
macro_rules! test_transpose_mat_impl(
|
macro_rules! test_transpose_mat_impl(
|
||||||
($t: ty) => (
|
($t: ty) => (
|
||||||
do 10000.times
|
do 10000.times {
|
||||||
{
|
|
||||||
let randmat : $t = random();
|
let randmat : $t = random();
|
||||||
|
|
||||||
assert!(randmat.transposed().transposed().eq(&randmat));
|
assert!(randmat.transposed().transposed().eq(&randmat));
|
||||||
|
@ -46,58 +44,68 @@ macro_rules! test_transpose_mat_impl(
|
||||||
)
|
)
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_transpose_mat1()
|
fn test_transpose_mat1() {
|
||||||
{ test_transpose_mat_impl!(Mat1<f64>); }
|
test_transpose_mat_impl!(Mat1<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_transpose_mat2()
|
fn test_transpose_mat2() {
|
||||||
{ test_transpose_mat_impl!(Mat2<f64>); }
|
test_transpose_mat_impl!(Mat2<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_transpose_mat3()
|
fn test_transpose_mat3() {
|
||||||
{ test_transpose_mat_impl!(Mat3<f64>); }
|
test_transpose_mat_impl!(Mat3<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_transpose_mat4()
|
fn test_transpose_mat4() {
|
||||||
{ test_transpose_mat_impl!(Mat4<f64>); }
|
test_transpose_mat_impl!(Mat4<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_transpose_mat5()
|
fn test_transpose_mat5() {
|
||||||
{ test_transpose_mat_impl!(Mat5<f64>); }
|
test_transpose_mat_impl!(Mat5<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_transpose_mat6()
|
fn test_transpose_mat6() {
|
||||||
{ test_transpose_mat_impl!(Mat6<f64>); }
|
test_transpose_mat_impl!(Mat6<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_inv_mat1()
|
fn test_inv_mat1() {
|
||||||
{ test_inv_mat_impl!(Mat1<f64>); }
|
test_inv_mat_impl!(Mat1<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_inv_mat2()
|
fn test_inv_mat2() {
|
||||||
{ test_inv_mat_impl!(Mat2<f64>); }
|
test_inv_mat_impl!(Mat2<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_inv_mat3()
|
fn test_inv_mat3() {
|
||||||
{ test_inv_mat_impl!(Mat3<f64>); }
|
test_inv_mat_impl!(Mat3<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_inv_mat4()
|
fn test_inv_mat4() {
|
||||||
{ test_inv_mat_impl!(Mat4<f64>); }
|
test_inv_mat_impl!(Mat4<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_inv_mat5()
|
fn test_inv_mat5() {
|
||||||
{ test_inv_mat_impl!(Mat5<f64>); }
|
test_inv_mat_impl!(Mat5<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_inv_mat6()
|
fn test_inv_mat6() {
|
||||||
{ test_inv_mat_impl!(Mat6<f64>); }
|
test_inv_mat_impl!(Mat6<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rotation2()
|
fn test_rotation2() {
|
||||||
{
|
do 10000.times {
|
||||||
do 10000.times
|
|
||||||
{
|
|
||||||
let randmat = One::one::<Rotmat<Mat2<f64>>>();
|
let randmat = One::one::<Rotmat<Mat2<f64>>>();
|
||||||
let ang = &Vec1::new(abs::<f64>(random()) % Real::pi());
|
let ang = &Vec1::new(abs::<f64>(random()) % Real::pi());
|
||||||
|
|
||||||
|
@ -106,18 +114,15 @@ fn test_rotation2()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_index_mat2()
|
fn test_index_mat2() {
|
||||||
{
|
|
||||||
let mat: Mat2<f64> = random();
|
let mat: Mat2<f64> = random();
|
||||||
|
|
||||||
assert!(mat.at((0, 1)) == mat.transposed().at((1, 0)));
|
assert!(mat.at((0, 1)) == mat.transposed().at((1, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_inv_rotation3()
|
fn test_inv_rotation3() {
|
||||||
{
|
do 10000.times {
|
||||||
do 10000.times
|
|
||||||
{
|
|
||||||
let randmat = One::one::<Rotmat<Mat3<f64>>>();
|
let randmat = One::one::<Rotmat<Mat3<f64>>>();
|
||||||
let dir: Vec3<f64> = random();
|
let dir: Vec3<f64> = random();
|
||||||
let ang = &dir.normalized().scalar_mul(&(abs::<f64>(random()) % Real::pi()));
|
let ang = &dir.normalized().scalar_mul(&(abs::<f64>(random()) % Real::pi()));
|
||||||
|
|
223
src/tests/vec.rs
223
src/tests/vec.rs
|
@ -23,16 +23,16 @@ use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||||
|
|
||||||
macro_rules! test_iterator_impl(
|
macro_rules! test_iterator_impl(
|
||||||
($t: ty, $n: ty) => (
|
($t: ty, $n: ty) => (
|
||||||
do 10000.times
|
do 10000.times {
|
||||||
{
|
|
||||||
let v: $t = random();
|
let v: $t = random();
|
||||||
let mut mv: $t = v.clone();
|
let mut mv: $t = v.clone();
|
||||||
let n: $n = random();
|
let n: $n = random();
|
||||||
|
|
||||||
let nv: $t = v.iter().transform(|e| e * n).collect();
|
let nv: $t = v.iter().transform(|e| e * n).collect();
|
||||||
|
|
||||||
for e in mv.mut_iter()
|
for e in mv.mut_iter() {
|
||||||
{ *e = *e * n }
|
*e = *e * n
|
||||||
|
}
|
||||||
|
|
||||||
assert!(nv == mv && nv == v.scalar_mul(&n));
|
assert!(nv == mv && nv == v.scalar_mul(&n));
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,7 @@ macro_rules! test_iterator_impl(
|
||||||
|
|
||||||
macro_rules! test_commut_dot_impl(
|
macro_rules! test_commut_dot_impl(
|
||||||
($t: ty) => (
|
($t: ty) => (
|
||||||
do 10000.times
|
do 10000.times {
|
||||||
{
|
|
||||||
let v1 : $t = random();
|
let v1 : $t = random();
|
||||||
let v2 : $t = random();
|
let v2 : $t = random();
|
||||||
|
|
||||||
|
@ -53,8 +52,7 @@ macro_rules! test_commut_dot_impl(
|
||||||
|
|
||||||
macro_rules! test_scalar_op_impl(
|
macro_rules! test_scalar_op_impl(
|
||||||
($t: ty, $n: ty) => (
|
($t: ty, $n: ty) => (
|
||||||
do 10000.times
|
do 10000.times {
|
||||||
{
|
|
||||||
let v1 : $t = random();
|
let v1 : $t = random();
|
||||||
let n : $n = random();
|
let n : $n = random();
|
||||||
|
|
||||||
|
@ -77,12 +75,11 @@ macro_rules! test_scalar_op_impl(
|
||||||
|
|
||||||
macro_rules! test_basis_impl(
|
macro_rules! test_basis_impl(
|
||||||
($t: ty) => (
|
($t: ty) => (
|
||||||
do 10000.times
|
do 10000.times {
|
||||||
{
|
do Basis::canonical_basis::<$t> |e1| {
|
||||||
do Basis::canonical_basis::<$t> |e1|
|
do Basis::canonical_basis::<$t> |e2| {
|
||||||
{
|
assert!(e1 == e2 || e1.dot(&e2).approx_eq(&Zero::zero()))
|
||||||
do Basis::canonical_basis::<$t> |e2|
|
}
|
||||||
{ assert!(e1 == e2 || e1.dot(&e2).approx_eq(&Zero::zero())) }
|
|
||||||
|
|
||||||
assert!(e1.norm().approx_eq(&One::one()));
|
assert!(e1.norm().approx_eq(&One::one()));
|
||||||
}
|
}
|
||||||
|
@ -92,30 +89,27 @@ macro_rules! test_basis_impl(
|
||||||
|
|
||||||
macro_rules! test_subspace_basis_impl(
|
macro_rules! test_subspace_basis_impl(
|
||||||
($t: ty) => (
|
($t: ty) => (
|
||||||
do 10000.times
|
do 10000.times {
|
||||||
{
|
|
||||||
let v : $t = random();
|
let v : $t = random();
|
||||||
let v1 = v.normalized();
|
let v1 = v.normalized();
|
||||||
|
|
||||||
do v1.orthonormal_subspace_basis() |e1|
|
do v1.orthonormal_subspace_basis() |e1| {
|
||||||
{
|
|
||||||
// check vectors are orthogonal to v1
|
// check vectors are orthogonal to v1
|
||||||
assert!(v1.dot(&e1).approx_eq(&Zero::zero()));
|
assert!(v1.dot(&e1).approx_eq(&Zero::zero()));
|
||||||
// check vectors form an orthonormal basis
|
// check vectors form an orthonormal basis
|
||||||
assert!(e1.norm().approx_eq(&One::one()));
|
assert!(e1.norm().approx_eq(&One::one()));
|
||||||
// check vectors form an ortogonal basis
|
// check vectors form an ortogonal basis
|
||||||
do v1.orthonormal_subspace_basis() |e2|
|
do v1.orthonormal_subspace_basis() |e2| {
|
||||||
{ assert!(e1 == e2 || e1.dot(&e2).approx_eq(&Zero::zero())) }
|
assert!(e1 == e2 || e1.dot(&e2).approx_eq(&Zero::zero()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
)
|
)
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cross_vec3()
|
fn test_cross_vec3() {
|
||||||
{
|
do 10000.times {
|
||||||
do 10000.times
|
|
||||||
{
|
|
||||||
let v1 : Vec3<f64> = random();
|
let v1 : Vec3<f64> = random();
|
||||||
let v2 : Vec3<f64> = random();
|
let v2 : Vec3<f64> = random();
|
||||||
let v3 : Vec3<f64> = v1.cross(&v2);
|
let v3 : Vec3<f64> = v1.cross(&v2);
|
||||||
|
@ -126,148 +120,182 @@ fn test_cross_vec3()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_commut_dot_vec0()
|
fn test_commut_dot_vec0() {
|
||||||
{ test_commut_dot_impl!(Vec0<f64>); }
|
test_commut_dot_impl!(Vec0<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_commut_dot_vec1()
|
fn test_commut_dot_vec1() {
|
||||||
{ test_commut_dot_impl!(Vec1<f64>); }
|
test_commut_dot_impl!(Vec1<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_commut_dot_vec2()
|
fn test_commut_dot_vec2() {
|
||||||
{ test_commut_dot_impl!(Vec2<f64>); }
|
test_commut_dot_impl!(Vec2<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_commut_dot_vec3()
|
fn test_commut_dot_vec3() {
|
||||||
{ test_commut_dot_impl!(Vec3<f64>); }
|
test_commut_dot_impl!(Vec3<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_commut_dot_vec4()
|
fn test_commut_dot_vec4() {
|
||||||
{ test_commut_dot_impl!(Vec4<f64>); }
|
test_commut_dot_impl!(Vec4<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_commut_dot_vec5()
|
fn test_commut_dot_vec5() {
|
||||||
{ test_commut_dot_impl!(Vec5<f64>); }
|
test_commut_dot_impl!(Vec5<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_commut_dot_vec6()
|
fn test_commut_dot_vec6() {
|
||||||
{ test_commut_dot_impl!(Vec6<f64>); }
|
test_commut_dot_impl!(Vec6<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basis_vec0()
|
fn test_basis_vec0() {
|
||||||
{ test_basis_impl!(Vec0<f64>); }
|
test_basis_impl!(Vec0<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basis_vec1()
|
fn test_basis_vec1() {
|
||||||
{ test_basis_impl!(Vec1<f64>); }
|
test_basis_impl!(Vec1<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basis_vec2()
|
fn test_basis_vec2() {
|
||||||
{ test_basis_impl!(Vec2<f64>); }
|
test_basis_impl!(Vec2<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basis_vec3()
|
fn test_basis_vec3() {
|
||||||
{ test_basis_impl!(Vec3<f64>); }
|
test_basis_impl!(Vec3<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basis_vec4()
|
fn test_basis_vec4() {
|
||||||
{ test_basis_impl!(Vec4<f64>); }
|
test_basis_impl!(Vec4<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basis_vec5()
|
fn test_basis_vec5() {
|
||||||
{ test_basis_impl!(Vec5<f64>); }
|
test_basis_impl!(Vec5<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basis_vec6()
|
fn test_basis_vec6() {
|
||||||
{ test_basis_impl!(Vec6<f64>); }
|
test_basis_impl!(Vec6<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_subspace_basis_vec0()
|
fn test_subspace_basis_vec0() {
|
||||||
{ test_subspace_basis_impl!(Vec0<f64>); }
|
test_subspace_basis_impl!(Vec0<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_subspace_basis_vec1()
|
fn test_subspace_basis_vec1() {
|
||||||
{ test_subspace_basis_impl!(Vec1<f64>); }
|
test_subspace_basis_impl!(Vec1<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_subspace_basis_vec2()
|
fn test_subspace_basis_vec2() {
|
||||||
{ test_subspace_basis_impl!(Vec2<f64>); }
|
test_subspace_basis_impl!(Vec2<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_subspace_basis_vec3()
|
fn test_subspace_basis_vec3() {
|
||||||
{ test_subspace_basis_impl!(Vec3<f64>); }
|
test_subspace_basis_impl!(Vec3<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_subspace_basis_vec4()
|
fn test_subspace_basis_vec4() {
|
||||||
{ test_subspace_basis_impl!(Vec4<f64>); }
|
test_subspace_basis_impl!(Vec4<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_subspace_basis_vec5()
|
fn test_subspace_basis_vec5() {
|
||||||
{ test_subspace_basis_impl!(Vec5<f64>); }
|
test_subspace_basis_impl!(Vec5<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_subspace_basis_vec6()
|
fn test_subspace_basis_vec6() {
|
||||||
{ test_subspace_basis_impl!(Vec6<f64>); }
|
test_subspace_basis_impl!(Vec6<f64>);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_scalar_op_vec0()
|
fn test_scalar_op_vec0() {
|
||||||
{ test_scalar_op_impl!(Vec0<f64>, f64); }
|
test_scalar_op_impl!(Vec0<f64>, f64);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_scalar_op_vec1()
|
fn test_scalar_op_vec1() {
|
||||||
{ test_scalar_op_impl!(Vec1<f64>, f64); }
|
test_scalar_op_impl!(Vec1<f64>, f64);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_scalar_op_vec2()
|
fn test_scalar_op_vec2() {
|
||||||
{ test_scalar_op_impl!(Vec2<f64>, f64); }
|
test_scalar_op_impl!(Vec2<f64>, f64);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_scalar_op_vec3()
|
fn test_scalar_op_vec3() {
|
||||||
{ test_scalar_op_impl!(Vec3<f64>, f64); }
|
test_scalar_op_impl!(Vec3<f64>, f64);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_scalar_op_vec4()
|
fn test_scalar_op_vec4() {
|
||||||
{ test_scalar_op_impl!(Vec4<f64>, f64); }
|
test_scalar_op_impl!(Vec4<f64>, f64);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_scalar_op_vec5()
|
fn test_scalar_op_vec5() {
|
||||||
{ test_scalar_op_impl!(Vec5<f64>, f64); }
|
test_scalar_op_impl!(Vec5<f64>, f64);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_scalar_op_vec6()
|
fn test_scalar_op_vec6() {
|
||||||
{ test_scalar_op_impl!(Vec6<f64>, f64); }
|
test_scalar_op_impl!(Vec6<f64>, f64);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_iterator_vec0()
|
fn test_iterator_vec0() {
|
||||||
{ test_iterator_impl!(Vec0<f64>, f64); }
|
test_iterator_impl!(Vec0<f64>, f64);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_iterator_vec1()
|
fn test_iterator_vec1() {
|
||||||
{ test_iterator_impl!(Vec1<f64>, f64); }
|
test_iterator_impl!(Vec1<f64>, f64);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_iterator_vec2()
|
fn test_iterator_vec2() {
|
||||||
{ test_iterator_impl!(Vec2<f64>, f64); }
|
test_iterator_impl!(Vec2<f64>, f64);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_iterator_vec3()
|
fn test_iterator_vec3() {
|
||||||
{ test_iterator_impl!(Vec3<f64>, f64); }
|
test_iterator_impl!(Vec3<f64>, f64);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_iterator_vec4()
|
fn test_iterator_vec4() {
|
||||||
{ test_iterator_impl!(Vec4<f64>, f64); }
|
test_iterator_impl!(Vec4<f64>, f64);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_iterator_vec5()
|
fn test_iterator_vec5() {
|
||||||
{ test_iterator_impl!(Vec5<f64>, f64); }
|
test_iterator_impl!(Vec5<f64>, f64);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_iterator_vec6()
|
fn test_iterator_vec6() {
|
||||||
{ test_iterator_impl!(Vec6<f64>, f64); }
|
test_iterator_impl!(Vec6<f64>, f64);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ord_vec3()
|
fn test_ord_vec3() {
|
||||||
{
|
|
||||||
// equality
|
// equality
|
||||||
assert!(Vec3::new(0.5, 0.5, 0.5) == Vec3::new(0.5, 0.5, 0.5));
|
assert!(Vec3::new(0.5, 0.5, 0.5) == Vec3::new(0.5, 0.5, 0.5));
|
||||||
assert!(!(Vec3::new(1.5, 0.5, 0.5) == Vec3::new(0.5, 0.5, 0.5)));
|
assert!(!(Vec3::new(1.5, 0.5, 0.5) == Vec3::new(0.5, 0.5, 0.5)));
|
||||||
|
@ -287,8 +315,7 @@ fn test_ord_vec3()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_min_max_vec3()
|
fn test_min_max_vec3() {
|
||||||
{
|
|
||||||
assert_eq!(Vec3::new(1, 2, 3).max(&Vec3::new(3, 2, 1)), Vec3::new(3, 2, 3));
|
assert_eq!(Vec3::new(1, 2, 3).max(&Vec3::new(3, 2, 1)), Vec3::new(3, 2, 3));
|
||||||
assert_eq!(Vec3::new(1, 2, 3).min(&Vec3::new(3, 2, 1)), Vec3::new(1, 2, 1));
|
assert_eq!(Vec3::new(1, 2, 3).min(&Vec3::new(3, 2, 1)), Vec3::new(1, 2, 1));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/// Traits of objecs which can form a basis.
|
/// Traits of objecs which can form a basis.
|
||||||
pub trait Basis
|
pub trait Basis {
|
||||||
{
|
|
||||||
/// Iterate through the canonical basis of the space in which this object lives.
|
/// Iterate through the canonical basis of the space in which this object lives.
|
||||||
fn canonical_basis(&fn(Self));
|
fn canonical_basis(&fn(Self));
|
||||||
|
|
||||||
|
@ -8,23 +7,23 @@ pub trait Basis
|
||||||
fn orthonormal_subspace_basis(&self, &fn(Self));
|
fn orthonormal_subspace_basis(&self, &fn(Self));
|
||||||
|
|
||||||
/// Creates the canonical basis of the space in which this object lives.
|
/// Creates the canonical basis of the space in which this object lives.
|
||||||
fn canonical_basis_list() -> ~[Self]
|
fn canonical_basis_list() -> ~[Self] {
|
||||||
{
|
|
||||||
let mut res = ~[];
|
let mut res = ~[];
|
||||||
|
|
||||||
do Basis::canonical_basis::<Self> |elem|
|
do Basis::canonical_basis::<Self> |elem| {
|
||||||
{ res.push(elem) }
|
res.push(elem)
|
||||||
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a basis of the subspace orthogonal to `self`.
|
/// Creates a basis of the subspace orthogonal to `self`.
|
||||||
fn orthonormal_subspace_basis_list(&self) -> ~[Self]
|
fn orthonormal_subspace_basis_list(&self) -> ~[Self] {
|
||||||
{
|
|
||||||
let mut res = ~[];
|
let mut res = ~[];
|
||||||
|
|
||||||
do self.orthonormal_subspace_basis |elem|
|
do self.orthonormal_subspace_basis |elem| {
|
||||||
{ res.push(elem) }
|
res.push(elem)
|
||||||
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/// Traits to access columns of a matrix.
|
/// Traits to access columns of a matrix.
|
||||||
pub trait Column<C>
|
pub trait Column<C> {
|
||||||
{
|
|
||||||
/// Reads the `i`-th column of `self`.
|
/// Reads the `i`-th column of `self`.
|
||||||
fn column(&self, i: uint) -> C;
|
fn column(&self, i: uint) -> C;
|
||||||
/// Writes the `i`-th column of `self`.
|
/// Writes the `i`-th column of `self`.
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
/// Traits of objects which can be put in homogeneous coordinates.
|
/// Traits of objects which can be put in homogeneous coordinates.
|
||||||
pub trait ToHomogeneous<U>
|
pub trait ToHomogeneous<U> {
|
||||||
{
|
|
||||||
/// Gets the homogeneous coordinates version of this object.
|
/// Gets the homogeneous coordinates version of this object.
|
||||||
fn to_homogeneous(&self) -> U;
|
fn to_homogeneous(&self) -> U;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Traits of objects which can be build from an homogeneous coordinate representation.
|
/// Traits of objects which can be build from an homogeneous coordinate representation.
|
||||||
pub trait FromHomogeneous<U>
|
pub trait FromHomogeneous<U> {
|
||||||
{
|
|
||||||
/// Builds an object with its homogeneous coordinate version. Note this it is not required for
|
/// Builds an object with its homogeneous coordinate version. Note this it is not required for
|
||||||
/// `from` to be the iverse of `to_homogeneous`. Typically, `from` will remove some informations
|
/// `from` to be the iverse of `to_homogeneous`. Typically, `from` will remove some informations
|
||||||
/// unrecoverable by `to_homogeneous`.
|
/// unrecoverable by `to_homogeneous`.
|
||||||
|
|
|
@ -7,8 +7,7 @@
|
||||||
/// It exists because the `Index` trait cannot be used to express write access.
|
/// It exists because the `Index` trait cannot be used to express write access.
|
||||||
/// Thus, this is the same as the `Index` trait but without the syntactic sugar and with a method
|
/// Thus, this is the same as the `Index` trait but without the syntactic sugar and with a method
|
||||||
/// to write to a specific index.
|
/// to write to a specific index.
|
||||||
pub trait Indexable<Index, Res>
|
pub trait Indexable<Index, Res> {
|
||||||
{
|
|
||||||
/// Reads the `i`-th element of `self`.
|
/// Reads the `i`-th element of `self`.
|
||||||
fn at(&self, i: Index) -> Res;
|
fn at(&self, i: Index) -> Res;
|
||||||
/// Writes to the `i`-th element of `self`.
|
/// Writes to the `i`-th element of `self`.
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* Trait of inversible objects. Typically used to implement matrix inverse.
|
* Trait of inversible objects. Typically used to implement matrix inverse.
|
||||||
*/
|
*/
|
||||||
pub trait Inv
|
pub trait Inv {
|
||||||
{
|
|
||||||
/// Returns the inverse of an element.
|
/// Returns the inverse of an element.
|
||||||
fn inverse(&self) -> Option<Self>;
|
fn inverse(&self) -> Option<Self>;
|
||||||
/// Inplace version of `inverse`.
|
/// Inplace version of `inverse`.
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
/// Traits of objects which can be iterated through like a vector.
|
/// Traits of objects which can be iterated through like a vector.
|
||||||
pub trait Iterable<N>
|
pub trait Iterable<N> {
|
||||||
{
|
|
||||||
/// Gets a vector-like read-only iterator.
|
/// Gets a vector-like read-only iterator.
|
||||||
fn iter<'l>(&'l self) -> vec::VecIterator<'l, N>;
|
fn iter<'l>(&'l self) -> vec::VecIterator<'l, N>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Traits of mutable objects which can be iterated through like a vector.
|
/// Traits of mutable objects which can be iterated through like a vector.
|
||||||
pub trait IterableMut<N>
|
pub trait IterableMut<N> {
|
||||||
{
|
|
||||||
/// Gets a vector-like read-write iterator.
|
/// Gets a vector-like read-write iterator.
|
||||||
fn mut_iter<'l>(&'l mut self) -> vec::VecMutIterator<'l, N>;
|
fn mut_iter<'l>(&'l mut self) -> vec::VecMutIterator<'l, N>;
|
||||||
}
|
}
|
||||||
|
@ -18,13 +16,11 @@ pub trait IterableMut<N>
|
||||||
* FIXME: the prevous traits are only workarounds.
|
* FIXME: the prevous traits are only workarounds.
|
||||||
* It should be something like:
|
* It should be something like:
|
||||||
|
|
||||||
pub trait Iterable<'self, N, I: Iterator<N>>
|
pub trait Iterable<'self, N, I: Iterator<N>> {
|
||||||
{
|
|
||||||
fn iter(&'self self) -> I;
|
fn iter(&'self self) -> I;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait IterableMut<'self, N, I: Iterator<N>>
|
pub trait IterableMut<'self, N, I: Iterator<N>> {
|
||||||
{
|
|
||||||
fn mut_iter(&'self self) -> I;
|
fn mut_iter(&'self self) -> I;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/// Trait of matrices which can be converted to another matrix. Used to change the type of a matrix
|
/// Trait of matrices which can be converted to another matrix. Used to change the type of a matrix
|
||||||
/// components.
|
/// components.
|
||||||
pub trait MatCast<M>
|
pub trait MatCast<M> {
|
||||||
{
|
|
||||||
/// Converts `m` to have the type `M`.
|
/// Converts `m` to have the type `M`.
|
||||||
fn from(m: Self) -> M;
|
fn from(m: Self) -> M;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* Trait of objects having a L² norm and which can be normalized.
|
* Trait of objects having a L² norm and which can be normalized.
|
||||||
*/
|
*/
|
||||||
pub trait Norm<N>
|
pub trait Norm<N> {
|
||||||
{
|
|
||||||
/// Computes the norm a an object.
|
/// Computes the norm a an object.
|
||||||
fn norm(&self) -> N;
|
fn norm(&self) -> N;
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,7 @@ use std::num::{One, Zero};
|
||||||
* `Zero`) respectively neutral and absorbant wrt the multiplication.
|
* `Zero`) respectively neutral and absorbant wrt the multiplication.
|
||||||
*/
|
*/
|
||||||
pub trait Ring :
|
pub trait Ring :
|
||||||
Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Mul<Self, Self> + One + Zero
|
Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Mul<Self, Self> + One + Zero { }
|
||||||
{ }
|
|
||||||
|
|
||||||
impl<N: Sub<N, N> + Add<N, N> + Neg<N> + Mul<N, N> + One + Zero>
|
impl<N: Sub<N, N> + Add<N, N> + Neg<N> + Mul<N, N> + One + Zero>
|
||||||
Ring for N;
|
Ring for N;
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* Trait of objects having a right multiplication with another element.
|
* Trait of objects having a right multiplication with another element.
|
||||||
*/
|
*/
|
||||||
pub trait RMul<V>
|
pub trait RMul<V> {
|
||||||
{
|
|
||||||
/// Computes self * v
|
/// Computes self * v
|
||||||
fn rmul(&self, v : &V) -> V;
|
fn rmul(&self, v : &V) -> V;
|
||||||
}
|
}
|
||||||
|
@ -10,8 +9,7 @@ pub trait RMul<V>
|
||||||
/**
|
/**
|
||||||
* Trait of objects having a left multiplication with another element.
|
* Trait of objects having a left multiplication with another element.
|
||||||
*/
|
*/
|
||||||
pub trait LMul<V>
|
pub trait LMul<V> {
|
||||||
{
|
|
||||||
/// Computes v * self
|
/// Computes v * self
|
||||||
fn lmul(&self, &V) -> V;
|
fn lmul(&self, &V) -> V;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,7 @@ use traits::translation::{Translation, Translatable};
|
||||||
/// Trait of object which represent a rotation, and to wich new rotations can
|
/// Trait of object which represent a rotation, and to wich new rotations can
|
||||||
/// be appended. A rotation is assumed to be an isomitry without translation
|
/// be appended. A rotation is assumed to be an isomitry without translation
|
||||||
/// and without reflexion.
|
/// and without reflexion.
|
||||||
pub trait Rotation<V>
|
pub trait Rotation<V> {
|
||||||
{
|
|
||||||
/// Gets the rotation associated with this object.
|
/// Gets the rotation associated with this object.
|
||||||
fn rotation(&self) -> V;
|
fn rotation(&self) -> V;
|
||||||
|
|
||||||
|
@ -18,8 +17,7 @@ pub trait Rotation<V>
|
||||||
/// Trait of objects which can be put on an alternate form which represent a rotation. This is
|
/// Trait of objects which can be put on an alternate form which represent a rotation. This is
|
||||||
/// typically implemented by structures requiring an internal restructuration to be able to
|
/// typically implemented by structures requiring an internal restructuration to be able to
|
||||||
/// represent a rotation.
|
/// represent a rotation.
|
||||||
pub trait Rotatable<V, Res: Rotation<V>>
|
pub trait Rotatable<V, Res: Rotation<V>> {
|
||||||
{
|
|
||||||
/// Appends a rotation from an alternative representation. Such
|
/// Appends a rotation from an alternative representation. Such
|
||||||
/// representation has the same format as the one returned by `rotation`.
|
/// representation has the same format as the one returned by `rotation`.
|
||||||
fn rotated(&self, &V) -> Res;
|
fn rotated(&self, &V) -> Res;
|
||||||
|
@ -27,8 +25,7 @@ pub trait Rotatable<V, Res: Rotation<V>>
|
||||||
|
|
||||||
/// Trait of objects able to rotate other objects. This is typically implemented by matrices which
|
/// Trait of objects able to rotate other objects. This is typically implemented by matrices which
|
||||||
/// rotate vectors.
|
/// rotate vectors.
|
||||||
pub trait Rotate<V>
|
pub trait Rotate<V> {
|
||||||
{
|
|
||||||
/// Apply a rotation to an object.
|
/// Apply a rotation to an object.
|
||||||
fn rotate(&self, &V) -> V;
|
fn rotate(&self, &V) -> V;
|
||||||
/// Apply an inverse rotation to an object.
|
/// Apply an inverse rotation to an object.
|
||||||
|
@ -50,8 +47,7 @@ pub fn rotated_wrt_point<M: Translatable<LV, M2>,
|
||||||
m: &M,
|
m: &M,
|
||||||
ammount: &AV,
|
ammount: &AV,
|
||||||
center: &LV)
|
center: &LV)
|
||||||
-> M2
|
-> M2 {
|
||||||
{
|
|
||||||
let mut res = m.translated(&-center);
|
let mut res = m.translated(&-center);
|
||||||
|
|
||||||
res.rotate_by(ammount);
|
res.rotate_by(ammount);
|
||||||
|
@ -72,8 +68,7 @@ pub fn rotate_wrt_point<M: Rotation<AV> + Translation<LV>,
|
||||||
AV>(
|
AV>(
|
||||||
m: &mut M,
|
m: &mut M,
|
||||||
ammount: &AV,
|
ammount: &AV,
|
||||||
center: &LV)
|
center: &LV) {
|
||||||
{
|
|
||||||
m.translate_by(&-center);
|
m.translate_by(&-center);
|
||||||
m.rotate_by(ammount);
|
m.rotate_by(ammount);
|
||||||
m.translate_by(center);
|
m.translate_by(center);
|
||||||
|
@ -93,8 +88,9 @@ pub fn rotated_wrt_center<M: Translatable<LV, M2> + Translation<LV>,
|
||||||
AV>(
|
AV>(
|
||||||
m: &M,
|
m: &M,
|
||||||
ammount: &AV)
|
ammount: &AV)
|
||||||
-> M2
|
-> M2 {
|
||||||
{ rotated_wrt_point(m, ammount, &m.translation()) }
|
rotated_wrt_point(m, ammount, &m.translation())
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies a rotation centered on the input translation.
|
* Applies a rotation centered on the input translation.
|
||||||
|
@ -108,8 +104,7 @@ pub fn rotate_wrt_center<M: Translatable<LV, M> + Translation<LV> + Rotation<AV>
|
||||||
LV: Neg<LV>,
|
LV: Neg<LV>,
|
||||||
AV>(
|
AV>(
|
||||||
m: &mut M,
|
m: &mut M,
|
||||||
ammount: &AV)
|
ammount: &AV) {
|
||||||
{
|
|
||||||
let t = m.translation();
|
let t = m.translation();
|
||||||
|
|
||||||
rotate_wrt_point(m, ammount, &t)
|
rotate_wrt_point(m, ammount, &t)
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
/// Traits of vectors able to sample a sphere. The number of sample must be sufficient to
|
/// Traits of vectors able to sample a sphere. The number of sample must be sufficient to
|
||||||
/// approximate a sphere using support mapping functions.
|
/// approximate a sphere using support mapping functions.
|
||||||
pub trait UniformSphereSample
|
pub trait UniformSphereSample {
|
||||||
{
|
|
||||||
/// Iterate throught the samples.
|
/// Iterate throught the samples.
|
||||||
pub fn sample(&fn(&'static Self));
|
pub fn sample(&fn(&'static Self));
|
||||||
|
|
||||||
/// Gets the list of all samples.
|
/// Gets the list of all samples.
|
||||||
pub fn sample_list() -> ~[&'static Self]
|
pub fn sample_list() -> ~[&'static Self] {
|
||||||
{
|
|
||||||
let mut res = ~[];
|
let mut res = ~[];
|
||||||
|
|
||||||
do UniformSphereSample::sample::<Self> |s|
|
do UniformSphereSample::sample::<Self> |s| {
|
||||||
{ res.push(s) }
|
res.push(s)
|
||||||
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* Trait of objects having a multiplication with a scalar.
|
* Trait of objects having a multiplication with a scalar.
|
||||||
*/
|
*/
|
||||||
pub trait ScalarMul<N>
|
pub trait ScalarMul<N> {
|
||||||
{
|
|
||||||
/// Gets the result of a multiplication by a scalar.
|
/// Gets the result of a multiplication by a scalar.
|
||||||
fn scalar_mul(&self, &N) -> Self;
|
fn scalar_mul(&self, &N) -> Self;
|
||||||
|
|
||||||
|
@ -13,8 +12,7 @@ pub trait ScalarMul<N>
|
||||||
/**
|
/**
|
||||||
* Trait of objects having a division with a scalar.
|
* Trait of objects having a division with a scalar.
|
||||||
*/
|
*/
|
||||||
pub trait ScalarDiv<N>
|
pub trait ScalarDiv<N> {
|
||||||
{
|
|
||||||
/// Gets the result of a division by a scalar.
|
/// Gets the result of a division by a scalar.
|
||||||
fn scalar_div(&self, &N) -> Self;
|
fn scalar_div(&self, &N) -> Self;
|
||||||
|
|
||||||
|
@ -25,8 +23,7 @@ pub trait ScalarDiv<N>
|
||||||
/**
|
/**
|
||||||
* Trait of objects having an addition with a scalar.
|
* Trait of objects having an addition with a scalar.
|
||||||
*/
|
*/
|
||||||
pub trait ScalarAdd<N>
|
pub trait ScalarAdd<N> {
|
||||||
{
|
|
||||||
/// Gets the result of an addition by a scalar.
|
/// Gets the result of an addition by a scalar.
|
||||||
fn scalar_add(&self, &N) -> Self;
|
fn scalar_add(&self, &N) -> Self;
|
||||||
|
|
||||||
|
@ -37,8 +34,7 @@ pub trait ScalarAdd<N>
|
||||||
/**
|
/**
|
||||||
* Trait of objects having a subtraction with a scalar.
|
* Trait of objects having a subtraction with a scalar.
|
||||||
*/
|
*/
|
||||||
pub trait ScalarSub<N>
|
pub trait ScalarSub<N> {
|
||||||
{
|
|
||||||
/// Gets the result of a subtraction by a scalar.
|
/// Gets the result of a subtraction by a scalar.
|
||||||
fn scalar_sub(&self, &N) -> Self;
|
fn scalar_sub(&self, &N) -> Self;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use traits::dot::Dot;
|
use traits::dot::Dot;
|
||||||
|
|
||||||
/// Traits of objects with a subtract and a dot product. Exists only for optimization purpose.
|
/// Traits of objects with a subtract and a dot product. Exists only for optimization purpose.
|
||||||
pub trait SubDot<N> : Sub<Self, Self> + Dot<N>
|
pub trait SubDot<N> : Sub<Self, Self> + Dot<N> {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* Short-cut to compute the projection of a point on a vector, but without
|
* Short-cut to compute the projection of a point on a vector, but without
|
||||||
* computing intermediate vectors.
|
* computing intermediate vectors.
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
/// Trait of object which represent a transformation, and to wich new transformations can
|
/// Trait of object which represent a transformation, and to wich new transformations can
|
||||||
/// be appended. A transformation is assumed to be an isomitry without translation
|
/// be appended. A transformation is assumed to be an isomitry without translation
|
||||||
/// and without reflexion.
|
/// and without reflexion.
|
||||||
pub trait Transformation<M>
|
pub trait Transformation<M> {
|
||||||
{
|
|
||||||
/// Gets the transformation associated with this object.
|
/// Gets the transformation associated with this object.
|
||||||
fn transformation(&self) -> M;
|
fn transformation(&self) -> M;
|
||||||
|
|
||||||
|
@ -15,8 +14,7 @@ pub trait Transformation<M>
|
||||||
|
|
||||||
/// Trait of objects able to transform other objects. This is typically implemented by matrices which
|
/// Trait of objects able to transform other objects. This is typically implemented by matrices which
|
||||||
/// transform vectors.
|
/// transform vectors.
|
||||||
pub trait Transform<V>
|
pub trait Transform<V> {
|
||||||
{
|
|
||||||
// XXX: sadly we cannot call this `transform` as it conflicts with the
|
// XXX: sadly we cannot call this `transform` as it conflicts with the
|
||||||
// iterators' `transform` function (which seems always exist).
|
// iterators' `transform` function (which seems always exist).
|
||||||
/// Apply a transformation to an object.
|
/// Apply a transformation to an object.
|
||||||
|
@ -28,8 +26,7 @@ pub trait Transform<V>
|
||||||
/// Trait of objects which can be put on an alternate form which represent a transformation. This is
|
/// Trait of objects which can be put on an alternate form which represent a transformation. This is
|
||||||
/// typically implemented by structures requiring an internal restructuration to be able to
|
/// typically implemented by structures requiring an internal restructuration to be able to
|
||||||
/// represent a transformation.
|
/// represent a transformation.
|
||||||
pub trait Transformable<M, Res: Transformation<M>>
|
pub trait Transformable<M, Res: Transformation<M>> {
|
||||||
{
|
|
||||||
/// Appends a transformation from an alternative representation. Such
|
/// Appends a transformation from an alternative representation. Such
|
||||||
/// representation has the same format as the one returned by `transformation`.
|
/// representation has the same format as the one returned by `transformation`.
|
||||||
fn transformed(&self, &M) -> Res;
|
fn transformed(&self, &M) -> Res;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/// Trait of object which represent a translation, and to wich new translation
|
/// Trait of object which represent a translation, and to wich new translation
|
||||||
/// can be appended.
|
/// can be appended.
|
||||||
pub trait Translation<V>
|
pub trait Translation<V> {
|
||||||
{
|
|
||||||
// FIXME: add a "from translation: translantion(V) -> Self ?
|
// FIXME: add a "from translation: translantion(V) -> Self ?
|
||||||
/// Gets the translation associated with this object.
|
/// Gets the translation associated with this object.
|
||||||
fn translation(&self) -> V;
|
fn translation(&self) -> V;
|
||||||
|
@ -15,8 +14,7 @@ pub trait Translation<V>
|
||||||
|
|
||||||
/// Trait of objects able to rotate other objects. This is typically implemented by matrices which
|
/// Trait of objects able to rotate other objects. This is typically implemented by matrices which
|
||||||
/// rotate vectors.
|
/// rotate vectors.
|
||||||
pub trait Translate<V>
|
pub trait Translate<V> {
|
||||||
{
|
|
||||||
/// Apply a translation to an object.
|
/// Apply a translation to an object.
|
||||||
fn translate(&self, &V) -> V;
|
fn translate(&self, &V) -> V;
|
||||||
/// Apply an inverse translation to an object.
|
/// Apply an inverse translation to an object.
|
||||||
|
@ -26,8 +24,7 @@ pub trait Translate<V>
|
||||||
/// Trait of objects which can be put on an alternate form which represent a translation. This is
|
/// Trait of objects which can be put on an alternate form which represent a translation. This is
|
||||||
/// typically implemented by structures requiring an internal restructuration to be able to
|
/// typically implemented by structures requiring an internal restructuration to be able to
|
||||||
/// represent a translation.
|
/// represent a translation.
|
||||||
pub trait Translatable<V, Res: Translation<V>>
|
pub trait Translatable<V, Res: Translation<V>> {
|
||||||
{
|
|
||||||
/// Appends a translation from an alternative representation. Such
|
/// Appends a translation from an alternative representation. Such
|
||||||
/// representation has the same format as the one returned by `translation`.
|
/// representation has the same format as the one returned by `translation`.
|
||||||
fn translated(&self, &V) -> Res;
|
fn translated(&self, &V) -> Res;
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
/// Trait of objects which can be transposed. Note that, for the moment, this
|
/// Trait of objects which can be transposed. Note that, for the moment, this
|
||||||
/// does not allow the implementation by non-square matrix (or anything which
|
/// does not allow the implementation by non-square matrix (or anything which
|
||||||
/// is not stable by transposition).
|
/// is not stable by transposition).
|
||||||
pub trait Transpose
|
pub trait Transpose {
|
||||||
{
|
|
||||||
/// Computes the transpose of a matrix.
|
/// Computes the transpose of a matrix.
|
||||||
fn transposed(&self) -> Self;
|
fn transposed(&self) -> Self;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/// Trait of vectors which can be converted to another matrix. Used to change the type of a vector
|
/// Trait of vectors which can be converted to another matrix. Used to change the type of a vector
|
||||||
/// components.
|
/// components.
|
||||||
pub trait VecCast<V>
|
pub trait VecCast<V> {
|
||||||
{
|
|
||||||
/// Converts `v` to have the type `V`.
|
/// Converts `v` to have the type `V`.
|
||||||
fn from(v: Self) -> V;
|
fn from(v: Self) -> V;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,7 @@ use traits::scalar_op::{ScalarMul, ScalarDiv};
|
||||||
/// has a distinct element (`Zero`) neutral wrt the addition.
|
/// has a distinct element (`Zero`) neutral wrt the addition.
|
||||||
pub trait VectorSpace<N>
|
pub trait VectorSpace<N>
|
||||||
: Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Zero +
|
: Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Zero +
|
||||||
ScalarMul<N> + ScalarDiv<N>
|
ScalarMul<N> + ScalarDiv<N> { }
|
||||||
{ }
|
|
||||||
|
|
||||||
impl<V: Sub<V, V> + Add<V, V> + Neg<V> + Zero + ScalarMul<N> + ScalarDiv<N>,
|
impl<V: Sub<V, V> + Add<V, V> + Neg<V> + Zero + ScalarMul<N> + ScalarDiv<N>,
|
||||||
N: DivisionRing> VectorSpace<N> for V;
|
N: DivisionRing> VectorSpace<N> for V;
|
||||||
|
|
18
src/vec.rs
18
src/vec.rs
|
@ -32,8 +32,7 @@ pub struct Vec0<N>;
|
||||||
|
|
||||||
/// Vector of dimension 1.
|
/// Vector of dimension 1.
|
||||||
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
pub struct Vec1<N>
|
pub struct Vec1<N> {
|
||||||
{
|
|
||||||
/// First component of the vector.
|
/// First component of the vector.
|
||||||
x: N
|
x: N
|
||||||
}
|
}
|
||||||
|
@ -70,8 +69,7 @@ from_homogeneous_impl!(Vec1, Vec2, y, x)
|
||||||
|
|
||||||
/// Vector of dimension 2.
|
/// Vector of dimension 2.
|
||||||
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
pub struct Vec2<N>
|
pub struct Vec2<N> {
|
||||||
{
|
|
||||||
/// First component of the vector.
|
/// First component of the vector.
|
||||||
x: N,
|
x: N,
|
||||||
/// Second component of the vector.
|
/// Second component of the vector.
|
||||||
|
@ -110,8 +108,7 @@ from_homogeneous_impl!(Vec2, Vec3, z, x, y)
|
||||||
|
|
||||||
/// Vector of dimension 3.
|
/// Vector of dimension 3.
|
||||||
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
pub struct Vec3<N>
|
pub struct Vec3<N> {
|
||||||
{
|
|
||||||
/// First component of the vector.
|
/// First component of the vector.
|
||||||
x: N,
|
x: N,
|
||||||
/// Second component of the vector.
|
/// Second component of the vector.
|
||||||
|
@ -152,8 +149,7 @@ from_homogeneous_impl!(Vec3, Vec4, w, x, y, z)
|
||||||
|
|
||||||
/// Vector of dimension 4.
|
/// Vector of dimension 4.
|
||||||
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
pub struct Vec4<N>
|
pub struct Vec4<N> {
|
||||||
{
|
|
||||||
/// First component of the vector.
|
/// First component of the vector.
|
||||||
x: N,
|
x: N,
|
||||||
/// Second component of the vector.
|
/// Second component of the vector.
|
||||||
|
@ -196,8 +192,7 @@ from_homogeneous_impl!(Vec4, Vec5, a, x, y, z, w)
|
||||||
|
|
||||||
/// Vector of dimension 5.
|
/// Vector of dimension 5.
|
||||||
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
pub struct Vec5<N>
|
pub struct Vec5<N> {
|
||||||
{
|
|
||||||
/// First component of the vector.
|
/// First component of the vector.
|
||||||
x: N,
|
x: N,
|
||||||
/// Second component of the vector.
|
/// Second component of the vector.
|
||||||
|
@ -242,8 +237,7 @@ from_homogeneous_impl!(Vec5, Vec6, b, x, y, z, w, a)
|
||||||
|
|
||||||
/// Vector of dimension 6.
|
/// Vector of dimension 6.
|
||||||
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)]
|
||||||
pub struct Vec6<N>
|
pub struct Vec6<N> {
|
||||||
{
|
|
||||||
/// First component of the vector.
|
/// First component of the vector.
|
||||||
x: N,
|
x: N,
|
||||||
/// Second component of the vector.
|
/// Second component of the vector.
|
||||||
|
|
283
src/vec0_spec.rs
283
src/vec0_spec.rs
|
@ -16,179 +16,176 @@ use traits::division_ring::DivisionRing;
|
||||||
use traits::indexable::Indexable;
|
use traits::indexable::Indexable;
|
||||||
use vec;
|
use vec;
|
||||||
|
|
||||||
impl<N> vec::Vec0<N>
|
impl<N> vec::Vec0<N> {
|
||||||
{
|
|
||||||
/// Creates a new vector.
|
/// Creates a new vector.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new() -> vec::Vec0<N>
|
pub fn new() -> vec::Vec0<N> {
|
||||||
{ vec::Vec0 }
|
vec::Vec0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone> Indexable<uint, N> for vec::Vec0<N>
|
impl<N: Clone> Indexable<uint, N> for vec::Vec0<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn at(&self, _: uint) -> N
|
pub fn at(&self, _: uint) -> N {
|
||||||
{ fail!("Cannot index a Vec0.") }
|
fail!("Cannot index a Vec0.")
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn set(&mut self, _: uint, _: N)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn swap(&mut self, _: uint, _: uint)
|
|
||||||
{ }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone> vec::Vec0<N>
|
#[inline]
|
||||||
{
|
pub fn set(&mut self, _: uint, _: N) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn swap(&mut self, _: uint, _: uint) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Clone> vec::Vec0<N> {
|
||||||
/// Creates a new vector. The parameter is not taken in account.
|
/// Creates a new vector. The parameter is not taken in account.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_repeat(_: N) -> vec::Vec0<N>
|
pub fn new_repeat(_: N) -> vec::Vec0<N> {
|
||||||
{ vec::Vec0 }
|
vec::Vec0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N> Iterable<N> for vec::Vec0<N>
|
impl<N> Iterable<N> for vec::Vec0<N> {
|
||||||
{
|
fn iter<'l>(&'l self) -> VecIterator<'l, N> {
|
||||||
fn iter<'l>(&'l self) -> VecIterator<'l, N>
|
unsafe { cast::transmute::<&'l vec::Vec0<N>, &'l [N, ..0]>(self).iter() }
|
||||||
{ unsafe { cast::transmute::<&'l vec::Vec0<N>, &'l [N, ..0]>(self).iter() } }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N> IterableMut<N> for vec::Vec0<N>
|
impl<N> IterableMut<N> for vec::Vec0<N> {
|
||||||
{
|
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> {
|
||||||
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N>
|
unsafe { cast::transmute::<&'l mut vec::Vec0<N>, &'l mut [N, ..0]>(self).mut_iter() }
|
||||||
{ unsafe { cast::transmute::<&'l mut vec::Vec0<N>, &'l mut [N, ..0]>(self).mut_iter() } }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N> Dim for vec::Vec0<N>
|
impl<N> Dim for vec::Vec0<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn dim() -> uint
|
fn dim() -> uint {
|
||||||
{ 0 }
|
0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> Basis for vec::Vec0<N>
|
impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> Basis for vec::Vec0<N> {
|
||||||
{
|
pub fn canonical_basis(_: &fn(vec::Vec0<N>)) { }
|
||||||
pub fn canonical_basis(_: &fn(vec::Vec0<N>))
|
|
||||||
{ }
|
|
||||||
|
|
||||||
pub fn orthonormal_subspace_basis(&self, _: &fn(vec::Vec0<N>))
|
pub fn orthonormal_subspace_basis(&self, _: &fn(vec::Vec0<N>)) { }
|
||||||
{ }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Add<N,N>> Add<vec::Vec0<N>, vec::Vec0<N>> for vec::Vec0<N>
|
impl<N: Clone + Add<N,N>> Add<vec::Vec0<N>, vec::Vec0<N>> for vec::Vec0<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add(&self, _: &vec::Vec0<N>) -> vec::Vec0<N>
|
fn add(&self, _: &vec::Vec0<N>) -> vec::Vec0<N> {
|
||||||
{ vec::Vec0 }
|
vec::Vec0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Sub<N,N>> Sub<vec::Vec0<N>, vec::Vec0<N>> for vec::Vec0<N>
|
impl<N: Clone + Sub<N,N>> Sub<vec::Vec0<N>, vec::Vec0<N>> for vec::Vec0<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sub(&self, _: &vec::Vec0<N>) -> vec::Vec0<N>
|
fn sub(&self, _: &vec::Vec0<N>) -> vec::Vec0<N> {
|
||||||
{ vec::Vec0 }
|
vec::Vec0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Neg<N>> Neg<vec::Vec0<N>> for vec::Vec0<N>
|
impl<N: Neg<N>> Neg<vec::Vec0<N>> for vec::Vec0<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn neg(&self) -> vec::Vec0<N>
|
fn neg(&self) -> vec::Vec0<N> {
|
||||||
{ vec::Vec0 }
|
vec::Vec0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Ring> Dot<N> for vec::Vec0<N>
|
impl<N: Ring> Dot<N> for vec::Vec0<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn dot(&self, _: &vec::Vec0<N>) -> N
|
fn dot(&self, _: &vec::Vec0<N>) -> N {
|
||||||
{ Zero::zero() }
|
Zero::zero()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Ring> SubDot<N> for vec::Vec0<N>
|
impl<N: Clone + Ring> SubDot<N> for vec::Vec0<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sub_dot(&self, _: &vec::Vec0<N>, _: &vec::Vec0<N>) -> N
|
fn sub_dot(&self, _: &vec::Vec0<N>, _: &vec::Vec0<N>) -> N {
|
||||||
{ Zero::zero() }
|
Zero::zero()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Mul<N, N>> ScalarMul<N> for vec::Vec0<N>
|
impl<N: Mul<N, N>> ScalarMul<N> for vec::Vec0<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_mul(&self, _: &N) -> vec::Vec0<N>
|
fn scalar_mul(&self, _: &N) -> vec::Vec0<N> {
|
||||||
{ vec::Vec0 }
|
vec::Vec0
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn scalar_mul_inplace(&mut self, _: &N)
|
|
||||||
{ }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Div<N, N>> ScalarDiv<N> for vec::Vec0<N>
|
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_div(&self, _: &N) -> vec::Vec0<N>
|
fn scalar_mul_inplace(&mut self, _: &N) { }
|
||||||
{ vec::Vec0 }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn scalar_div_inplace(&mut self, _: &N)
|
|
||||||
{ }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Add<N, N>> ScalarAdd<N> for vec::Vec0<N>
|
impl<N: Div<N, N>> ScalarDiv<N> for vec::Vec0<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_add(&self, _: &N) -> vec::Vec0<N>
|
fn scalar_div(&self, _: &N) -> vec::Vec0<N> {
|
||||||
{ vec::Vec0 }
|
vec::Vec0
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn scalar_add_inplace(&mut self, _: &N)
|
|
||||||
{ }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Sub<N, N>> ScalarSub<N> for vec::Vec0<N>
|
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_sub(&self, _: &N) -> vec::Vec0<N>
|
fn scalar_div_inplace(&mut self, _: &N) { }
|
||||||
{ vec::Vec0 }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
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: Add<N, N>> ScalarAdd<N> for vec::Vec0<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn translation(&self) -> vec::Vec0<N>
|
fn scalar_add(&self, _: &N) -> vec::Vec0<N> {
|
||||||
{ self.clone() }
|
vec::Vec0
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn inv_translation(&self) -> vec::Vec0<N>
|
|
||||||
{ -self }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
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>
|
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn translated(&self, t: &vec::Vec0<N>) -> vec::Vec0<N>
|
fn scalar_add_inplace(&mut self, _: &N) { }
|
||||||
{ self + *t }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + DivisionRing + Algebraic> Norm<N> for vec::Vec0<N>
|
impl<N: Sub<N, N>> ScalarSub<N> for vec::Vec0<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sqnorm(&self) -> N
|
fn scalar_sub(&self, _: &N) -> vec::Vec0<N> {
|
||||||
{ self.dot(self) }
|
vec::Vec0
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn norm(&self) -> N
|
fn scalar_sub_inplace(&mut self, _: &N) { }
|
||||||
{ self.sqnorm().sqrt() }
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn normalized(&self) -> vec::Vec0<N>
|
fn inv_translation(&self) -> vec::Vec0<N> {
|
||||||
{
|
-self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
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> {
|
||||||
|
#[inline]
|
||||||
|
fn translated(&self, t: &vec::Vec0<N>) -> vec::Vec0<N> {
|
||||||
|
self + *t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Clone + DivisionRing + Algebraic> Norm<N> for vec::Vec0<N> {
|
||||||
|
#[inline]
|
||||||
|
fn sqnorm(&self) -> N {
|
||||||
|
self.dot(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn norm(&self) -> N {
|
||||||
|
self.sqnorm().sqrt()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn normalized(&self) -> vec::Vec0<N> {
|
||||||
let mut res : vec::Vec0<N> = self.clone();
|
let mut res : vec::Vec0<N> = self.clone();
|
||||||
|
|
||||||
res.normalize();
|
res.normalize();
|
||||||
|
@ -197,8 +194,7 @@ impl<N: Clone + DivisionRing + Algebraic> Norm<N> for vec::Vec0<N>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn normalize(&mut self) -> N
|
fn normalize(&mut self) -> N {
|
||||||
{
|
|
||||||
let l = self.norm();
|
let l = self.norm();
|
||||||
|
|
||||||
self.scalar_div_inplace(&l);
|
self.scalar_div_inplace(&l);
|
||||||
|
@ -207,41 +203,44 @@ impl<N: Clone + DivisionRing + Algebraic> Norm<N> for vec::Vec0<N>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: ApproxEq<N>> ApproxEq<N> for vec::Vec0<N>
|
impl<N: ApproxEq<N>> ApproxEq<N> for vec::Vec0<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_epsilon() -> N
|
fn approx_epsilon() -> N {
|
||||||
{ ApproxEq::approx_epsilon::<N, N>() }
|
ApproxEq::approx_epsilon::<N, N>()
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq(&self, _: &vec::Vec0<N>) -> bool
|
|
||||||
{ true }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq_eps(&self, _: &vec::Vec0<N>, _: &N) -> bool
|
|
||||||
{ true }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + One> One for vec::Vec0<N>
|
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn one() -> vec::Vec0<N>
|
fn approx_eq(&self, _: &vec::Vec0<N>) -> bool {
|
||||||
{ vec::Vec0 }
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for vec::Vec0<N>
|
#[inline]
|
||||||
{
|
fn approx_eq_eps(&self, _: &vec::Vec0<N>, _: &N) -> bool {
|
||||||
fn from_iterator(_: &mut Iter) -> vec::Vec0<N>
|
true
|
||||||
{ vec::Vec0 }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Bounded + Clone> Bounded for vec::Vec0<N>
|
impl<N: Clone + One> One for vec::Vec0<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn max_value() -> vec::Vec0<N>
|
fn one() -> vec::Vec0<N> {
|
||||||
{ vec::Vec0 }
|
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> {
|
||||||
|
#[inline]
|
||||||
|
fn max_value() -> vec::Vec0<N> {
|
||||||
|
vec::Vec0
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn min_value() -> vec::Vec0<N>
|
fn min_value() -> vec::Vec0<N> {
|
||||||
{ vec::Vec0 }
|
vec::Vec0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,10 @@
|
||||||
|
|
||||||
macro_rules! new_impl(
|
macro_rules! new_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N> $t<N>
|
impl<N> $t<N> {
|
||||||
{
|
|
||||||
/// Creates a new vector.
|
/// Creates a new vector.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new($comp0: N $( , $compN: N )*) -> $t<N>
|
pub fn new($comp0: N $( , $compN: N )*) -> $t<N> {
|
||||||
{
|
|
||||||
$t {
|
$t {
|
||||||
$comp0: $comp0
|
$comp0: $comp0
|
||||||
$(, $compN: $compN )*
|
$(, $compN: $compN )*
|
||||||
|
@ -19,42 +17,45 @@ macro_rules! new_impl(
|
||||||
|
|
||||||
macro_rules! ord_impl(
|
macro_rules! ord_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Ord> Ord for $t<N>
|
impl<N: Ord> Ord for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn lt(&self, other: &$t<N>) -> bool
|
fn lt(&self, other: &$t<N>) -> bool {
|
||||||
{ self.$comp0 < other.$comp0 $(&& self.$compN < other.$compN)* }
|
self.$comp0 < other.$comp0 $(&& self.$compN < other.$compN)*
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn le(&self, other: &$t<N>) -> bool
|
fn le(&self, other: &$t<N>) -> bool {
|
||||||
{ self.$comp0 <= other.$comp0 $(&& self.$compN <= other.$compN)* }
|
self.$comp0 <= other.$comp0 $(&& self.$compN <= other.$compN)*
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn gt(&self, other: &$t<N>) -> bool
|
fn gt(&self, other: &$t<N>) -> bool {
|
||||||
{ self.$comp0 > other.$comp0 $(&& self.$compN > other.$compN)* }
|
self.$comp0 > other.$comp0 $(&& self.$compN > other.$compN)*
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ge(&self, other: &$t<N>) -> bool
|
fn ge(&self, other: &$t<N>) -> bool {
|
||||||
{ self.$comp0 >= other.$comp0 $(&& self.$compN >= other.$compN)* }
|
self.$comp0 >= other.$comp0 $(&& self.$compN >= other.$compN)*
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! orderable_impl(
|
macro_rules! orderable_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Orderable> Orderable for $t<N>
|
impl<N: Orderable> Orderable for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn max(&self, other: &$t<N>) -> $t<N>
|
fn max(&self, other: &$t<N>) -> $t<N> {
|
||||||
{ $t::new(self.$comp0.max(&other.$comp0) $(, self.$compN.max(&other.$compN))*) }
|
$t::new(self.$comp0.max(&other.$comp0) $(, self.$compN.max(&other.$compN))*)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn min(&self, other: &$t<N>) -> $t<N>
|
fn min(&self, other: &$t<N>) -> $t<N> {
|
||||||
{ $t::new(self.$comp0.min(&other.$comp0) $(, self.$compN.min(&other.$compN))*) }
|
$t::new(self.$comp0.min(&other.$comp0) $(, self.$compN.min(&other.$compN))*)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clamp(&self, min: &$t<N>, max: &$t<N>) -> $t<N>
|
fn clamp(&self, min: &$t<N>, max: &$t<N>) -> $t<N> {
|
||||||
{
|
|
||||||
$t::new(self.$comp0.clamp(&min.$comp0, &max.$comp0)
|
$t::new(self.$comp0.clamp(&min.$comp0, &max.$comp0)
|
||||||
$(, self.$compN.clamp(&min.$comp0, &max.$comp0))*)
|
$(, self.$compN.clamp(&min.$comp0, &max.$comp0))*)
|
||||||
}
|
}
|
||||||
|
@ -64,12 +65,10 @@ macro_rules! orderable_impl(
|
||||||
|
|
||||||
macro_rules! vec_axis_impl(
|
macro_rules! vec_axis_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Zero + One> $t<N>
|
impl<N: Zero + One> $t<N> {
|
||||||
{
|
|
||||||
/// Create a unit vector with its `$comp0` component equal to 1.0.
|
/// Create a unit vector with its `$comp0` component equal to 1.0.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn $comp0() -> $t<N>
|
pub fn $comp0() -> $t<N> {
|
||||||
{
|
|
||||||
let mut res: $t<N> = Zero::zero();
|
let mut res: $t<N> = Zero::zero();
|
||||||
|
|
||||||
res.$comp0 = One::one();
|
res.$comp0 = One::one();
|
||||||
|
@ -80,8 +79,7 @@ macro_rules! vec_axis_impl(
|
||||||
$(
|
$(
|
||||||
/// Create a unit vector with its `$compN` component equal to 1.0.
|
/// Create a unit vector with its `$compN` component equal to 1.0.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn $compN() -> $t<N>
|
pub fn $compN() -> $t<N> {
|
||||||
{
|
|
||||||
let mut res: $t<N> = Zero::zero();
|
let mut res: $t<N> = Zero::zero();
|
||||||
|
|
||||||
res.$compN = One::one();
|
res.$compN = One::one();
|
||||||
|
@ -95,42 +93,48 @@ macro_rules! vec_axis_impl(
|
||||||
|
|
||||||
macro_rules! vec_cast_impl(
|
macro_rules! vec_cast_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<Nin: NumCast + Clone, Nout: NumCast> VecCast<$t<Nout>> for $t<Nin>
|
impl<Nin: NumCast + Clone, Nout: NumCast> VecCast<$t<Nout>> for $t<Nin> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from(v: $t<Nin>) -> $t<Nout>
|
pub fn from(v: $t<Nin>) -> $t<Nout> {
|
||||||
{ $t::new(NumCast::from(v.$comp0.clone()) $(, NumCast::from(v.$compN.clone()))*) }
|
$t::new(NumCast::from(v.$comp0.clone()) $(, NumCast::from(v.$compN.clone()))*)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! indexable_impl(
|
macro_rules! indexable_impl(
|
||||||
($t: ident, $dim: expr) => (
|
($t: ident, $dim: expr) => (
|
||||||
impl<N: Clone> Indexable<uint, N> for $t<N>
|
impl<N: Clone> Indexable<uint, N> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn at(&self, i: uint) -> N
|
pub fn at(&self, i: uint) -> N {
|
||||||
{ unsafe { cast::transmute::<&$t<N>, &[N, ..$dim]>(self)[i].clone() } }
|
unsafe {
|
||||||
|
cast::transmute::<&$t<N>, &[N, ..$dim]>(self)[i].clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set(&mut self, i: uint, val: N)
|
pub fn set(&mut self, i: uint, val: N) {
|
||||||
{ unsafe { cast::transmute::<&mut $t<N>, &mut [N, ..$dim]>(self)[i] = val } }
|
unsafe {
|
||||||
|
cast::transmute::<&mut $t<N>, &mut [N, ..$dim]>(self)[i] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn swap(&mut self, i1: uint, i2: uint)
|
pub fn swap(&mut self, i1: uint, i2: uint) {
|
||||||
{ unsafe { cast::transmute::<&mut $t<N>, &mut [N, ..$dim]>(self).swap(i1, i2) } }
|
unsafe {
|
||||||
|
cast::transmute::<&mut $t<N>, &mut [N, ..$dim]>(self).swap(i1, i2)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! new_repeat_impl(
|
macro_rules! new_repeat_impl(
|
||||||
($t: ident, $param: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $param: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Clone> $t<N>
|
impl<N: Clone> $t<N> {
|
||||||
{
|
|
||||||
/// Creates a new vector with all its components equal to a given value.
|
/// Creates a new vector with all its components equal to a given value.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_repeat($param: N) -> $t<N>
|
pub fn new_repeat($param: N) -> $t<N> {
|
||||||
{
|
|
||||||
$t{
|
$t{
|
||||||
$comp0: $param.clone()
|
$comp0: $param.clone()
|
||||||
$(, $compN: $param.clone() )*
|
$(, $compN: $param.clone() )*
|
||||||
|
@ -142,43 +146,44 @@ macro_rules! new_repeat_impl(
|
||||||
|
|
||||||
macro_rules! iterable_impl(
|
macro_rules! iterable_impl(
|
||||||
($t: ident, $dim: expr) => (
|
($t: ident, $dim: expr) => (
|
||||||
impl<N> Iterable<N> for $t<N>
|
impl<N> Iterable<N> for $t<N> {
|
||||||
{
|
fn iter<'l>(&'l self) -> VecIterator<'l, N> {
|
||||||
fn iter<'l>(&'l self) -> VecIterator<'l, N>
|
unsafe {
|
||||||
{ unsafe { cast::transmute::<&'l $t<N>, &'l [N, ..$dim]>(self).iter() } }
|
cast::transmute::<&'l $t<N>, &'l [N, ..$dim]>(self).iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! iterable_mut_impl(
|
macro_rules! iterable_mut_impl(
|
||||||
($t: ident, $dim: expr) => (
|
($t: ident, $dim: expr) => (
|
||||||
impl<N> IterableMut<N> for $t<N>
|
impl<N> IterableMut<N> for $t<N> {
|
||||||
{
|
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> {
|
||||||
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N>
|
unsafe {
|
||||||
{ unsafe { cast::transmute::<&'l mut $t<N>, &'l mut [N, ..$dim]>(self).mut_iter() } }
|
cast::transmute::<&'l mut $t<N>, &'l mut [N, ..$dim]>(self).mut_iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! dim_impl(
|
macro_rules! dim_impl(
|
||||||
($t: ident, $dim: expr) => (
|
($t: ident, $dim: expr) => (
|
||||||
impl<N> Dim for $t<N>
|
impl<N> Dim for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn dim() -> uint
|
fn dim() -> uint {
|
||||||
{ $dim }
|
$dim
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! basis_impl(
|
macro_rules! basis_impl(
|
||||||
($t: ident, $dim: expr) => (
|
($t: ident, $dim: expr) => (
|
||||||
impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> Basis for $t<N>
|
impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> Basis for $t<N> {
|
||||||
{
|
pub fn canonical_basis(f: &fn($t<N>)) {
|
||||||
pub fn canonical_basis(f: &fn($t<N>))
|
for i in range(0u, $dim) {
|
||||||
{
|
|
||||||
for i in range(0u, $dim)
|
|
||||||
{
|
|
||||||
let mut basis_element : $t<N> = Zero::zero();
|
let mut basis_element : $t<N> = Zero::zero();
|
||||||
|
|
||||||
basis_element.set(i, One::one());
|
basis_element.set(i, One::one());
|
||||||
|
@ -187,30 +192,29 @@ macro_rules! basis_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn orthonormal_subspace_basis(&self, f: &fn($t<N>))
|
pub fn orthonormal_subspace_basis(&self, f: &fn($t<N>)) {
|
||||||
{
|
|
||||||
// compute the basis of the orthogonal subspace using Gram-Schmidt
|
// compute the basis of the orthogonal subspace using Gram-Schmidt
|
||||||
// orthogonalization algorithm
|
// orthogonalization algorithm
|
||||||
let mut basis: ~[$t<N>] = ~[];
|
let mut basis: ~[$t<N>] = ~[];
|
||||||
|
|
||||||
for i in range(0u, $dim)
|
for i in range(0u, $dim) {
|
||||||
{
|
|
||||||
let mut basis_element : $t<N> = Zero::zero();
|
let mut basis_element : $t<N> = Zero::zero();
|
||||||
|
|
||||||
basis_element.set(i, One::one());
|
basis_element.set(i, One::one());
|
||||||
|
|
||||||
if basis.len() == $dim - 1
|
if basis.len() == $dim - 1 {
|
||||||
{ break; }
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
let mut elt = basis_element.clone();
|
let mut elt = basis_element.clone();
|
||||||
|
|
||||||
elt = elt - self.scalar_mul(&basis_element.dot(self));
|
elt = elt - self.scalar_mul(&basis_element.dot(self));
|
||||||
|
|
||||||
for v in basis.iter()
|
for v in basis.iter() {
|
||||||
{ elt = elt - v.scalar_mul(&elt.dot(v)) };
|
elt = elt - v.scalar_mul(&elt.dot(v))
|
||||||
|
};
|
||||||
|
|
||||||
if !elt.sqnorm().approx_eq(&Zero::zero())
|
if !elt.sqnorm().approx_eq(&Zero::zero()) {
|
||||||
{
|
|
||||||
let new_element = elt.normalized();
|
let new_element = elt.normalized();
|
||||||
|
|
||||||
f(new_element.clone());
|
f(new_element.clone());
|
||||||
|
@ -225,70 +229,69 @@ macro_rules! basis_impl(
|
||||||
|
|
||||||
macro_rules! add_impl(
|
macro_rules! add_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Clone + Add<N, N>> Add<$t<N>, $t<N>> for $t<N>
|
impl<N: Clone + Add<N, N>> Add<$t<N>, $t<N>> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add(&self, other: &$t<N>) -> $t<N>
|
fn add(&self, other: &$t<N>) -> $t<N> {
|
||||||
{ $t::new(self.$comp0 + other.$comp0 $(, self.$compN + other.$compN)*) }
|
$t::new(self.$comp0 + other.$comp0 $(, self.$compN + other.$compN)*)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! sub_impl(
|
macro_rules! sub_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Clone + Sub<N, N>> Sub<$t<N>, $t<N>> for $t<N>
|
impl<N: Clone + Sub<N, N>> Sub<$t<N>, $t<N>> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sub(&self, other: &$t<N>) -> $t<N>
|
fn sub(&self, other: &$t<N>) -> $t<N> {
|
||||||
{ $t::new(self.$comp0 - other.$comp0 $(, self.$compN - other.$compN)*) }
|
$t::new(self.$comp0 - other.$comp0 $(, self.$compN - other.$compN)*)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! neg_impl(
|
macro_rules! neg_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Neg<N>> Neg<$t<N>> for $t<N>
|
impl<N: Neg<N>> Neg<$t<N>> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn neg(&self) -> $t<N>
|
fn neg(&self) -> $t<N> {
|
||||||
{ $t::new(-self.$comp0 $(, -self.$compN )*) }
|
$t::new(-self.$comp0 $(, -self.$compN )*)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! dot_impl(
|
macro_rules! dot_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Ring> Dot<N> for $t<N>
|
impl<N: Ring> Dot<N> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn dot(&self, other: &$t<N>) -> N
|
fn dot(&self, other: &$t<N>) -> N {
|
||||||
{ self.$comp0 * other.$comp0 $(+ self.$compN * other.$compN )* }
|
self.$comp0 * other.$comp0 $(+ self.$compN * other.$compN )*
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! sub_dot_impl(
|
macro_rules! sub_dot_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Clone + Ring> SubDot<N> for $t<N>
|
impl<N: Clone + Ring> SubDot<N> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sub_dot(&self, a: &$t<N>, b: &$t<N>) -> N
|
fn sub_dot(&self, a: &$t<N>, b: &$t<N>) -> N {
|
||||||
{ (self.$comp0 - a.$comp0) * b.$comp0 $(+ (self.$compN - a.$compN) * b.$compN )* }
|
(self.$comp0 - a.$comp0) * b.$comp0 $(+ (self.$compN - a.$compN) * b.$compN )*
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! scalar_mul_impl(
|
macro_rules! scalar_mul_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Mul<N, N>> ScalarMul<N> for $t<N>
|
impl<N: Mul<N, N>> ScalarMul<N> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_mul(&self, s: &N) -> $t<N>
|
fn scalar_mul(&self, s: &N) -> $t<N> {
|
||||||
{ $t::new(self.$comp0 * *s $(, self.$compN * *s)*) }
|
$t::new(self.$comp0 * *s $(, self.$compN * *s)*)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_mul_inplace(&mut self, s: &N)
|
fn scalar_mul_inplace(&mut self, s: &N) {
|
||||||
{
|
|
||||||
self.$comp0 = self.$comp0 * *s;
|
self.$comp0 = self.$comp0 * *s;
|
||||||
$(self.$compN = self.$compN * *s;)*
|
$(self.$compN = self.$compN * *s;)*
|
||||||
}
|
}
|
||||||
|
@ -298,15 +301,14 @@ macro_rules! scalar_mul_impl(
|
||||||
|
|
||||||
macro_rules! scalar_div_impl(
|
macro_rules! scalar_div_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Div<N, N>> ScalarDiv<N> for $t<N>
|
impl<N: Div<N, N>> ScalarDiv<N> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_div(&self, s: &N) -> $t<N>
|
fn scalar_div(&self, s: &N) -> $t<N> {
|
||||||
{ $t::new(self.$comp0 / *s $(, self.$compN / *s)*) }
|
$t::new(self.$comp0 / *s $(, self.$compN / *s)*)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_div_inplace(&mut self, s: &N)
|
fn scalar_div_inplace(&mut self, s: &N) {
|
||||||
{
|
|
||||||
self.$comp0 = self.$comp0 / *s;
|
self.$comp0 = self.$comp0 / *s;
|
||||||
$(self.$compN = self.$compN / *s;)*
|
$(self.$compN = self.$compN / *s;)*
|
||||||
}
|
}
|
||||||
|
@ -316,15 +318,14 @@ macro_rules! scalar_div_impl(
|
||||||
|
|
||||||
macro_rules! scalar_add_impl(
|
macro_rules! scalar_add_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Add<N, N>> ScalarAdd<N> for $t<N>
|
impl<N: Add<N, N>> ScalarAdd<N> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_add(&self, s: &N) -> $t<N>
|
fn scalar_add(&self, s: &N) -> $t<N> {
|
||||||
{ $t::new(self.$comp0 + *s $(, self.$compN + *s)*) }
|
$t::new(self.$comp0 + *s $(, self.$compN + *s)*)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_add_inplace(&mut self, s: &N)
|
fn scalar_add_inplace(&mut self, s: &N) {
|
||||||
{
|
|
||||||
self.$comp0 = self.$comp0 + *s;
|
self.$comp0 = self.$comp0 + *s;
|
||||||
$(self.$compN = self.$compN + *s;)*
|
$(self.$compN = self.$compN + *s;)*
|
||||||
}
|
}
|
||||||
|
@ -334,15 +335,14 @@ macro_rules! scalar_add_impl(
|
||||||
|
|
||||||
macro_rules! scalar_sub_impl(
|
macro_rules! scalar_sub_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Sub<N, N>> ScalarSub<N> for $t<N>
|
impl<N: Sub<N, N>> ScalarSub<N> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_sub(&self, s: &N) -> $t<N>
|
fn scalar_sub(&self, s: &N) -> $t<N> {
|
||||||
{ $t::new(self.$comp0 - *s $(, self.$compN - *s)*) }
|
$t::new(self.$comp0 - *s $(, self.$compN - *s)*)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn scalar_sub_inplace(&mut self, s: &N)
|
fn scalar_sub_inplace(&mut self, s: &N) {
|
||||||
{
|
|
||||||
self.$comp0 = self.$comp0 - *s;
|
self.$comp0 = self.$comp0 - *s;
|
||||||
$(self.$compN = self.$compN - *s;)*
|
$(self.$compN = self.$compN - *s;)*
|
||||||
}
|
}
|
||||||
|
@ -352,49 +352,51 @@ macro_rules! scalar_sub_impl(
|
||||||
|
|
||||||
macro_rules! translation_impl(
|
macro_rules! translation_impl(
|
||||||
($t: ident) => (
|
($t: ident) => (
|
||||||
impl<N: Clone + Add<N, N> + Neg<N>> Translation<$t<N>> for $t<N>
|
impl<N: Clone + Add<N, N> + Neg<N>> Translation<$t<N>> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn translation(&self) -> $t<N>
|
fn translation(&self) -> $t<N> {
|
||||||
{ self.clone() }
|
self.clone()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inv_translation(&self) -> $t<N>
|
fn inv_translation(&self) -> $t<N> {
|
||||||
{ -self }
|
-self
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn translate_by(&mut self, t: &$t<N>)
|
fn translate_by(&mut self, t: &$t<N>) {
|
||||||
{ *self = *self + *t; }
|
*self = *self + *t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! translatable_impl(
|
macro_rules! translatable_impl(
|
||||||
($t: ident) => (
|
($t: ident) => (
|
||||||
impl<N: Add<N, N> + Neg<N> + Clone> Translatable<$t<N>, $t<N>> for $t<N>
|
impl<N: Add<N, N> + Neg<N> + Clone> Translatable<$t<N>, $t<N>> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn translated(&self, t: &$t<N>) -> $t<N>
|
fn translated(&self, t: &$t<N>) -> $t<N> {
|
||||||
{ self + *t }
|
self + *t
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! norm_impl(
|
macro_rules! norm_impl(
|
||||||
($t: ident) => (
|
($t: ident) => (
|
||||||
impl<N: Clone + DivisionRing + Algebraic> Norm<N> for $t<N>
|
impl<N: Clone + DivisionRing + Algebraic> Norm<N> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sqnorm(&self) -> N
|
fn sqnorm(&self) -> N {
|
||||||
{ self.dot(self) }
|
self.dot(self)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn norm(&self) -> N
|
fn norm(&self) -> N {
|
||||||
{ self.sqnorm().sqrt() }
|
self.sqnorm().sqrt()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn normalized(&self) -> $t<N>
|
fn normalized(&self) -> $t<N> {
|
||||||
{
|
|
||||||
let mut res : $t<N> = self.clone();
|
let mut res : $t<N> = self.clone();
|
||||||
|
|
||||||
res.normalize();
|
res.normalize();
|
||||||
|
@ -403,8 +405,7 @@ macro_rules! norm_impl(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn normalize(&mut self) -> N
|
fn normalize(&mut self) -> N {
|
||||||
{
|
|
||||||
let l = self.norm();
|
let l = self.norm();
|
||||||
|
|
||||||
self.scalar_div_inplace(&l);
|
self.scalar_div_inplace(&l);
|
||||||
|
@ -417,65 +418,66 @@ macro_rules! norm_impl(
|
||||||
|
|
||||||
macro_rules! approx_eq_impl(
|
macro_rules! approx_eq_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N>
|
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_epsilon() -> N
|
fn approx_epsilon() -> N {
|
||||||
{ ApproxEq::approx_epsilon::<N, N>() }
|
ApproxEq::approx_epsilon::<N, N>()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_eq(&self, other: &$t<N>) -> bool
|
fn approx_eq(&self, other: &$t<N>) -> bool {
|
||||||
{ self.$comp0.approx_eq(&other.$comp0) $(&& self.$compN.approx_eq(&other.$compN))* }
|
self.$comp0.approx_eq(&other.$comp0) $(&& self.$compN.approx_eq(&other.$compN))*
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_eq_eps(&self, other: &$t<N>, eps: &N) -> bool
|
fn approx_eq_eps(&self, other: &$t<N>, eps: &N) -> bool {
|
||||||
{ self.$comp0.approx_eq_eps(&other.$comp0, eps) $(&& self.$compN.approx_eq_eps(&other.$compN, eps))* }
|
self.$comp0.approx_eq_eps(&other.$comp0, eps) $(&& self.$compN.approx_eq_eps(&other.$compN, eps))*
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! one_impl(
|
macro_rules! one_impl(
|
||||||
($t: ident) => (
|
($t: ident) => (
|
||||||
impl<N: Clone + One> One for $t<N>
|
impl<N: Clone + One> One for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn one() -> $t<N>
|
fn one() -> $t<N> {
|
||||||
{ $t::new_repeat(One::one()) }
|
$t::new_repeat(One::one())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! from_iterator_impl(
|
macro_rules! from_iterator_impl(
|
||||||
($t: ident, $param0: ident $(, $paramN: ident)*) => (
|
($t: ident, $param0: ident $(, $paramN: ident)*) => (
|
||||||
impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for $t<N>
|
impl<N, Iter: Iterator<N>> FromIterator<N, Iter> for $t<N> {
|
||||||
{
|
fn from_iterator($param0: &mut Iter) -> $t<N> {
|
||||||
fn from_iterator($param0: &mut Iter) -> $t<N>
|
$t::new($param0.next().unwrap() $(, $paramN.next().unwrap())*)
|
||||||
{ $t::new($param0.next().unwrap() $(, $paramN.next().unwrap())*) }
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! bounded_impl(
|
macro_rules! bounded_impl(
|
||||||
($t: ident) => (
|
($t: ident) => (
|
||||||
impl<N: Bounded + Clone> Bounded for $t<N>
|
impl<N: Bounded + Clone> Bounded for $t<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn max_value() -> $t<N>
|
fn max_value() -> $t<N> {
|
||||||
{ $t::new_repeat(Bounded::max_value()) }
|
$t::new_repeat(Bounded::max_value())
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn min_value() -> $t<N>
|
fn min_value() -> $t<N> {
|
||||||
{ $t::new_repeat(Bounded::min_value()) }
|
$t::new_repeat(Bounded::min_value())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! to_homogeneous_impl(
|
macro_rules! to_homogeneous_impl(
|
||||||
($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Clone + One + Zero> ToHomogeneous<$t2<N>> for $t<N>
|
impl<N: Clone + One + Zero> ToHomogeneous<$t2<N>> for $t<N> {
|
||||||
{
|
fn to_homogeneous(&self) -> $t2<N> {
|
||||||
fn to_homogeneous(&self) -> $t2<N>
|
|
||||||
{
|
|
||||||
let mut res: $t2<N> = One::one();
|
let mut res: $t2<N> = One::one();
|
||||||
|
|
||||||
res.$comp0 = self.$comp0.clone();
|
res.$comp0 = self.$comp0.clone();
|
||||||
|
@ -489,10 +491,8 @@ macro_rules! to_homogeneous_impl(
|
||||||
|
|
||||||
macro_rules! from_homogeneous_impl(
|
macro_rules! from_homogeneous_impl(
|
||||||
($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Clone + Div<N, N> + One + Zero> FromHomogeneous<$t2<N>> for $t<N>
|
impl<N: Clone + Div<N, N> + One + Zero> FromHomogeneous<$t2<N>> for $t<N> {
|
||||||
{
|
fn from(v: &$t2<N>) -> $t<N> {
|
||||||
fn from(v: &$t2<N>) -> $t<N>
|
|
||||||
{
|
|
||||||
let mut res: $t<N> = Zero::zero();
|
let mut res: $t<N> = Zero::zero();
|
||||||
|
|
||||||
res.$comp0 = v.$comp0.clone();
|
res.$comp0 = v.$comp0.clone();
|
||||||
|
|
|
@ -6,18 +6,16 @@ use traits::norm::Norm;
|
||||||
use traits::sample::UniformSphereSample;
|
use traits::sample::UniformSphereSample;
|
||||||
use vec::{Vec1, Vec2, Vec3};
|
use vec::{Vec1, Vec2, Vec3};
|
||||||
|
|
||||||
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec1<N>> for Vec2<N>
|
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec1<N>> for Vec2<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn cross(&self, other : &Vec2<N>) -> Vec1<N>
|
fn cross(&self, other : &Vec2<N>) -> Vec1<N> {
|
||||||
{ Vec1::new(self.x * other.y - self.y * other.x) }
|
Vec1::new(self.x * other.y - self.y * other.x)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec3<N>> for Vec3<N>
|
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec3<N>> for Vec3<N> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn cross(&self, other : &Vec3<N>) -> Vec3<N>
|
fn cross(&self, other : &Vec3<N>) -> Vec3<N> {
|
||||||
{
|
|
||||||
Vec3::new(
|
Vec3::new(
|
||||||
self.y * other.z - self.z * other.y,
|
self.y * other.z - self.z * other.y,
|
||||||
self.z * other.x - self.x * other.z,
|
self.z * other.x - self.x * other.z,
|
||||||
|
@ -26,50 +24,47 @@ impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec3<N>> for Vec3<N>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: One> Basis for Vec1<N>
|
impl<N: One> Basis for Vec1<N> {
|
||||||
{
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn canonical_basis(f: &fn(Vec1<N>))
|
fn canonical_basis(f: &fn(Vec1<N>)) {
|
||||||
{ f(Vec1::new(One::one())) }
|
f(Vec1::new(One::one()))
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn orthonormal_subspace_basis(&self, _: &fn(Vec1<N>))
|
|
||||||
{ }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + One + Zero + Neg<N>> Basis for Vec2<N>
|
#[inline(always)]
|
||||||
{
|
fn orthonormal_subspace_basis(&self, _: &fn(Vec1<N>)) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Clone + One + Zero + Neg<N>> Basis for Vec2<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn canonical_basis(f: &fn(Vec2<N>))
|
fn canonical_basis(f: &fn(Vec2<N>)) {
|
||||||
{
|
|
||||||
f(Vec2::new(One::one(), Zero::zero()));
|
f(Vec2::new(One::one(), Zero::zero()));
|
||||||
f(Vec2::new(Zero::zero(), One::one()));
|
f(Vec2::new(Zero::zero(), One::one()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn orthonormal_subspace_basis(&self, f: &fn(Vec2<N>))
|
fn orthonormal_subspace_basis(&self, f: &fn(Vec2<N>)) {
|
||||||
{ f(Vec2::new(-self.y, self.x.clone())) }
|
f(Vec2::new(-self.y, self.x.clone()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + DivisionRing + Ord + Algebraic + Signed>
|
impl<N: Clone + DivisionRing + Ord + Algebraic + Signed>
|
||||||
Basis for Vec3<N>
|
Basis for Vec3<N> {
|
||||||
{
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn canonical_basis(f: &fn(Vec3<N>))
|
fn canonical_basis(f: &fn(Vec3<N>)) {
|
||||||
{
|
|
||||||
f(Vec3::new(One::one(), Zero::zero(), Zero::zero()));
|
f(Vec3::new(One::one(), Zero::zero(), Zero::zero()));
|
||||||
f(Vec3::new(Zero::zero(), One::one(), Zero::zero()));
|
f(Vec3::new(Zero::zero(), One::one(), Zero::zero()));
|
||||||
f(Vec3::new(Zero::zero(), Zero::zero(), One::one()));
|
f(Vec3::new(Zero::zero(), Zero::zero(), One::one()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn orthonormal_subspace_basis(&self, f: &fn(Vec3<N>))
|
fn orthonormal_subspace_basis(&self, f: &fn(Vec3<N>)) {
|
||||||
{
|
|
||||||
let a =
|
let a =
|
||||||
if self.x.clone().abs() > self.y.clone().abs()
|
if self.x.clone().abs() > self.y.clone().abs() {
|
||||||
{ Vec3::new(self.z.clone(), Zero::zero(), -self.x).normalized() }
|
Vec3::new(self.z.clone(), Zero::zero(), -self.x).normalized()
|
||||||
else
|
}
|
||||||
{ Vec3::new(Zero::zero(), -self.z, self.y.clone()).normalized() };
|
else {
|
||||||
|
Vec3::new(Zero::zero(), -self.z, self.y.clone()).normalized()
|
||||||
|
};
|
||||||
|
|
||||||
f(a.cross(self));
|
f(a.cross(self));
|
||||||
f(a);
|
f(a);
|
||||||
|
@ -147,20 +142,18 @@ static SAMPLES_3_F64: [Vec3<f64>, ..42] = [
|
||||||
Vec3 { x: 0.162456 , y: 0.499995 , z: 0.850654 }
|
Vec3 { x: 0.162456 , y: 0.499995 , z: 0.850654 }
|
||||||
];
|
];
|
||||||
|
|
||||||
impl UniformSphereSample for Vec2<f64>
|
impl UniformSphereSample for Vec2<f64> {
|
||||||
{
|
pub fn sample(f: &fn(&'static Vec2<f64>)) {
|
||||||
pub fn sample(f: &fn(&'static Vec2<f64>))
|
for sample in SAMPLES_2_F64.iter() {
|
||||||
{
|
f(sample)
|
||||||
for sample in SAMPLES_2_F64.iter()
|
}
|
||||||
{ f(sample) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UniformSphereSample for Vec3<f64>
|
impl UniformSphereSample for Vec3<f64> {
|
||||||
{
|
pub fn sample(f: &fn(&'static Vec3<f64>)) {
|
||||||
pub fn sample(f: &fn(&'static Vec3<f64>))
|
for sample in SAMPLES_3_F64.iter() {
|
||||||
{
|
f(sample)
|
||||||
for sample in SAMPLES_3_F64.iter()
|
}
|
||||||
{ f(sample) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue