Using rust-lang/num

This commit is contained in:
Dzmitry Malyshau 2015-04-04 21:19:11 -04:00
parent 94d428d23e
commit 8db429acae
15 changed files with 84 additions and 100 deletions

View file

@ -24,4 +24,5 @@ name = "cgmath"
rustc_serialize = "*"
[dependencies]
num = "*"
rand = "*"

View file

@ -20,15 +20,18 @@
//! dimension) where the slope of every line is either 0 or undefined. These
//! are useful for very cheap collision detection.
use std::fmt;
use rust_num::{Float, zero, one};
use bound::*;
use point::{Point, Point2, Point3};
use vector::{Vector, Vector2, Vector3};
use ray::{Ray2};
use intersect::Intersect;
use num::{zero, one, BaseNum, BaseFloat};
use num::{BaseNum, BaseFloat};
use plane::Plane;
use std::fmt;
use std::num::Float;
pub trait Aabb<S: BaseNum, V: Vector<S>, P: Point<S, V>>: Sized {
/// Create a new AABB using two points as opposing corners.

View file

@ -17,14 +17,16 @@
use std::fmt;
use std::f64;
use std::num::{cast, Float};
use std::num::cast;
use std::ops::*;
use rand::{Rand, Rng};
use rand::distributions::range::SampleRange;
use rust_num::{One, Zero, one, zero};
use approx::ApproxEq;
use num::{BaseFloat, One, one, Zero, zero};
use num::BaseFloat;
/// An angle, in radians
#[derive(Copy, Clone, PartialEq, PartialOrd, Hash, RustcEncodable, RustcDecodable)]

View file

@ -13,12 +13,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::num;
use std::num::Float;
use std::num::cast;
use rust_num::Float;
pub trait ApproxEq<T: Float>: Sized {
fn approx_epsilon(_hack: Option<Self>) -> T {
num::cast(1.0e-5f64).unwrap()
cast(1.0e-5f64).unwrap()
}
fn approx_eq(&self, other: &Self) -> bool {

View file

@ -31,6 +31,7 @@
//! `look_at`, `from_angle`, `from_euler`, and `from_axis_angle` methods.
//! These are provided for convenience.
extern crate num as rust_num;
extern crate rustc_serialize;
extern crate rand;

View file

@ -16,7 +16,10 @@
//! Line segments
use std::marker::PhantomData;
use num::{BaseNum, BaseFloat, Zero, zero, One, one};
use rust_num::{Zero, zero, One, one};
use num::{BaseNum, BaseFloat};
use point::{Point, Point2, Point3};
use vector::{Vector, Vector2, Vector3};
use ray::{Ray2};

View file

@ -22,10 +22,12 @@ use std::ops::*;
use rand::{Rand, Rng};
use rust_num::{Zero, zero, One, one};
use angle::{Rad, sin, cos, sin_cos};
use approx::ApproxEq;
use array::{Array1, Array2, FixedArray};
use num::{BaseFloat, BaseNum, Zero, zero, One, one};
use num::{BaseFloat, BaseNum};
use point::{Point, Point3};
use quaternion::{Quaternion, ToQuaternion};
use vector::{Vector, EuclideanVector};
@ -82,7 +84,7 @@ impl<S: BaseNum> Matrix2<S> {
}
}
impl<S: BaseFloat + 'static> Matrix2<S> {
impl<S: BaseFloat> Matrix2<S> {
/// Create a transformation matrix that will cause a vector to point at
/// `dir`, using `up` for orientation.
pub fn look_at(dir: &Vector2<S>, up: &Vector2<S>) -> Matrix2<S> {
@ -109,7 +111,7 @@ impl<S: Copy + Neg<Output = S>> Matrix2<S> {
}
}
impl<S: BaseNum> Matrix3<S> {
impl<S> Matrix3<S> {
/// Create a new matrix, providing values for each index.
#[inline]
pub fn new(c0r0:S, c0r1:S, c0r2:S,
@ -125,7 +127,9 @@ impl<S: BaseNum> Matrix3<S> {
pub fn from_cols(c0: Vector3<S>, c1: Vector3<S>, c2: Vector3<S>) -> Matrix3<S> {
Matrix3 { x: c0, y: c1, z: c2 }
}
}
impl<S: BaseNum> Matrix3<S> {
/// Create a new diagonal matrix, providing a single value to use for each
/// non-zero index.
#[inline]
@ -148,7 +152,7 @@ impl<S: BaseNum> Matrix3<S> {
}
}
impl<S: BaseFloat + 'static> Matrix3<S> {
impl<S: BaseFloat> Matrix3<S> {
/// Create a transformation matrix that will cause a vector to point at
/// `dir`, using `up` for orientation.
pub fn look_at(dir: &Vector3<S>, up: &Vector3<S>) -> Matrix3<S> {
@ -240,7 +244,7 @@ impl<S: Copy + Neg<Output = S>> Matrix3<S> {
}
}
impl<S: BaseNum> Matrix4<S> {
impl<S> Matrix4<S> {
/// Create a new matrix, providing values for each index.
#[inline]
pub fn new(c0r0: S, c0r1: S, c0r2: S, c0r3: S,
@ -258,7 +262,9 @@ impl<S: BaseNum> Matrix4<S> {
pub fn from_cols(c0: Vector4<S>, c1: Vector4<S>, c2: Vector4<S>, c3: Vector4<S>) -> Matrix4<S> {
Matrix4 { x: c0, y: c1, z: c2, w: c3 }
}
}
impl<S: BaseNum> Matrix4<S> {
/// Create a new diagonal matrix, providing a single value to use for each
/// non-zero index.
#[inline]
@ -407,42 +413,42 @@ pub trait Matrix<S: BaseFloat, V: Clone + Vector<S>>: Array2<V, V, S>
fn is_symmetric(&self) -> bool;
}
impl<S: BaseFloat + 'static> Add for Matrix2<S> {
impl<S: BaseFloat> Add for Matrix2<S> {
type Output = Matrix2<S>;
#[inline]
fn add(self, other: Matrix2<S>) -> Matrix2<S> { self.add_m(&other) }
}
impl<S: BaseFloat + 'static> Add for Matrix3<S> {
impl<S: BaseFloat> Add for Matrix3<S> {
type Output = Matrix3<S>;
#[inline]
fn add(self, other: Matrix3<S>) -> Matrix3<S> { self.add_m(&other) }
}
impl<S: BaseFloat + 'static> Add for Matrix4<S> {
impl<S: BaseFloat> Add for Matrix4<S> {
type Output = Matrix4<S>;
#[inline]
fn add(self, other: Matrix4<S>) -> Matrix4<S> { self.add_m(&other) }
}
impl<S: BaseFloat + 'static> Sub for Matrix2<S> {
impl<S: BaseFloat> Sub for Matrix2<S> {
type Output = Matrix2<S>;
#[inline]
fn sub(self, other: Matrix2<S>) -> Matrix2<S> { self.sub_m(&other) }
}
impl<S: BaseFloat + 'static> Sub for Matrix3<S> {
impl<S: BaseFloat> Sub for Matrix3<S> {
type Output = Matrix3<S>;
#[inline]
fn sub(self, other: Matrix3<S>) -> Matrix3<S> { self.sub_m(&other) }
}
impl<S: BaseFloat + 'static> Sub for Matrix4<S> {
impl<S: BaseFloat> Sub for Matrix4<S> {
type Output = Matrix4<S>;
#[inline]
@ -458,18 +464,22 @@ impl<S: Neg> Neg for Matrix2<S> {
}
}
impl<S: BaseFloat> Neg for Matrix3<S> {
type Output = Matrix3<S>;
impl<S: Neg> Neg for Matrix3<S> {
type Output = Matrix3<S::Output>;
#[inline]
fn neg(self) -> Matrix3<S> { Matrix3::from_cols(self[0].neg(), self[1].neg(), self[2].neg()) }
fn neg(self) -> Matrix3<S::Output> {
Matrix3::from_cols(self.x.neg(), self.y.neg(), self.z.neg())
}
}
impl<S: BaseFloat> Neg for Matrix4<S> {
type Output = Matrix4<S>;
impl<S: Neg> Neg for Matrix4<S> {
type Output = Matrix4<S::Output>;
#[inline]
fn neg(self) -> Matrix4<S> { Matrix4::from_cols(self[0].neg(), self[1].neg(), self[2].neg(), self[3].neg()) }
fn neg(self) -> Matrix4<S::Output> {
Matrix4::from_cols(self.x.neg(), self.y.neg(), self.z.neg(), self.w.neg())
}
}
impl<S: BaseFloat> Zero for Matrix2<S> {
@ -493,21 +503,21 @@ impl<S: BaseFloat> Zero for Matrix4<S> {
fn is_zero(&self) -> bool{ *self == zero() }
}
impl<S: BaseFloat + 'static> Mul for Matrix2<S> {
impl<S: BaseFloat> Mul for Matrix2<S> {
type Output = Matrix2<S>;
#[inline]
fn mul(self, other: Matrix2<S>) -> Matrix2<S> { self.mul_m(&other) }
}
impl<S: BaseFloat + 'static> Mul for Matrix3<S> {
impl<S: BaseFloat> Mul for Matrix3<S> {
type Output = Matrix3<S>;
#[inline]
fn mul(self, other: Matrix3<S>) -> Matrix3<S> { self.mul_m(&other) }
}
impl<S: BaseFloat + 'static> Mul for Matrix4<S> {
impl<S: BaseFloat> Mul for Matrix4<S> {
type Output = Matrix4<S>;
#[inline]
@ -781,7 +791,7 @@ impl<S: Copy + 'static> Array2<Vector4<S>, Vector4<S>, S> for Matrix4<S> {
}
}
impl<S: BaseFloat + 'static> Matrix<S, Vector2<S>> for Matrix2<S> {
impl<S: BaseFloat> Matrix<S, Vector2<S>> for Matrix2<S> {
#[inline]
fn mul_s(&self, s: S) -> Matrix2<S> {
Matrix2::from_cols(self[0].mul_s(s),
@ -899,7 +909,7 @@ impl<S: BaseFloat + 'static> Matrix<S, Vector2<S>> for Matrix2<S> {
}
}
impl<S: BaseFloat + 'static> Matrix<S, Vector3<S>> for Matrix3<S> {
impl<S: BaseFloat> Matrix<S, Vector3<S>> for Matrix3<S> {
#[inline]
fn mul_s(&self, s: S) -> Matrix3<S> {
Matrix3::from_cols(self[0].mul_s(s),
@ -1053,7 +1063,7 @@ macro_rules! dot_matrix4(
($A[3][$I]) * ($B[$J][3])
));
impl<S: BaseFloat + 'static> Matrix<S, Vector4<S>> for Matrix4<S> {
impl<S: BaseFloat> Matrix<S, Vector4<S>> for Matrix4<S> {
#[inline]
fn mul_s(&self, s: S) -> Matrix4<S> {
Matrix4::from_cols(self[0].mul_s(s),
@ -1345,7 +1355,7 @@ impl<S: BaseFloat> ToMatrix4<S> for Matrix3<S> {
}
}
impl<S: BaseFloat + 'static> ToQuaternion<S> for Matrix3<S> {
impl<S: BaseFloat> ToQuaternion<S> for Matrix3<S> {
/// Convert the matrix to a quaternion
fn to_quaternion(&self) -> Quaternion<S> {
// http://www.cs.ucr.edu/~vbz/resources/quatut.pdf

View file

@ -17,9 +17,10 @@ use approx::ApproxEq;
use std::cmp;
use std::fmt;
use std::num::{Float, Int, NumCast};
use std::ops::*;
use rust_num::{Float, Num, NumCast};
/// A trait providing a [partial ordering](http://mathworld.wolfram.com/PartialOrder.html).
pub trait PartialOrd {
fn partial_min(self, other: Self) -> Self;
@ -58,43 +59,18 @@ macro_rules! partial_ord_float (
partial_ord_float!(f32);
partial_ord_float!(f64);
/// Additive neutral element
pub trait Zero {
fn zero() -> Self;
fn is_zero(&self) -> bool;
}
/// Multiplicative neutral element
pub trait One {
fn one() -> Self;
}
/// Base numeric types with partial ordering
pub trait BaseNum:
Copy + NumCast + Clone + Add<Output=Self> + Sub<Output=Self> +
Mul<Output=Self> + Div<Output=Self> + Rem<Output=Self> + PartialEq
+ PartialOrd + cmp::PartialOrd + fmt::Debug + Zero + One
Copy + NumCast + Clone + Num
+ PartialOrd + cmp::PartialOrd + fmt::Debug
+ 'static
{}
macro_rules! impl_basenum_int (
($T: ident) => (
impl BaseNum for $T {}
impl Zero for $T {
fn zero() -> $T {
Int::zero()
}
fn is_zero(&self) -> bool {
*self == Int::zero()
}
}
impl One for $T {
fn one() -> $T {
Int::one()
}
}
)
);
@ -113,38 +89,15 @@ impl_basenum_int!(usize);
macro_rules! impl_basenum_float (
($T: ident) => (
impl BaseNum for $T {}
impl Zero for $T {
fn zero() -> $T {
Float::zero()
}
fn is_zero(&self) -> bool {
*self == Float::zero()
}
}
impl One for $T {
fn one() -> $T {
Float::one()
}
}
)
);
impl_basenum_float!(f32);
impl_basenum_float!(f64);
pub fn zero<T: Zero>() -> T {
Zero::zero()
}
pub fn one<T: One>() -> T {
One::one()
}
/// Base integer types
pub trait BaseInt : BaseNum + Int {}
pub trait BaseInt : BaseNum {}
impl BaseInt for i8 {}
impl BaseInt for i16 {}

View file

@ -15,9 +15,11 @@
use std::fmt;
use rust_num::{one, Zero, zero};
use approx::ApproxEq;
use intersect::Intersect;
use num::{BaseFloat, one, Zero, zero};
use num::{BaseFloat};
use point::{Point, Point3};
use ray::Ray3;
use vector::{Vector3, Vector4};

View file

@ -21,11 +21,13 @@ use std::fmt;
use std::mem;
use std::ops::*;
use rust_num::{one, zero};
use approx::ApproxEq;
use array::{Array1, FixedArray};
use bound::*;
use matrix::{Matrix, Matrix4};
use num::{BaseNum, BaseFloat, one, zero};
use num::{BaseNum, BaseFloat};
use plane::Plane;
use vector::*;

View file

@ -15,10 +15,12 @@
use std::num::cast;
use rust_num::{zero, one};
use angle::{Angle, tan, cot};
use frustum::Frustum;
use matrix::{Matrix4, ToMatrix4};
use num::{BaseFloat, zero, one};
use num::BaseFloat;
use plane::Plane;
/// Create a perspective projection matrix.

View file

@ -13,19 +13,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::f64;
use std::fmt;
use std::mem;
use std::f64;
use std::num::{cast, Float};
use std::num::cast;
use std::ops::*;
use rand::{Rand, Rng};
use rust_num::{Float, one, zero};
use angle::{Angle, Rad, acos, sin, sin_cos, rad};
use approx::ApproxEq;
use array::Array1;
use matrix::{Matrix3, ToMatrix3, ToMatrix4, Matrix4};
use num::{BaseFloat, one, zero};
use num::BaseFloat;
use point::Point3;
use rotation::{Rotation, Rotation3, Basis3, ToBasis3};
use vector::{Vector3, Vector, EuclideanVector};

View file

@ -15,9 +15,11 @@
//! Bounding sphere
use rust_num::zero;
use bound::*;
use intersect::Intersect;
use num::{BaseFloat, zero};
use num::BaseFloat;
use point::{Point, Point3};
use plane::Plane;
use ray::Ray3;

View file

@ -15,19 +15,20 @@
use std::fmt;
use rust_num::{zero, one};
use approx::ApproxEq;
use matrix::*;
use num::*;
use point::*;
use ray::Ray;
use rotation::*;
use std::marker::PhantomFn;
use vector::*;
/// A trait representing an [affine
/// transformation](https://en.wikipedia.org/wiki/Affine_transformation) that
/// can be applied to points or vectors. An affine transformation is one which
pub trait Transform<S: BaseNum, V: Vector<S>, P: Point<S, V>>: Sized + PhantomFn<S> {
pub trait Transform<S: BaseNum, V: Vector<S>, P: Point<S, V>>: Sized {
/// Create an identity transformation. That is, a transformation which
/// does nothing.
fn identity() -> Self;
@ -236,7 +237,7 @@ impl<S: BaseFloat + 'static> Transform3<S> for AffineMatrix3<S> {}
/// A trait that allows extracting components (rotation, translation, scale)
/// from an arbitrary transformations
pub trait ToComponents<S, V: Vector<S>, P: Point<S, V>, R: Rotation<S, V, P>>: PhantomFn<(S, P)> {
pub trait ToComponents<S, V: Vector<S>, P: Point<S, V>, R: Rotation<S, V, P>> {
/// Extract the (scale, rotation, translation) triple
fn decompose(&self) -> (V, R, V);
}

View file

@ -98,15 +98,16 @@
use std::fmt;
use std::mem;
use std::num::NumCast;
use std::ops::*;
use rand::{Rand, Rng};
use rust_num::{NumCast, Zero, One, zero, one};
use angle::{Rad, atan2, acos};
use approx::ApproxEq;
use array::{Array1, FixedArray};
use num::{BaseNum, BaseFloat, Zero, One, zero, one};
use num::{BaseNum, BaseFloat};
/// A trait that specifies a range of numeric operations for vectors. Not all
/// of these make sense from a linear algebra point of view, but are included
@ -214,7 +215,7 @@ macro_rules! vec(
$Self_::new($($field),+)
}
impl<$S: Zero> Zero for $Self_<$S> {
impl<$S: Zero + BaseNum> Zero for $Self_<$S> {
#[inline]
fn zero() -> $Self_<S> { $Self_ { $($field: zero()),+ } }
@ -222,7 +223,7 @@ macro_rules! vec(
fn is_zero(&self) -> bool { $((self.$field.is_zero()) )&&+ }
}
impl<$S: One> One for $Self_<$S> {
impl<$S: One + BaseNum> One for $Self_<$S> {
#[inline]
fn one() -> $Self_<$S> { $Self_ { $($field: one()),+ } }
}