diff --git a/src/lib.rs b/src/lib.rs index 584ca7f6..9354f010 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -108,7 +108,7 @@ extern crate serialize; #[cfg(test)] extern crate test; -use std::num::{Zero, One, FloatMath}; +use std::num::{Zero, One}; use std::cmp; pub use traits::{PartialLess, PartialEqual, PartialGreater, NotComparable}; pub use traits::{ @@ -119,6 +119,7 @@ pub use traits::{ ApproxEq, Axpy, Basis, + BaseFloat, Cast, Col, ColSlice, RowSlice, @@ -357,7 +358,7 @@ pub fn orig() -> P { /// Returns the center of two points. #[inline] -pub fn center, V>(a: &P, b: &P) -> P { +pub fn center, V>(a: &P, b: &P) -> P { let _2 = one::() + one(); (*a + *b.as_vec()) / _2 } @@ -367,13 +368,13 @@ pub fn center, V>(a: &P, b: &P) -> P { */ /// Returns the distance between two points. #[inline(always)] -pub fn dist, V: Norm>(a: &P, b: &P) -> N { +pub fn dist, V: Norm>(a: &P, b: &P) -> N { FloatPnt::::dist(a, b) } /// Returns the squared distance between two points. #[inline(always)] -pub fn sqdist, V: Norm>(a: &P, b: &P) -> N { +pub fn sqdist, V: Norm>(a: &P, b: &P) -> N { FloatPnt::::sqdist(a, b) } @@ -383,7 +384,7 @@ pub fn sqdist, V: Norm>(a: &P, b: &P) -> N { /// Computes a projection matrix given the frustrum near plane width, height, the field of /// view, and the distance to the clipping planes (`znear` and `zfar`). #[deprecated = "Use `Persp3::new(width / height, fov, znear, zfar).as_mat()` instead"] -pub fn perspective3d + Zero + One>(width: N, height: N, fov: N, znear: N, zfar: N) -> Mat4 { +pub fn perspective3d + Zero + One>(width: N, height: N, fov: N, znear: N, zfar: N) -> Mat4 { let aspect = width / height; let _1: N = one(); @@ -713,19 +714,19 @@ pub fn dot, N>(a: &V, b: &V) -> N { /// Computes the L2 norm of a vector. #[inline(always)] -pub fn norm, N: Float>(v: &V) -> N { +pub fn norm, N: BaseFloat>(v: &V) -> N { Norm::norm(v) } /// Computes the squared L2 norm of a vector. #[inline(always)] -pub fn sqnorm, N: Float>(v: &V) -> N { +pub fn sqnorm, N: BaseFloat>(v: &V) -> N { Norm::sqnorm(v) } /// Gets the normalized version of a vector. #[inline(always)] -pub fn normalize, N: Float>(v: &V) -> V { +pub fn normalize, N: BaseFloat>(v: &V) -> V { Norm::normalize_cpy(v) } diff --git a/src/linalg/decompositions.rs b/src/linalg/decompositions.rs index 7fdfda6d..63f68043 100644 --- a/src/linalg/decompositions.rs +++ b/src/linalg/decompositions.rs @@ -1,6 +1,6 @@ -use std::num::{Zero, Float}; +use std::num::Zero; use traits::operations::{Transpose, ApproxEq}; -use traits::structure::{ColSlice, Eye, Indexable, Diag, SquareMat}; +use traits::structure::{ColSlice, Eye, Indexable, Diag, SquareMat, BaseFloat}; use traits::geometry::Norm; use std::cmp::min; @@ -12,7 +12,7 @@ use std::cmp::min; /// * `start` - the starting dimension of the subspace of the reflexion /// * `vec` - the vector defining the reflection. pub fn householder_matrix(dim: uint, start: uint, vec: V) -> M - where N: Float, + where N: BaseFloat, M: Eye + Indexable<(uint, uint), N>, V: Indexable { let mut qk : M = Eye::new_identity(dim); @@ -39,7 +39,7 @@ pub fn householder_matrix(dim: uint, start: uint, vec: V) -> M /// # Arguments /// * `m` - matrix to decompose pub fn qr(m: &M) -> (M, M) - where N: Float, + where N: BaseFloat, V: Indexable + Norm, M: Clone + Eye + ColSlice + Transpose + Indexable<(uint, uint), N> + Mul { let (rows, cols) = m.shape(); @@ -74,7 +74,7 @@ pub fn qr(m: &M) -> (M, M) /// Eigendecomposition of a square matrix using the qr algorithm. pub fn eigen_qr(m: &M, eps: &N, niter: uint) -> (M, V) - where N: Float, + where N: BaseFloat, VS: Indexable + Norm, M: Indexable<(uint, uint), N> + SquareMat + Add + Sub + ColSlice + ApproxEq + Clone { diff --git a/src/structs/dmat.rs b/src/structs/dmat.rs index d5abefab..174676d3 100644 --- a/src/structs/dmat.rs +++ b/src/structs/dmat.rs @@ -5,7 +5,7 @@ use std::cmp; use std::rand::Rand; use std::rand; -use std::num::{One, Zero}; +use std::num::{One, Zero, Num}; use traits::operations::ApproxEq; use std::mem; use structs::dvec::{DVec, DVecMulRhs}; diff --git a/src/structs/dvec.rs b/src/structs/dvec.rs index 0560caff..f7a643a2 100644 --- a/src/structs/dvec.rs +++ b/src/structs/dvec.rs @@ -2,14 +2,14 @@ #![allow(missing_docs)] // we hide doc to not have to document the $trhs double dispatch trait. -use std::num::{Zero, One, Float}; +use std::num::{Zero, One, Num}; use std::rand::Rand; use std::rand; use std::slice::{Items, MutItems}; use traits::operations::ApproxEq; use std::iter::FromIterator; use traits::geometry::{Dot, Norm}; -use traits::structure::{Iterable, IterableMut, Indexable, Shape}; +use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat}; /// Heap allocated, dynamically sized vector. #[deriving(Eq, PartialEq, Show, Clone)] diff --git a/src/structs/dvec_macros.rs b/src/structs/dvec_macros.rs index 92b745f1..f033d374 100644 --- a/src/structs/dvec_macros.rs +++ b/src/structs/dvec_macros.rs @@ -132,7 +132,7 @@ macro_rules! dvec_impl( } } - impl + $mul>> $dvec { + impl + $mul>> $dvec { /// 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 except one which is equal /// to 1.0. @@ -240,7 +240,7 @@ macro_rules! dvec_impl( } } - impl Norm for $dvec { + impl Norm for $dvec { #[inline] fn sqnorm(v: &$dvec) -> N { Dot::dot(v, v) diff --git a/src/structs/iso.rs b/src/structs/iso.rs index c3ae5cfc..b85d9040 100644 --- a/src/structs/iso.rs +++ b/src/structs/iso.rs @@ -2,11 +2,11 @@ #![allow(missing_docs)] -use std::num::{Zero, One}; +use std::num::{Zero, One, Num}; use std::rand::{Rand, Rng}; use structs::mat::{Mat3, Mat4, Mat5}; -use traits::structure::{Cast, Dim, Col}; -use traits::operations::{Inv, ApproxEq}; +use traits::structure::{Cast, Dim, Col, BaseFloat}; +use traits::operations::{Inv, ApproxEq, Absolute}; use traits::geometry::{RotationMatrix, Rotation, Rotate, AbsoluteRotate, Transform, Transformation, Translate, Translation, ToHomogeneous}; @@ -50,7 +50,7 @@ pub struct Iso4 { pub translation: Vec4 } -impl Iso3 { +impl Iso3 { /// 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 /// `z` axis. See `look_at_z` for that. diff --git a/src/structs/iso_macros.rs b/src/structs/iso_macros.rs index e70acedd..9faa1097 100644 --- a/src/structs/iso_macros.rs +++ b/src/structs/iso_macros.rs @@ -2,7 +2,7 @@ macro_rules! iso_impl( ($t: ident, $submat: ident, $subvec: ident, $subrotvec: ident) => ( - impl $t { + impl $t { /// Creates a new isometry from a rotation matrix and a vector. #[inline] pub fn new(translation: $subvec, rotation: $subrotvec) -> $t { @@ -26,7 +26,7 @@ macro_rules! iso_impl( macro_rules! rotation_matrix_impl( ($t: ident, $trot: ident, $tlv: ident, $tav: ident) => ( - impl + FloatMath + Num + Clone> + impl + BaseFloat + Num + Clone> RotationMatrix, $tav, $trot> for $t { #[inline] fn to_rot_mat(&self) -> $trot { @@ -50,7 +50,7 @@ macro_rules! dim_impl( macro_rules! one_impl( ($t: ident) => ( - impl One for $t { + impl One for $t { #[inline] fn one() -> $t { $t::new_with_rotmat(Zero::zero(), One::one()) @@ -61,7 +61,7 @@ macro_rules! one_impl( macro_rules! iso_mul_iso_impl( ($t: ident, $tmul: ident) => ( - impl $tmul> for $t { + impl $tmul> for $t { #[inline] fn binop(left: &$t, right: &$t) -> $t { $t::new_with_rotmat( @@ -96,7 +96,7 @@ macro_rules! pnt_mul_iso_impl( macro_rules! translation_impl( ($t: ident, $tv: ident) => ( - impl Translation<$tv> for $t { + impl Translation<$tv> for $t { #[inline] fn translation(&self) -> $tv { self.translation.clone() @@ -153,7 +153,7 @@ macro_rules! translate_impl( macro_rules! rotation_impl( ($t: ident, $trot: ident, $tav: ident) => ( - impl + FloatMath + Clone> Rotation<$tav> for $t { + impl + BaseFloat + Clone> Rotation<$tav> for $t { #[inline] fn rotation(&self) -> $tav { self.rotation.rotation() @@ -220,7 +220,7 @@ macro_rules! rotate_impl( macro_rules! transformation_impl( ($t: ident) => ( - impl Transformation<$t> for $t { + impl Transformation<$t> for $t { fn transformation(&self) -> $t { self.clone() } @@ -357,7 +357,7 @@ macro_rules! approx_eq_impl( macro_rules! rand_impl( ($t: ident) => ( - impl Rand for $t { + impl Rand for $t { #[inline] fn rand(rng: &mut R) -> $t { $t::new(rng.gen(), rng.gen()) @@ -368,7 +368,7 @@ macro_rules! rand_impl( macro_rules! absolute_rotate_impl( ($t: ident, $tv: ident) => ( - impl AbsoluteRotate<$tv> for $t { + impl AbsoluteRotate<$tv> for $t { #[inline] fn absolute_rotate(&self, v: &$tv) -> $tv { self.rotation.absolute_rotate(v) diff --git a/src/structs/mat.rs b/src/structs/mat.rs index a4feb657..66c44ea7 100644 --- a/src/structs/mat.rs +++ b/src/structs/mat.rs @@ -3,7 +3,7 @@ #![allow(missing_docs)] // we allow missing to avoid having to document the mij components. use std::mem; -use std::num::{One, Zero}; +use std::num::{One, Zero, Num}; use traits::operations::ApproxEq; use std::slice::{Items, MutItems}; use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6, @@ -12,7 +12,7 @@ use structs::pnt::{Pnt1, Pnt4, Pnt5, Pnt6, Pnt1MulRhs, Pnt4MulRhs, Pnt5MulRhs, P use structs::dvec::{DVec1, DVec2, DVec3, DVec4, DVec5, DVec6}; use traits::structure::{Cast, Row, Col, Iterable, IterableMut, Dim, Indexable, - Eye, ColSlice, RowSlice, Diag, Shape}; + Eye, ColSlice, RowSlice, Diag, Shape, BaseFloat}; use traits::operations::{Absolute, Transpose, Inv, Outer, EigenQR}; use traits::geometry::{ToHomogeneous, FromHomogeneous, Orig}; use linalg; diff --git a/src/structs/mat_macros.rs b/src/structs/mat_macros.rs index 44b55053..e2d6afcf 100644 --- a/src/structs/mat_macros.rs +++ b/src/structs/mat_macros.rs @@ -125,10 +125,10 @@ macro_rules! mat_sub_scalar_impl( macro_rules! absolute_impl( ($t: ident, $comp0: ident $(,$compN: ident)*) => ( - impl Absolute<$t> for $t { + impl> Absolute<$t> for $t { #[inline] fn abs(m: &$t) -> $t { - $t::new(m.$comp0.abs() $(, m.$compN.abs() )*) + $t::new(::abs(&m.$comp0) $(, ::abs(&m.$compN) )*) } } ) @@ -642,7 +642,7 @@ macro_rules! outer_impl( macro_rules! eigen_qr_impl( ($t: ident, $v: ident) => ( impl EigenQR> for $t - where N: Float + ApproxEq + Clone { + where N: Num + One + Zero + BaseFloat + ApproxEq + Clone { fn eigen_qr(m: &$t, eps: &N, niter: uint) -> ($t, $v) { linalg::eigen_qr(m, eps, niter) } diff --git a/src/structs/ortho.rs b/src/structs/ortho.rs index aae2fbef..e92bee6a 100644 --- a/src/structs/ortho.rs +++ b/src/structs/ortho.rs @@ -1,5 +1,6 @@ -use std::num::{Zero, One}; +use std::num::{Zero, One }; use std::num; +use traits::structure::BaseFloat; use structs::{Pnt3, Vec3, Mat4}; /// A 3D orthographic projection stored without any matrix. @@ -21,7 +22,7 @@ pub struct OrthoMat3 { mat: Mat4 } -impl Ortho3 { +impl Ortho3 { /// Creates a new 3D orthographic projection. pub fn new(width: N, height: N, znear: N, zfar: N) -> Ortho3 { assert!(!(zfar - znear).is_zero()); @@ -47,7 +48,7 @@ impl Ortho3 { } } -impl Ortho3 { +impl Ortho3 { /// The width of the view cuboid. #[inline] pub fn width(&self) -> N { @@ -111,7 +112,7 @@ impl Ortho3 { } } -impl OrthoMat3 { +impl OrthoMat3 { /// Creates a new orthographic projection matrix from the width, heihgt, znear and zfar planes of the view cuboid. pub fn new(width: N, height: N, znear: N, zfar: N) -> OrthoMat3 { assert!(!(zfar - znear).is_zero()); @@ -225,7 +226,7 @@ impl OrthoMat3 { } } -impl OrthoMat3 { +impl OrthoMat3 { /// Returns the 4D matrix (using homogeneous coordinates) of this projection. #[inline] pub fn to_mat<'a>(&'a self) -> Mat4 { diff --git a/src/structs/persp.rs b/src/structs/persp.rs index 618d5707..df829577 100644 --- a/src/structs/persp.rs +++ b/src/structs/persp.rs @@ -1,4 +1,5 @@ use std::num::{Zero, One}; +use traits::structure::BaseFloat; use structs::{Pnt3, Vec3, Mat4}; /// A 3D perspective projection stored without any matrix. @@ -20,7 +21,7 @@ pub struct PerspMat3 { mat: Mat4 } -impl Persp3 { +impl Persp3 { /// Creates a new 3D perspective projection. pub fn new(aspect: N, fov: N, znear: N, zfar: N) -> Persp3 { assert!(!(zfar - znear).is_zero()); @@ -45,7 +46,7 @@ impl Persp3 { } } -impl Persp3 { +impl Persp3 { /// Gets the `width / height` aspect ratio. #[inline] pub fn aspect(&self) -> N { @@ -117,7 +118,7 @@ impl Persp3 { } } -impl PerspMat3 { +impl PerspMat3 { /// Creates a new persepctive matrix from the aspect ratio, field of view, and near/far planes. pub fn new(aspect: N, fov: N, znear: N, zfar: N) -> PerspMat3 { assert!(!(znear - zfar).is_zero()); @@ -256,7 +257,7 @@ impl PerspMat3 { } } -impl PerspMat3 { +impl PerspMat3 { /// Returns the 4D matrix (using homogeneous coordinates) of this projection. #[inline] pub fn to_mat<'a>(&'a self) -> Mat4 { diff --git a/src/structs/pnt.rs b/src/structs/pnt.rs index f15cf57b..bc90eb83 100644 --- a/src/structs/pnt.rs +++ b/src/structs/pnt.rs @@ -3,14 +3,14 @@ #![allow(missing_docs)] // we allow missing to avoid having to document the point components. use std::mem; -use std::num::{Zero, One, Bounded}; +use std::num::{Zero, One, Bounded, Num}; use std::slice::{Items, MutItems}; use std::iter::{Iterator, FromIterator}; use traits::operations::{ApproxEq, POrd, POrdering, PartialLess, PartialEqual, PartialGreater, NotComparable, Axpy, ScalarAdd, ScalarSub, ScalarMul, ScalarDiv}; use traits::structure::{Cast, Dim, Indexable, Iterable, IterableMut, PntAsVec, Shape, - NumPnt, FloatPnt}; + NumPnt, FloatPnt, BaseFloat}; use traits::geometry::{Orig, FromHomogeneous, ToHomogeneous}; use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6}; diff --git a/src/structs/pnt_macros.rs b/src/structs/pnt_macros.rs index 69837575..d8ef262b 100644 --- a/src/structs/pnt_macros.rs +++ b/src/structs/pnt_macros.rs @@ -136,7 +136,7 @@ macro_rules! num_float_pnt_impl( } impl FloatPnt> for $t - where N: ApproxEq + Float $(+ $trhs>)* { + where N: Num + One + Zero + ApproxEq + BaseFloat $(+ $trhs>)* { } ) ) diff --git a/src/structs/quat.rs b/src/structs/quat.rs index 9de90954..5e1d03af 100644 --- a/src/structs/quat.rs +++ b/src/structs/quat.rs @@ -3,7 +3,7 @@ #![allow(missing_docs)] // we allow missing to avoid having to document the dispatch trait. use std::mem; -use std::num::{Zero, One, Bounded}; +use std::num::{Zero, One, Bounded, Num}; use std::num; use std::rand::{Rand, Rng}; use std::slice::{Items, MutItems}; @@ -11,7 +11,7 @@ use structs::{Vec3, Pnt3, Rot3, Mat3, Vec3MulRhs, Pnt3MulRhs}; use traits::operations::{ApproxEq, Inv, POrd, POrdering, NotComparable, PartialLess, PartialGreater, PartialEqual, Axpy, ScalarAdd, ScalarSub, ScalarMul, ScalarDiv}; -use traits::structure::{Cast, Indexable, Iterable, IterableMut, Dim, Shape}; +use traits::structure::{Cast, Indexable, Iterable, IterableMut, Dim, Shape, BaseFloat}; use traits::geometry::{Norm, Cross, Rotation, Rotate, Transform}; /// A quaternion. @@ -65,7 +65,7 @@ impl> Quat { } } -impl + Clone> Inv for Quat { +impl + Clone> Inv for Quat { #[inline] fn inv_cpy(m: &Quat) -> Option> { let mut res = m.clone(); @@ -97,7 +97,7 @@ impl + Clone> Inv for Quat { } } -impl Norm for Quat { +impl Norm for Quat { #[inline] fn sqnorm(q: &Quat) -> N { q.w * q.w + q.i * q.i + q.j * q.j + q.k * q.k @@ -133,7 +133,7 @@ impl + Sub + Add> QuatMulRhs> for Quat { } } -impl + Float + Clone> QuatDivRhs> for Quat { +impl + BaseFloat + Clone> QuatDivRhs> for Quat { #[inline] fn binop(left: &Quat, right: &Quat) -> Quat { *left * Inv::inv_cpy(right).expect("Unable to invert the denominator.") @@ -146,7 +146,7 @@ pub struct UnitQuat { q: Quat } -impl UnitQuat { +impl UnitQuat { /// Creates a new unit quaternion from the axis-angle representation of a rotation. #[inline] pub fn new(axisangle: Vec3) -> UnitQuat { @@ -277,7 +277,7 @@ impl> Inv for UnitQuat { } } -impl Rand for UnitQuat { +impl Rand for UnitQuat { #[inline] fn rand(rng: &mut R) -> UnitQuat { UnitQuat::new(rng.gen()) @@ -301,7 +301,7 @@ impl> ApproxEq for UnitQuat { } } -impl + Clone> Div, UnitQuat> for UnitQuat { +impl + Clone> Div, UnitQuat> for UnitQuat { #[inline] fn div(&self, other: &UnitQuat) -> UnitQuat { UnitQuat { q: self.q / other.q } @@ -354,7 +354,7 @@ impl Pnt3MulRhs> for UnitQuat { } } -impl Rotation> for UnitQuat { +impl Rotation> for UnitQuat { #[inline] fn rotation(&self) -> Vec3 { let _2 = num::one::() + num::one(); diff --git a/src/structs/rot.rs b/src/structs/rot.rs index b31d7522..d1e63a98 100644 --- a/src/structs/rot.rs +++ b/src/structs/rot.rs @@ -2,11 +2,11 @@ #![allow(missing_docs)] -use std::num::{Zero, One}; +use std::num::{Zero, One, Num}; use std::rand::{Rand, Rng}; use traits::geometry::{Rotate, Rotation, AbsoluteRotate, RotationMatrix, Transform, ToHomogeneous, Norm, Cross}; -use traits::structure::{Cast, Dim, Row, Col}; +use traits::structure::{Cast, Dim, Row, Col, BaseFloat}; use traits::operations::{Absolute, Inv, Transpose, ApproxEq}; use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec2MulRhs, Vec3MulRhs, Vec4MulRhs}; use structs::pnt::{Pnt2, Pnt3, Pnt4, Pnt2MulRhs, Pnt3MulRhs, Pnt4MulRhs}; @@ -19,7 +19,7 @@ pub struct Rot2 { submat: Mat2 } -impl> Rot2 { +impl> Rot2 { /// Builds a 2 dimensional rotation matrix from an angle in radian. pub fn new(angle: Vec1) -> Rot2 { let (sia, coa) = angle.x.sin_cos(); @@ -30,7 +30,7 @@ impl> Rot2 { } } -impl Rotation> for Rot2 { +impl Rotation> for Rot2 { #[inline] fn rotation(&self) -> Vec1 { Vec1::new((-self.submat.m12).atan2(self.submat.m11.clone())) @@ -67,21 +67,21 @@ impl Rotation> for Rot2 { } } -impl> Rand for Rot2 { +impl> Rand for Rot2 { #[inline] fn rand(rng: &mut R) -> Rot2 { Rot2::new(rng.gen()) } } -impl AbsoluteRotate> for Rot2 { +impl AbsoluteRotate> for Rot2 { #[inline] fn absolute_rotate(&self, v: &Vec2) -> Vec2 { // the matrix is skew-symetric, so we dont need to compute the absolute value of every // component. - let m11 = self.submat.m11.abs(); - let m12 = self.submat.m12.abs(); - let m22 = self.submat.m22.abs(); + let m11 = ::abs(&self.submat.m11); + let m12 = ::abs(&self.submat.m12); + let m22 = ::abs(&self.submat.m22); Vec2::new(m11 * v.x + m12 * v.y, m12 * v.x + m22 * v.y) } @@ -97,7 +97,7 @@ pub struct Rot3 { } -impl Rot3 { +impl Rot3 { /// Builds a 3 dimensional rotation matrix from an axis and an angle. /// /// # Arguments @@ -166,7 +166,7 @@ impl Rot3 { } } -impl Rot3 { +impl Rot3 { /// 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` /// for that. @@ -205,7 +205,7 @@ impl Rot3 { } } -impl> +impl> Rotation> for Rot3 { #[inline] fn rotation(&self) -> Vec3 { @@ -270,7 +270,7 @@ Rotation> for Rot3 { } } -impl +impl Rand for Rot3 { #[inline] fn rand(rng: &mut R) -> Rot3 { @@ -278,13 +278,13 @@ Rand for Rot3 { } } -impl AbsoluteRotate> for Rot3 { +impl AbsoluteRotate> for Rot3 { #[inline] fn absolute_rotate(&self, v: &Vec3) -> Vec3 { Vec3::new( - self.submat.m11.abs() * v.x + self.submat.m12.abs() * v.y + self.submat.m13.abs() * v.z, - self.submat.m21.abs() * v.x + self.submat.m22.abs() * v.y + self.submat.m23.abs() * v.z, - self.submat.m31.abs() * v.x + self.submat.m32.abs() * v.y + self.submat.m33.abs() * v.z) + ::abs(&self.submat.m11) * v.x + ::abs(&self.submat.m12) * v.y + ::abs(&self.submat.m13) * v.z, + ::abs(&self.submat.m21) * v.x + ::abs(&self.submat.m22) * v.y + ::abs(&self.submat.m23) * v.z, + ::abs(&self.submat.m31) * v.x + ::abs(&self.submat.m32) * v.y + ::abs(&self.submat.m33) * v.z) } } @@ -316,25 +316,25 @@ pub struct Rot4 { // } // } -impl AbsoluteRotate> for Rot4 { +impl AbsoluteRotate> for Rot4 { #[inline] fn absolute_rotate(&self, v: &Vec4) -> Vec4 { Vec4::new( - self.submat.m11.abs() * v.x + self.submat.m12.abs() * v.y + - self.submat.m13.abs() * v.z + self.submat.m14.abs() * v.w, + ::abs(&self.submat.m11) * v.x + ::abs(&self.submat.m12) * v.y + + ::abs(&self.submat.m13) * v.z + ::abs(&self.submat.m14) * v.w, - self.submat.m21.abs() * v.x + self.submat.m22.abs() * v.y + - self.submat.m23.abs() * v.z + self.submat.m24.abs() * v.w, + ::abs(&self.submat.m21) * v.x + ::abs(&self.submat.m22) * v.y + + ::abs(&self.submat.m23) * v.z + ::abs(&self.submat.m24) * v.w, - self.submat.m31.abs() * v.x + self.submat.m32.abs() * v.y + - self.submat.m33.abs() * v.z + self.submat.m34.abs() * v.w, + ::abs(&self.submat.m31) * v.x + ::abs(&self.submat.m32) * v.y + + ::abs(&self.submat.m33) * v.z + ::abs(&self.submat.m34) * v.w, - self.submat.m41.abs() * v.x + self.submat.m42.abs() * v.y + - self.submat.m43.abs() * v.z + self.submat.m44.abs() * v.w) + ::abs(&self.submat.m41) * v.x + ::abs(&self.submat.m42) * v.y + + ::abs(&self.submat.m43) * v.z + ::abs(&self.submat.m44) * v.w) } } -impl +impl Rotation> for Rot4 { #[inline] fn rotation(&self) -> Vec4 { diff --git a/src/structs/rot_macros.rs b/src/structs/rot_macros.rs index d8a7c5dd..ef1d06e4 100644 --- a/src/structs/rot_macros.rs +++ b/src/structs/rot_macros.rs @@ -122,7 +122,7 @@ macro_rules! dim_impl( macro_rules! rotation_matrix_impl( ($t: ident, $tlv: ident, $tav: ident) => ( - impl + FloatMath> RotationMatrix, $tav, $t> for $t { + impl + BaseFloat> RotationMatrix, $tav, $t> for $t { #[inline] fn to_rot_mat(&self) -> $t { self.clone() @@ -313,7 +313,7 @@ macro_rules! approx_eq_impl( macro_rules! absolute_impl( ($t: ident, $tm: ident) => ( - impl Absolute<$tm> for $t { + impl> Absolute<$tm> for $t { #[inline] fn abs(m: &$t) -> $tm { Absolute::abs(&m.submat) diff --git a/src/structs/spec/mat.rs b/src/structs/spec/mat.rs index 19d5c573..767caf34 100644 --- a/src/structs/spec/mat.rs +++ b/src/structs/spec/mat.rs @@ -1,9 +1,9 @@ -use std::num::{Zero, One}; +use std::num::{Zero, One, Num}; use structs::vec::{Vec2, Vec3, Vec2MulRhs, Vec3MulRhs}; use structs::pnt::{Pnt2, Pnt3, Pnt2MulRhs, Pnt3MulRhs}; use structs::mat::{Mat1, Mat2, Mat3, Mat3MulRhs, Mat2MulRhs}; use traits::operations::{Inv, Det, ApproxEq}; -use traits::structure::{Row, Col}; +use traits::structure::{Row, Col, BaseFloat}; // some specializations: impl + Clone> Inv for Mat1 { diff --git a/src/structs/spec/vec.rs b/src/structs/spec/vec.rs index a5e2154e..ebaf1b45 100644 --- a/src/structs/spec/vec.rs +++ b/src/structs/spec/vec.rs @@ -1,5 +1,5 @@ -use std::num::{Zero, One}; -use traits::structure::{Cast, Row, Basis}; +use std::num::{Zero, One, Num}; +use traits::structure::{Cast, Row, Basis, BaseFloat}; use traits::geometry::{Norm, Cross, CrossMatrix, UniformSphereSample}; use structs::vec::{Vec1, Vec2, Vec3, Vec4}; use structs::mat::Mat3; @@ -114,7 +114,7 @@ impl> Basis for Vec2 { } } -impl Basis for Vec3 { +impl Basis for Vec3 { #[inline(always)] fn canonical_basis(f: |Vec3| -> bool) { if !f(Vec3::new(One::one(), Zero::zero(), Zero::zero())) { return }; diff --git a/src/structs/spec/vec0.rs b/src/structs/spec/vec0.rs index dfb8a391..ed575ceb 100644 --- a/src/structs/spec/vec0.rs +++ b/src/structs/spec/vec0.rs @@ -1,9 +1,9 @@ use std::mem; -use std::num::{Zero, One, Float, Bounded}; +use std::num::{Zero, One, Bounded, Num}; use std::slice::{Items, MutItems}; use std::iter::{Iterator, FromIterator}; use traits::operations::ApproxEq; -use traits::structure::{Iterable, IterableMut, Indexable, Basis, Dim, Shape}; +use traits::structure::{Iterable, IterableMut, Indexable, Basis, Dim, Shape, BaseFloat}; use traits::geometry::{Translation, Dot, Norm}; use structs::vec; @@ -164,7 +164,7 @@ impl + Neg> Translation> for vec::Vec0 { } } -impl Norm for vec::Vec0 { +impl Norm for vec::Vec0 { #[inline] fn sqnorm(_: &vec::Vec0) -> N { Zero::zero() diff --git a/src/structs/vec.rs b/src/structs/vec.rs index 85435040..f7d7d0e6 100644 --- a/src/structs/vec.rs +++ b/src/structs/vec.rs @@ -3,7 +3,7 @@ #![allow(missing_docs)] // we allow missing to avoid having to document the dispatch traits. use std::mem; -use std::num::{Zero, One, Float, Bounded}; +use std::num::{Zero, One, Bounded, Num}; use std::slice::{Items, MutItems}; use std::iter::{Iterator, FromIterator}; use traits::operations::{ApproxEq, POrd, POrdering, PartialLess, PartialEqual, @@ -12,7 +12,7 @@ use traits::operations::{ApproxEq, POrd, POrdering, PartialLess, PartialEqual, use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm, Translation, Translate}; use traits::structure::{Basis, Cast, Dim, Indexable, Iterable, IterableMut, VecAsPnt, Shape, - NumVec, FloatVec}; + NumVec, FloatVec, BaseFloat}; use structs::pnt::{Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6}; diff --git a/src/structs/vec_macros.rs b/src/structs/vec_macros.rs index f09a046f..b8e502c2 100644 --- a/src/structs/vec_macros.rs +++ b/src/structs/vec_macros.rs @@ -54,11 +54,11 @@ macro_rules! at_fast_impl( ) ) -// FIXME: N should be bounded by Ord instead of Float… +// FIXME: N should be bounded by Ord instead of BaseFloat… // However, f32/f64 does not implement Ord… macro_rules! ord_impl( ($t: ident, $comp0: ident $(,$compN: ident)*) => ( - impl POrd for $t { + impl POrd for $t { #[inline] fn inf(a: &$t, b: &$t) -> $t { $t::new(a.$comp0.min(b.$comp0.clone()) @@ -293,7 +293,7 @@ macro_rules! container_impl( macro_rules! basis_impl( ($t: ident, $trhs: ident, $dim: expr) => ( - impl + $trhs>> Basis for $t { + impl + $trhs>> Basis for $t { #[inline] fn canonical_basis(f: |$t| -> bool) { for i in range(0u, $dim) { @@ -552,7 +552,7 @@ macro_rules! translation_impl( macro_rules! norm_impl( ($t: ident, $comp0: ident $(,$compN: ident)*) => ( - impl Norm for $t { + impl Norm for $t { #[inline] fn sqnorm(v: &$t) -> N { Dot::dot(v, v) @@ -769,17 +769,17 @@ macro_rules! num_float_vec_impl( } impl FloatVec for $t - where N: ApproxEq + Float $(+ $trhs>)* { + where N: Num + Zero + One + ApproxEq + BaseFloat $(+ $trhs>)* { } ) ) macro_rules! absolute_vec_impl( ($t: ident, $comp0: ident $(,$compN: ident)*) => ( - impl Absolute<$t> for $t { + impl> Absolute<$t> for $t { #[inline] fn abs(m: &$t) -> $t { - $t::new(m.$comp0.abs() $(, m.$compN.abs() )*) + $t::new(::abs(&m.$comp0) $(, ::abs(&m.$compN) )*) } } ) diff --git a/src/traits/geometry.rs b/src/traits/geometry.rs index 84205500..fc06edf9 100644 --- a/src/traits/geometry.rs +++ b/src/traits/geometry.rs @@ -1,7 +1,7 @@ //! Traits of operations having a well-known or explicit geometric meaning. -use traits::structure::Mat; +use traits::structure::{BaseFloat, Mat}; /// Trait of object which represent a translation, and to wich new translation /// can be appended. @@ -205,7 +205,7 @@ pub trait Dot { } /// Traits of objects having an euclidian norm. -pub trait Norm { +pub trait Norm { /// Computes the norm of `self`. #[inline] fn norm(v: &Self) -> N { diff --git a/src/traits/mod.rs b/src/traits/mod.rs index 1a46bfcd..64a90352 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -6,7 +6,7 @@ pub use traits::geometry::{AbsoluteRotate, Cross, CrossMatrix, Dot, FromHomogene pub use traits::structure::{FloatVec, FloatPnt, Basis, Cast, Col, Dim, Indexable, Iterable, IterableMut, Mat, SquareMat, Row, NumVec, NumPnt, PntAsVec, VecAsPnt, - ColSlice, RowSlice, Diag, Eye, Shape}; + ColSlice, RowSlice, Diag, Eye, Shape, BaseFloat}; pub use traits::operations::{Absolute, ApproxEq, Axpy, Cov, Det, Inv, LMul, Mean, Outer, POrd, RMul, ScalarAdd, ScalarSub, ScalarMul, ScalarDiv, Transpose, EigenQR}; diff --git a/src/traits/operations.rs b/src/traits/operations.rs index 3f2973c9..7333eff4 100644 --- a/src/traits/operations.rs +++ b/src/traits/operations.rs @@ -1,5 +1,6 @@ //! Low level operations on vectors and matrices. +use std::num::{Float, SignedInt}; use traits::structure::SquareMat; /// Result of a partial ordering. @@ -170,7 +171,7 @@ impl ApproxEq for f32 { #[inline] fn approx_eq_eps(a: &f32, b: &f32, epsilon: &f32) -> bool { - (*a - *b).abs() < *epsilon + ::abs(&(*a - *b)) < *epsilon } } @@ -182,7 +183,7 @@ impl ApproxEq for f64 { #[inline] fn approx_eq_eps(a: &f64, b: &f64, approx_epsilon: &f64) -> bool { - (*a - *b).abs() < *approx_epsilon + ::abs(&(*a - *b)) < *approx_epsilon } } @@ -344,3 +345,40 @@ pub trait Axpy { /// Adds $$a * x$$ to `self`. fn axpy(&mut self, a: &N, x: &Self); } + +/* + * Some implementation for scalar types. + */ +// FIXME: move this to another module ? +macro_rules! impl_absolute( + ($n: ty) => { + impl Absolute<$n> for $n { + #[inline] + fn abs(n: &$n) -> $n { + n.abs() + } + } + } +) +macro_rules! impl_absolute_id( + ($n: ty) => { + impl Absolute<$n> for $n { + #[inline] + fn abs(n: &$n) -> $n { + *n + } + } + } +) + +impl_absolute!(f32) +impl_absolute!(f64) +impl_absolute!(i16) +impl_absolute!(i32) +impl_absolute!(i64) +impl_absolute!(int) +impl_absolute_id!(u8) +impl_absolute_id!(u16) +impl_absolute_id!(u32) +impl_absolute_id!(u64) +impl_absolute_id!(uint) diff --git a/src/traits/structure.rs b/src/traits/structure.rs index f7b90bff..e6dbbbfa 100644 --- a/src/traits/structure.rs +++ b/src/traits/structure.rs @@ -1,10 +1,16 @@ //! Traits giving structural informations on linear algebra objects or the space they live in. -use std::num::{Zero, One}; +use std::num::{Zero, One, FloatMath, Num}; use std::slice::{Items, MutItems}; -use traits::operations::{RMul, LMul, Axpy, Transpose, Inv}; +use traits::operations::{RMul, LMul, Axpy, Transpose, Inv, Absolute}; use traits::geometry::{Dot, Norm, Orig}; +pub trait BaseFloat: FloatMath + Zero + One + Num + Absolute { +} + +impl BaseFloat for f32 { } +impl BaseFloat for f64 { } + /// Traits of objects which can be created from an object of type `T`. pub trait Cast { /// Converts an element of type `T` to an element of type `Self`. @@ -174,8 +180,8 @@ pub trait NumVec: Dim + Sub + Add + Neg + Zero Mul + Div + Dot + Axpy + Index { } -/// Trait of vector with components implementing the `Float` trait. -pub trait FloatVec: NumVec + Norm + Basis { +/// Trait of vector with components implementing the `BaseFloat` trait. +pub trait FloatVec: NumVec + Norm + Basis { } /* @@ -203,8 +209,8 @@ pub trait NumPnt: Div + Add + Axpy + Index { // FIXME: + Sub } -/// Trait of points with components implementing the `Float` trait. -pub trait FloatPnt>: NumPnt { +/// Trait of points with components implementing the `BaseFloat` trait. +pub trait FloatPnt>: NumPnt { /// Computes the square distance between two points. #[inline] fn sqdist(a: &Self, b: &Self) -> N { diff --git a/tests/mat.rs b/tests/mat.rs index c2eefbd4..17dd540a 100644 --- a/tests/mat.rs +++ b/tests/mat.rs @@ -2,7 +2,7 @@ extern crate "nalgebra" as na; -use std::num::{Float, abs}; +use std::num::Float; use std::rand::random; use std::cmp::{min, max}; use na::{Vec1, Vec3, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6, Rot3, Persp3, PerspMat3, Ortho3, OrthoMat3, @@ -131,7 +131,7 @@ fn test_inv_mat6() { fn test_rotation2() { for _ in range(0u, 10000) { let randmat: na::Rot2 = na::one(); - let ang = Vec1::new(abs::(random()) % Float::pi()); + let ang = Vec1::new(na::abs(&random::()) % Float::pi()); assert!(na::approx_eq(&na::rotation(&na::append_rotation(&randmat, &ang)), &ang)); } @@ -149,7 +149,7 @@ fn test_inv_rotation3() { for _ in range(0u, 10000) { let randmat: Rot3 = na::one(); let dir: Vec3 = random(); - let ang = na::normalize(&dir) * (abs::(random()) % Float::pi()); + let ang = na::normalize(&dir) * (na::abs(&random::()) % Float::pi()); let rot = na::append_rotation(&randmat, &ang); assert!(na::approx_eq(&(na::transpose(&rot) * rot), &na::one()));