Add the ApproxEq trait.
It is no longer part of std::num
This commit is contained in:
parent
31904cad6f
commit
f5b0b76d8d
26
src/na.rs
26
src/na.rs
@ -4,8 +4,9 @@ use std::num::{Zero, One};
|
||||
pub use traits::{
|
||||
Absolute,
|
||||
AbsoluteRotate,
|
||||
AlgebraicVec,
|
||||
AlgebraicVecExt,
|
||||
ApproxEq,
|
||||
RealVec,
|
||||
RealVecExt,
|
||||
Basis,
|
||||
Cast,
|
||||
Col,
|
||||
@ -431,19 +432,19 @@ pub fn sub_dot<V: Dot<N>, N>(a: &V, b: &V, c: &V) -> N {
|
||||
|
||||
/// Computes the L2 norm of a vector.
|
||||
#[inline(always)]
|
||||
pub fn norm<V: Norm<N>, N: Algebraic>(v: &V) -> N {
|
||||
pub fn norm<V: Norm<N>, N: Real>(v: &V) -> N {
|
||||
Norm::norm(v)
|
||||
}
|
||||
|
||||
/// Computes the squared L2 norm of a vector.
|
||||
#[inline(always)]
|
||||
pub fn sqnorm<V: Norm<N>, N: Algebraic>(v: &V) -> N {
|
||||
pub fn sqnorm<V: Norm<N>, N: Real>(v: &V) -> N {
|
||||
Norm::sqnorm(v)
|
||||
}
|
||||
|
||||
/// Gets the normalized version of a vector.
|
||||
#[inline(always)]
|
||||
pub fn normalize<V: Norm<N>, N: Algebraic>(v: &V) -> V {
|
||||
pub fn normalize<V: Norm<N>, N: Real>(v: &V) -> V {
|
||||
Norm::normalize_cpy(v)
|
||||
}
|
||||
|
||||
@ -508,6 +509,21 @@ pub fn sample_sphere<V: UniformSphereSample>(f: |V| -> ()) {
|
||||
//
|
||||
//
|
||||
|
||||
/*
|
||||
* AproxEq<N>
|
||||
*/
|
||||
/// Tests approximate equality.
|
||||
#[inline(always)]
|
||||
pub fn approx_eq<T: ApproxEq<N>, N>(a: &T, b: &T) -> bool {
|
||||
ApproxEq::approx_eq(a, b)
|
||||
}
|
||||
|
||||
/// Tests approximate equality using a custom epsilon.
|
||||
#[inline(always)]
|
||||
pub fn approx_eq_eps<T: ApproxEq<N>, N>(a: &T, b: &T, eps: &N) -> bool {
|
||||
ApproxEq::approx_eq_eps(a, b, eps)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Absolute<A>
|
||||
|
@ -6,7 +6,7 @@ use std::rand::Rand;
|
||||
use std::rand;
|
||||
use std::num::{One, Zero};
|
||||
use std::vec;
|
||||
use std::cmp::ApproxEq;
|
||||
use traits::operations::ApproxEq;
|
||||
use std::util;
|
||||
use structs::dvec::{DVec, DVecMulRhs};
|
||||
use traits::operations::{Inv, Transpose, Mean, Cov};
|
||||
@ -499,25 +499,22 @@ impl<N: Clone + Num + Cast<f32> + DMatDivRhs<N, DMat<N>> + ToStr > Cov<DMat<N>>
|
||||
|
||||
impl<N: ApproxEq<N>> ApproxEq<N> for DMat<N> {
|
||||
#[inline]
|
||||
fn approx_epsilon() -> N {
|
||||
fail!("This function cannot work due to a compiler bug.")
|
||||
// let res: N = ApproxEq::<N>::approx_epsilon();
|
||||
|
||||
// res
|
||||
fn approx_epsilon(_: Option<DMat<N>>) -> N {
|
||||
ApproxEq::approx_epsilon(None::<N>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq(&self, other: &DMat<N>) -> bool {
|
||||
let mut zip = self.mij.iter().zip(other.mij.iter());
|
||||
fn approx_eq(a: &DMat<N>, b: &DMat<N>) -> bool {
|
||||
let mut zip = a.mij.iter().zip(b.mij.iter());
|
||||
|
||||
zip.all(|(a, b)| a.approx_eq(b))
|
||||
zip.all(|(a, b)| ApproxEq::approx_eq(a, b))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &DMat<N>, epsilon: &N) -> bool {
|
||||
let mut zip = self.mij.iter().zip(other.mij.iter());
|
||||
fn approx_eq_eps(a: &DMat<N>, b: &DMat<N>, epsilon: &N) -> bool {
|
||||
let mut zip = a.mij.iter().zip(b.mij.iter());
|
||||
|
||||
zip.all(|(a, b)| a.approx_eq_eps(b, epsilon))
|
||||
zip.all(|(a, b)| ApproxEq::approx_eq_eps(a, b, epsilon))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
#[allow(missing_doc)]; // we hide doc to not have to document the $trhs double dispatch trait.
|
||||
|
||||
use std::num::{Zero, One, Algebraic};
|
||||
use std::num::{Zero, One, Real};
|
||||
use std::rand::Rand;
|
||||
use std::rand;
|
||||
use std::vec;
|
||||
use std::vec::{VecIterator, VecMutIterator};
|
||||
use std::cmp::ApproxEq;
|
||||
use traits::operations::ApproxEq;
|
||||
use std::iter::FromIterator;
|
||||
use traits::geometry::{Dot, Norm};
|
||||
use traits::structure::{Iterable, IterableMut};
|
||||
@ -177,7 +177,7 @@ impl<N> FromIterator<N> for DVec<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Num + Algebraic + ApproxEq<N> + DVecMulRhs<N, DVec<N>>> DVec<N> {
|
||||
impl<N: Clone + Num + Real + ApproxEq<N> + DVecMulRhs<N, DVec<N>>> DVec<N> {
|
||||
/// Computes the canonical basis for the given dimension. A canonical basis is a set of
|
||||
/// vectors, mutually orthogonal, with all its component equal to 0.0 exept one which is equal
|
||||
/// to 1.0.
|
||||
@ -220,7 +220,7 @@ impl<N: Clone + Num + Algebraic + ApproxEq<N> + DVecMulRhs<N, DVec<N>>> DVec<N>
|
||||
elt = elt - v * Dot::dot(&elt, v)
|
||||
};
|
||||
|
||||
if !Norm::sqnorm(&elt).approx_eq(&Zero::zero()) {
|
||||
if !ApproxEq::approx_eq(&Norm::sqnorm(&elt), &Zero::zero()) {
|
||||
res.push(Norm::normalize_cpy(&elt));
|
||||
}
|
||||
}
|
||||
@ -284,7 +284,7 @@ impl<N: Num + Clone> Dot<N> for DVec<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Num + Algebraic + Clone> Norm<N> for DVec<N> {
|
||||
impl<N: Num + Real + Clone> Norm<N> for DVec<N> {
|
||||
#[inline]
|
||||
fn sqnorm(v: &DVec<N>) -> N {
|
||||
Dot::dot(v, v)
|
||||
@ -318,25 +318,22 @@ impl<N: Num + Algebraic + Clone> Norm<N> for DVec<N> {
|
||||
|
||||
impl<N: ApproxEq<N>> ApproxEq<N> for DVec<N> {
|
||||
#[inline]
|
||||
fn approx_epsilon() -> N {
|
||||
fail!("Fix me.")
|
||||
// let res: N = ApproxEq::<N>::approx_epsilon();
|
||||
|
||||
// res
|
||||
fn approx_epsilon(_: Option<DVec<N>>) -> N {
|
||||
ApproxEq::approx_epsilon(None::<N>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq(&self, other: &DVec<N>) -> bool {
|
||||
let mut zip = self.at.iter().zip(other.at.iter());
|
||||
fn approx_eq(a: &DVec<N>, b: &DVec<N>) -> bool {
|
||||
let mut zip = a.at.iter().zip(b.at.iter());
|
||||
|
||||
zip.all(|(a, b)| a.approx_eq(b))
|
||||
zip.all(|(a, b)| ApproxEq::approx_eq(a, b))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &DVec<N>, epsilon: &N) -> bool {
|
||||
let mut zip = self.at.iter().zip(other.at.iter());
|
||||
fn approx_eq_eps(a: &DVec<N>, b: &DVec<N>, epsilon: &N) -> bool {
|
||||
let mut zip = a.at.iter().zip(b.at.iter());
|
||||
|
||||
zip.all(|(a, b)| a.approx_eq_eps(b, epsilon))
|
||||
zip.all(|(a, b)| ApproxEq::approx_eq_eps(a, b, epsilon))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ use std::num::{Zero, One};
|
||||
use std::rand::{Rand, Rng};
|
||||
use structs::mat::{Mat3, Mat4, Mat5};
|
||||
use traits::structure::{Cast, Dim, Col};
|
||||
use traits::operations::{Inv};
|
||||
use traits::operations::{Inv, ApproxEq};
|
||||
use traits::geometry::{RotationMatrix, Rotation, Rotate, AbsoluteRotate, Transform, Transformation,
|
||||
Translate, Translation, ToHomogeneous};
|
||||
|
||||
@ -51,7 +51,7 @@ pub struct Iso4<N> {
|
||||
translation: Vec4<N>
|
||||
}
|
||||
|
||||
impl<N: Clone + Num + Algebraic> Iso3<N> {
|
||||
impl<N: Clone + Num + Real> Iso3<N> {
|
||||
/// 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.
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
macro_rules! iso_impl(
|
||||
($t: ident, $submat: ident, $subvec: ident, $subrotvec: ident) => (
|
||||
impl<N: Clone + Trigonometric + Algebraic + Num> $t<N> {
|
||||
impl<N: Clone + Real + Real + Num> $t<N> {
|
||||
/// Creates a new isometry from a rotation matrix and a vector.
|
||||
#[inline]
|
||||
pub fn new(translation: $subvec<N>, rotation: $subrotvec<N>) -> $t<N> {
|
||||
@ -26,7 +26,7 @@ macro_rules! iso_impl(
|
||||
|
||||
macro_rules! rotation_matrix_impl(
|
||||
($t: ident, $trot: ident, $tlv: ident, $tav: ident) => (
|
||||
impl<N: Cast<f32> + Algebraic + Trigonometric + Num + Clone>
|
||||
impl<N: Cast<f32> + Real + Real + Num + Clone>
|
||||
RotationMatrix<$tlv<N>, $tav<N>, $trot<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn to_rot_mat(&self) -> $trot<N> {
|
||||
@ -50,7 +50,7 @@ macro_rules! dim_impl(
|
||||
|
||||
macro_rules! one_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Trigonometric + Algebraic + Num + Clone> One for $t<N> {
|
||||
impl<N: Real + Real + Num + Clone> One for $t<N> {
|
||||
#[inline]
|
||||
fn one() -> $t<N> {
|
||||
$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<N: Num + Trigonometric + Algebraic + Clone> $tmul<N, $t<N>> for $t<N> {
|
||||
impl<N: Num + Real + Real + Clone> $tmul<N, $t<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn binop(left: &$t<N>, right: &$t<N>) -> $t<N> {
|
||||
$t::new_with_rotmat(
|
||||
@ -96,7 +96,7 @@ macro_rules! vec_mul_iso_impl(
|
||||
|
||||
macro_rules! translation_impl(
|
||||
($t: ident, $tv: ident) => (
|
||||
impl<N: Trigonometric + Num + Algebraic + Clone> Translation<$tv<N>> for $t<N> {
|
||||
impl<N: Real + Num + Real + Clone> Translation<$tv<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn translation(&self) -> $tv<N> {
|
||||
self.translation.clone()
|
||||
@ -153,7 +153,7 @@ macro_rules! translate_impl(
|
||||
|
||||
macro_rules! rotation_impl(
|
||||
($t: ident, $trot: ident, $tav: ident) => (
|
||||
impl<N: Cast<f32> + Num + Trigonometric + Algebraic + Clone> Rotation<$tav<N>> for $t<N> {
|
||||
impl<N: Cast<f32> + Num + Real + Real + Clone> Rotation<$tav<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn rotation(&self) -> $tav<N> {
|
||||
self.rotation.rotation()
|
||||
@ -220,7 +220,7 @@ macro_rules! rotate_impl(
|
||||
|
||||
macro_rules! transformation_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Num + Trigonometric + Algebraic + Clone> Transformation<$t<N>> for $t<N> {
|
||||
impl<N: Num + Real + Real + Clone> Transformation<$t<N>> for $t<N> {
|
||||
fn transformation(&self) -> $t<N> {
|
||||
self.clone()
|
||||
}
|
||||
@ -315,21 +315,20 @@ macro_rules! approx_eq_impl(
|
||||
($t: ident) => (
|
||||
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
|
||||
#[inline]
|
||||
fn approx_epsilon() -> N {
|
||||
fail!("approx_epsilon is broken since rust revision 8693943676487c01fa09f5f3daf0df6a1f71e24d.")
|
||||
// ApproxEq::<N>::approx_epsilon()
|
||||
fn approx_epsilon(_: Option<$t<N>>) -> N {
|
||||
ApproxEq::approx_epsilon(None::<N>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq(&self, other: &$t<N>) -> bool {
|
||||
self.rotation.approx_eq(&other.rotation) &&
|
||||
self.translation.approx_eq(&other.translation)
|
||||
fn approx_eq(a: &$t<N>, b: &$t<N>) -> bool {
|
||||
ApproxEq::approx_eq(&a.rotation, &b.rotation) &&
|
||||
ApproxEq::approx_eq(&a.translation, &b.translation)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N) -> bool {
|
||||
self.rotation.approx_eq_eps(&other.rotation, epsilon) &&
|
||||
self.translation.approx_eq_eps(&other.translation, epsilon)
|
||||
fn approx_eq_eps(a: &$t<N>, b: &$t<N>, epsilon: &N) -> bool {
|
||||
ApproxEq::approx_eq_eps(&a.rotation, &b.rotation, epsilon) &&
|
||||
ApproxEq::approx_eq_eps(&a.translation, &b.translation, epsilon)
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -337,7 +336,7 @@ macro_rules! approx_eq_impl(
|
||||
|
||||
macro_rules! rand_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Rand + Clone + Trigonometric + Algebraic + Num> Rand for $t<N> {
|
||||
impl<N: Rand + Clone + Real + Real + Num> Rand for $t<N> {
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> $t<N> {
|
||||
$t::new(rng.gen(), rng.gen())
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use std::cast;
|
||||
use std::num::{One, Zero};
|
||||
use std::cmp::ApproxEq;
|
||||
use traits::operations::ApproxEq;
|
||||
use std::vec::{VecIterator, VecMutIterator};
|
||||
use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6, Vec1MulRhs, Vec4MulRhs,
|
||||
Vec5MulRhs, Vec6MulRhs};
|
||||
|
@ -449,23 +449,22 @@ macro_rules! approx_eq_impl(
|
||||
($t: ident) => (
|
||||
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
|
||||
#[inline]
|
||||
fn approx_epsilon() -> N {
|
||||
fail!("approx_epsilon is broken since rust revision 8693943676487c01fa09f5f3daf0df6a1f71e24d.")
|
||||
// ApproxEq::<N>::approx_epsilon()
|
||||
fn approx_epsilon(_: Option<$t<N>>) -> N {
|
||||
ApproxEq::approx_epsilon(None::<N>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq(&self, other: &$t<N>) -> bool {
|
||||
let mut zip = self.iter().zip(other.iter());
|
||||
fn approx_eq(a: &$t<N>, b: &$t<N>) -> bool {
|
||||
let mut zip = a.iter().zip(b.iter());
|
||||
|
||||
zip.all(|(a, b)| a.approx_eq(b))
|
||||
zip.all(|(a, b)| ApproxEq::approx_eq(a, b))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N) -> bool {
|
||||
let mut zip = self.iter().zip(other.iter());
|
||||
fn approx_eq_eps(a: &$t<N>, b: &$t<N>, epsilon: &N) -> bool {
|
||||
let mut zip = a.iter().zip(b.iter());
|
||||
|
||||
zip.all(|(a, b)| a.approx_eq_eps(b, epsilon))
|
||||
zip.all(|(a, b)| ApproxEq::approx_eq_eps(a, b, epsilon))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -7,7 +7,7 @@ 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::operations::{Absolute, Inv, Transpose};
|
||||
use traits::operations::{Absolute, Inv, Transpose, ApproxEq};
|
||||
use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec2MulRhs, Vec3MulRhs, Vec4MulRhs};
|
||||
use structs::mat::{Mat2, Mat3, Mat4, Mat5};
|
||||
|
||||
@ -20,7 +20,7 @@ pub struct Rot2<N> {
|
||||
priv submat: Mat2<N>
|
||||
}
|
||||
|
||||
impl<N: Clone + Trigonometric + Neg<N>> Rot2<N> {
|
||||
impl<N: Clone + Real + Neg<N>> Rot2<N> {
|
||||
/// Builds a 2 dimensional rotation matrix from an angle in radian.
|
||||
pub fn new(angle: Vec1<N>) -> Rot2<N> {
|
||||
let (sia, coa) = angle.x.sin_cos();
|
||||
@ -31,7 +31,7 @@ impl<N: Clone + Trigonometric + Neg<N>> Rot2<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Trigonometric + Num + Clone>
|
||||
impl<N: Real + Num + Clone>
|
||||
Rotation<Vec1<N>> for Rot2<N> {
|
||||
#[inline]
|
||||
fn rotation(&self) -> Vec1<N> {
|
||||
@ -69,7 +69,7 @@ Rotation<Vec1<N>> for Rot2<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Rand + Trigonometric + Neg<N>> Rand for Rot2<N> {
|
||||
impl<N: Clone + Rand + Real + Neg<N>> Rand for Rot2<N> {
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> Rot2<N> {
|
||||
Rot2::new(rng.gen())
|
||||
@ -99,7 +99,7 @@ pub struct Rot3<N> {
|
||||
}
|
||||
|
||||
|
||||
impl<N: Clone + Trigonometric + Num + Algebraic> Rot3<N> {
|
||||
impl<N: Clone + Real + Num + Real> Rot3<N> {
|
||||
/// Builds a 3 dimensional rotation matrix from an axis and an angle.
|
||||
///
|
||||
/// # Arguments
|
||||
@ -140,7 +140,7 @@ impl<N: Clone + Trigonometric + Num + Algebraic> Rot3<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Num + Algebraic> Rot3<N> {
|
||||
impl<N: Clone + Num + Real> Rot3<N> {
|
||||
/// 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.
|
||||
@ -180,7 +180,7 @@ impl<N: Clone + Num + Algebraic> Rot3<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Trigonometric + Num + Algebraic + Cast<f32>>
|
||||
impl<N: Clone + Real + Num + Real + Cast<f32>>
|
||||
Rotation<Vec3<N>> for Rot3<N> {
|
||||
#[inline]
|
||||
fn rotation(&self) -> Vec3<N> {
|
||||
@ -245,7 +245,7 @@ Rotation<Vec3<N>> for Rot3<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Rand + Trigonometric + Num + Algebraic>
|
||||
impl<N: Clone + Rand + Real + Num + Real>
|
||||
Rand for Rot3<N> {
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> Rot3<N> {
|
||||
@ -309,7 +309,7 @@ impl<N: Signed> AbsoluteRotate<Vec4<N>> for Rot4<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Trigonometric + Num + Clone>
|
||||
impl<N: Real + Num + Clone>
|
||||
Rotation<Vec4<N>> for Rot4<N> {
|
||||
#[inline]
|
||||
fn rotation(&self) -> Vec4<N> {
|
||||
|
@ -56,7 +56,7 @@ macro_rules! dim_impl(
|
||||
|
||||
macro_rules! rotation_matrix_impl(
|
||||
($t: ident, $tlv: ident, $tav: ident) => (
|
||||
impl<N: Cast<f32> + Algebraic + Trigonometric + Num + Clone>
|
||||
impl<N: Cast<f32> + Real + Real + Num + Clone>
|
||||
RotationMatrix<$tlv<N>, $tav<N>, $t<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn to_rot_mat(&self) -> $t<N> {
|
||||
@ -201,19 +201,18 @@ macro_rules! approx_eq_impl(
|
||||
($t: ident) => (
|
||||
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
|
||||
#[inline]
|
||||
fn approx_epsilon() -> N {
|
||||
// ApproxEq::<N>::approx_epsilon()
|
||||
fail!("approx_epsilon is broken since rust revision 8693943676487c01fa09f5f3daf0df6a1f71e24d.")
|
||||
fn approx_epsilon(_: Option<$t<N>>) -> N {
|
||||
ApproxEq::approx_epsilon(None::<N>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq(&self, other: &$t<N>) -> bool {
|
||||
self.submat.approx_eq(&other.submat)
|
||||
fn approx_eq(a: &$t<N>, b: &$t<N>) -> bool {
|
||||
ApproxEq::approx_eq(&a.submat, &b.submat)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N) -> bool {
|
||||
self.submat.approx_eq_eps(&other.submat, epsilon)
|
||||
fn approx_eq_eps(a: &$t<N>, b: &$t<N>, epsilon: &N) -> bool {
|
||||
ApproxEq::approx_eq_eps(&a.submat, &b.submat, epsilon)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -91,7 +91,7 @@ impl<N: Clone + One + Zero + Neg<N>> Basis for Vec2<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Ord + Algebraic + Signed> Basis for Vec3<N> {
|
||||
impl<N: Clone + Ord + Real + Signed> Basis for Vec3<N> {
|
||||
#[inline(always)]
|
||||
fn canonical_basis(f: |Vec3<N>| -> bool) {
|
||||
if !f(Vec3::new(One::one(), Zero::zero(), Zero::zero())) { return };
|
||||
|
@ -1,8 +1,8 @@
|
||||
use std::cast;
|
||||
use std::num::{Zero, One, Algebraic, Bounded};
|
||||
use std::num::{Zero, One, Real, Bounded};
|
||||
use std::vec::{VecIterator, VecMutIterator};
|
||||
use std::iter::{Iterator, FromIterator};
|
||||
use std::cmp::ApproxEq;
|
||||
use traits::operations::ApproxEq;
|
||||
use traits::structure::{Iterable, IterableMut, Indexable, Basis, Dim};
|
||||
use traits::geometry::{Translation, Dot, Norm};
|
||||
use structs::vec;
|
||||
@ -159,7 +159,7 @@ impl<N: Clone + Add<N, N> + Neg<N>> Translation<vec::Vec0<N>> for vec::Vec0<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Num + Algebraic> Norm<N> for vec::Vec0<N> {
|
||||
impl<N: Clone + Num + Real> Norm<N> for vec::Vec0<N> {
|
||||
#[inline]
|
||||
fn sqnorm(_: &vec::Vec0<N>) -> N {
|
||||
Zero::zero()
|
||||
@ -183,18 +183,17 @@ impl<N: Clone + Num + Algebraic> Norm<N> for vec::Vec0<N> {
|
||||
|
||||
impl<N: ApproxEq<N>> ApproxEq<N> for vec::Vec0<N> {
|
||||
#[inline]
|
||||
fn approx_epsilon() -> N {
|
||||
fail!("approx_epsilon is broken since rust revision 8693943676487c01fa09f5f3daf0df6a1f71e24d.")
|
||||
// ApproxEq::<N>::approx_epsilon()
|
||||
fn approx_epsilon(_: Option<vec::Vec0<N>>) -> N {
|
||||
ApproxEq::approx_epsilon(None::<N>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq(&self, _: &vec::Vec0<N>) -> bool {
|
||||
fn approx_eq(_: &vec::Vec0<N>, _: &vec::Vec0<N>) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, _: &vec::Vec0<N>, _: &N) -> bool {
|
||||
fn approx_eq_eps(_: &vec::Vec0<N>, _: &vec::Vec0<N>, _: &N) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,10 @@
|
||||
#[allow(missing_doc)]; // we allow missing to avoid having to document the vector components.
|
||||
|
||||
use std::cast;
|
||||
use std::num::{Zero, One, Algebraic, Bounded};
|
||||
use std::num::{Zero, One, Real, Bounded};
|
||||
use std::vec::{VecIterator, VecMutIterator};
|
||||
use std::iter::{Iterator, FromIterator};
|
||||
use std::cmp::ApproxEq;
|
||||
use traits::operations::ApproxEq;
|
||||
|
||||
use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm,
|
||||
Translation, Translate};
|
||||
|
@ -223,7 +223,7 @@ macro_rules! container_impl(
|
||||
|
||||
macro_rules! basis_impl(
|
||||
($t: ident, $trhs: ident, $dim: expr) => (
|
||||
impl<N: Clone + Num + Algebraic + ApproxEq<N> + $trhs<N, $t<N>>> Basis for $t<N> {
|
||||
impl<N: Clone + Num + Real + ApproxEq<N> + $trhs<N, $t<N>>> Basis for $t<N> {
|
||||
#[inline]
|
||||
fn canonical_basis(f: |$t<N>| -> bool) {
|
||||
for i in range(0u, $dim) {
|
||||
@ -262,7 +262,7 @@ macro_rules! basis_impl(
|
||||
elt = elt - v * Dot::dot(&elt, v)
|
||||
};
|
||||
|
||||
if !Norm::sqnorm(&elt).approx_eq(&Zero::zero()) {
|
||||
if !ApproxEq::approx_eq(&Norm::sqnorm(&elt), &Zero::zero()) {
|
||||
let new_element = Norm::normalize_cpy(&elt);
|
||||
|
||||
if !f(new_element.clone()) { return };
|
||||
@ -433,7 +433,7 @@ macro_rules! translation_impl(
|
||||
|
||||
macro_rules! norm_impl(
|
||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||
impl<N: Clone + Num + Algebraic> Norm<N> for $t<N> {
|
||||
impl<N: Clone + Num + Real> Norm<N> for $t<N> {
|
||||
#[inline]
|
||||
fn sqnorm(v: &$t<N>) -> N {
|
||||
Dot::dot(v, v)
|
||||
@ -496,19 +496,20 @@ macro_rules! approx_eq_impl(
|
||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
|
||||
#[inline]
|
||||
fn approx_epsilon() -> N {
|
||||
fail!("approx_epsilon is broken since rust revision 8693943676487c01fa09f5f3daf0df6a1f71e24d.")
|
||||
// ApproxEq::<N>::approx_epsilon()
|
||||
fn approx_epsilon(_: Option<$t<N>>) -> N {
|
||||
ApproxEq::approx_epsilon(None::<N>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq(&self, other: &$t<N>) -> bool {
|
||||
self.$comp0.approx_eq(&other.$comp0) $(&& self.$compN.approx_eq(&other.$compN))*
|
||||
fn approx_eq(a: &$t<N>, b: &$t<N>) -> bool {
|
||||
ApproxEq::approx_eq(&a.$comp0, &b.$comp0)
|
||||
$(&& ApproxEq::approx_eq(&a.$compN, &b.$compN))*
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &$t<N>, eps: &N) -> bool {
|
||||
self.$comp0.approx_eq_eps(&other.$comp0, eps) $(&& self.$compN.approx_eq_eps(&other.$compN, eps))*
|
||||
fn approx_eq_eps(a: &$t<N>, b: &$t<N>, eps: &N) -> bool {
|
||||
ApproxEq::approx_eq_eps(&a.$comp0, &b.$comp0, eps)
|
||||
$(&& ApproxEq::approx_eq_eps(&a.$compN, &b.$compN, eps))*
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -1,6 +1,5 @@
|
||||
use std::num::{Real, abs};
|
||||
use std::rand::random;
|
||||
use std::cmp::ApproxEq;
|
||||
use na::{Vec1, Vec3, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6, Rot3, DMat, DVec, Indexable};
|
||||
use na;
|
||||
|
||||
@ -9,7 +8,7 @@ macro_rules! test_inv_mat_impl(
|
||||
10000.times(|| {
|
||||
let randmat : $t = random();
|
||||
|
||||
assert!((na::inv(&randmat).unwrap() * randmat).approx_eq(&na::one()));
|
||||
assert!(na::approx_eq(&(na::inv(&randmat).unwrap() * randmat), &na::one()));
|
||||
})
|
||||
);
|
||||
)
|
||||
@ -90,7 +89,7 @@ fn test_rotation2() {
|
||||
let randmat: na::Rot2<f64> = na::one();
|
||||
let ang = Vec1::new(abs::<f64>(random()) % Real::pi());
|
||||
|
||||
assert!(na::rotation(&na::append_rotation(&randmat, &ang)).approx_eq(&ang));
|
||||
assert!(na::approx_eq(&na::rotation(&na::append_rotation(&randmat, &ang)), &ang));
|
||||
})
|
||||
}
|
||||
|
||||
@ -109,7 +108,7 @@ fn test_inv_rotation3() {
|
||||
let ang = na::normalize(&dir) * (abs::<f64>(random()) % Real::pi());
|
||||
let rot = na::append_rotation(&randmat, &ang);
|
||||
|
||||
assert!((na::transpose(&rot) * rot).approx_eq(&na::one()));
|
||||
assert!(na::approx_eq(&(na::transpose(&rot) * rot), &na::one()));
|
||||
})
|
||||
}
|
||||
|
||||
@ -125,7 +124,7 @@ fn test_mean_dmat() {
|
||||
]
|
||||
);
|
||||
|
||||
assert!(na::mean(&mat).approx_eq(&DVec::from_vec(3, [4.0f64, 5.0, 6.0])));
|
||||
assert!(na::approx_eq(&na::mean(&mat), &DVec::from_vec(3, [4.0f64, 5.0, 6.0])));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -152,7 +151,7 @@ fn test_cov_dmat() {
|
||||
]
|
||||
);
|
||||
|
||||
assert!(na::cov(&mat).approx_eq(&expected));
|
||||
assert!(na::approx_eq(&na::cov(&mat), &expected));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1,5 +1,4 @@
|
||||
use std::rand::{random};
|
||||
use std::cmp::ApproxEq;
|
||||
use na::{Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6};
|
||||
use na::{Mat3, Iterable, IterableMut}; // FIXME: get rid of that
|
||||
use na;
|
||||
@ -28,7 +27,7 @@ macro_rules! test_commut_dot_impl(
|
||||
let v1 : $t = random();
|
||||
let v2 : $t = random();
|
||||
|
||||
assert!(na::dot(&v1, &v2).approx_eq(&na::dot(&v2, &v1)));
|
||||
assert!(na::approx_eq(&na::dot(&v1, &v2), &na::dot(&v2, &v1)));
|
||||
})
|
||||
);
|
||||
)
|
||||
@ -39,10 +38,10 @@ macro_rules! test_scalar_op_impl(
|
||||
let v1 : $t = random();
|
||||
let n : $n = random();
|
||||
|
||||
assert!(((v1 * n) / n).approx_eq(&v1));
|
||||
assert!(((v1 / n) * n).approx_eq(&v1));
|
||||
assert!(((v1 - n) + n).approx_eq(&v1));
|
||||
assert!(((v1 + n) - n).approx_eq(&v1));
|
||||
assert!(na::approx_eq(&((v1 * n) / n), &v1));
|
||||
assert!(na::approx_eq(&((v1 / n) * n), &v1));
|
||||
assert!(na::approx_eq(&((v1 - n) + n), &v1));
|
||||
assert!(na::approx_eq(&((v1 + n) - n), &v1));
|
||||
|
||||
let mut v1 : $t = random();
|
||||
let v0 : $t = v1.clone();
|
||||
@ -51,7 +50,7 @@ macro_rules! test_scalar_op_impl(
|
||||
v1 = v1 * n;
|
||||
v1 = v1 / n;
|
||||
|
||||
assert!(v1.approx_eq(&v0));
|
||||
assert!(na::approx_eq(&v1, &v0));
|
||||
})
|
||||
);
|
||||
)
|
||||
@ -61,12 +60,12 @@ macro_rules! test_basis_impl(
|
||||
10000.times(|| {
|
||||
na::canonical_basis(|e1: $t| {
|
||||
na::canonical_basis(|e2: $t| {
|
||||
assert!(e1 == e2 || na::dot(&e1, &e2).approx_eq(&na::zero()));
|
||||
assert!(e1 == e2 || na::approx_eq(&na::dot(&e1, &e2), &na::zero()));
|
||||
|
||||
true
|
||||
});
|
||||
|
||||
assert!(na::norm(&e1).approx_eq(&na::one()));
|
||||
assert!(na::approx_eq(&na::norm(&e1), &na::one()));
|
||||
|
||||
true
|
||||
})
|
||||
@ -82,12 +81,12 @@ macro_rules! test_subspace_basis_impl(
|
||||
|
||||
na::orthonormal_subspace_basis(&v1, |e1| {
|
||||
// check vectors are orthogonal to v1
|
||||
assert!(na::dot(&v1, &e1).approx_eq(&na::zero()));
|
||||
assert!(na::approx_eq(&na::dot(&v1, &e1), &na::zero()));
|
||||
// check vectors form an orthonormal basis
|
||||
assert!(na::norm(&e1).approx_eq(&na::one()));
|
||||
assert!(na::approx_eq(&na::norm(&e1), &na::one()));
|
||||
// check vectors form an ortogonal basis
|
||||
na::orthonormal_subspace_basis(&v1, |e2| {
|
||||
assert!(e1 == e2 || na::dot(&e1, &e2).approx_eq(&na::zero()));
|
||||
assert!(e1 == e2 || na::approx_eq(&na::dot(&e1, &e2), &na::zero()));
|
||||
|
||||
true
|
||||
});
|
||||
@ -105,8 +104,8 @@ fn test_cross_vec3() {
|
||||
let v2 : Vec3<f64> = random();
|
||||
let v3 : Vec3<f64> = na::cross(&v1, &v2);
|
||||
|
||||
assert!(na::dot(&v3, &v2).approx_eq(&na::zero()));
|
||||
assert!(na::dot(&v3, &v1).approx_eq(&na::zero()));
|
||||
assert!(na::approx_eq(&na::dot(&v3, &v2), &na::zero()));
|
||||
assert!(na::approx_eq(&na::dot(&v3, &v1), &na::zero()));
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -218,7 +218,7 @@ pub trait Dot<N> {
|
||||
}
|
||||
|
||||
/// Traits of objects having an euclidian norm.
|
||||
pub trait Norm<N: Algebraic> {
|
||||
pub trait Norm<N: Real> {
|
||||
/// Computes the norm of `self`.
|
||||
#[inline]
|
||||
fn norm(v: &Self) -> N {
|
||||
|
@ -4,11 +4,11 @@ pub use self::geometry::{AbsoluteRotate, Cross, CrossMatrix, Dot, FromHomogeneou
|
||||
Rotation, RotationMatrix, RotationWithTranslation, ToHomogeneous,
|
||||
Transform, Transformation, Translate, Translation, UniformSphereSample};
|
||||
|
||||
pub use self::structure::{AlgebraicVec, AlgebraicVecExt, Basis, Cast, Col, Dim, Indexable,
|
||||
pub use self::structure::{RealVec, RealVecExt, Basis, Cast, Col, Dim, Indexable,
|
||||
Iterable, IterableMut, Mat, Row, Vec, VecExt};
|
||||
|
||||
pub use self::operations::{Absolute, Cov, Inv, LMul, Mean, Outer, RMul, ScalarAdd, ScalarSub,
|
||||
Transpose};
|
||||
pub use self::operations::{Absolute, ApproxEq, Cov, Inv, LMul, Mean, Outer, RMul, ScalarAdd,
|
||||
ScalarSub, Transpose};
|
||||
|
||||
pub mod geometry;
|
||||
pub mod structure;
|
||||
|
@ -1,5 +1,42 @@
|
||||
//! Low level operations on vectors and matrices.
|
||||
|
||||
/// Trait for testing approximate equality
|
||||
pub trait ApproxEq<Eps> {
|
||||
/// Default epsilon for approximation.
|
||||
fn approx_epsilon(unused_self: Option<Self>) -> Eps;
|
||||
|
||||
/// Tests approximate equality using a custom epsilon.
|
||||
fn approx_eq_eps(a: &Self, other: &Self, epsilon: &Eps) -> bool;
|
||||
|
||||
/// Tests approximate equality.
|
||||
fn approx_eq(a: &Self, b: &Self) -> bool {
|
||||
ApproxEq::approx_eq_eps(a, b, &ApproxEq::approx_epsilon(None::<Self>))
|
||||
}
|
||||
}
|
||||
|
||||
impl ApproxEq<f32> for f32 {
|
||||
#[inline]
|
||||
fn approx_epsilon(_: Option<f32>) -> f32 {
|
||||
1.0e-6
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(a: &f32, b: &f32, epsilon: &f32) -> bool {
|
||||
(*a - *b).abs() < *epsilon
|
||||
}
|
||||
}
|
||||
|
||||
impl ApproxEq<f64> for f64 {
|
||||
#[inline]
|
||||
fn approx_epsilon(_: Option<f64>) -> f64 {
|
||||
1.0e-6
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(a: &f64, b: &f64, approx_epsilon: &f64) -> bool {
|
||||
(*a - *b).abs() < *approx_epsilon
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait of objects having an absolute value.
|
||||
/// This is useful if the object does not have the same type as its absolute value.
|
||||
|
@ -27,8 +27,8 @@ pub trait Vec<N>: Dim + Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Zero + E
|
||||
+ Div<N, Self> + Dot<N> {
|
||||
}
|
||||
|
||||
/// Trait of vector with components implementing the `Algebraic` trait.
|
||||
pub trait AlgebraicVec<N: Algebraic>: Vec<N> + Norm<N> {
|
||||
/// Trait of vector with components implementing the `Real` trait.
|
||||
pub trait RealVec<N: Real>: Vec<N> + Norm<N> {
|
||||
}
|
||||
|
||||
/// Trait grouping uncommon, low-level and borderline (from the mathematical point of view)
|
||||
@ -39,19 +39,19 @@ pub trait VecExt<N>: Vec<N> + Indexable<uint, N> + Iterable<N> +
|
||||
|
||||
/// Trait grouping uncommon, low-level and borderline (from the mathematical point of view)
|
||||
/// operations on vectors.
|
||||
pub trait AlgebraicVecExt<N: Algebraic>: AlgebraicVec<N> + VecExt<N> + Basis + Round { }
|
||||
pub trait RealVecExt<N: Real>: RealVec<N> + VecExt<N> + Basis + Round { }
|
||||
|
||||
impl<N, V: Dim + Sub<V, V> + Add<V, V> + Neg<V> + Zero + Eq + Mul<N, V> + Div<N, V> + Dot<N>>
|
||||
Vec<N> for V { }
|
||||
|
||||
impl<N: Algebraic, V: Vec<N> + Norm<N>> AlgebraicVec<N> for V { }
|
||||
impl<N: Real, V: Vec<N> + Norm<N>> RealVec<N> for V { }
|
||||
|
||||
impl<N,
|
||||
V: Vec<N> + Indexable<uint, N> + Iterable<N> +
|
||||
UniformSphereSample + ScalarAdd<N> + ScalarSub<N> + Bounded + Orderable>
|
||||
VecExt<N> for V { }
|
||||
|
||||
impl<N: Algebraic, V: AlgebraicVec<N> + VecExt<N> + Basis + Round> AlgebraicVecExt<N> for V { }
|
||||
impl<N: Real, V: RealVec<N> + VecExt<N> + Basis + Round> RealVecExt<N> for V { }
|
||||
|
||||
// FIXME: return an iterator instead
|
||||
/// Traits of objects which can form a basis (typically vectors).
|
||||
|
Loading…
Reference in New Issue
Block a user