Make epsilon an associated type on ApproxEq
This commit is contained in:
parent
78f86a33cd
commit
0584bcac64
8 changed files with 49 additions and 27 deletions
12
src/angle.rs
12
src/angle.rs
|
@ -80,7 +80,7 @@ pub trait Angle
|
|||
>
|
||||
: Clone + Zero
|
||||
+ PartialEq + PartialOrd
|
||||
+ ApproxEq<S>
|
||||
+ ApproxEq<Epsilon = S>
|
||||
+ Neg<Output=Self>
|
||||
+ Into<Rad<S>>
|
||||
+ Into<Deg<S>>
|
||||
|
@ -279,16 +279,18 @@ fmt::Debug for Deg<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat>
|
||||
ApproxEq<S> for Rad<S> {
|
||||
impl<S: BaseFloat> ApproxEq for Rad<S> {
|
||||
type Epsilon = S;
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Rad<S>, epsilon: &S) -> bool {
|
||||
self.s.approx_eq_eps(&other.s, epsilon)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat>
|
||||
ApproxEq<S> for Deg<S> {
|
||||
impl<S: BaseFloat> ApproxEq for Deg<S> {
|
||||
type Epsilon = S;
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Deg<S>, epsilon: &S) -> bool {
|
||||
self.s.approx_eq_eps(&other.s, epsilon)
|
||||
|
|
|
@ -16,23 +16,26 @@
|
|||
use rust_num::{Float, NumCast};
|
||||
use rust_num::traits::cast;
|
||||
|
||||
pub trait ApproxEq<T: NumCast + Float>: Sized {
|
||||
fn approx_epsilon(_hack: Option<Self>) -> T {
|
||||
pub trait ApproxEq: Sized {
|
||||
type Epsilon: NumCast + Float;
|
||||
|
||||
fn approx_epsilon() -> Self::Epsilon {
|
||||
cast(1.0e-5f64).unwrap()
|
||||
}
|
||||
|
||||
fn approx_eq(&self, other: &Self) -> bool {
|
||||
let eps: T = ApproxEq::approx_epsilon(None::<Self>);
|
||||
self.approx_eq_eps(other, &eps)
|
||||
self.approx_eq_eps(other, &Self::approx_epsilon())
|
||||
}
|
||||
|
||||
fn approx_eq_eps(&self, other: &Self, epsilon: &T) -> bool;
|
||||
fn approx_eq_eps(&self, other: &Self, epsilon: &Self::Epsilon) -> bool;
|
||||
}
|
||||
|
||||
|
||||
macro_rules! approx_float(
|
||||
($S:ident) => (
|
||||
impl ApproxEq<$S> for $S {
|
||||
impl ApproxEq for $S {
|
||||
type Epsilon = $S;
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &$S, epsilon: &$S) -> bool {
|
||||
(*self - *other).abs() < *epsilon
|
||||
|
@ -62,9 +65,8 @@ macro_rules! assert_approx_eq(
|
|||
($given: expr, $expected: expr) => ({
|
||||
let (given_val, expected_val) = (&($given), &($expected));
|
||||
if !given_val.approx_eq(expected_val) {
|
||||
panic!("assertion failed: `left ≈ right` (left: `{:?}`, right: `{:?}`, tolerance: `{:?}`)",
|
||||
*given_val, *expected_val,
|
||||
ApproxEq::approx_epsilon(Some(*given_val))
|
||||
panic!("assertion failed: `left ≈ right` (left: `{:?}`, right: `{:?}`)",
|
||||
*given_val, *expected_val
|
||||
);
|
||||
}
|
||||
})
|
||||
|
|
|
@ -249,7 +249,7 @@ impl<S: Copy + Neg<Output = S>> Matrix4<S> {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait Matrix<S: BaseFloat, V: Vector<S> + 'static>: Array2<V, V, S> + ApproxEq<S> + Sized // where
|
||||
pub trait Matrix<S: BaseFloat, V: Vector<S> + 'static>: Array2<V, V, S> + ApproxEq<Epsilon = S> + Sized // where
|
||||
// FIXME: blocked by rust-lang/rust#20671
|
||||
//
|
||||
// for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>,
|
||||
|
@ -790,7 +790,9 @@ impl<S: BaseFloat> Matrix<S, Vector4<S>> for Matrix4<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> ApproxEq<S> for Matrix2<S> {
|
||||
impl<S: BaseFloat> ApproxEq for Matrix2<S> {
|
||||
type Epsilon = S;
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Matrix2<S>, epsilon: &S) -> bool {
|
||||
self[0].approx_eq_eps(&other[0], epsilon) &&
|
||||
|
@ -798,7 +800,9 @@ impl<S: BaseFloat> ApproxEq<S> for Matrix2<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> ApproxEq<S> for Matrix3<S> {
|
||||
impl<S: BaseFloat> ApproxEq for Matrix3<S> {
|
||||
type Epsilon = S;
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Matrix3<S>, epsilon: &S) -> bool {
|
||||
self[0].approx_eq_eps(&other[0], epsilon) &&
|
||||
|
@ -807,7 +811,9 @@ impl<S: BaseFloat> ApproxEq<S> for Matrix3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> ApproxEq<S> for Matrix4<S> {
|
||||
impl<S: BaseFloat> ApproxEq for Matrix4<S> {
|
||||
type Epsilon = S;
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Matrix4<S>, epsilon: &S) -> bool {
|
||||
self[0].approx_eq_eps(&other[0], epsilon) &&
|
||||
|
|
|
@ -110,7 +110,7 @@ impl BaseInt for u64 {}
|
|||
impl BaseInt for usize {}
|
||||
|
||||
/// Base floating point types
|
||||
pub trait BaseFloat : BaseNum + Float + ApproxEq<Self> {}
|
||||
pub trait BaseFloat : BaseNum + Float + ApproxEq<Epsilon = Self> {}
|
||||
|
||||
impl BaseFloat for f32 {}
|
||||
impl BaseFloat for f64 {}
|
||||
|
|
|
@ -190,7 +190,9 @@ impl<S: BaseNum> Point<S> for Point2<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> ApproxEq<S> for Point2<S> {
|
||||
impl<S: BaseFloat> ApproxEq for Point2<S> {
|
||||
type Epsilon = S;
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Point2<S>, epsilon: &S) -> bool {
|
||||
self.x.approx_eq_eps(&other.x, epsilon) &&
|
||||
|
@ -270,7 +272,9 @@ impl<S: BaseNum> Point<S> for Point3<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> ApproxEq<S> for Point3<S> {
|
||||
impl<S: BaseFloat> ApproxEq for Point3<S> {
|
||||
type Epsilon = S;
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Point3<S>, epsilon: &S) -> bool {
|
||||
self.x.approx_eq_eps(&other.x, epsilon) &&
|
||||
|
|
|
@ -170,7 +170,9 @@ impl<'a, 'b, S: BaseFloat> Mul<&'b Quaternion<S>> for &'a Quaternion<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> ApproxEq<S> for Quaternion<S> {
|
||||
impl<S: BaseFloat> ApproxEq for Quaternion<S> {
|
||||
type Epsilon = S;
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Quaternion<S>, epsilon: &S) -> bool {
|
||||
self.s.approx_eq_eps(&other.s, epsilon) &&
|
||||
|
|
|
@ -25,7 +25,7 @@ use vector::{Vector, Vector2, Vector3};
|
|||
|
||||
/// A trait for a generic rotation. A rotation is a transformation that
|
||||
/// creates a circular motion, and preserves at least one point in the space.
|
||||
pub trait Rotation<S: BaseFloat, P: Point<S>>: PartialEq + ApproxEq<S> + Sized {
|
||||
pub trait Rotation<S: BaseFloat, P: Point<S>>: PartialEq + ApproxEq<Epsilon = S> + Sized {
|
||||
/// Create the identity transform (causes no transformation).
|
||||
fn one() -> Self;
|
||||
|
||||
|
@ -206,7 +206,9 @@ impl<S: BaseFloat> Rotation<S, Point2<S>> for Basis2<S> {
|
|||
fn invert_self(&mut self) { self.mat.invert_self(); }
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> ApproxEq<S> for Basis2<S> {
|
||||
impl<S: BaseFloat> ApproxEq for Basis2<S> {
|
||||
type Epsilon = S;
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Basis2<S>, epsilon: &S) -> bool {
|
||||
self.mat.approx_eq_eps(&other.mat, epsilon)
|
||||
|
@ -288,7 +290,9 @@ impl<S: BaseFloat> Rotation<S, Point3<S>> for Basis3<S> {
|
|||
fn invert_self(&mut self) { self.mat.invert_self(); }
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> ApproxEq<S> for Basis3<S> {
|
||||
impl<S: BaseFloat> ApproxEq for Basis3<S> {
|
||||
type Epsilon = S;
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &Basis3<S>, epsilon: &S) -> bool {
|
||||
self.mat.approx_eq_eps(&other.mat, epsilon)
|
||||
|
|
|
@ -287,7 +287,9 @@ macro_rules! vec {
|
|||
fn neg(self) -> $VectorN<S> { $VectorN::new($(-self.$field),+) }
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> ApproxEq<S> for $VectorN<S> {
|
||||
impl<S: BaseFloat> ApproxEq for $VectorN<S> {
|
||||
type Epsilon = S;
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &$VectorN<S>, epsilon: &S) -> bool {
|
||||
$(self.$field.approx_eq_eps(&other.$field, epsilon))&&+
|
||||
|
@ -618,7 +620,7 @@ impl<S: BaseNum> Vector4<S> {
|
|||
/// Specifies geometric operations for vectors. This is only implemented for
|
||||
/// 2-dimensional and 3-dimensional vectors.
|
||||
pub trait EuclideanVector<S: BaseFloat>: Vector<S>
|
||||
+ ApproxEq<S>
|
||||
+ ApproxEq<Epsilon = S>
|
||||
+ Sized {
|
||||
/// Returns `true` if the vector is perpendicular (at right angles) to the
|
||||
/// other vector.
|
||||
|
|
Loading…
Reference in a new issue