diff --git a/src/adaptors/rotmat.rs b/src/adaptors/rotmat.rs index 0c033ddd..540cf78c 100644 --- a/src/adaptors/rotmat.rs +++ b/src/adaptors/rotmat.rs @@ -19,40 +19,38 @@ use vec::Vec3; pub struct Rotmat { priv submat: M } -impl Rotmat +impl Rotmat { pub fn submat(&self) -> M - { copy self.submat } + { self.submat.clone() } } -pub fn rotmat2>(angle: N) -> Rotmat> +pub fn rotmat2>(angle: N) -> Rotmat> { - 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 +pub fn rotmat3 (axisangle: Vec3) -> Rotmat> { if axisangle.sqnorm().is_zero() { One::one() } else { - let mut axis = axisangle; - let angle = axis.normalize(); - let _1 = One::one::(); - 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::(); + 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 } } -impl +impl Rotation> for Rotmat> { #[inline] fn rotation(&self) -> Vec1 - { 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 @@ -87,15 +85,15 @@ Rotation> for Rotmat> { *self = self.rotated(rot) } } -impl +impl Rotatable, Rotmat>> for Rotmat> { #[inline] fn rotated(&self, rot: &Vec1) -> Rotmat> - { rotmat2(copy rot.at[0]) * *self } + { rotmat2(rot.at[0].clone()) * *self } } -impl +impl Rotation> for Rotmat> { #[inline] @@ -112,15 +110,15 @@ Rotation> for Rotmat> { *self = self.rotated(rot) } } -impl +impl Rotatable, Rotmat>> for Rotmat> { #[inline] fn rotated(&self, axisangle: &Vec3) -> Rotmat> - { rotmat3(copy *axisangle) * *self } + { rotmat3(axisangle.clone()) * *self } } -impl> Rand for Rotmat> +impl> Rand for Rotmat> { #[inline] fn rand(rng: &mut R) -> Rotmat> @@ -149,7 +147,7 @@ impl + LMul, V> Transform for Rotmat { self.inv_rotate(v) } } -impl +impl Rand for Rotmat> { #[inline] @@ -195,12 +193,16 @@ impl> LMul for Rotmat impl Inv for Rotmat { #[inline] - fn invert(&mut self) - { self.transpose() } + fn invert(&mut self) -> bool + { + self.transpose(); + + true + } #[inline] - fn inverse(&self) -> Rotmat - { self.transposed() } + fn inverse(&self) -> Option> + { Some(self.transposed()) } } impl diff --git a/src/adaptors/transform.rs b/src/adaptors/transform.rs index 01564d3a..d3fd3857 100644 --- a/src/adaptors/transform.rs +++ b/src/adaptors/transform.rs @@ -179,7 +179,14 @@ Transformation> for Transform { copy *self } fn inv_transformation(&self) -> Transform - { self.inverse() } + { + // FIXME: fail or return a Some> ? + match self.inverse() + { + Some(t) => t, + None => fail!("This transformation was not inversible.") + } + } fn transform_by(&mut self, other: &Transform) { *self = other * *self; } @@ -211,20 +218,26 @@ impl, V: Copy + Neg> Inv for Transform { #[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 + fn inverse(&self) -> Option> { let mut res = copy *self; - res.invert(); - - res + if res.invert() + { Some(res) } + else + { None } } } diff --git a/src/dmat.rs b/src/dmat.rs index db5d11a1..ebe7f2cf 100644 --- a/src/dmat.rs +++ b/src/dmat.rs @@ -137,16 +137,17 @@ impl Inv for DMat { #[inline] - fn inverse(&self) -> DMat + fn inverse(&self) -> Option> { let mut res : DMat = 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::(dim); @@ -169,7 +170,8 @@ Inv for DMat 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 } *self = res; + + true } } diff --git a/src/mat.rs b/src/mat.rs index 4fe5ef7d..2cf6b695 100644 --- a/src/mat.rs +++ b/src/mat.rs @@ -22,6 +22,7 @@ mod mat_impl; pub struct Mat1 { 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 { 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 { 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 { 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 { 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 { mij: [N, ..6 * 6] } +clone_impl!(Mat6) mat_impl!(Mat6, 6) one_impl!(Mat6, [ _1 | _0 | _0 | _0 | _0 | _0 | diff --git a/src/mat_impl.rs b/src/mat_impl.rs index 0b7ed0d6..6918f2cb 100644 --- a/src/mat_impl.rs +++ b/src/mat_impl.rs @@ -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 Clone for $t + { + #[inline] + fn clone(&self) -> $t + { + $t { + mij: copy self.mij + } + } + } + ) +) + macro_rules! mat_impl( ($t: ident, $dim: expr) => ( impl $t @@ -17,13 +34,13 @@ macro_rules! mat_impl( macro_rules! one_impl( ($t: ident, [ $($value: ident)|+ ] ) => ( - impl One for $t + impl One for $t { #[inline] fn one() -> $t { let (_0, _1) = (Zero::zero::(), One::one::()); - 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 Zero for $t + impl Zero for $t { #[inline] fn zero() -> $t { - let _0 = Zero::zero(); - return $t::new( [ $( copy $value, )+ ] ) + let _0 = Zero::zero::(); + return $t::new( [ $( $value.clone(), )+ ] ) } #[inline] @@ -60,11 +77,11 @@ macro_rules! dim_impl( macro_rules! mat_indexable_impl( ($t: ident, $dim: expr) => ( - impl Indexable<(uint, uint), N> for $t + impl Indexable<(uint, uint), N> for $t { #[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 + IterableMut> Column for $t + impl + IterableMut> Column for $t { fn set_column(&mut self, col: uint, v: V) { @@ -84,7 +101,7 @@ macro_rules! column_impl( if i == Dim::dim::<$t>() { 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 + impl Mul<$t, $t> for $t { fn mul(&self, other: &$t) -> $t @@ -136,7 +153,7 @@ macro_rules! mul_impl( macro_rules! rmul_impl( ($t: ident, $v: ident, $dim: expr) => ( - impl + impl RMul<$v> for $t { fn rmul(&self, other: &$v) -> $v @@ -157,7 +174,7 @@ macro_rules! rmul_impl( macro_rules! lmul_impl( ($t: ident, $v: ident, $dim: expr) => ( - impl + impl LMul<$v> for $t { fn lmul(&self, other: &$v) -> $v @@ -179,7 +196,7 @@ macro_rules! lmul_impl( macro_rules! transform_impl( ($t: ident, $v: ident) => ( - impl + impl Transform<$v> for $t { #[inline] @@ -188,27 +205,34 @@ macro_rules! transform_impl( #[inline] fn inv_transform(&self, v: &$v) -> $v - { 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 + impl Inv for $t { #[inline] - fn inverse(&self) -> $t + fn inverse(&self) -> Option<$t> { - let mut res : $t = copy *self; + let mut res : $t = 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 = One::one(); let _0N: N = Zero::zero(); @@ -229,6 +253,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 Transpose for $t + impl Transpose for $t { #[inline] fn transposed(&self) -> $t { - 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 ToHomogeneous<$t2> for $t + impl ToHomogeneous<$t2> for $t { fn to_homogeneous(&self) -> $t2 { @@ -375,7 +404,7 @@ macro_rules! to_homogeneous_impl( macro_rules! from_homogeneous_impl( ($t: ident, $t2: ident, $dim2: expr) => ( - impl FromHomogeneous<$t2> for $t + impl FromHomogeneous<$t2> for $t { fn from_homogeneous(m: &$t2) -> $t { diff --git a/src/mat_spec.rs b/src/mat_spec.rs index 3f2613c0..6f85f306 100644 --- a/src/mat_spec.rs +++ b/src/mat_spec.rs @@ -8,21 +8,26 @@ impl Inv for Mat1 { #[inline] - fn inverse(&self) -> Mat1 + fn inverse(&self) -> Option> { let mut res : Mat1 = 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::() / self.mij[0] + if self.mij[0].is_zero() + { false } + else + { + self.mij[0] = One::one::() / self.mij[0]; + true + } } } @@ -30,24 +35,30 @@ impl Inv for Mat2 { #[inline] - fn inverse(&self) -> Mat2 + fn inverse(&self) -> Option> { let mut res : Mat2 = 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 Inv for Mat3 { #[inline] - fn inverse(&self) -> Mat3 + fn inverse(&self) -> Option> { 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 - 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 + } } } diff --git a/src/nalgebra.rc b/src/nalgebra.rc index bd3e6129..078ee818 100644 --- a/src/nalgebra.rc +++ b/src/nalgebra.rc @@ -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; diff --git a/src/tests/mat.rs b/src/tests/mat.rs index d7ed2ea0..f7bff18d 100644 --- a/src/tests/mat.rs +++ b/src/tests/mat.rs @@ -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())); } ); ) diff --git a/src/traits/inv.rs b/src/traits/inv.rs index fc42bebe..932b2a1c 100644 --- a/src/traits/inv.rs +++ b/src/traits/inv.rs @@ -4,7 +4,7 @@ pub trait Inv { /// Returns the inverse of an element. - fn inverse(&self) -> Self; + fn inverse(&self) -> Option; /// Inplace version of `inverse`. - fn invert(&mut self); + fn invert(&mut self) -> bool; } diff --git a/src/traits/sample.rs b/src/traits/sample.rs new file mode 100644 index 00000000..a0ee726d --- /dev/null +++ b/src/traits/sample.rs @@ -0,0 +1,4 @@ +pub trait UniformSphereSample +{ + pub fn sample(&fn(&'static Self)); +} diff --git a/src/vec.rs b/src/vec.rs index 26881efb..3bb6d9ed 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -24,6 +24,7 @@ mod vec_impl; pub struct Vec1 { 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 { 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 { 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 { 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 { 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 { at: [N, ..6] } +clone_impl!(Vec6) new_impl!(Vec6, 6) new_repeat_impl!(Vec6, elem, [elem | elem | elem | elem | elem | elem]) indexable_impl!(Vec6) diff --git a/src/vec_impl.rs b/src/vec_impl.rs index 63716426..a2e99e7d 100644 --- a/src/vec_impl.rs +++ b/src/vec_impl.rs @@ -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 Clone for $t + { + fn clone(&self) -> $t + { + $t { at: copy self.at } + } + } + ) +) + macro_rules! new_impl( ($t: ident, $dim: expr) => ( impl $t @@ -13,11 +27,11 @@ macro_rules! new_impl( macro_rules! indexable_impl( ($t: ident) => ( - impl Indexable for $t + impl Indexable for $t { #[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 $t + impl $t { #[inline] pub fn new_repeat($param: N) -> $t - { $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> Basis for $t + impl> Basis for $t { pub fn canonical_basis(f: &fn($t)) { @@ -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> Add<$t, $t> for $t + impl> Add<$t, $t> for $t { #[inline] fn add(&self, other: &$t) -> $t @@ -154,7 +168,7 @@ macro_rules! add_impl( macro_rules! sub_impl( ($t: ident) => ( - impl> Sub<$t, $t> for $t + impl> Sub<$t, $t> for $t { #[inline] fn sub(&self, other: &$t) -> $t @@ -290,11 +304,11 @@ macro_rules! scalar_sub_impl( macro_rules! translation_impl( ($t: ident) => ( - impl + Neg> Translation<$t> for $t + impl + Neg> Translation<$t> for $t { #[inline] fn translation(&self) -> $t - { copy *self } + { self.clone() } #[inline] fn inv_translation(&self) -> $t @@ -309,7 +323,7 @@ macro_rules! translation_impl( macro_rules! translatable_impl( ($t: ident) => ( - impl + Neg + Copy> Translatable<$t, $t> for $t + impl + Neg + Clone> Translatable<$t, $t> for $t { #[inline] fn translated(&self, t: &$t) -> $t @@ -320,7 +334,7 @@ macro_rules! translatable_impl( macro_rules! norm_impl( ($t: ident, $dim: expr) => ( - impl Norm for $t + impl Norm for $t { #[inline] fn sqnorm(&self) -> N @@ -333,7 +347,7 @@ macro_rules! norm_impl( #[inline] fn normalized(&self) -> $t { - let mut res : $t = copy *self; + let mut res : $t = self.clone(); res.normalize(); @@ -383,7 +397,7 @@ macro_rules! approx_eq_impl( macro_rules! zero_impl( ($t: ident) => ( - impl Zero for $t + impl Zero for $t { #[inline] fn zero() -> $t @@ -398,7 +412,7 @@ macro_rules! zero_impl( macro_rules! one_impl( ($t: ident) => ( - impl One for $t + impl One for $t { #[inline] fn one() -> $t @@ -420,13 +434,13 @@ macro_rules! rand_impl( macro_rules! from_any_iterator_impl( ($t: ident, $param: ident, [ $($elem: ident)|+ ]) => ( - impl FromAnyIterator for $t + impl FromAnyIterator for $t { fn from_iterator<'l>($param: &mut VecIterator<'l, N>) -> $t - { $t { at: [ $( copy *$elem.next().unwrap(), )+ ] } } + { $t { at: [ $( $elem.next().unwrap().clone(), )+ ] } } fn from_mut_iterator<'l>($param: &mut VecMutIterator<'l, N>) -> $t - { $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 Bounded for $t + impl Bounded for $t { #[inline] fn max_value() -> $t @@ -459,14 +473,14 @@ macro_rules! bounded_impl( macro_rules! to_homogeneous_impl( ($t: ident, $t2: ident) => { - impl ToHomogeneous<$t2> for $t + impl ToHomogeneous<$t2> for $t { fn to_homogeneous(&self) -> $t2 { let mut res: $t2 = 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 + One + Zero> FromHomogeneous<$t2> for $t + impl + One + Zero> FromHomogeneous<$t2> for $t { fn from_homogeneous(v: &$t2) -> $t { let mut res: $t = 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]); diff --git a/src/vec_spec.rs b/src/vec_spec.rs index 164b5e4d..dabcc548 100644 --- a/src/vec_spec.rs +++ b/src/vec_spec.rs @@ -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 + Sub> Cross> for Vec2 @@ -36,7 +37,7 @@ impl Basis for Vec1 { } } -impl> Basis for Vec2 +impl> Basis for Vec2 { #[inline] fn canonical_basis(f: &fn(Vec2)) @@ -47,10 +48,10 @@ impl> Basis for Vec2 #[inline] fn orthonormal_subspace_basis(&self, f: &fn(Vec2)) - { f(Vec2::new([-self.at[1], copy self.at[0]])) } + { f(Vec2::new([-self.at[1], self.at[0].clone()])) } } -impl +impl Basis for Vec3 { #[inline(always)] @@ -65,12 +66,46 @@ Basis for Vec3 fn orthonormal_subspace_basis(&self, f: &fn(Vec3)) { 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, ..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 +{ + pub fn sample(f: &fn(&'static Vec2)) + { + for SAMPLES_2_F64.iter().advance |sample| + { f(sample) } + } +}