Clean up numeric traits

This commit is contained in:
Brendan Zabarauskas 2014-05-26 10:10:04 -07:00
parent c54dc4fd61
commit d4ce9c7613
18 changed files with 317 additions and 317 deletions

View file

@ -1,4 +1,4 @@
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -23,14 +23,14 @@
use point::{Point, Point2, Point3};
use vector::{Vector, Vector2, Vector3};
use array::build;
use partial_ord::PartOrdPrim;
use num::BaseNum;
use std::fmt;
use std::num::{zero, one};
use std::iter::Iterator;
pub trait Aabb
<
S: PartOrdPrim,
S: BaseNum,
V: Vector<S, Slice>,
P: Point<S, V, Slice>,
Slice
@ -65,8 +65,8 @@ pub trait Aabb
/// Returns a new AABB that is grown to include the given point.
fn grow(&self, p: &P) -> Self {
let min : P = build(|i| self.min().i(i).min(*p.i(i)));
let max : P = build(|i| self.max().i(i).max(*p.i(i)));
let min : P = build(|i| self.min().i(i).partial_min(*p.i(i)));
let max : P = build(|i| self.max().i(i).partial_max(*p.i(i)));
Aabb::new(min, max)
}
@ -95,26 +95,26 @@ pub struct Aabb2<S> {
pub max: Point2<S>,
}
impl<S: PartOrdPrim> Aabb2<S> {
impl<S: BaseNum> Aabb2<S> {
/// Construct a new axis-aligned bounding box from two points.
#[inline]
pub fn new(p1: Point2<S>, p2: Point2<S>) -> Aabb2<S> {
Aabb2 {
min: Point2::new(p1.x.min(p2.x),
p1.y.min(p2.y)),
max: Point2::new(p1.x.max(p2.x),
p1.y.max(p2.y)),
min: Point2::new(p1.x.partial_min(p2.x),
p1.y.partial_min(p2.y)),
max: Point2::new(p1.x.partial_max(p2.x),
p1.y.partial_max(p2.y)),
}
}
}
impl<S: PartOrdPrim> Aabb<S, Vector2<S>, Point2<S>, [S, ..2]> for Aabb2<S> {
impl<S: BaseNum> Aabb<S, Vector2<S>, Point2<S>, [S, ..2]> for Aabb2<S> {
fn new(p1: Point2<S>, p2: Point2<S>) -> Aabb2<S> { Aabb2::new(p1, p2) }
#[inline] fn min<'a>(&'a self) -> &'a Point2<S> { &self.min }
#[inline] fn max<'a>(&'a self) -> &'a Point2<S> { &self.max }
}
impl<S: fmt::Show> fmt::Show for Aabb2<S> {
impl<S: BaseNum> fmt::Show for Aabb2<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{} - {}]", self.min, self.max)
}
@ -127,28 +127,28 @@ pub struct Aabb3<S> {
pub max: Point3<S>,
}
impl<S: PartOrdPrim> Aabb3<S> {
impl<S: BaseNum> Aabb3<S> {
/// Construct a new axis-aligned bounding box from two points.
#[inline]
pub fn new(p1: Point3<S>, p2: Point3<S>) -> Aabb3<S> {
Aabb3 {
min: Point3::new(p1.x.min(p2.x),
p1.y.min(p2.y),
p1.z.min(p2.z)),
max: Point3::new(p1.x.max(p2.x),
p1.y.max(p2.y),
p1.z.max(p2.z)),
min: Point3::new(p1.x.partial_min(p2.x),
p1.y.partial_min(p2.y),
p1.z.partial_min(p2.z)),
max: Point3::new(p1.x.partial_max(p2.x),
p1.y.partial_max(p2.y),
p1.z.partial_max(p2.z)),
}
}
}
impl<S: PartOrdPrim> Aabb<S, Vector3<S>, Point3<S>, [S, ..3]> for Aabb3<S> {
impl<S: BaseNum> Aabb<S, Vector3<S>, Point3<S>, [S, ..3]> for Aabb3<S> {
fn new(p1: Point3<S>, p2: Point3<S>) -> Aabb3<S> { Aabb3::new(p1, p2) }
#[inline] fn min<'a>(&'a self) -> &'a Point3<S> { &self.min }
#[inline] fn max<'a>(&'a self) -> &'a Point3<S> { &self.max }
}
impl<S: fmt::Show> fmt::Show for Aabb3<S> {
impl<S: BaseNum> fmt::Show for Aabb3<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{} - {}]", self.min, self.max)
}

View file

@ -1,4 +1,4 @@
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -19,6 +19,7 @@ use std::fmt;
use std::num::{One, one, Zero, zero, cast};
use approx::ApproxEq;
use num::BaseFloat;
/// An angle, in radians
#[deriving(Clone, Eq, Ord, Hash)] pub struct Rad<S> { pub s: S }
@ -26,27 +27,27 @@ use approx::ApproxEq;
#[deriving(Clone, Eq, Ord, Hash)] pub struct Deg<S> { pub s: S }
/// Create a new angle, in radians
#[inline] pub fn rad<S: Float>(s: S) -> Rad<S> { Rad { s: s } }
#[inline] pub fn rad<S: BaseFloat>(s: S) -> Rad<S> { Rad { s: s } }
/// Create a new angle, in degrees
#[inline] pub fn deg<S: Float>(s: S) -> Deg<S> { Deg { s: s } }
#[inline] pub fn deg<S: BaseFloat>(s: S) -> Deg<S> { Deg { s: s } }
/// Represents types that can be converted to radians.
pub trait ToRad<S: Float> {
pub trait ToRad<S: BaseFloat> {
/// Convert this value to radians.
fn to_rad(&self) -> Rad<S>;
}
/// Represents types that can be converted to degrees.
pub trait ToDeg<S: Float> {
pub trait ToDeg<S: BaseFloat> {
/// Convert this value to degrees.
fn to_deg(&self) -> Deg<S>;
}
impl<S: Float> ToRad<S> for Rad<S> { #[inline] fn to_rad(&self) -> Rad<S> { self.clone() } }
impl<S: Float> ToRad<S> for Deg<S> { #[inline] fn to_rad(&self) -> Rad<S> { rad(self.s.to_radians()) } }
impl<S: BaseFloat> ToRad<S> for Rad<S> { #[inline] fn to_rad(&self) -> Rad<S> { self.clone() } }
impl<S: BaseFloat> ToRad<S> for Deg<S> { #[inline] fn to_rad(&self) -> Rad<S> { rad(self.s.to_radians()) } }
impl<S: Float> ToDeg<S> for Rad<S> { #[inline] fn to_deg(&self) -> Deg<S> { deg(self.s.to_degrees()) } }
impl<S: Float> ToDeg<S> for Deg<S> { #[inline] fn to_deg(&self) -> Deg<S> { self.clone() } }
impl<S: BaseFloat> ToDeg<S> for Rad<S> { #[inline] fn to_deg(&self) -> Deg<S> { deg(self.s.to_degrees()) } }
impl<S: BaseFloat> ToDeg<S> for Deg<S> { #[inline] fn to_deg(&self) -> Deg<S> { self.clone() } }
/// Private utility functions for converting to/from scalars
trait ScalarConv<S> {
@ -55,13 +56,13 @@ trait ScalarConv<S> {
fn mut_s<'a>(&'a mut self) -> &'a mut S;
}
impl<S: Float> ScalarConv<S> for Rad<S> {
impl<S: BaseFloat> ScalarConv<S> for Rad<S> {
#[inline] fn from(s: S) -> Rad<S> { rad(s) }
#[inline] fn s<'a>(&'a self) -> &'a S { &'a self.s }
#[inline] fn mut_s<'a>(&'a mut self) -> &'a mut S { &'a mut self.s }
}
impl<S: Float> ScalarConv<S> for Deg<S> {
impl<S: BaseFloat> ScalarConv<S> for Deg<S> {
#[inline] fn from(s: S) -> Deg<S> { deg(s) }
#[inline] fn s<'a>(&'a self) -> &'a S { &'a self.s }
#[inline] fn mut_s<'a>(&'a mut self) -> &'a mut S { &'a mut self.s }
@ -70,7 +71,7 @@ impl<S: Float> ScalarConv<S> for Deg<S> {
/// Operations on angles.
pub trait Angle
<
S: Float
S: BaseFloat
>
: Clone + Zero
+ Eq + Equiv<Self> + Ord
@ -150,9 +151,9 @@ pub trait Angle
#[inline] fn turn_div_6() -> Self { let full_turn: Self = Angle::full_turn(); full_turn.div_s(cast(6).unwrap()) }
}
#[inline] pub fn bisect<S: Float, A: Angle<S>>(a: A, b: A) -> A { a.bisect(b) }
#[inline] pub fn bisect<S: BaseFloat, A: Angle<S>>(a: A, b: A) -> A { a.bisect(b) }
impl<S: Float + ApproxEq<S>>
impl<S: BaseFloat>
Rad<S> {
#[inline] pub fn zero() -> Rad<S> { zero() }
#[inline] pub fn full_turn() -> Rad<S> { Angle::full_turn() }
@ -162,7 +163,7 @@ Rad<S> {
#[inline] pub fn turn_div_6() -> Rad<S> { Angle::turn_div_6() }
}
impl<S: Float + ApproxEq<S>>
impl<S: BaseFloat>
Deg<S> {
#[inline] pub fn zero() -> Deg<S> { zero() }
#[inline] pub fn full_turn() -> Deg<S> { Angle::full_turn() }
@ -173,79 +174,79 @@ Deg<S> {
}
impl<S: Float> Add<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn add(&self, other: &Rad<S>) -> Rad<S> { rad(self.s + other.s) } }
impl<S: Float> Add<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn add(&self, other: &Deg<S>) -> Deg<S> { deg(self.s + other.s) } }
impl<S: BaseFloat> Add<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn add(&self, other: &Rad<S>) -> Rad<S> { rad(self.s + other.s) } }
impl<S: BaseFloat> Add<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn add(&self, other: &Deg<S>) -> Deg<S> { deg(self.s + other.s) } }
impl<S: Float> Sub<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn sub(&self, other: &Rad<S>) -> Rad<S> { rad(self.s - other.s) } }
impl<S: Float> Sub<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn sub(&self, other: &Deg<S>) -> Deg<S> { deg(self.s - other.s) } }
impl<S: BaseFloat> Sub<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn sub(&self, other: &Rad<S>) -> Rad<S> { rad(self.s - other.s) } }
impl<S: BaseFloat> Sub<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn sub(&self, other: &Deg<S>) -> Deg<S> { deg(self.s - other.s) } }
impl<S: Float> Neg<Rad<S>> for Rad<S> { #[inline] fn neg(&self) -> Rad<S> { rad(-self.s) } }
impl<S: Float> Neg<Deg<S>> for Deg<S> { #[inline] fn neg(&self) -> Deg<S> { deg(-self.s) } }
impl<S: BaseFloat> Neg<Rad<S>> for Rad<S> { #[inline] fn neg(&self) -> Rad<S> { rad(-self.s) } }
impl<S: BaseFloat> Neg<Deg<S>> for Deg<S> { #[inline] fn neg(&self) -> Deg<S> { deg(-self.s) } }
impl<S: Float> Zero for Rad<S> { #[inline] fn zero() -> Rad<S> { rad(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: Float> Zero for Deg<S> { #[inline] fn zero() -> Deg<S> { deg(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: BaseFloat> Zero for Rad<S> { #[inline] fn zero() -> Rad<S> { rad(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: BaseFloat> Zero for Deg<S> { #[inline] fn zero() -> Deg<S> { deg(zero()) } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: Float> Mul<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn mul(&self, other: &Rad<S>) -> Rad<S> { rad(self.s * other.s) } }
impl<S: Float> Mul<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn mul(&self, other: &Deg<S>) -> Deg<S> { deg(self.s * other.s) } }
impl<S: BaseFloat> Mul<Rad<S>, Rad<S>> for Rad<S> { #[inline] fn mul(&self, other: &Rad<S>) -> Rad<S> { rad(self.s * other.s) } }
impl<S: BaseFloat> Mul<Deg<S>, Deg<S>> for Deg<S> { #[inline] fn mul(&self, other: &Deg<S>) -> Deg<S> { deg(self.s * other.s) } }
impl<S: Float> One for Rad<S> { #[inline] fn one() -> Rad<S> { rad(one()) } }
impl<S: Float> One for Deg<S> { #[inline] fn one() -> Deg<S> { deg(one()) } }
impl<S: BaseFloat> One for Rad<S> { #[inline] fn one() -> Rad<S> { rad(one()) } }
impl<S: BaseFloat> One for Deg<S> { #[inline] fn one() -> Deg<S> { deg(one()) } }
impl<S: Float + ApproxEq<S>>
impl<S: BaseFloat>
Equiv<Rad<S>> for Rad<S> {
fn equiv(&self, other: &Rad<S>) -> bool {
self.normalize() == other.normalize()
}
}
impl<S: Float + ApproxEq<S>>
impl<S: BaseFloat>
Equiv<Deg<S>> for Deg<S> {
fn equiv(&self, other: &Deg<S>) -> bool {
self.normalize() == other.normalize()
}
}
impl<S: Float + ApproxEq<S>>
impl<S: BaseFloat>
Angle<S> for Rad<S> {
#[inline] fn from<A: Angle<S>>(theta: A) -> Rad<S> { theta.to_rad() }
#[inline] fn full_turn() -> Rad<S> { rad(Float::two_pi()) }
}
impl<S: Float + ApproxEq<S>>
impl<S: BaseFloat>
Angle<S> for Deg<S> {
#[inline] fn from<A: Angle<S>>(theta: A) -> Deg<S> { theta.to_deg() }
#[inline] fn full_turn() -> Deg<S> { deg(cast(360).unwrap()) }
}
#[inline] pub fn sin<S: FloatMath>(theta: Rad<S>) -> S { theta.s.sin() }
#[inline] pub fn cos<S: FloatMath>(theta: Rad<S>) -> S { theta.s.cos() }
#[inline] pub fn tan<S: FloatMath>(theta: Rad<S>) -> S { theta.s.tan() }
#[inline] pub fn sin_cos<S: FloatMath>(theta: Rad<S>) -> (S, S) { theta.s.sin_cos() }
#[inline] pub fn sin<S: BaseFloat>(theta: Rad<S>) -> S { theta.s.sin() }
#[inline] pub fn cos<S: BaseFloat>(theta: Rad<S>) -> S { theta.s.cos() }
#[inline] pub fn tan<S: BaseFloat>(theta: Rad<S>) -> S { theta.s.tan() }
#[inline] pub fn sin_cos<S: BaseFloat>(theta: Rad<S>) -> (S, S) { theta.s.sin_cos() }
#[inline] pub fn cot<S: FloatMath>(theta: Rad<S>) -> S { tan(theta).recip() }
#[inline] pub fn sec<S: FloatMath>(theta: Rad<S>) -> S { cos(theta).recip() }
#[inline] pub fn csc<S: FloatMath>(theta: Rad<S>) -> S { sin(theta).recip() }
#[inline] pub fn cot<S: BaseFloat>(theta: Rad<S>) -> S { tan(theta).recip() }
#[inline] pub fn sec<S: BaseFloat>(theta: Rad<S>) -> S { cos(theta).recip() }
#[inline] pub fn csc<S: BaseFloat>(theta: Rad<S>) -> S { sin(theta).recip() }
#[inline] pub fn asin<S: FloatMath>(s: S) -> Rad<S> { rad(s.asin()) }
#[inline] pub fn acos<S: FloatMath>(s: S) -> Rad<S> { rad(s.acos()) }
#[inline] pub fn atan<S: FloatMath>(s: S) -> Rad<S> { rad(s.atan()) }
#[inline] pub fn atan2<S: FloatMath>(a: S, b: S) -> Rad<S> { rad(a.atan2(b)) }
#[inline] pub fn asin<S: BaseFloat>(s: S) -> Rad<S> { rad(s.asin()) }
#[inline] pub fn acos<S: BaseFloat>(s: S) -> Rad<S> { rad(s.acos()) }
#[inline] pub fn atan<S: BaseFloat>(s: S) -> Rad<S> { rad(s.atan()) }
#[inline] pub fn atan2<S: BaseFloat>(a: S, b: S) -> Rad<S> { rad(a.atan2(b)) }
impl<S: Float + fmt::Show>
impl<S: BaseFloat + fmt::Show>
fmt::Show for Rad<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} rad", self.s)
}
}
impl<S: Float + fmt::Show>
impl<S: BaseFloat + fmt::Show>
fmt::Show for Deg<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}°", self.s)
}
}
impl<S: Float + ApproxEq<S>>
impl<S: BaseFloat>
ApproxEq<S> for Rad<S> {
#[inline]
fn approx_eq_eps(&self, other: &Rad<S>, epsilon: &S) -> bool {
@ -253,7 +254,7 @@ ApproxEq<S> for Rad<S> {
}
}
impl<S: Float + ApproxEq<S>>
impl<S: BaseFloat>
ApproxEq<S> for Deg<S> {
#[inline]
fn approx_eq_eps(&self, other: &Deg<S>, epsilon: &S) -> bool {

View file

@ -74,4 +74,3 @@ approx_array!(impl<S> Vector4<S>)
approx_array!(impl<S> Point2<S>)
approx_array!(impl<S> Point3<S>)

View file

@ -1,4 +1,4 @@
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -16,10 +16,10 @@
//! View frustum for visibility determination
use matrix::{Matrix, Matrix4};
use num::BaseFloat;
use plane::Plane;
use point::Point3;
use vector::{Vector, EuclideanVector};
use partial_ord::PartOrdFloat;
#[deriving(Clone, Eq)]
pub struct Frustum<S> {
@ -31,7 +31,7 @@ pub struct Frustum<S> {
pub far: Plane<S>,
}
impl<S: PartOrdFloat<S>>
impl<S: BaseFloat>
Frustum<S> {
/// Constructs a frustum
pub fn new(left: Plane<S>, right: Plane<S>,

View file

@ -1,4 +1,4 @@
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -62,6 +62,6 @@ pub mod obb;
pub mod sphere;
pub mod approx;
pub mod num;
pub mod ptr;
pub mod partial_ord;

View file

@ -1,4 +1,4 @@
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directionectory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -17,9 +17,9 @@
use std::num::{Zero, zero, One, one};
use num::{BaseFloat, BaseNum};
use point::{Point, Point2, Point3};
use vector::{Vector, Vector2};
use partial_ord::PartOrdFloat;
use intersect::Intersect;
/// A generic directed line segment from `origin` to `dest`.
@ -32,7 +32,7 @@ pub struct Line<P>
impl
<
S: Primitive,
S: BaseNum,
Slice,
V: Vector<S,Slice>,
P: Point<S,V,Slice>
@ -49,7 +49,7 @@ pub type Line3<S> = Line<Point3<S>>;
/// Determines if an intersection between two line segments is found. If the segments are
/// collinear and overlapping, the intersection point that will be returned will be the first
/// intersection point found by traversing the first line segment, starting at its origin.
impl<S: PartOrdFloat<S>> Intersect<Option<Point2<S>>> for (Line2<S>, Line2<S>) {
impl<S: BaseFloat> Intersect<Option<Point2<S>>> for (Line2<S>, Line2<S>) {
fn intersection(&self) -> Option<Point2<S>> {
match *self {
(ref l1, ref l2) => {

View file

@ -1,4 +1,4 @@
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -21,11 +21,11 @@ use std::num::{Zero, zero, One, one, cast};
use angle::{Rad, sin, cos, sin_cos};
use approx::ApproxEq;
use array::{Array, build};
use num::{BaseFloat, BaseNum};
use point::{Point, Point3};
use quaternion::{Quaternion, ToQuaternion};
use vector::{Vector, EuclideanVector};
use vector::{Vector2, Vector3, Vector4};
use partial_ord::PartOrdFloat;
/// A 2 x 2, column major matrix
#[deriving(Clone, Eq)]
@ -40,7 +40,7 @@ pub struct Matrix3<S> { pub x: Vector3<S>, pub y: Vector3<S>, pub z: Vector3<S>
pub struct Matrix4<S> { pub x: Vector4<S>, pub y: Vector4<S>, pub z: Vector4<S>, pub w: Vector4<S> }
impl<S: Primitive> Matrix2<S> {
impl<S: BaseNum> Matrix2<S> {
/// Create a new matrix, providing values for each index.
#[inline]
pub fn new(c0r0: S, c0r1: S,
@ -76,7 +76,7 @@ impl<S: Primitive> Matrix2<S> {
}
}
impl<S: PartOrdFloat<S>> 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> {
@ -94,7 +94,7 @@ impl<S: PartOrdFloat<S>> Matrix2<S> {
}
}
impl<S: Primitive> Matrix3<S> {
impl<S: BaseNum> Matrix3<S> {
/// Create a new matrix, providing values for each index.
#[inline]
pub fn new(c0r0:S, c0r1:S, c0r2:S,
@ -133,7 +133,7 @@ impl<S: Primitive> Matrix3<S> {
}
}
impl<S: PartOrdFloat<S>>
impl<S: BaseFloat>
Matrix3<S> {
/// Create a transformation matrix that will cause a vector to point at
/// `dir`, using `up` for orientation.
@ -209,7 +209,7 @@ Matrix3<S> {
}
}
impl<S: Primitive> Matrix4<S> {
impl<S: BaseNum> Matrix4<S> {
/// Create a new matrix, providing values for each index.
#[inline]
pub fn new(c0r0: S, c0r1: S, c0r2: S, c0r3: S,
@ -251,7 +251,7 @@ impl<S: Primitive> Matrix4<S> {
}
}
impl<S: PartOrdFloat<S>>
impl<S: BaseFloat>
Matrix4<S> {
/// Create a transformation matrix that will cause a vector to point at
/// `dir`, using `up` for orientation.
@ -273,7 +273,7 @@ array!(impl<S> Matrix4<S> -> [Vector4<S>, ..4] _4)
pub trait Matrix
<
S: PartOrdFloat<S>, Slice,
S: BaseFloat, Slice,
V: Clone + Vector<S, VSlice> + Array<S, VSlice>, VSlice
>
: Array<V, Slice>
@ -417,31 +417,31 @@ pub trait Matrix
fn is_symmetric(&self) -> bool;
}
impl<S: PartOrdFloat<S>> Add<Matrix2<S>, Matrix2<S>> for Matrix2<S> { #[inline] fn add(&self, other: &Matrix2<S>) -> Matrix2<S> { build(|i| self.i(i).add_v(other.i(i))) } }
impl<S: PartOrdFloat<S>> Add<Matrix3<S>, Matrix3<S>> for Matrix3<S> { #[inline] fn add(&self, other: &Matrix3<S>) -> Matrix3<S> { build(|i| self.i(i).add_v(other.i(i))) } }
impl<S: PartOrdFloat<S>> Add<Matrix4<S>, Matrix4<S>> for Matrix4<S> { #[inline] fn add(&self, other: &Matrix4<S>) -> Matrix4<S> { build(|i| self.i(i).add_v(other.i(i))) } }
impl<S: BaseFloat> Add<Matrix2<S>, Matrix2<S>> for Matrix2<S> { #[inline] fn add(&self, other: &Matrix2<S>) -> Matrix2<S> { build(|i| self.i(i).add_v(other.i(i))) } }
impl<S: BaseFloat> Add<Matrix3<S>, Matrix3<S>> for Matrix3<S> { #[inline] fn add(&self, other: &Matrix3<S>) -> Matrix3<S> { build(|i| self.i(i).add_v(other.i(i))) } }
impl<S: BaseFloat> Add<Matrix4<S>, Matrix4<S>> for Matrix4<S> { #[inline] fn add(&self, other: &Matrix4<S>) -> Matrix4<S> { build(|i| self.i(i).add_v(other.i(i))) } }
impl<S: PartOrdFloat<S>> Sub<Matrix2<S>, Matrix2<S>> for Matrix2<S> { #[inline] fn sub(&self, other: &Matrix2<S>) -> Matrix2<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
impl<S: PartOrdFloat<S>> Sub<Matrix3<S>, Matrix3<S>> for Matrix3<S> { #[inline] fn sub(&self, other: &Matrix3<S>) -> Matrix3<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
impl<S: PartOrdFloat<S>> Sub<Matrix4<S>, Matrix4<S>> for Matrix4<S> { #[inline] fn sub(&self, other: &Matrix4<S>) -> Matrix4<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
impl<S: BaseFloat> Sub<Matrix2<S>, Matrix2<S>> for Matrix2<S> { #[inline] fn sub(&self, other: &Matrix2<S>) -> Matrix2<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
impl<S: BaseFloat> Sub<Matrix3<S>, Matrix3<S>> for Matrix3<S> { #[inline] fn sub(&self, other: &Matrix3<S>) -> Matrix3<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
impl<S: BaseFloat> Sub<Matrix4<S>, Matrix4<S>> for Matrix4<S> { #[inline] fn sub(&self, other: &Matrix4<S>) -> Matrix4<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
impl<S: PartOrdFloat<S>> Neg<Matrix2<S>> for Matrix2<S> { #[inline] fn neg(&self) -> Matrix2<S> { build(|i| self.i(i).neg()) } }
impl<S: PartOrdFloat<S>> Neg<Matrix3<S>> for Matrix3<S> { #[inline] fn neg(&self) -> Matrix3<S> { build(|i| self.i(i).neg()) } }
impl<S: PartOrdFloat<S>> Neg<Matrix4<S>> for Matrix4<S> { #[inline] fn neg(&self) -> Matrix4<S> { build(|i| self.i(i).neg()) } }
impl<S: BaseFloat> Neg<Matrix2<S>> for Matrix2<S> { #[inline] fn neg(&self) -> Matrix2<S> { build(|i| self.i(i).neg()) } }
impl<S: BaseFloat> Neg<Matrix3<S>> for Matrix3<S> { #[inline] fn neg(&self) -> Matrix3<S> { build(|i| self.i(i).neg()) } }
impl<S: BaseFloat> Neg<Matrix4<S>> for Matrix4<S> { #[inline] fn neg(&self) -> Matrix4<S> { build(|i| self.i(i).neg()) } }
impl<S: PartOrdFloat<S>> Zero for Matrix2<S> { #[inline] fn zero() -> Matrix2<S> { Matrix2::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: PartOrdFloat<S>> Zero for Matrix3<S> { #[inline] fn zero() -> Matrix3<S> { Matrix3::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: PartOrdFloat<S>> Zero for Matrix4<S> { #[inline] fn zero() -> Matrix4<S> { Matrix4::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: BaseFloat> Zero for Matrix2<S> { #[inline] fn zero() -> Matrix2<S> { Matrix2::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: BaseFloat> Zero for Matrix3<S> { #[inline] fn zero() -> Matrix3<S> { Matrix3::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: BaseFloat> Zero for Matrix4<S> { #[inline] fn zero() -> Matrix4<S> { Matrix4::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: PartOrdFloat<S>> Mul<Matrix2<S>, Matrix2<S>> for Matrix2<S> { #[inline] fn mul(&self, other: &Matrix2<S>) -> Matrix2<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
impl<S: PartOrdFloat<S>> Mul<Matrix3<S>, Matrix3<S>> for Matrix3<S> { #[inline] fn mul(&self, other: &Matrix3<S>) -> Matrix3<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
impl<S: PartOrdFloat<S>> Mul<Matrix4<S>, Matrix4<S>> for Matrix4<S> { #[inline] fn mul(&self, other: &Matrix4<S>) -> Matrix4<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
impl<S: BaseFloat> Mul<Matrix2<S>, Matrix2<S>> for Matrix2<S> { #[inline] fn mul(&self, other: &Matrix2<S>) -> Matrix2<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
impl<S: BaseFloat> Mul<Matrix3<S>, Matrix3<S>> for Matrix3<S> { #[inline] fn mul(&self, other: &Matrix3<S>) -> Matrix3<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
impl<S: BaseFloat> Mul<Matrix4<S>, Matrix4<S>> for Matrix4<S> { #[inline] fn mul(&self, other: &Matrix4<S>) -> Matrix4<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
impl<S: PartOrdFloat<S>> One for Matrix2<S> { #[inline] fn one() -> Matrix2<S> { Matrix2::identity() } }
impl<S: PartOrdFloat<S>> One for Matrix3<S> { #[inline] fn one() -> Matrix3<S> { Matrix3::identity() } }
impl<S: PartOrdFloat<S>> One for Matrix4<S> { #[inline] fn one() -> Matrix4<S> { Matrix4::identity() } }
impl<S: BaseFloat> One for Matrix2<S> { #[inline] fn one() -> Matrix2<S> { Matrix2::identity() } }
impl<S: BaseFloat> One for Matrix3<S> { #[inline] fn one() -> Matrix3<S> { Matrix3::identity() } }
impl<S: BaseFloat> One for Matrix4<S> { #[inline] fn one() -> Matrix4<S> { Matrix4::identity() } }
impl<S: PartOrdFloat<S>>
impl<S: BaseFloat>
Matrix<S, [Vector2<S>, ..2], Vector2<S>, [S, ..2]>
for Matrix2<S>
{
@ -490,7 +490,7 @@ for Matrix2<S>
}
}
impl<S: PartOrdFloat<S>>
impl<S: BaseFloat>
Matrix<S, [Vector3<S>, ..3], Vector3<S>, [S, ..3]>
for Matrix3<S>
{
@ -563,7 +563,7 @@ macro_rules! dot_matrix4(
(*$A.cr(3, $I)) * (*$B.cr($J, 3))
))
impl<S: PartOrdFloat<S>>
impl<S: BaseFloat>
Matrix<S, [Vector4<S>, ..4], Vector4<S>, [S, ..4]>
for Matrix4<S>
{
@ -694,24 +694,24 @@ for Matrix4<S>
// Conversion traits
/// Represents types which can be converted to a Matrix2
pub trait ToMatrix2<S: Primitive> {
pub trait ToMatrix2<S: BaseNum> {
/// Convert this value to a Matrix2
fn to_matrix2(&self) -> Matrix2<S>;
}
/// Represents types which can be converted to a Matrix3
pub trait ToMatrix3<S: Primitive> {
pub trait ToMatrix3<S: BaseNum> {
/// Convert this value to a Matrix3
fn to_matrix3(&self) -> Matrix3<S>;
}
/// Represents types which can be converted to a Matrix4
pub trait ToMatrix4<S: Primitive> {
pub trait ToMatrix4<S: BaseNum> {
/// Convert this value to a Matrix4
fn to_matrix4(&self) -> Matrix4<S>;
}
impl<S: PartOrdFloat<S>>
impl<S: BaseFloat>
ToMatrix3<S> for Matrix2<S> {
/// Clone the elements of a 2-dimensional matrix into the top-left corner
/// of a 3-dimensional identity matrix.
@ -722,7 +722,7 @@ ToMatrix3<S> for Matrix2<S> {
}
}
impl<S: PartOrdFloat<S>>
impl<S: BaseFloat>
ToMatrix4<S> for Matrix2<S> {
/// Clone the elements of a 2-dimensional matrix into the top-left corner
/// of a 4-dimensional identity matrix.
@ -734,7 +734,7 @@ ToMatrix4<S> for Matrix2<S> {
}
}
impl<S: PartOrdFloat<S>>
impl<S: BaseFloat>
ToMatrix4<S> for Matrix3<S> {
/// Clone the elements of a 3-dimensional matrix into the top-left corner
/// of a 4-dimensional identity matrix.
@ -746,7 +746,7 @@ ToMatrix4<S> for Matrix3<S> {
}
}
impl<S: PartOrdFloat<S>>
impl<S: BaseFloat>
ToQuaternion<S> for Matrix3<S> {
/// Convert the matrix to a quaternion
fn to_quaternion(&self) -> Quaternion<S> {
@ -794,7 +794,7 @@ ToQuaternion<S> for Matrix3<S> {
}
}
impl<S: PartOrdFloat<S> + fmt::Show> fmt::Show for Matrix2<S> {
impl<S: BaseFloat> fmt::Show for Matrix2<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[[{}, {}], [{}, {}]]",
self.cr(0, 0), self.cr(0, 1),
@ -802,7 +802,7 @@ impl<S: PartOrdFloat<S> + fmt::Show> fmt::Show for Matrix2<S> {
}
}
impl<S: PartOrdFloat<S> + fmt::Show> fmt::Show for Matrix3<S> {
impl<S: BaseFloat> fmt::Show for Matrix3<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[[{}, {}, {}], [{}, {}, {}], [{}, {}, {}]]",
self.cr(0, 0), self.cr(0, 1), self.cr(0, 2),
@ -811,7 +811,7 @@ impl<S: PartOrdFloat<S> + fmt::Show> fmt::Show for Matrix3<S> {
}
}
impl<S: PartOrdFloat<S> + fmt::Show> fmt::Show for Matrix4<S> {
impl<S: BaseFloat> fmt::Show for Matrix4<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[[{}, {}, {}, {}], [{}, {}, {}, {}], [{}, {}, {}, {}], [{}, {}, {}, {}]]",
self.cr(0, 0), self.cr(0, 1), self.cr(0, 2), self.cr(0, 3),

95
src/cgmath/num.rs Normal file
View file

@ -0,0 +1,95 @@
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use approx::ApproxEq;
use std::cmp;
use std::fmt;
/// A trait providing a [partial ordering][po]
///
/// [po]: http://mathworld.wolfram.com/PartialOrder.html
pub trait PartialOrd {
fn partial_min(self, other: Self) -> Self;
fn partial_max(self, other: Self) -> Self;
}
macro_rules! partial_ord_int (
($T:ident) => (
impl PartialOrd for $T {
fn partial_min(self, other: $T) -> $T { cmp::min(self, other) }
fn partial_max(self, other: $T) -> $T { cmp::max(self, other) }
}
)
)
partial_ord_int!(int)
partial_ord_int!(i8)
partial_ord_int!(i16)
partial_ord_int!(i32)
partial_ord_int!(i64)
partial_ord_int!(uint)
partial_ord_int!(u8)
partial_ord_int!(u16)
partial_ord_int!(u32)
partial_ord_int!(u64)
macro_rules! partial_ord_float (
($T:ident) => (
impl PartialOrd for $T {
fn partial_min(self, other: $T) -> $T { self.min(other) }
fn partial_max(self, other: $T) -> $T { self.max(other) }
}
)
)
partial_ord_float!(f32)
partial_ord_float!(f64)
/// Base numeric types with partial ordering
pub trait BaseNum: Primitive + PartialOrd + fmt::Show {}
impl BaseNum for i8 {}
impl BaseNum for i16 {}
impl BaseNum for i32 {}
impl BaseNum for i64 {}
impl BaseNum for int {}
impl BaseNum for u8 {}
impl BaseNum for u16 {}
impl BaseNum for u32 {}
impl BaseNum for u64 {}
impl BaseNum for uint {}
impl BaseNum for f32 {}
impl BaseNum for f64 {}
/// Base integer types
pub trait BaseInt : BaseNum + Int {}
impl BaseInt for i8 {}
impl BaseInt for i16 {}
impl BaseInt for i32 {}
impl BaseInt for i64 {}
impl BaseInt for int {}
impl BaseInt for u8 {}
impl BaseInt for u16 {}
impl BaseInt for u32 {}
impl BaseInt for u64 {}
impl BaseInt for uint {}
/// Base floating point types
pub trait BaseFloat : BaseNum + FloatMath + ApproxEq<Self> + fmt::Float {}
impl BaseFloat for f32 {}
impl BaseFloat for f64 {}

View file

@ -1,55 +0,0 @@
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use approx::ApproxEq;
use std::cmp;
/// A trait providing a [partial order][po] over a primitive type.
///
/// [po]: http://mathworld.wolfram.com/PartialOrder.html
pub trait PartOrdPrim : Primitive {
fn min(&self, b: Self) -> Self;
fn max(&self, b: Self) -> Self;
}
macro_rules! gen_minmax_for_floats (
( $($T:ident),+ ) => (
$(
impl PartOrdPrim for $T {
fn min(&self, b: $T) -> $T { (*self).min(b) }
fn max(&self, b: $T) -> $T { (*self).max(b) }
}
)+
)
)
macro_rules! gen_minmax_for_not_floats (
( $($T:ident),+ ) => (
$(
impl PartOrdPrim for $T {
fn min(&self, b: $T) -> $T { cmp::min((*self), b) }
fn max(&self, b: $T) -> $T { cmp::max((*self), b) }
}
)+
)
)
gen_minmax_for_floats!(f32, f64)
gen_minmax_for_not_floats!(int, i8, i16, i32, i64, uint, u8, u16, u32, u64)
pub trait PartOrdFloat<S> : FloatMath + ApproxEq<S> + PartOrdPrim {}
impl PartOrdFloat<f32> for f32 {}
impl PartOrdFloat<f64> for f64 {}

View file

@ -1,4 +1,4 @@
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -19,11 +19,11 @@ use std::num::Zero;
use approx::ApproxEq;
use intersect::Intersect;
use num::BaseFloat;
use point::{Point, Point3};
use ray::Ray3;
use vector::{Vector3, Vector4};
use vector::{Vector, EuclideanVector};
use partial_ord::PartOrdFloat;
/// A 3-dimensional plane formed from the equation: `A*x + B*y + C*z - D = 0`.
@ -47,8 +47,7 @@ pub struct Plane<S> {
pub d: S,
}
impl<S: PartOrdFloat<S>>
Plane<S> {
impl<S: BaseFloat> Plane<S> {
/// Construct a plane from a normal vector and a scalar distance. The
/// plane will be perpendicular to `n`, and `d` units offset from the
/// origin.
@ -91,7 +90,7 @@ Plane<S> {
}
}
impl<S: PartOrdFloat<S>> Intersect<Option<Point3<S>>> for (Plane<S>, Ray3<S>) {
impl<S: BaseFloat> Intersect<Option<Point3<S>>> for (Plane<S>, Ray3<S>) {
fn intersection(&self) -> Option<Point3<S>> {
match *self {
(ref p, ref r) => {
@ -103,19 +102,19 @@ impl<S: PartOrdFloat<S>> Intersect<Option<Point3<S>>> for (Plane<S>, Ray3<S>) {
}
}
impl<S: Float> Intersect<Option<Ray3<S>>> for (Plane<S>, Plane<S>) {
impl<S: BaseFloat> Intersect<Option<Ray3<S>>> for (Plane<S>, Plane<S>) {
fn intersection(&self) -> Option<Ray3<S>> {
fail!("Not yet implemented");
}
}
impl<S: Float> Intersect<Option<Point3<S>>> for (Plane<S>, Plane<S>, Plane<S>) {
impl<S: BaseFloat> Intersect<Option<Point3<S>>> for (Plane<S>, Plane<S>, Plane<S>) {
fn intersection(&self) -> Option<Point3<S>> {
fail!("Not yet implemented");
}
}
impl<S: Float + ApproxEq<S>>
impl<S: BaseFloat + ApproxEq<S>>
ApproxEq<S> for Plane<S> {
#[inline]
fn approx_eq_eps(&self, other: &Plane<S>, epsilon: &S) -> bool {
@ -124,7 +123,7 @@ ApproxEq<S> for Plane<S> {
}
}
impl<S: Clone + fmt::Float> fmt::Show for Plane<S> {
impl<S: BaseFloat> fmt::Show for Plane<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:f}x + {:f}y + {:f}z - {:f} = 0",
self.n.x, self.n.y, self.n.z, self.d)

View file

@ -1,4 +1,4 @@
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -21,8 +21,8 @@ use std::fmt;
use std::num::{one, zero};
use array::*;
use num::BaseNum;
use vector::*;
use partial_ord::PartOrdPrim;
/// A point in 2-dimensional space.
#[deriving(Eq, Clone, Hash)]
@ -33,21 +33,21 @@ pub struct Point2<S> { pub x: S, pub y: S }
pub struct Point3<S> { pub x: S, pub y: S, pub z: S }
impl<S: Num> Point2<S> {
impl<S: BaseNum> Point2<S> {
#[inline]
pub fn new(x: S, y: S) -> Point2<S> {
Point2 { x: x, y: y }
}
}
impl<S: Num> Point3<S> {
impl<S: BaseNum> Point3<S> {
#[inline]
pub fn new(x: S, y: S, z: S) -> Point3<S> {
Point3 { x: x, y: y, z: z }
}
}
impl<S: PartOrdPrim> Point3<S> {
impl<S: BaseNum> Point3<S> {
#[inline]
pub fn from_homogeneous(v: &Vector4<S>) -> Point3<S> {
let e = v.truncate().mul_s(one::<S>() / v.w);
@ -63,7 +63,7 @@ impl<S: PartOrdPrim> Point3<S> {
/// Specifies the numeric operations for point types.
pub trait Point
<
S: PartOrdPrim,
S: BaseNum,
V: Vector<S, Slice>,
Slice
>
@ -109,16 +109,16 @@ pub trait Point
array!(impl<S> Point2<S> -> [S, ..2] _2)
array!(impl<S> Point3<S> -> [S, ..3] _3)
impl<S: PartOrdPrim> Point<S, Vector2<S>, [S, ..2]> for Point2<S> {}
impl<S: PartOrdPrim> Point<S, Vector3<S>, [S, ..3]> for Point3<S> {}
impl<S: BaseNum> Point<S, Vector2<S>, [S, ..2]> for Point2<S> {}
impl<S: BaseNum> Point<S, Vector3<S>, [S, ..3]> for Point3<S> {}
impl<S: fmt::Show> fmt::Show for Point2<S> {
impl<S: BaseNum> fmt::Show for Point2<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{}, {}]", self.x, self.y)
}
}
impl<S: fmt::Show> fmt::Show for Point3<S> {
impl<S: BaseNum> fmt::Show for Point3<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{}, {}, {}]", self.x, self.y, self.z)
}

View file

@ -1,4 +1,4 @@
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -18,14 +18,14 @@ use std::num::{zero, one, cast};
use angle::{Angle, tan, cot};
use frustum::Frustum;
use matrix::{Matrix4, ToMatrix4};
use num::BaseFloat;
use plane::Plane;
use partial_ord::PartOrdFloat;
/// Create a perspective projection matrix.
///
/// This is the equivalent to the [gluPerspective]
/// (http://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml) function.
pub fn perspective<S: FloatMath, A: Angle<S>>(fovy: A, aspect: S, near: S, far: S) -> Matrix4<S> {
pub fn perspective<S: BaseFloat, A: Angle<S>>(fovy: A, aspect: S, near: S, far: S) -> Matrix4<S> {
PerspectiveFov {
fovy: fovy,
aspect: aspect,
@ -38,7 +38,7 @@ pub fn perspective<S: FloatMath, A: Angle<S>>(fovy: A, aspect: S, near: S, far:
///
/// This is the equivalent of the now deprecated [glFrustrum]
/// (http://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml) function.
pub fn frustum<S: Float>(left: S, right: S, bottom: S, top: S, near: S, far: S) -> Matrix4<S> {
pub fn frustum<S: BaseFloat>(left: S, right: S, bottom: S, top: S, near: S, far: S) -> Matrix4<S> {
Perspective {
left: left,
right: right,
@ -53,7 +53,7 @@ pub fn frustum<S: Float>(left: S, right: S, bottom: S, top: S, near: S, far: S)
///
/// This is the equivalent of the now deprecated [glOrtho]
/// (http://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml) function.
pub fn ortho<S: Float>(left: S, right: S, bottom: S, top: S, near: S, far: S) -> Matrix4<S> {
pub fn ortho<S: BaseFloat>(left: S, right: S, bottom: S, top: S, near: S, far: S) -> Matrix4<S> {
Ortho {
left: left,
right: right,
@ -77,7 +77,7 @@ pub struct PerspectiveFov<S, A> {
pub far: S,
}
impl<S: FloatMath, A: Angle<S>> PerspectiveFov<S, A> {
impl<S: BaseFloat, A: Angle<S>> PerspectiveFov<S, A> {
pub fn to_perspective(&self) -> Perspective<S> {
let angle = self.fovy.div_s(cast(2).unwrap());
let ymax = self.near * tan(angle.to_rad());
@ -94,15 +94,14 @@ impl<S: FloatMath, A: Angle<S>> PerspectiveFov<S, A> {
}
}
impl<S: PartOrdFloat<S>, A: Angle<S>>
Projection<S> for PerspectiveFov<S, A> {
impl<S: BaseFloat, A: Angle<S>> Projection<S> for PerspectiveFov<S, A> {
fn to_frustum(&self) -> Frustum<S> {
// TODO: Could this be faster?
Frustum::from_matrix4(self.to_matrix4())
}
}
impl<S: FloatMath, A: Angle<S>> ToMatrix4<S> for PerspectiveFov<S, A> {
impl<S: BaseFloat, A: Angle<S>> ToMatrix4<S> for PerspectiveFov<S, A> {
fn to_matrix4(&self) -> Matrix4<S> {
let half_turn: A = Angle::turn_div_2();
@ -151,15 +150,14 @@ pub struct Perspective<S> {
pub near: S, far: S,
}
impl<S: PartOrdFloat<S>>
Projection<S> for Perspective<S> {
impl<S: BaseFloat> Projection<S> for Perspective<S> {
fn to_frustum(&self) -> Frustum<S> {
// TODO: Could this be faster?
Frustum::from_matrix4(self.to_matrix4())
}
}
impl<S: Float> ToMatrix4<S> for Perspective<S> {
impl<S: BaseFloat> ToMatrix4<S> for Perspective<S> {
fn to_matrix4(&self) -> Matrix4<S> {
assert!(self.left > self.right, "`left` cannot be greater than `right`, found: left: {:?} right: {:?}", self.left, self.right);
assert!(self.bottom > self.top, "`bottom` cannot be greater than `top`, found: bottom: {:?} top: {:?}", self.bottom, self.top);
@ -202,8 +200,7 @@ pub struct Ortho<S> {
pub near: S, far: S,
}
impl<S: PartOrdFloat<S>>
Projection<S> for Ortho<S> {
impl<S: BaseFloat> Projection<S> for Ortho<S> {
fn to_frustum(&self) -> Frustum<S> {
Frustum {
left: Plane::from_abcd( one::<S>(), zero::<S>(), zero::<S>(), self.left.clone()),
@ -216,7 +213,7 @@ Projection<S> for Ortho<S> {
}
}
impl<S: Float> ToMatrix4<S> for Ortho<S> {
impl<S: BaseFloat> ToMatrix4<S> for Ortho<S> {
fn to_matrix4(&self) -> Matrix4<S> {
assert!(self.left < self.right, "`left` cannot be greater than `right`, found: left: {:?} right: {:?}", self.left, self.right);
assert!(self.bottom < self.top, "`bottom` cannot be greater than `top`, found: bottom: {:?} top: {:?}", self.bottom, self.top);

View file

@ -1,4 +1,4 @@
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -17,13 +17,12 @@ use std::fmt;
use std::num::{zero, one, cast};
use angle::{Angle, Rad, acos, sin, sin_cos};
use approx::ApproxEq;
use array::{Array, build};
use matrix::{Matrix3, ToMatrix3, ToMatrix4, Matrix4};
use num::BaseFloat;
use point::{Point3};
use rotation::{Rotation, Rotation3, Basis3, ToBasis3};
use vector::{Vector3, Vector, EuclideanVector};
use partial_ord::PartOrdFloat;
/// A [quaternion](https://en.wikipedia.org/wiki/Quaternion) in scalar/vector
/// form.
@ -33,13 +32,12 @@ pub struct Quaternion<S> { pub s: S, pub v: Vector3<S> }
array!(impl<S> Quaternion<S> -> [S, ..4] _4)
/// Represents types which can be expressed as a quaternion.
pub trait ToQuaternion<S: Float> {
pub trait ToQuaternion<S: BaseFloat> {
/// Convert this value to a quaternion.
fn to_quaternion(&self) -> Quaternion<S>;
}
impl<S: PartOrdFloat<S>>
Quaternion<S> {
impl<S: BaseFloat> Quaternion<S> {
/// Construct a new quaternion from one scalar component and three
/// imaginary components
#[inline]
@ -178,8 +176,7 @@ Quaternion<S> {
}
}
impl<S: PartOrdFloat<S>>
Quaternion<S> {
impl<S: BaseFloat> Quaternion<S> {
/// Spherical Linear Intoperlation
///
/// Return the spherical linear interpolation between the quaternion and
@ -228,8 +225,7 @@ Quaternion<S> {
}
}
impl<S: Float + ApproxEq<S>>
ToMatrix3<S> for Quaternion<S> {
impl<S: BaseFloat> ToMatrix3<S> for Quaternion<S> {
/// Convert the quaternion to a 3 x 3 rotation matrix
fn to_matrix3(&self) -> Matrix3<S> {
let x2 = self.v.x + self.v.x;
@ -254,8 +250,7 @@ ToMatrix3<S> for Quaternion<S> {
}
}
impl<S: Float + ApproxEq<S>>
ToMatrix4<S> for Quaternion<S> {
impl<S: BaseFloat> ToMatrix4<S> for Quaternion<S> {
/// Convert the quaternion to a 4 x 4 rotation matrix
fn to_matrix4(&self) -> Matrix4<S> {
let x2 = self.v.x + self.v.x;
@ -281,15 +276,14 @@ ToMatrix4<S> for Quaternion<S> {
}
}
impl<S: PartOrdFloat<S>>
Neg<Quaternion<S>> for Quaternion<S> {
impl<S: BaseFloat> Neg<Quaternion<S>> for Quaternion<S> {
#[inline]
fn neg(&self) -> Quaternion<S> {
Quaternion::from_sv(-self.s, -self.v)
}
}
impl<S: fmt::Show> fmt::Show for Quaternion<S> {
impl<S: BaseFloat> fmt::Show for Quaternion<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} + {}i + {}j + {}k",
self.s,
@ -301,19 +295,17 @@ impl<S: fmt::Show> fmt::Show for Quaternion<S> {
// Quaternion Rotation impls
impl<S: PartOrdFloat<S>>
ToBasis3<S> for Quaternion<S> {
impl<S: BaseFloat> ToBasis3<S> for Quaternion<S> {
#[inline]
fn to_rot3(&self) -> Basis3<S> { Basis3::from_quaternion(self) }
}
impl<S: Float> ToQuaternion<S> for Quaternion<S> {
impl<S: BaseFloat> ToQuaternion<S> for Quaternion<S> {
#[inline]
fn to_quaternion(&self) -> Quaternion<S> { self.clone() }
}
impl<S: PartOrdFloat<S>>
Rotation<S, [S, ..3], Vector3<S>, Point3<S>> for Quaternion<S> {
impl<S: BaseFloat> Rotation<S, [S, ..3], Vector3<S>, Point3<S>> for Quaternion<S> {
#[inline]
fn identity() -> Quaternion<S> { Quaternion::identity() }
@ -345,9 +337,7 @@ Rotation<S, [S, ..3], Vector3<S>, Point3<S>> for Quaternion<S> {
fn invert_self(&mut self) { *self = self.invert() }
}
impl<S: PartOrdFloat<S>>
Rotation3<S> for Quaternion<S>
{
impl<S: BaseFloat> Rotation3<S> for Quaternion<S> {
#[inline]
fn from_axis_angle(axis: &Vector3<S>, angle: Rad<S>) -> Quaternion<S> {
let (s, c) = sin_cos(angle.mul_s(cast(0.5).unwrap()));

View file

@ -1,4 +1,4 @@
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directionectory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -13,30 +13,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use num::BaseNum;
use point::{Point, Point2, Point3};
use vector::{Vector, Vector2, Vector3};
/// A generic ray starting at `origin` and extending infinitely in
/// `direction`.
#[deriving(Clone, Eq)]
pub struct Ray<P,V>
{
pub struct Ray<P,V> {
pub origin: P,
pub direction: V,
}
impl
<
S: Primitive,
Slice,
V: Vector<S,Slice>,
P: Point<S,V,Slice>
> Ray<P,V>
{
impl<S: BaseNum, Slice, V: Vector<S, Slice>, P: Point<S, V, Slice>> Ray<P, V> {
pub fn new(origin: P, direction: V) -> Ray<P,V> {
Ray { origin:origin, direction:direction }
Ray { origin: origin, direction: direction }
}
}
pub type Ray2<S> = Ray<Point2<S>,Vector2<S>>;
pub type Ray3<S> = Ray<Point3<S>,Vector3<S>>;
pub type Ray2<S> = Ray<Point2<S>, Vector2<S>>;
pub type Ray3<S> = Ray<Point3<S>, Vector3<S>>;

View file

@ -19,17 +19,17 @@ use array::Array;
use matrix::Matrix;
use matrix::{Matrix2, ToMatrix2};
use matrix::{Matrix3, ToMatrix3};
use num::{BaseNum, BaseFloat};
use point::{Point, Point2, Point3};
use quaternion::{Quaternion, ToQuaternion};
use ray::Ray;
use vector::{Vector, Vector2, Vector3};
use partial_ord::{PartOrdPrim, PartOrdFloat};
/// 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: PartOrdPrim,
S: BaseNum,
Slice,
V: Vector<S,Slice>,
P: Point<S,V,Slice>
@ -102,7 +102,7 @@ pub trait Rotation2
/// A three-dimensional rotation.
pub trait Rotation3
<
S: Primitive
S: BaseNum
>
: Rotation<S, [S, ..3], Vector3<S>, Point3<S>>
+ ToMatrix3<S>
@ -152,30 +152,29 @@ pub struct Basis2<S> {
mat: Matrix2<S>
}
impl<S: Float> Basis2<S> {
impl<S: BaseFloat> Basis2<S> {
/// Coerce to a `Matrix2`
#[inline]
pub fn as_matrix2<'a>(&'a self) -> &'a Matrix2<S> { &'a self.mat }
}
/// Represents types which can be converted to a rotation matrix.
pub trait ToBasis2<S: Float> {
pub trait ToBasis2<S: BaseFloat> {
/// Convert this type to a rotation matrix.
fn to_rot2(&self) -> Basis2<S>;
}
impl<S: Float> ToBasis2<S> for Basis2<S> {
impl<S: BaseFloat> ToBasis2<S> for Basis2<S> {
#[inline]
fn to_rot2(&self) -> Basis2<S> { self.clone() }
}
impl<S: Float> ToMatrix2<S> for Basis2<S> {
impl<S: BaseFloat> ToMatrix2<S> for Basis2<S> {
#[inline]
fn to_matrix2(&self) -> Matrix2<S> { self.mat.clone() }
}
impl<S: PartOrdFloat<S>>
Rotation<S, [S, ..2], Vector2<S>, Point2<S>> for Basis2<S> {
impl<S: BaseFloat> Rotation<S, [S, ..2], Vector2<S>, Point2<S>> for Basis2<S> {
#[inline]
fn identity() -> Basis2<S> { Basis2{ mat: Matrix2::identity() } }
@ -209,16 +208,14 @@ Rotation<S, [S, ..2], Vector2<S>, Point2<S>> for Basis2<S> {
fn invert_self(&mut self) { self.mat.invert_self(); }
}
impl<S: PartOrdFloat<S>>
ApproxEq<S> for Basis2<S> {
impl<S: BaseFloat> ApproxEq<S> for Basis2<S> {
#[inline]
fn approx_eq_eps(&self, other: &Basis2<S>, epsilon: &S) -> bool {
self.mat.approx_eq_eps(&other.mat, epsilon)
}
}
impl<S: PartOrdFloat<S>>
Rotation2<S> for Basis2<S> {
impl<S: BaseFloat> Rotation2<S> for Basis2<S> {
fn from_angle(theta: Rad<S>) -> Basis2<S> { Basis2 { mat: Matrix2::from_angle(theta) } }
}
@ -233,8 +230,7 @@ pub struct Basis3<S> {
mat: Matrix3<S>
}
impl<S: PartOrdFloat<S>>
Basis3<S> {
impl<S: BaseFloat> Basis3<S> {
/// Create a new rotation matrix from a quaternion.
#[inline]
pub fn from_quaternion(quaternion: &Quaternion<S>) -> Basis3<S> {
@ -247,29 +243,27 @@ Basis3<S> {
}
/// Represents types which can be converted to a rotation matrix.
pub trait ToBasis3<S: Float> {
pub trait ToBasis3<S: BaseFloat> {
/// Convert this type to a rotation matrix.
fn to_rot3(&self) -> Basis3<S>;
}
impl<S: Float> ToBasis3<S> for Basis3<S> {
impl<S: BaseFloat> ToBasis3<S> for Basis3<S> {
#[inline]
fn to_rot3(&self) -> Basis3<S> { self.clone() }
}
impl<S: Float> ToMatrix3<S> for Basis3<S> {
impl<S: BaseFloat> ToMatrix3<S> for Basis3<S> {
#[inline]
fn to_matrix3(&self) -> Matrix3<S> { self.mat.clone() }
}
impl<S: PartOrdFloat<S>>
ToQuaternion<S> for Basis3<S> {
impl<S: BaseFloat> ToQuaternion<S> for Basis3<S> {
#[inline]
fn to_quaternion(&self) -> Quaternion<S> { self.mat.to_quaternion() }
}
impl<S: PartOrdFloat<S>>
Rotation<S, [S, ..3], Vector3<S>, Point3<S>> for Basis3<S> {
impl<S: BaseFloat> Rotation<S, [S, ..3], Vector3<S>, Point3<S>> for Basis3<S> {
#[inline]
fn identity() -> Basis3<S> { Basis3{ mat: Matrix3::identity() } }
@ -304,16 +298,14 @@ Rotation<S, [S, ..3], Vector3<S>, Point3<S>> for Basis3<S> {
fn invert_self(&mut self) { self.mat.invert_self(); }
}
impl<S: Float + ApproxEq<S>>
ApproxEq<S> for Basis3<S> {
impl<S: BaseFloat> ApproxEq<S> for Basis3<S> {
#[inline]
fn approx_eq_eps(&self, other: &Basis3<S>, epsilon: &S) -> bool {
self.mat.approx_eq_eps(&other.mat, epsilon)
}
}
impl<S: PartOrdFloat<S>>
Rotation3<S> for Basis3<S> {
impl<S: BaseFloat> Rotation3<S> for Basis3<S> {
fn from_axis_angle(axis: &Vector3<S>, angle: Rad<S>) -> Basis3<S> {
Basis3 { mat: Matrix3::from_axis_angle(axis, angle) }
}

View file

@ -1,4 +1,4 @@
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -16,17 +16,12 @@
//! Bounding sphere
use intersect::Intersect;
use num::BaseFloat;
use point::{Point, Point3};
use ray::Ray3;
use vector::Vector;
use partial_ord::PartOrdFloat;
use std::num::NumCast;
use std::num;
fn cast<T: NumCast, U: NumCast>(n: T) -> U {
num::cast(n).unwrap()
}
use std::num::zero;
#[deriving(Clone, Eq)]
pub struct Sphere<S> {
@ -34,13 +29,13 @@ pub struct Sphere<S> {
pub radius: S,
}
impl<S: PartOrdFloat<S>> Intersect<Option<Point3<S>>> for (Sphere<S>, Ray3<S>) {
impl<S: BaseFloat> Intersect<Option<Point3<S>>> for (Sphere<S>, Ray3<S>) {
fn intersection(&self) -> Option<Point3<S>> {
match *self {
(ref s, ref r) => {
let l = s.center.sub_p(&r.origin);
let tca = l.dot(&r.direction);
if tca < cast(0.0) { return None; }
if tca < zero() { return None; }
let d2 = l.dot(&l) - tca*tca;
if d2 > s.radius*s.radius { return None; }
let thc = (s.radius*s.radius - d2).sqrt();

View file

@ -19,19 +19,19 @@ use std::num::one;
use approx::ApproxEq;
use matrix::{Matrix, Matrix4, ToMatrix4};
use num::{BaseNum, BaseFloat};
use point::{Point, Point3};
use ray::Ray;
use rotation::{Rotation, Rotation3};
use quaternion::Quaternion;
use vector::{Vector, Vector3};
use partial_ord::{PartOrdPrim, PartOrdFloat};
/// 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: PartOrdPrim,
S: BaseNum,
Slice,
V: Vector<S,Slice>,
P: Point<S,V,Slice>
@ -94,7 +94,7 @@ pub struct Decomposed<S,V,R> {
impl
<
S: PartOrdFloat<S>,
S: BaseFloat,
Slice,
V: Vector<S, Slice>,
P: Point<S, V, Slice>,
@ -162,8 +162,7 @@ pub trait Transform3<S>
+ ToMatrix4<S>
{}
impl<S: PartOrdFloat<S>, R: Rotation3<S>>
ToMatrix4<S> for Decomposed<S, Vector3<S>, R> {
impl<S: BaseFloat, R: Rotation3<S>> ToMatrix4<S> for Decomposed<S, Vector3<S>, R> {
fn to_matrix4(&self) -> Matrix4<S> {
let mut m = self.rot.to_matrix3().mul_s( self.scale.clone() ).to_matrix4();
m.w = self.disp.extend( num::one() );
@ -171,11 +170,9 @@ ToMatrix4<S> for Decomposed<S, Vector3<S>, R> {
}
}
impl<S: PartOrdFloat<S>, R: Rotation3<S>>
Transform3<S> for Decomposed<S,Vector3<S>,R> {}
impl<S: BaseFloat, R: Rotation3<S>> Transform3<S> for Decomposed<S,Vector3<S>,R> {}
impl<S: fmt::Show + Float, R: fmt::Show + Rotation3<S>>
fmt::Show for Decomposed<S,Vector3<S>,R> {
impl<S: BaseFloat, R: fmt::Show + Rotation3<S>> fmt::Show for Decomposed<S,Vector3<S>,R> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "(scale({}), rot({}), disp{})",
self.scale, self.rot, self.disp)
@ -188,8 +185,7 @@ pub struct AffineMatrix3<S> {
pub mat: Matrix4<S>,
}
impl<S : PartOrdFloat<S>>
Transform<S, [S, ..3], Vector3<S>, Point3<S>> for AffineMatrix3<S> {
impl<S : BaseFloat> Transform<S, [S, ..3], Vector3<S>, Point3<S>> for AffineMatrix3<S> {
#[inline]
fn identity() -> AffineMatrix3<S> {
AffineMatrix3 { mat: Matrix4::identity() }
@ -221,20 +217,18 @@ Transform<S, [S, ..3], Vector3<S>, Point3<S>> for AffineMatrix3<S> {
}
}
impl<S: PartOrdPrim>
ToMatrix4<S> for AffineMatrix3<S> {
impl<S: BaseNum> ToMatrix4<S> for AffineMatrix3<S> {
#[inline] fn to_matrix4(&self) -> Matrix4<S> { self.mat.clone() }
}
impl<S: PartOrdFloat<S>>
Transform3<S> for AffineMatrix3<S> {}
impl<S: BaseFloat> Transform3<S> for AffineMatrix3<S> {}
/// A transformation in three dimensions consisting of a rotation,
/// displacement vector and scale amount.
pub struct Transform3D<S>( Decomposed<S,Vector3<S>,Quaternion<S>> );
impl<S: PartOrdFloat<S>> Transform3D<S> {
impl<S: BaseFloat> Transform3D<S> {
#[inline]
pub fn new(scale: S, rot: Quaternion<S>, disp: Vector3<S>) -> Transform3D<S> {
Transform3D( Decomposed { scale: scale, rot: rot, disp: disp })
@ -252,6 +246,6 @@ impl<S: PartOrdFloat<S>> Transform3D<S> {
}
}
impl<S: PartOrdFloat<S>> ToMatrix4<S> for Transform3D<S> {
impl<S: BaseFloat> ToMatrix4<S> for Transform3D<S> {
fn to_matrix4(&self) -> Matrix4<S> { self.get().to_matrix4() }
}

View file

@ -1,4 +1,4 @@
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -19,14 +19,14 @@ use std::num::{Zero, zero, One, one};
use angle::{Rad, atan2, acos};
use approx::ApproxEq;
use array::{Array, build};
use partial_ord::{PartOrdPrim, PartOrdFloat};
use num::{BaseNum, BaseFloat, PartialOrd};
/// 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
/// for pragmatic reasons.
pub trait Vector
<
S: PartOrdPrim,
S: BaseNum,
Slice
>
: Array<S, Slice>
@ -90,14 +90,14 @@ pub trait Vector
#[inline] fn dot(&self, other: &Self) -> S { self.mul_v(other).comp_add() }
/// The minimum component of the vector.
#[inline] fn comp_min(&self) -> S { self.fold(|a, b| if *a < *b { *a } else {*b }) }
#[inline] fn comp_min(&self) -> S { self.fold(|a, b| a.partial_min(*b)) }
/// The maximum component of the vector.
#[inline] fn comp_max(&self) -> S { self.fold(|a, b| if *a > *b { *a } else {*b }) }
#[inline] fn comp_max(&self) -> S { self.fold(|a, b| a.partial_max(*b)) }
}
/// Dot product of two vectors.
#[inline] pub fn dot<S: PartOrdPrim, Slice, V: Vector<S, Slice>>(a: V, b: V) -> S { a.dot(&b) }
#[inline] pub fn dot<S: BaseNum, Slice, V: Vector<S, Slice>>(a: V, b: V) -> S { a.dot(&b) }
// Utility macro for generating associated functions for the vectors
macro_rules! vec(
@ -105,7 +105,7 @@ macro_rules! vec(
#[deriving(Eq, TotalEq, Clone, Hash)]
pub struct $Self<S> { $(pub $field: S),+ }
impl<$S: Primitive> $Self<$S> {
impl<$S: BaseNum> $Self<$S> {
/// Construct a new vector, using the provided values.
#[inline]
pub fn new($($field: $S),+) -> $Self<$S> {
@ -127,32 +127,32 @@ macro_rules! vec(
pub fn ident() -> $Self<$S> { $Self::from_value(one()) }
}
impl<S: PartOrdPrim> Add<$Self<S>, $Self<S>> for $Self<S> {
impl<S: BaseNum> Add<$Self<S>, $Self<S>> for $Self<S> {
#[inline] fn add(&self, other: &$Self<S>) -> $Self<S> { self.add_v(other) }
}
impl<S: PartOrdPrim> Sub<$Self<S>, $Self<S>> for $Self<S> {
impl<S: BaseNum> Sub<$Self<S>, $Self<S>> for $Self<S> {
#[inline] fn sub(&self, other: &$Self<S>) -> $Self<S> { self.sub_v(other) }
}
impl<S: PartOrdPrim> Zero for $Self<S> {
impl<S: BaseNum> Zero for $Self<S> {
#[inline] fn zero() -> $Self<S> { $Self::from_value(zero()) }
#[inline] fn is_zero(&self) -> bool { *self == zero() }
}
impl<S: PartOrdPrim> Neg<$Self<S>> for $Self<S> {
impl<S: BaseNum> Neg<$Self<S>> for $Self<S> {
#[inline] fn neg(&self) -> $Self<S> { build(|i| self.i(i).neg()) }
}
impl<S: PartOrdPrim> Mul<$Self<S>, $Self<S>> for $Self<S> {
impl<S: BaseNum> Mul<$Self<S>, $Self<S>> for $Self<S> {
#[inline] fn mul(&self, other: &$Self<S>) -> $Self<S> { self.mul_v(other) }
}
impl<S: PartOrdPrim> One for $Self<S> {
impl<S: BaseNum> One for $Self<S> {
#[inline] fn one() -> $Self<S> { $Self::from_value(one()) }
}
impl<S: PartOrdPrim> Vector<S, [S, ..$n]> for $Self<S> {}
impl<S: BaseNum> Vector<S, [S, ..$n]> for $Self<S> {}
)
)
@ -165,7 +165,7 @@ array!(impl<S> Vector3<S> -> [S, ..3] _3)
array!(impl<S> Vector4<S> -> [S, ..4] _4)
/// Operations specific to numeric two-dimensional vectors.
impl<S: Primitive> Vector2<S> {
impl<S: BaseNum> Vector2<S> {
/// A unit vector in the `x` direction.
#[inline] pub fn unit_x() -> Vector2<S> { Vector2::new(one(), zero()) }
/// A unit vector in the `y` direction.
@ -186,7 +186,7 @@ impl<S: Primitive> Vector2<S> {
}
/// Operations specific to numeric three-dimensional vectors.
impl<S: Primitive> Vector3<S> {
impl<S: BaseNum> Vector3<S> {
/// A unit vector in the `x` direction.
#[inline] pub fn unit_x() -> Vector3<S> { Vector3::new(one(), zero(), zero()) }
/// A unit vector in the `y` direction.
@ -224,7 +224,7 @@ impl<S: Primitive> Vector3<S> {
}
/// Operations specific to numeric four-dimensional vectors.
impl<S: Primitive> Vector4<S> {
impl<S: BaseNum> Vector4<S> {
/// A unit vector in the `x` direction.
#[inline] pub fn unit_x() -> Vector4<S> { Vector4::new(one(), zero(), zero(), zero()) }
/// A unit vector in the `y` direction.
@ -245,7 +245,7 @@ impl<S: Primitive> Vector4<S> {
/// 2-dimensional and 3-dimensional vectors.
pub trait EuclideanVector
<
S: PartOrdFloat<S>,
S: BaseFloat,
Slice
>
: Vector<S, Slice>
@ -316,7 +316,7 @@ pub trait EuclideanVector
}
}
impl<S: PartOrdFloat<S>>
impl<S: BaseFloat>
EuclideanVector<S, [S, ..2]> for Vector2<S> {
#[inline]
fn angle(&self, other: &Vector2<S>) -> Rad<S> {
@ -324,7 +324,7 @@ EuclideanVector<S, [S, ..2]> for Vector2<S> {
}
}
impl<S: PartOrdFloat<S>>
impl<S: BaseFloat>
EuclideanVector<S, [S, ..3]> for Vector3<S> {
#[inline]
fn angle(&self, other: &Vector3<S>) -> Rad<S> {
@ -332,7 +332,7 @@ EuclideanVector<S, [S, ..3]> for Vector3<S> {
}
}
impl<S: PartOrdFloat<S>>
impl<S: BaseFloat>
EuclideanVector<S, [S, ..4]> for Vector4<S> {
#[inline]
fn angle(&self, other: &Vector4<S>) -> Rad<S> {