Add sphere sempling trait + Copy becomes Clone
This commit is contained in:
parent
51fd2bc744
commit
6f081b70b8
|
@ -19,22 +19,21 @@ use vec::Vec3;
|
|||
pub struct Rotmat<M>
|
||||
{ priv submat: M }
|
||||
|
||||
impl<M: Copy> Rotmat<M>
|
||||
impl<M: Clone> Rotmat<M>
|
||||
{
|
||||
pub fn submat(&self) -> M
|
||||
{ copy self.submat }
|
||||
{ self.submat.clone() }
|
||||
}
|
||||
|
||||
pub fn rotmat2<N: Copy + Trigonometric + Neg<N>>(angle: N) -> Rotmat<Mat2<N>>
|
||||
pub fn rotmat2<N: Clone + Trigonometric + Neg<N>>(angle: N) -> Rotmat<Mat2<N>>
|
||||
{
|
||||
let coa = angle.cos();
|
||||
let sia = angle.sin();
|
||||
let (sia, coa) = angle.sin_cos();
|
||||
|
||||
Rotmat
|
||||
{ submat: Mat2::new( [ copy coa, -sia, copy sia, copy coa ] ) }
|
||||
{ submat: Mat2::new( [ coa.clone(), -sia, sia.clone(), coa ] ) }
|
||||
}
|
||||
|
||||
pub fn rotmat3<N: Copy + Trigonometric + DivisionRing + Algebraic>
|
||||
pub fn rotmat3<N: Clone + Copy + Trigonometric + DivisionRing + Algebraic>
|
||||
(axisangle: Vec3<N>) -> Rotmat<Mat3<N>>
|
||||
{
|
||||
if axisangle.sqnorm().is_zero()
|
||||
|
@ -44,15 +43,14 @@ pub fn rotmat3<N: Copy + Trigonometric + DivisionRing + Algebraic>
|
|||
let mut axis = axisangle;
|
||||
let angle = axis.normalize();
|
||||
let _1 = One::one::<N>();
|
||||
let ux = copy axis.at[0];
|
||||
let uy = copy axis.at[1];
|
||||
let uz = copy axis.at[2];
|
||||
let ux = axis.at[0].clone();
|
||||
let uy = axis.at[1].clone();
|
||||
let uz = axis.at[2].clone();
|
||||
let sqx = ux * ux;
|
||||
let sqy = uy * uy;
|
||||
let sqz = uz * uz;
|
||||
let cos = angle.cos();
|
||||
let (sin, cos) = angle.sin_cos();
|
||||
let one_m_cos = _1 - cos;
|
||||
let sin = angle.sin();
|
||||
|
||||
Rotmat {
|
||||
submat: Mat3::new( [
|
||||
|
@ -71,12 +69,12 @@ pub fn rotmat3<N: Copy + Trigonometric + DivisionRing + Algebraic>
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Trigonometric + DivisionRing + Copy>
|
||||
impl<N: Trigonometric + DivisionRing + Clone>
|
||||
Rotation<Vec1<N>> for Rotmat<Mat2<N>>
|
||||
{
|
||||
#[inline]
|
||||
fn rotation(&self) -> Vec1<N>
|
||||
{ Vec1::new([ -(self.submat.at((0, 1)) / self.submat.at((0, 0))).atan() ]) }
|
||||
{ Vec1::new([ (-self.submat.at((0, 1))).atan2(&self.submat.at((0, 0))) ]) }
|
||||
|
||||
#[inline]
|
||||
fn inv_rotation(&self) -> Vec1<N>
|
||||
|
@ -87,15 +85,15 @@ Rotation<Vec1<N>> for Rotmat<Mat2<N>>
|
|||
{ *self = self.rotated(rot) }
|
||||
}
|
||||
|
||||
impl<N: Trigonometric + DivisionRing + Copy>
|
||||
impl<N: Trigonometric + DivisionRing + Clone>
|
||||
Rotatable<Vec1<N>, Rotmat<Mat2<N>>> for Rotmat<Mat2<N>>
|
||||
{
|
||||
#[inline]
|
||||
fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>>
|
||||
{ rotmat2(copy rot.at[0]) * *self }
|
||||
{ rotmat2(rot.at[0].clone()) * *self }
|
||||
}
|
||||
|
||||
impl<N: Copy + Trigonometric + DivisionRing + Algebraic>
|
||||
impl<N: Clone + Copy + Trigonometric + DivisionRing + Algebraic>
|
||||
Rotation<Vec3<N>> for Rotmat<Mat3<N>>
|
||||
{
|
||||
#[inline]
|
||||
|
@ -112,15 +110,15 @@ Rotation<Vec3<N>> for Rotmat<Mat3<N>>
|
|||
{ *self = self.rotated(rot) }
|
||||
}
|
||||
|
||||
impl<N: Copy + Trigonometric + DivisionRing + Algebraic>
|
||||
impl<N: Clone + Copy + Trigonometric + DivisionRing + Algebraic>
|
||||
Rotatable<Vec3<N>, Rotmat<Mat3<N>>> for Rotmat<Mat3<N>>
|
||||
{
|
||||
#[inline]
|
||||
fn rotated(&self, axisangle: &Vec3<N>) -> Rotmat<Mat3<N>>
|
||||
{ rotmat3(copy *axisangle) * *self }
|
||||
{ rotmat3(axisangle.clone()) * *self }
|
||||
}
|
||||
|
||||
impl<N: Copy + Rand + Trigonometric + Neg<N>> Rand for Rotmat<Mat2<N>>
|
||||
impl<N: Clone + Rand + Trigonometric + Neg<N>> Rand for Rotmat<Mat2<N>>
|
||||
{
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat2<N>>
|
||||
|
@ -149,7 +147,7 @@ impl<M: RMul<V> + LMul<V>, V> Transform<V> for Rotmat<M>
|
|||
{ self.inv_rotate(v) }
|
||||
}
|
||||
|
||||
impl<N: Copy + Rand + Trigonometric + DivisionRing + Algebraic>
|
||||
impl<N: Clone + Copy + Rand + Trigonometric + DivisionRing + Algebraic>
|
||||
Rand for Rotmat<Mat3<N>>
|
||||
{
|
||||
#[inline]
|
||||
|
@ -195,12 +193,16 @@ impl<V, M: LMul<V>> LMul<V> for Rotmat<M>
|
|||
impl<M: Transpose> Inv for Rotmat<M>
|
||||
{
|
||||
#[inline]
|
||||
fn invert(&mut self)
|
||||
{ self.transpose() }
|
||||
fn invert(&mut self) -> bool
|
||||
{
|
||||
self.transpose();
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inverse(&self) -> Rotmat<M>
|
||||
{ self.transposed() }
|
||||
fn inverse(&self) -> Option<Rotmat<M>>
|
||||
{ Some(self.transposed()) }
|
||||
}
|
||||
|
||||
impl<M: Transpose>
|
||||
|
|
|
@ -179,7 +179,14 @@ Transformation<Transform<M, V>> for Transform<M, V>
|
|||
{ copy *self }
|
||||
|
||||
fn inv_transformation(&self) -> Transform<M, V>
|
||||
{ self.inverse() }
|
||||
{
|
||||
// FIXME: fail or return a Some<Transform<M, V>> ?
|
||||
match self.inverse()
|
||||
{
|
||||
Some(t) => t,
|
||||
None => fail!("This transformation was not inversible.")
|
||||
}
|
||||
}
|
||||
|
||||
fn transform_by(&mut self, other: &Transform<M, V>)
|
||||
{ *self = other * *self; }
|
||||
|
@ -211,20 +218,26 @@ impl<M: Copy + Inv + RMul<V>, V: Copy + Neg<V>>
|
|||
Inv for Transform<M, V>
|
||||
{
|
||||
#[inline]
|
||||
fn invert(&mut self)
|
||||
fn invert(&mut self) -> bool
|
||||
{
|
||||
if !self.submat.invert()
|
||||
{ false }
|
||||
else
|
||||
{
|
||||
self.submat.invert();
|
||||
self.subtrans = self.submat.rmul(&-self.subtrans);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inverse(&self) -> Transform<M, V>
|
||||
fn inverse(&self) -> Option<Transform<M, V>>
|
||||
{
|
||||
let mut res = copy *self;
|
||||
|
||||
res.invert();
|
||||
|
||||
res
|
||||
if res.invert()
|
||||
{ Some(res) }
|
||||
else
|
||||
{ None }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
16
src/dmat.rs
16
src/dmat.rs
|
@ -137,16 +137,17 @@ impl<N: Copy + Eq + DivisionRing>
|
|||
Inv for DMat<N>
|
||||
{
|
||||
#[inline]
|
||||
fn inverse(&self) -> DMat<N>
|
||||
fn inverse(&self) -> Option<DMat<N>>
|
||||
{
|
||||
let mut res : DMat<N> = copy *self;
|
||||
|
||||
res.invert();
|
||||
|
||||
res
|
||||
if res.invert()
|
||||
{ Some(res) }
|
||||
else
|
||||
{ None }
|
||||
}
|
||||
|
||||
fn invert(&mut self)
|
||||
fn invert(&mut self) -> bool
|
||||
{
|
||||
let dim = self.dim;
|
||||
let mut res = one_mat_with_dim::<N>(dim);
|
||||
|
@ -169,7 +170,8 @@ Inv for DMat<N>
|
|||
n0 = n0 + 1;
|
||||
}
|
||||
|
||||
assert!(n0 != dim); // non inversible matrix
|
||||
if n0 == dim
|
||||
{ return false }
|
||||
|
||||
// swap pivot line
|
||||
if n0 != k
|
||||
|
@ -220,6 +222,8 @@ Inv for DMat<N>
|
|||
}
|
||||
|
||||
*self = res;
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ mod mat_impl;
|
|||
pub struct Mat1<N>
|
||||
{ mij: [N, ..1 * 1] }
|
||||
|
||||
clone_impl!(Mat1)
|
||||
mat_impl!(Mat1, 1)
|
||||
one_impl!(Mat1, [ _1 ])
|
||||
zero_impl!(Mat1, [ _0 ])
|
||||
|
@ -43,6 +44,7 @@ column_impl!(Mat1, 1)
|
|||
pub struct Mat2<N>
|
||||
{ mij: [N, ..2 * 2] }
|
||||
|
||||
clone_impl!(Mat2)
|
||||
mat_impl!(Mat2, 2)
|
||||
one_impl!(Mat2, [ _1 | _0 |
|
||||
_0 | _1 ])
|
||||
|
@ -67,6 +69,7 @@ column_impl!(Mat2, 2)
|
|||
pub struct Mat3<N>
|
||||
{ mij: [N, ..3 * 3] }
|
||||
|
||||
clone_impl!(Mat3)
|
||||
mat_impl!(Mat3, 3)
|
||||
one_impl!(Mat3, [ _1 | _0 | _0 |
|
||||
_0 | _1 | _0 |
|
||||
|
@ -94,6 +97,7 @@ column_impl!(Mat3, 3)
|
|||
pub struct Mat4<N>
|
||||
{ mij: [N, ..4 * 4] }
|
||||
|
||||
clone_impl!(Mat4)
|
||||
mat_impl!(Mat4, 4)
|
||||
one_impl!(Mat4, [
|
||||
_1 | _0 | _0 | _0 |
|
||||
|
@ -130,6 +134,7 @@ column_impl!(Mat4, 4)
|
|||
pub struct Mat5<N>
|
||||
{ mij: [N, ..5 * 5] }
|
||||
|
||||
clone_impl!(Mat5)
|
||||
mat_impl!(Mat5, 5)
|
||||
one_impl!(Mat5, [
|
||||
_1 | _0 | _0 | _0 | _0 |
|
||||
|
@ -169,6 +174,7 @@ column_impl!(Mat5, 5)
|
|||
pub struct Mat6<N>
|
||||
{ mij: [N, ..6 * 6] }
|
||||
|
||||
clone_impl!(Mat6)
|
||||
mat_impl!(Mat6, 6)
|
||||
one_impl!(Mat6, [
|
||||
_1 | _0 | _0 | _0 | _0 | _0 |
|
||||
|
|
|
@ -1,5 +1,22 @@
|
|||
#[macro_escape];
|
||||
|
||||
macro_rules! clone_impl(
|
||||
// FIXME: use 'Clone' alone. For the moment, we need 'Copy' because the automatic
|
||||
// implementation of Clone for [t, ..n] is badly typed.
|
||||
($t: ident) => (
|
||||
impl<N: Clone + Copy> Clone for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn clone(&self) -> $t<N>
|
||||
{
|
||||
$t {
|
||||
mij: copy self.mij
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! mat_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N> $t<N>
|
||||
|
@ -17,13 +34,13 @@ macro_rules! mat_impl(
|
|||
|
||||
macro_rules! one_impl(
|
||||
($t: ident, [ $($value: ident)|+ ] ) => (
|
||||
impl<N: Copy + One + Zero> One for $t<N>
|
||||
impl<N: Clone + One + Zero> One for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn one() -> $t<N>
|
||||
{
|
||||
let (_0, _1) = (Zero::zero::<N>(), One::one::<N>());
|
||||
return $t::new( [ $( copy $value, )+ ] )
|
||||
return $t::new( [ $( $value.clone(), )+ ] )
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -31,13 +48,13 @@ macro_rules! one_impl(
|
|||
|
||||
macro_rules! zero_impl(
|
||||
($t: ident, [ $($value: ident)|+ ] ) => (
|
||||
impl<N: Copy + Zero> Zero for $t<N>
|
||||
impl<N: Clone + Zero> Zero for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn zero() -> $t<N>
|
||||
{
|
||||
let _0 = Zero::zero();
|
||||
return $t::new( [ $( copy $value, )+ ] )
|
||||
let _0 = Zero::zero::<N>();
|
||||
return $t::new( [ $( $value.clone(), )+ ] )
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -60,11 +77,11 @@ macro_rules! dim_impl(
|
|||
|
||||
macro_rules! mat_indexable_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Copy> Indexable<(uint, uint), N> for $t<N>
|
||||
impl<N: Clone> Indexable<(uint, uint), N> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
pub fn at(&self, (i, j): (uint, uint)) -> N
|
||||
{ copy self.mij[self.offset(i, j)] }
|
||||
{ self.mij[self.offset(i, j)].clone() }
|
||||
|
||||
#[inline]
|
||||
pub fn set(&mut self, (i, j): (uint, uint), t: N)
|
||||
|
@ -75,7 +92,7 @@ macro_rules! mat_indexable_impl(
|
|||
|
||||
macro_rules! column_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Copy, 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)
|
||||
{
|
||||
|
@ -84,7 +101,7 @@ macro_rules! column_impl(
|
|||
if i == Dim::dim::<$t<N>>()
|
||||
{ break }
|
||||
|
||||
self.set((i, col), copy *e);
|
||||
self.set((i, col), e.clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +125,7 @@ macro_rules! column_impl(
|
|||
|
||||
macro_rules! mul_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Copy + Ring>
|
||||
impl<N: Clone + Ring>
|
||||
Mul<$t<N>, $t<N>> for $t<N>
|
||||
{
|
||||
fn mul(&self, other: &$t<N>) -> $t<N>
|
||||
|
@ -136,7 +153,7 @@ macro_rules! mul_impl(
|
|||
|
||||
macro_rules! rmul_impl(
|
||||
($t: ident, $v: ident, $dim: expr) => (
|
||||
impl<N: Copy + Ring>
|
||||
impl<N: Clone + Ring>
|
||||
RMul<$v<N>> for $t<N>
|
||||
{
|
||||
fn rmul(&self, other: &$v<N>) -> $v<N>
|
||||
|
@ -157,7 +174,7 @@ macro_rules! rmul_impl(
|
|||
|
||||
macro_rules! lmul_impl(
|
||||
($t: ident, $v: ident, $dim: expr) => (
|
||||
impl<N: Copy + Ring>
|
||||
impl<N: Clone + Ring>
|
||||
LMul<$v<N>> for $t<N>
|
||||
{
|
||||
fn lmul(&self, other: &$v<N>) -> $v<N>
|
||||
|
@ -179,7 +196,7 @@ macro_rules! lmul_impl(
|
|||
|
||||
macro_rules! transform_impl(
|
||||
($t: ident, $v: ident) => (
|
||||
impl<N: Copy + DivisionRing + Eq>
|
||||
impl<N: Clone + Copy + DivisionRing + Eq>
|
||||
Transform<$v<N>> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
|
@ -188,27 +205,34 @@ macro_rules! transform_impl(
|
|||
|
||||
#[inline]
|
||||
fn inv_transform(&self, v: &$v<N>) -> $v<N>
|
||||
{ self.inverse().transform_vec(v) }
|
||||
{
|
||||
match self.inverse()
|
||||
{
|
||||
Some(t) => t.transform_vec(v),
|
||||
None => fail!("Cannot use inv_transform on a non-inversible matrix.")
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! inv_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Copy + Eq + DivisionRing>
|
||||
impl<N: Clone + Copy + Eq + DivisionRing>
|
||||
Inv for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn inverse(&self) -> $t<N>
|
||||
fn inverse(&self) -> Option<$t<N>>
|
||||
{
|
||||
let mut res : $t<N> = copy *self;
|
||||
let mut res : $t<N> = self.clone();
|
||||
|
||||
res.invert();
|
||||
|
||||
res
|
||||
if res.invert()
|
||||
{ Some(res) }
|
||||
else
|
||||
{ None }
|
||||
}
|
||||
|
||||
fn invert(&mut self)
|
||||
fn invert(&mut self) -> bool
|
||||
{
|
||||
let mut res: $t<N> = One::one();
|
||||
let _0N: N = Zero::zero();
|
||||
|
@ -230,6 +254,9 @@ macro_rules! inv_impl(
|
|||
n0 = n0 + 1;
|
||||
}
|
||||
|
||||
if n0 == $dim
|
||||
{ return false }
|
||||
|
||||
// swap pivot line
|
||||
if n0 != k
|
||||
{
|
||||
|
@ -279,6 +306,8 @@ macro_rules! inv_impl(
|
|||
}
|
||||
|
||||
*self = res;
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -286,12 +315,12 @@ macro_rules! inv_impl(
|
|||
|
||||
macro_rules! transpose_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Copy> Transpose for $t<N>
|
||||
impl<N: Clone + Copy> Transpose for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn transposed(&self) -> $t<N>
|
||||
{
|
||||
let mut res = copy *self;
|
||||
let mut res = self.clone();
|
||||
|
||||
res.transpose();
|
||||
|
||||
|
@ -355,7 +384,7 @@ macro_rules! rand_impl(
|
|||
|
||||
macro_rules! to_homogeneous_impl(
|
||||
($t: ident, $t2: ident, $dim: expr) => (
|
||||
impl<N: One + Zero + Copy> ToHomogeneous<$t2<N>> for $t<N>
|
||||
impl<N: One + Zero + Clone> ToHomogeneous<$t2<N>> for $t<N>
|
||||
{
|
||||
fn to_homogeneous(&self) -> $t2<N>
|
||||
{
|
||||
|
@ -375,7 +404,7 @@ macro_rules! to_homogeneous_impl(
|
|||
|
||||
macro_rules! from_homogeneous_impl(
|
||||
($t: ident, $t2: ident, $dim2: expr) => (
|
||||
impl<N: One + Zero + Copy> FromHomogeneous<$t2<N>> for $t<N>
|
||||
impl<N: One + Zero + Clone> FromHomogeneous<$t2<N>> for $t<N>
|
||||
{
|
||||
fn from_homogeneous(m: &$t2<N>) -> $t<N>
|
||||
{
|
||||
|
|
|
@ -8,21 +8,26 @@ impl<N: Copy + DivisionRing>
|
|||
Inv for Mat1<N>
|
||||
{
|
||||
#[inline]
|
||||
fn inverse(&self) -> Mat1<N>
|
||||
fn inverse(&self) -> Option<Mat1<N>>
|
||||
{
|
||||
let mut res : Mat1<N> = copy *self;
|
||||
|
||||
res.invert();
|
||||
|
||||
res
|
||||
if res.invert()
|
||||
{ Some(res) }
|
||||
else
|
||||
{ None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn invert(&mut self)
|
||||
fn invert(&mut self) -> bool
|
||||
{
|
||||
assert!(!self.mij[0].is_zero());
|
||||
|
||||
self.mij[0] = One::one::<N>() / self.mij[0]
|
||||
if self.mij[0].is_zero()
|
||||
{ false }
|
||||
else
|
||||
{
|
||||
self.mij[0] = One::one::<N>() / self.mij[0];
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,24 +35,30 @@ impl<N: Copy + DivisionRing>
|
|||
Inv for Mat2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn inverse(&self) -> Mat2<N>
|
||||
fn inverse(&self) -> Option<Mat2<N>>
|
||||
{
|
||||
let mut res : Mat2<N> = copy *self;
|
||||
|
||||
res.invert();
|
||||
|
||||
res
|
||||
if res.invert()
|
||||
{ Some(res) }
|
||||
else
|
||||
{ None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn invert(&mut self)
|
||||
fn invert(&mut self) -> bool
|
||||
{
|
||||
let det = self.mij[0 * 2 + 0] * self.mij[1 * 2 + 1] - self.mij[1 * 2 + 0] * self.mij[0 * 2 + 1];
|
||||
|
||||
assert!(!det.is_zero());
|
||||
|
||||
if det.is_zero()
|
||||
{ false }
|
||||
else
|
||||
{
|
||||
*self = Mat2::new([self.mij[1 * 2 + 1] / det , -self.mij[0 * 2 + 1] / det,
|
||||
-self.mij[1 * 2 + 0] / det, self.mij[0 * 2 + 0] / det])
|
||||
-self.mij[1 * 2 + 0] / det, self.mij[0 * 2 + 0] / det]);
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,17 +66,18 @@ impl<N: Copy + DivisionRing>
|
|||
Inv for Mat3<N>
|
||||
{
|
||||
#[inline]
|
||||
fn inverse(&self) -> Mat3<N>
|
||||
fn inverse(&self) -> Option<Mat3<N>>
|
||||
{
|
||||
let mut res = copy *self;
|
||||
|
||||
res.invert();
|
||||
|
||||
res
|
||||
if res.invert()
|
||||
{ Some(res) }
|
||||
else
|
||||
{ None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn invert(&mut self)
|
||||
fn invert(&mut self) -> bool
|
||||
{
|
||||
let minor_m12_m23 = self.mij[1 * 3 + 1] * self.mij[2 * 3 + 2] - self.mij[2 * 3 + 1] * self.mij[1 * 3 + 2];
|
||||
let minor_m11_m23 = self.mij[1 * 3 + 0] * self.mij[2 * 3 + 2] - self.mij[2 * 3 + 0] * self.mij[1 * 3 + 2];
|
||||
|
@ -75,8 +87,10 @@ Inv for Mat3<N>
|
|||
- self.mij[0 * 3 + 1] * minor_m11_m23
|
||||
+ self.mij[0 * 3 + 2] * minor_m11_m22;
|
||||
|
||||
assert!(!det.is_zero());
|
||||
|
||||
if det.is_zero()
|
||||
{ false }
|
||||
else
|
||||
{
|
||||
*self = Mat3::new( [
|
||||
(minor_m12_m23 / det),
|
||||
((self.mij[0 * 3 + 2] * self.mij[2 * 3 + 1] - self.mij[2 * 3 + 2] * self.mij[0 * 3 + 1]) / det),
|
||||
|
@ -89,6 +103,9 @@ Inv for Mat3<N>
|
|||
(minor_m11_m22 / det),
|
||||
((self.mij[0 * 3 + 1] * self.mij[2 * 3 + 0] - self.mij[2 * 3 + 1] * self.mij[0 * 3 + 0]) / det),
|
||||
((self.mij[0 * 3 + 0] * self.mij[1 * 3 + 1] - self.mij[1 * 3 + 0] * self.mij[0 * 3 + 1]) / det)
|
||||
] )
|
||||
] );
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ pub mod adaptors
|
|||
/// Useful linear-algebra related traits.
|
||||
pub mod traits
|
||||
{
|
||||
pub mod sample;
|
||||
pub mod indexable;
|
||||
pub mod column;
|
||||
pub mod iterable;
|
||||
|
|
|
@ -25,7 +25,7 @@ macro_rules! test_inv_mat_impl(
|
|||
{
|
||||
let randmat : $t = random();
|
||||
|
||||
assert!((randmat.inverse() * randmat).approx_eq(&One::one()));
|
||||
assert!((randmat.inverse().unwrap() * randmat).approx_eq(&One::one()));
|
||||
}
|
||||
);
|
||||
)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
pub trait Inv
|
||||
{
|
||||
/// Returns the inverse of an element.
|
||||
fn inverse(&self) -> Self;
|
||||
fn inverse(&self) -> Option<Self>;
|
||||
/// Inplace version of `inverse`.
|
||||
fn invert(&mut self);
|
||||
fn invert(&mut self) -> bool;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
pub trait UniformSphereSample
|
||||
{
|
||||
pub fn sample(&fn(&'static Self));
|
||||
}
|
|
@ -24,6 +24,7 @@ mod vec_impl;
|
|||
pub struct Vec1<N>
|
||||
{ at: [N, ..1] }
|
||||
|
||||
clone_impl!(Vec1)
|
||||
new_impl!(Vec1, 1)
|
||||
new_repeat_impl!(Vec1, elem, [elem])
|
||||
indexable_impl!(Vec1)
|
||||
|
@ -58,6 +59,7 @@ from_homogeneous_impl!(Vec2, Vec1, 2)
|
|||
pub struct Vec2<N>
|
||||
{ at: [N, ..2] }
|
||||
|
||||
clone_impl!(Vec2)
|
||||
new_impl!(Vec2, 2)
|
||||
new_repeat_impl!(Vec2, elem, [elem | elem])
|
||||
indexable_impl!(Vec2)
|
||||
|
@ -92,6 +94,7 @@ from_homogeneous_impl!(Vec3, Vec2, 3)
|
|||
pub struct Vec3<N>
|
||||
{ at: [N, ..3] }
|
||||
|
||||
clone_impl!(Vec3)
|
||||
new_impl!(Vec3, 3)
|
||||
new_repeat_impl!(Vec3, elem, [elem | elem | elem])
|
||||
indexable_impl!(Vec3)
|
||||
|
@ -126,6 +129,7 @@ from_homogeneous_impl!(Vec4, Vec3, 4)
|
|||
pub struct Vec4<N>
|
||||
{ at: [N, ..4] }
|
||||
|
||||
clone_impl!(Vec4)
|
||||
new_impl!(Vec4, 4)
|
||||
new_repeat_impl!(Vec4, elem, [elem | elem | elem | elem])
|
||||
indexable_impl!(Vec4)
|
||||
|
@ -160,6 +164,7 @@ from_homogeneous_impl!(Vec5, Vec4, 5)
|
|||
pub struct Vec5<N>
|
||||
{ at: [N, ..5] }
|
||||
|
||||
clone_impl!(Vec5)
|
||||
new_impl!(Vec5, 5)
|
||||
new_repeat_impl!(Vec5, elem, [elem | elem | elem | elem | elem])
|
||||
indexable_impl!(Vec5)
|
||||
|
@ -194,6 +199,7 @@ from_homogeneous_impl!(Vec6, Vec5, 6)
|
|||
pub struct Vec6<N>
|
||||
{ at: [N, ..6] }
|
||||
|
||||
clone_impl!(Vec6)
|
||||
new_impl!(Vec6, 6)
|
||||
new_repeat_impl!(Vec6, elem, [elem | elem | elem | elem | elem | elem])
|
||||
indexable_impl!(Vec6)
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
#[macro_escape];
|
||||
|
||||
macro_rules! clone_impl(
|
||||
($t:ident) => (
|
||||
// FIXME: use 'Clone' alone. For the moment, we need 'Copy' because the automatic
|
||||
// implementation of Clone for [t, ..n] is badly typed.
|
||||
impl<N: Clone + Copy> Clone for $t<N>
|
||||
{
|
||||
fn clone(&self) -> $t<N>
|
||||
{
|
||||
$t { at: copy self.at }
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! new_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N> $t<N>
|
||||
|
@ -13,11 +27,11 @@ macro_rules! new_impl(
|
|||
|
||||
macro_rules! indexable_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Copy> Indexable<uint, N> for $t<N>
|
||||
impl<N: Clone> Indexable<uint, N> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
pub fn at(&self, i: uint) -> N
|
||||
{ copy self.at[i] }
|
||||
{ self.at[i].clone() }
|
||||
|
||||
#[inline]
|
||||
pub fn set(&mut self, i: uint, val: N)
|
||||
|
@ -28,11 +42,11 @@ macro_rules! indexable_impl(
|
|||
|
||||
macro_rules! new_repeat_impl(
|
||||
($t: ident, $param: ident, [ $($elem: ident)|+ ]) => (
|
||||
impl<N: Copy> $t<N>
|
||||
impl<N: Clone> $t<N>
|
||||
{
|
||||
#[inline]
|
||||
pub fn new_repeat($param: N) -> $t<N>
|
||||
{ $t{ at: [ $( copy $elem, )+ ] } }
|
||||
{ $t{ at: [ $( $elem.clone(), )+ ] } }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
@ -86,7 +100,7 @@ macro_rules! dim_impl(
|
|||
// FIXME: add the possibility to specialize that
|
||||
macro_rules! basis_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Copy + DivisionRing + Algebraic + ApproxEq<N>> Basis for $t<N>
|
||||
impl<N: Clone + Copy + DivisionRing + Algebraic + ApproxEq<N>> Basis for $t<N>
|
||||
{
|
||||
pub fn canonical_basis(f: &fn($t<N>))
|
||||
{
|
||||
|
@ -115,7 +129,7 @@ macro_rules! basis_impl(
|
|||
if basis.len() == $dim - 1
|
||||
{ break; }
|
||||
|
||||
let mut elt = copy basis_element;
|
||||
let mut elt = basis_element.clone();
|
||||
|
||||
elt = elt - self.scalar_mul(&basis_element.dot(self));
|
||||
|
||||
|
@ -126,7 +140,7 @@ macro_rules! basis_impl(
|
|||
{
|
||||
let new_element = elt.normalized();
|
||||
|
||||
f(copy new_element);
|
||||
f(new_element.clone());
|
||||
|
||||
basis.push(new_element);
|
||||
}
|
||||
|
@ -138,7 +152,7 @@ macro_rules! basis_impl(
|
|||
|
||||
macro_rules! add_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Copy + Add<N,N>> Add<$t<N>, $t<N>> for $t<N>
|
||||
impl<N: Clone + Add<N,N>> Add<$t<N>, $t<N>> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn add(&self, other: &$t<N>) -> $t<N>
|
||||
|
@ -154,7 +168,7 @@ macro_rules! add_impl(
|
|||
|
||||
macro_rules! sub_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Copy + Sub<N,N>> Sub<$t<N>, $t<N>> for $t<N>
|
||||
impl<N: Clone + Sub<N,N>> Sub<$t<N>, $t<N>> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn sub(&self, other: &$t<N>) -> $t<N>
|
||||
|
@ -290,11 +304,11 @@ macro_rules! scalar_sub_impl(
|
|||
|
||||
macro_rules! translation_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Copy + Add<N, N> + Neg<N>> Translation<$t<N>> for $t<N>
|
||||
impl<N: Clone + Copy + Add<N, N> + Neg<N>> Translation<$t<N>> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn translation(&self) -> $t<N>
|
||||
{ copy *self }
|
||||
{ self.clone() }
|
||||
|
||||
#[inline]
|
||||
fn inv_translation(&self) -> $t<N>
|
||||
|
@ -309,7 +323,7 @@ macro_rules! translation_impl(
|
|||
|
||||
macro_rules! translatable_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Add<N, N> + Neg<N> + Copy> Translatable<$t<N>, $t<N>> for $t<N>
|
||||
impl<N: Add<N, N> + Neg<N> + Clone> Translatable<$t<N>, $t<N>> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn translated(&self, t: &$t<N>) -> $t<N>
|
||||
|
@ -320,7 +334,7 @@ macro_rules! translatable_impl(
|
|||
|
||||
macro_rules! norm_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Copy + DivisionRing + Algebraic> Norm<N> for $t<N>
|
||||
impl<N: Clone + Copy + DivisionRing + Algebraic> Norm<N> for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn sqnorm(&self) -> N
|
||||
|
@ -333,7 +347,7 @@ macro_rules! norm_impl(
|
|||
#[inline]
|
||||
fn normalized(&self) -> $t<N>
|
||||
{
|
||||
let mut res : $t<N> = copy *self;
|
||||
let mut res : $t<N> = self.clone();
|
||||
|
||||
res.normalize();
|
||||
|
||||
|
@ -383,7 +397,7 @@ macro_rules! approx_eq_impl(
|
|||
|
||||
macro_rules! zero_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Copy + Zero> Zero for $t<N>
|
||||
impl<N: Clone + Zero> Zero for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn zero() -> $t<N>
|
||||
|
@ -398,7 +412,7 @@ macro_rules! zero_impl(
|
|||
|
||||
macro_rules! one_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Copy + One> One for $t<N>
|
||||
impl<N: Clone + One> One for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn one() -> $t<N>
|
||||
|
@ -420,13 +434,13 @@ macro_rules! rand_impl(
|
|||
|
||||
macro_rules! from_any_iterator_impl(
|
||||
($t: ident, $param: ident, [ $($elem: ident)|+ ]) => (
|
||||
impl<N: Copy> FromAnyIterator<N> for $t<N>
|
||||
impl<N: Clone> FromAnyIterator<N> for $t<N>
|
||||
{
|
||||
fn from_iterator<'l>($param: &mut VecIterator<'l, N>) -> $t<N>
|
||||
{ $t { at: [ $( copy *$elem.next().unwrap(), )+ ] } }
|
||||
{ $t { at: [ $( $elem.next().unwrap().clone(), )+ ] } }
|
||||
|
||||
fn from_mut_iterator<'l>($param: &mut VecMutIterator<'l, N>) -> $t<N>
|
||||
{ $t { at: [ $( copy *$elem.next().unwrap(), )+ ] } }
|
||||
{ $t { at: [ $( $elem.next().unwrap().clone(), )+ ] } }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
@ -443,7 +457,7 @@ macro_rules! from_iterator_impl(
|
|||
|
||||
macro_rules! bounded_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Bounded + Copy> Bounded for $t<N>
|
||||
impl<N: Bounded + Clone> Bounded for $t<N>
|
||||
{
|
||||
#[inline]
|
||||
fn max_value() -> $t<N>
|
||||
|
@ -459,14 +473,14 @@ macro_rules! bounded_impl(
|
|||
macro_rules! to_homogeneous_impl(
|
||||
($t: ident, $t2: ident) =>
|
||||
{
|
||||
impl<N: Copy + One> ToHomogeneous<$t2<N>> for $t<N>
|
||||
impl<N: Clone + One> ToHomogeneous<$t2<N>> for $t<N>
|
||||
{
|
||||
fn to_homogeneous(&self) -> $t2<N>
|
||||
{
|
||||
let mut res: $t2<N> = One::one();
|
||||
|
||||
for self.iter().zip(res.mut_iter()).advance |(in, out)|
|
||||
{ *out = copy *in }
|
||||
{ *out = in.clone() }
|
||||
|
||||
res
|
||||
}
|
||||
|
@ -477,14 +491,14 @@ macro_rules! to_homogeneous_impl(
|
|||
macro_rules! from_homogeneous_impl(
|
||||
($t: ident, $t2: ident, $dim2: expr) =>
|
||||
{
|
||||
impl<N: Copy + 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_homogeneous(v: &$t2<N>) -> $t<N>
|
||||
{
|
||||
let mut res: $t<N> = Zero::zero();
|
||||
|
||||
for v.iter().zip(res.mut_iter()).advance |(in, out)|
|
||||
{ *out = copy *in }
|
||||
{ *out = in.clone() }
|
||||
|
||||
res.scalar_div(&v.at[$dim2 - 1]);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ use traits::basis::Basis;
|
|||
use traits::cross::Cross;
|
||||
use traits::division_ring::DivisionRing;
|
||||
use traits::norm::Norm;
|
||||
use traits::sample::UniformSphereSample;
|
||||
use vec::{Vec1, Vec2, Vec3};
|
||||
|
||||
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec1<N>> for Vec2<N>
|
||||
|
@ -36,7 +37,7 @@ impl<N: One> Basis for Vec1<N>
|
|||
{ }
|
||||
}
|
||||
|
||||
impl<N: Copy + One + Zero + Neg<N>> Basis for Vec2<N>
|
||||
impl<N: Clone + One + Zero + Neg<N>> Basis for Vec2<N>
|
||||
{
|
||||
#[inline]
|
||||
fn canonical_basis(f: &fn(Vec2<N>))
|
||||
|
@ -47,10 +48,10 @@ impl<N: Copy + One + Zero + Neg<N>> Basis for Vec2<N>
|
|||
|
||||
#[inline]
|
||||
fn orthonormal_subspace_basis(&self, f: &fn(Vec2<N>))
|
||||
{ f(Vec2::new([-self.at[1], copy self.at[0]])) }
|
||||
{ f(Vec2::new([-self.at[1], self.at[0].clone()])) }
|
||||
}
|
||||
|
||||
impl<N: Copy + DivisionRing + Ord + Algebraic>
|
||||
impl<N: Clone + Copy + DivisionRing + Ord + Algebraic>
|
||||
Basis for Vec3<N>
|
||||
{
|
||||
#[inline(always)]
|
||||
|
@ -65,12 +66,46 @@ Basis for Vec3<N>
|
|||
fn orthonormal_subspace_basis(&self, f: &fn(Vec3<N>))
|
||||
{
|
||||
let a =
|
||||
if abs(copy self.at[0]) > abs(copy self.at[1])
|
||||
{ Vec3::new([copy self.at[2], Zero::zero(), -copy self.at[0]]).normalized() }
|
||||
if abs(self.at[0].clone()) > abs(self.at[1].clone())
|
||||
{ Vec3::new([self.at[2].clone(), Zero::zero(), -self.at[0]]).normalized() }
|
||||
else
|
||||
{ Vec3::new([Zero::zero(), -self.at[2], copy self.at[1]]).normalized() };
|
||||
{ Vec3::new([Zero::zero(), -self.at[2], self.at[1].clone()]).normalized() };
|
||||
|
||||
f(a.cross(self));
|
||||
f(a);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: this bad: this fixes definitly the number of samples…
|
||||
static SAMPLES_2_F64: [Vec2<f64>, ..21] = [
|
||||
Vec2 { at: [1.0, 0.0] },
|
||||
Vec2 { at: [0.95557281, 0.29475517] },
|
||||
Vec2 { at: [0.82623877, 0.56332006] },
|
||||
Vec2 { at: [0.6234898, 0.78183148] },
|
||||
Vec2 { at: [0.36534102, 0.93087375] },
|
||||
Vec2 { at: [0.07473009, 0.9972038] },
|
||||
Vec2 { at: [-0.22252093, 0.97492791] },
|
||||
Vec2 { at: [-0.5, 0.8660254] },
|
||||
Vec2 { at: [-0.73305187, 0.68017274] },
|
||||
Vec2 { at: [-0.90096887, 0.43388374] },
|
||||
Vec2 { at: [-0.98883083, 0.14904227] },
|
||||
Vec2 { at: [-0.98883083, -0.14904227] },
|
||||
Vec2 { at: [-0.90096887, -0.43388374] },
|
||||
Vec2 { at: [-0.73305187, -0.68017274] },
|
||||
Vec2 { at: [-0.5, -0.8660254] },
|
||||
Vec2 { at: [-0.22252093, -0.97492791] },
|
||||
Vec2 { at: [0.07473009, -0.9972038] },
|
||||
Vec2 { at: [0.36534102, -0.93087375] },
|
||||
Vec2 { at: [0.6234898, -0.78183148] },
|
||||
Vec2 { at: [0.82623877, -0.56332006] },
|
||||
Vec2 { at: [0.95557281, -0.29475517] },
|
||||
];
|
||||
|
||||
impl UniformSphereSample for Vec2<f64>
|
||||
{
|
||||
pub fn sample(f: &fn(&'static Vec2<f64>))
|
||||
{
|
||||
for SAMPLES_2_F64.iter().advance |sample|
|
||||
{ f(sample) }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue