Add sphere sempling trait + Copy becomes Clone

This commit is contained in:
Sébastien Crozet 2013-07-04 14:23:08 +00:00
parent 51fd2bc744
commit 6f081b70b8
13 changed files with 268 additions and 137 deletions

View File

@ -19,40 +19,38 @@ 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()
{ One::one() }
else
{
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 sqx = ux * ux;
let sqy = uy * uy;
let sqz = uz * uz;
let cos = angle.cos();
let one_m_cos = _1 - cos;
let sin = angle.sin();
let mut axis = axisangle;
let angle = axis.normalize();
let _1 = One::one::<N>();
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 (sin, cos) = angle.sin_cos();
let one_m_cos = _1 - cos;
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>

View File

@ -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
{
self.submat.invert();
self.subtrans = self.submat.rmul(&-self.subtrans);
if !self.submat.invert()
{ false }
else
{
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 }
}
}

View File

@ -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
}
}

View File

@ -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 |

View File

@ -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>
{

View File

@ -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 = 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])
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,20 +87,25 @@ 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),
((self.mij[0 * 3 + 1] * self.mij[1 * 3 + 2] - self.mij[1 * 3 + 1] * self.mij[0 * 3 + 2]) / det),
*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),
((self.mij[0 * 3 + 1] * self.mij[1 * 3 + 2] - self.mij[1 * 3 + 1] * self.mij[0 * 3 + 2]) / det),
(-minor_m11_m23 / det),
((self.mij[0 * 3 + 0] * self.mij[2 * 3 + 2] - self.mij[2 * 3 + 0] * self.mij[0 * 3 + 2]) / det),
((self.mij[0 * 3 + 2] * self.mij[1 * 3 + 0] - self.mij[1 * 3 + 2] * self.mij[0 * 3 + 0]) / det),
(-minor_m11_m23 / det),
((self.mij[0 * 3 + 0] * self.mij[2 * 3 + 2] - self.mij[2 * 3 + 0] * self.mij[0 * 3 + 2]) / det),
((self.mij[0 * 3 + 2] * self.mij[1 * 3 + 0] - self.mij[1 * 3 + 2] * self.mij[0 * 3 + 0]) / det),
(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)
] );
(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
}
}
}

View File

@ -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;

View File

@ -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()));
}
);
)

View File

@ -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;
}

4
src/traits/sample.rs Normal file
View File

@ -0,0 +1,4 @@
pub trait UniformSphereSample
{
pub fn sample(&fn(&'static Self));
}

View File

@ -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)

View File

@ -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]);

View File

@ -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) }
}
}