Merge pull request #56 from ozkriff/partial_ord

Replaced partial_{min,max} funcs with PartOrdPrim trait
This commit is contained in:
Brendan Zabarauskas 2014-03-19 20:52:27 +11:00
commit 563b77a885
13 changed files with 161 additions and 101 deletions

View file

@ -18,16 +18,14 @@
use point::{Point, Point2, Point3}; use point::{Point, Point2, Point3};
use vector::{Vector, Vec2, Vec3}; use vector::{Vector, Vec2, Vec3};
use array::build; use array::build;
use partial_ord::PartOrdPrim;
use std::fmt; use std::fmt;
use std::num::{zero, one}; use std::num::{zero, one};
use std::iter::Iterator; use std::iter::Iterator;
fn partial_min<S: Ord>(a: S, b: S) -> S { if a < b { a } else { b }}
fn partial_max<S: Ord>(a: S, b: S) -> S { if a > b { a } else { b }}
pub trait Aabb pub trait Aabb
< <
S: Primitive, S: PartOrdPrim,
V: Vector<S, Slice>, V: Vector<S, Slice>,
P: Point<S, V, Slice>, P: Point<S, V, Slice>,
Slice Slice
@ -51,8 +49,8 @@ pub trait Aabb
// Returns a new AABB that is grown to include the given point. // Returns a new AABB that is grown to include the given point.
fn grow(&self, p: &P) -> Self { fn grow(&self, p: &P) -> Self {
let min : P = build(|i| partial_min(*self.min().i(i), *p.i(i))); let min : P = build(|i| self.min().i(i).min(*p.i(i)));
let max : P = build(|i| partial_max(*self.max().i(i), *p.i(i))); let max : P = build(|i| self.max().i(i).max(*p.i(i)));
Aabb::new(min, max) Aabb::new(min, max)
} }
@ -78,20 +76,20 @@ pub struct Aabb2<S> {
max: Point2<S>, max: Point2<S>,
} }
impl<S: Num + Ord + Clone> Aabb2<S> { impl<S: PartOrdPrim> Aabb2<S> {
/// Construct a new axis-aligned bounding box from two points. /// Construct a new axis-aligned bounding box from two points.
#[inline] #[inline]
pub fn new(p1: Point2<S>, p2: Point2<S>) -> Aabb2<S> { pub fn new(p1: Point2<S>, p2: Point2<S>) -> Aabb2<S> {
Aabb2 { Aabb2 {
min: Point2::new(partial_min(p1.x.clone(), p2.x.clone()), min: Point2::new(p1.x.min(p2.x),
partial_min(p1.y.clone(), p2.y.clone())), p1.y.min(p2.y)),
max: Point2::new(partial_max(p1.x.clone(), p2.x.clone()), max: Point2::new(p1.x.max(p2.x),
partial_max(p1.y.clone(), p2.y.clone())), p1.y.max(p2.y)),
} }
} }
} }
impl<S: Primitive> Aabb<S, Vec2<S>, Point2<S>, [S, ..2]> for Aabb2<S> { impl<S: PartOrdPrim> Aabb<S, Vec2<S>, Point2<S>, [S, ..2]> for Aabb2<S> {
fn new(p1: Point2<S>, p2: Point2<S>) -> Aabb2<S> { Aabb2::new(p1, p2) } 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 min<'a>(&'a self) -> &'a Point2<S> { &self.min }
#[inline] fn max<'a>(&'a self) -> &'a Point2<S> { &self.max } #[inline] fn max<'a>(&'a self) -> &'a Point2<S> { &self.max }
@ -109,22 +107,22 @@ pub struct Aabb3<S> {
max: Point3<S>, max: Point3<S>,
} }
impl<S: Num + Ord + Clone> Aabb3<S> { impl<S: PartOrdPrim> Aabb3<S> {
/// Construct a new axis-aligned bounding box from two points. /// Construct a new axis-aligned bounding box from two points.
#[inline] #[inline]
pub fn new(p1: Point3<S>, p2: Point3<S>) -> Aabb3<S> { pub fn new(p1: Point3<S>, p2: Point3<S>) -> Aabb3<S> {
Aabb3 { Aabb3 {
min: Point3::new(partial_min(p1.x.clone(), p2.x.clone()), min: Point3::new(p1.x.min(p2.x),
partial_min(p1.y.clone(), p2.y.clone()), p1.y.min(p2.y),
partial_min(p1.z.clone(), p2.z.clone())), p1.z.min(p2.z)),
max: Point3::new(partial_max(p1.x.clone(), p2.x.clone()), max: Point3::new(p1.x.max(p2.x),
partial_max(p1.y.clone(), p2.y.clone()), p1.y.max(p2.y),
partial_max(p1.z.clone(), p2.z.clone())), p1.z.max(p2.z)),
} }
} }
} }
impl<S: Primitive> Aabb<S, Vec3<S>, Point3<S>, [S, ..3]> for Aabb3<S> { impl<S: PartOrdPrim> Aabb<S, Vec3<S>, Point3<S>, [S, ..3]> for Aabb3<S> {
fn new(p1: Point3<S>, p2: Point3<S>) -> Aabb3<S> { Aabb3::new(p1, p2) } 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 min<'a>(&'a self) -> &'a Point3<S> { &self.min }
#[inline] fn max<'a>(&'a self) -> &'a Point3<S> { &self.max } #[inline] fn max<'a>(&'a self) -> &'a Point3<S> { &self.max }

View file

@ -15,11 +15,11 @@
//! View frustum for visibility determination //! View frustum for visibility determination
use approx::ApproxEq;
use matrix::{Matrix, Mat4}; use matrix::{Matrix, Mat4};
use plane::Plane; use plane::Plane;
use point::Point3; use point::Point3;
use vector::{Vector, EuclideanVector}; use vector::{Vector, EuclideanVector};
use partial_ord::PartOrdFloat;
#[deriving(Clone, Eq)] #[deriving(Clone, Eq)]
pub struct Frustum<S> { pub struct Frustum<S> {
@ -31,7 +31,7 @@ pub struct Frustum<S> {
far: Plane<S>, far: Plane<S>,
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Frustum<S> { Frustum<S> {
/// Constructs a frustum /// Constructs a frustum
pub fn new(left: Plane<S>, right: Plane<S>, pub fn new(left: Plane<S>, right: Plane<S>,

View file

@ -45,3 +45,5 @@ pub mod sphere;
pub mod approx; pub mod approx;
pub mod ptr; pub mod ptr;
pub mod partial_ord;

View file

@ -25,6 +25,7 @@ use point::{Point, Point3};
use quaternion::{Quat, ToQuat}; use quaternion::{Quat, ToQuat};
use vector::{Vector, EuclideanVector}; use vector::{Vector, EuclideanVector};
use vector::{Vec2, Vec3, Vec4}; use vector::{Vec2, Vec3, Vec4};
use partial_ord::PartOrdFloat;
/// A 2 x 2, column major matrix /// A 2 x 2, column major matrix
#[deriving(Clone, Eq)] #[deriving(Clone, Eq)]
@ -69,7 +70,7 @@ impl<S: Primitive> Mat2<S> {
} }
} }
impl<S: Float + ApproxEq<S>> Mat2<S> { impl<S: PartOrdFloat<S>> Mat2<S> {
pub fn look_at(dir: &Vec2<S>, up: &Vec2<S>) -> Mat2<S> { pub fn look_at(dir: &Vec2<S>, up: &Vec2<S>) -> Mat2<S> {
//TODO: verify look_at 2D //TODO: verify look_at 2D
Mat2::from_cols(up.clone(), dir.clone()).transpose() Mat2::from_cols(up.clone(), dir.clone()).transpose()
@ -118,7 +119,7 @@ impl<S: Primitive> Mat3<S> {
} }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Mat3<S> { Mat3<S> {
pub fn look_at(dir: &Vec3<S>, up: &Vec3<S>) -> Mat3<S> { pub fn look_at(dir: &Vec3<S>, up: &Vec3<S>) -> Mat3<S> {
let dir = dir.normalize(); let dir = dir.normalize();
@ -228,7 +229,7 @@ impl<S: Primitive> Mat4<S> {
} }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Mat4<S> { Mat4<S> {
pub fn look_at(eye: &Point3<S>, center: &Point3<S>, up: &Vec3<S>) -> Mat4<S> { pub fn look_at(eye: &Point3<S>, center: &Point3<S>, up: &Vec3<S>) -> Mat4<S> {
let f = center.sub_p(eye).normalize(); let f = center.sub_p(eye).normalize();
@ -248,7 +249,7 @@ array!(impl<S> Mat4<S> -> [Vec4<S>, ..4] _4)
pub trait Matrix pub trait Matrix
< <
S: Float + ApproxEq<S>, Slice, S: PartOrdFloat<S>, Slice,
V: Clone + Vector<S, VSlice> + Array<S, VSlice>, VSlice V: Clone + Vector<S, VSlice> + Array<S, VSlice>, VSlice
> >
: Array<V, Slice> : Array<V, Slice>
@ -360,31 +361,31 @@ pub trait Matrix
fn is_symmetric(&self) -> bool; fn is_symmetric(&self) -> bool;
} }
impl<S: Float> Add<Mat2<S>, Mat2<S>> for Mat2<S> { #[inline] fn add(&self, other: &Mat2<S>) -> Mat2<S> { build(|i| self.i(i).add_v(other.i(i))) } } impl<S: PartOrdFloat<S>> Add<Mat2<S>, Mat2<S>> for Mat2<S> { #[inline] fn add(&self, other: &Mat2<S>) -> Mat2<S> { build(|i| self.i(i).add_v(other.i(i))) } }
impl<S: Float> Add<Mat3<S>, Mat3<S>> for Mat3<S> { #[inline] fn add(&self, other: &Mat3<S>) -> Mat3<S> { build(|i| self.i(i).add_v(other.i(i))) } } impl<S: PartOrdFloat<S>> Add<Mat3<S>, Mat3<S>> for Mat3<S> { #[inline] fn add(&self, other: &Mat3<S>) -> Mat3<S> { build(|i| self.i(i).add_v(other.i(i))) } }
impl<S: Float> Add<Mat4<S>, Mat4<S>> for Mat4<S> { #[inline] fn add(&self, other: &Mat4<S>) -> Mat4<S> { build(|i| self.i(i).add_v(other.i(i))) } } impl<S: PartOrdFloat<S>> Add<Mat4<S>, Mat4<S>> for Mat4<S> { #[inline] fn add(&self, other: &Mat4<S>) -> Mat4<S> { build(|i| self.i(i).add_v(other.i(i))) } }
impl<S: Float> Sub<Mat2<S>, Mat2<S>> for Mat2<S> { #[inline] fn sub(&self, other: &Mat2<S>) -> Mat2<S> { build(|i| self.i(i).sub_v(other.i(i))) } } impl<S: PartOrdFloat<S>> Sub<Mat2<S>, Mat2<S>> for Mat2<S> { #[inline] fn sub(&self, other: &Mat2<S>) -> Mat2<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
impl<S: Float> Sub<Mat3<S>, Mat3<S>> for Mat3<S> { #[inline] fn sub(&self, other: &Mat3<S>) -> Mat3<S> { build(|i| self.i(i).sub_v(other.i(i))) } } impl<S: PartOrdFloat<S>> Sub<Mat3<S>, Mat3<S>> for Mat3<S> { #[inline] fn sub(&self, other: &Mat3<S>) -> Mat3<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
impl<S: Float> Sub<Mat4<S>, Mat4<S>> for Mat4<S> { #[inline] fn sub(&self, other: &Mat4<S>) -> Mat4<S> { build(|i| self.i(i).sub_v(other.i(i))) } } impl<S: PartOrdFloat<S>> Sub<Mat4<S>, Mat4<S>> for Mat4<S> { #[inline] fn sub(&self, other: &Mat4<S>) -> Mat4<S> { build(|i| self.i(i).sub_v(other.i(i))) } }
impl<S: Float> Neg<Mat2<S>> for Mat2<S> { #[inline] fn neg(&self) -> Mat2<S> { build(|i| self.i(i).neg()) } } impl<S: PartOrdFloat<S>> Neg<Mat2<S>> for Mat2<S> { #[inline] fn neg(&self) -> Mat2<S> { build(|i| self.i(i).neg()) } }
impl<S: Float> Neg<Mat3<S>> for Mat3<S> { #[inline] fn neg(&self) -> Mat3<S> { build(|i| self.i(i).neg()) } } impl<S: PartOrdFloat<S>> Neg<Mat3<S>> for Mat3<S> { #[inline] fn neg(&self) -> Mat3<S> { build(|i| self.i(i).neg()) } }
impl<S: Float> Neg<Mat4<S>> for Mat4<S> { #[inline] fn neg(&self) -> Mat4<S> { build(|i| self.i(i).neg()) } } impl<S: PartOrdFloat<S>> Neg<Mat4<S>> for Mat4<S> { #[inline] fn neg(&self) -> Mat4<S> { build(|i| self.i(i).neg()) } }
impl<S: Float> Zero for Mat2<S> { #[inline] fn zero() -> Mat2<S> { Mat2::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } } impl<S: PartOrdFloat<S>> Zero for Mat2<S> { #[inline] fn zero() -> Mat2<S> { Mat2::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: Float> Zero for Mat3<S> { #[inline] fn zero() -> Mat3<S> { Mat3::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } } impl<S: PartOrdFloat<S>> Zero for Mat3<S> { #[inline] fn zero() -> Mat3<S> { Mat3::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: Float> Zero for Mat4<S> { #[inline] fn zero() -> Mat4<S> { Mat4::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } } impl<S: PartOrdFloat<S>> Zero for Mat4<S> { #[inline] fn zero() -> Mat4<S> { Mat4::zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() } }
impl<S: Float> Mul<Mat2<S>, Mat2<S>> for Mat2<S> { #[inline] fn mul(&self, other: &Mat2<S>) -> Mat2<S> { build(|i| self.i(i).mul_v(other.i(i))) } } impl<S: PartOrdFloat<S>> Mul<Mat2<S>, Mat2<S>> for Mat2<S> { #[inline] fn mul(&self, other: &Mat2<S>) -> Mat2<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
impl<S: Float> Mul<Mat3<S>, Mat3<S>> for Mat3<S> { #[inline] fn mul(&self, other: &Mat3<S>) -> Mat3<S> { build(|i| self.i(i).mul_v(other.i(i))) } } impl<S: PartOrdFloat<S>> Mul<Mat3<S>, Mat3<S>> for Mat3<S> { #[inline] fn mul(&self, other: &Mat3<S>) -> Mat3<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
impl<S: Float> Mul<Mat4<S>, Mat4<S>> for Mat4<S> { #[inline] fn mul(&self, other: &Mat4<S>) -> Mat4<S> { build(|i| self.i(i).mul_v(other.i(i))) } } impl<S: PartOrdFloat<S>> Mul<Mat4<S>, Mat4<S>> for Mat4<S> { #[inline] fn mul(&self, other: &Mat4<S>) -> Mat4<S> { build(|i| self.i(i).mul_v(other.i(i))) } }
impl<S: Float> One for Mat2<S> { #[inline] fn one() -> Mat2<S> { Mat2::identity() } } impl<S: PartOrdFloat<S>> One for Mat2<S> { #[inline] fn one() -> Mat2<S> { Mat2::identity() } }
impl<S: Float> One for Mat3<S> { #[inline] fn one() -> Mat3<S> { Mat3::identity() } } impl<S: PartOrdFloat<S>> One for Mat3<S> { #[inline] fn one() -> Mat3<S> { Mat3::identity() } }
impl<S: Float> One for Mat4<S> { #[inline] fn one() -> Mat4<S> { Mat4::identity() } } impl<S: PartOrdFloat<S>> One for Mat4<S> { #[inline] fn one() -> Mat4<S> { Mat4::identity() } }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Matrix<S, [Vec2<S>, ..2], Vec2<S>, [S, ..2]> Matrix<S, [Vec2<S>, ..2], Vec2<S>, [S, ..2]>
for Mat2<S> for Mat2<S>
{ {
@ -433,7 +434,7 @@ for Mat2<S>
} }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Matrix<S, [Vec3<S>, ..3], Vec3<S>, [S, ..3]> Matrix<S, [Vec3<S>, ..3], Vec3<S>, [S, ..3]>
for Mat3<S> for Mat3<S>
{ {
@ -506,7 +507,7 @@ macro_rules! dot_mat4(
(*$A.cr(3, $I)) * (*$B.cr($J, 3)) (*$A.cr(3, $I)) * (*$B.cr($J, 3))
)) ))
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Matrix<S, [Vec4<S>, ..4], Vec4<S>, [S, ..4]> Matrix<S, [Vec4<S>, ..4], Vec4<S>, [S, ..4]>
for Mat4<S> for Mat4<S>
{ {
@ -639,7 +640,7 @@ pub trait ToMat2<S: Primitive> { fn to_mat2(&self) -> Mat2<S>; }
pub trait ToMat3<S: Primitive> { fn to_mat3(&self) -> Mat3<S>; } pub trait ToMat3<S: Primitive> { fn to_mat3(&self) -> Mat3<S>; }
pub trait ToMat4<S: Primitive> { fn to_mat4(&self) -> Mat4<S>; } pub trait ToMat4<S: Primitive> { fn to_mat4(&self) -> Mat4<S>; }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
ToMat3<S> for Mat2<S> { ToMat3<S> for Mat2<S> {
/// Clone the elements of a 2-dimensional matrix into the top corner of a /// Clone the elements of a 2-dimensional matrix into the top corner of a
/// 3-dimensional identity matrix. /// 3-dimensional identity matrix.
@ -650,7 +651,7 @@ ToMat3<S> for Mat2<S> {
} }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
ToMat4<S> for Mat2<S> { ToMat4<S> for Mat2<S> {
/// Clone the elements of a 2-dimensional matrix into the top corner of a /// Clone the elements of a 2-dimensional matrix into the top corner of a
/// 4-dimensional identity matrix. /// 4-dimensional identity matrix.
@ -662,7 +663,7 @@ ToMat4<S> for Mat2<S> {
} }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
ToMat4<S> for Mat3<S> { ToMat4<S> for Mat3<S> {
/// Clone the elements of a 3-dimensional matrix into the top corner of a /// Clone the elements of a 3-dimensional matrix into the top corner of a
/// 4-dimensional identity matrix. /// 4-dimensional identity matrix.
@ -674,7 +675,7 @@ ToMat4<S> for Mat3<S> {
} }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
ToQuat<S> for Mat3<S> { ToQuat<S> for Mat3<S> {
/// Convert the matrix to a quaternion /// Convert the matrix to a quaternion
fn to_quat(&self) -> Quat<S> { fn to_quat(&self) -> Quat<S> {
@ -722,7 +723,7 @@ ToQuat<S> for Mat3<S> {
} }
} }
impl<S: Float + ApproxEq<S> + fmt::Show> fmt::Show for Mat2<S> { impl<S: PartOrdFloat<S> + fmt::Show> fmt::Show for Mat2<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f.buf, "[[{}, {}], [{}, {}]]", write!(f.buf, "[[{}, {}], [{}, {}]]",
self.cr(0, 0), self.cr(0, 1), self.cr(0, 0), self.cr(0, 1),
@ -730,7 +731,7 @@ impl<S: Float + ApproxEq<S> + fmt::Show> fmt::Show for Mat2<S> {
} }
} }
impl<S: Float + ApproxEq<S> + fmt::Show> fmt::Show for Mat3<S> { impl<S: PartOrdFloat<S> + fmt::Show> fmt::Show for Mat3<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f.buf, "[[{}, {}, {}], [{}, {}, {}], [{}, {}, {}]]", write!(f.buf, "[[{}, {}, {}], [{}, {}, {}], [{}, {}, {}]]",
self.cr(0, 0), self.cr(0, 1), self.cr(0, 2), self.cr(0, 0), self.cr(0, 1), self.cr(0, 2),
@ -739,7 +740,7 @@ impl<S: Float + ApproxEq<S> + fmt::Show> fmt::Show for Mat3<S> {
} }
} }
impl<S: Float + ApproxEq<S> + fmt::Show> fmt::Show for Mat4<S> { impl<S: PartOrdFloat<S> + fmt::Show> fmt::Show for Mat4<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f.buf, "[[{}, {}, {}, {}], [{}, {}, {}, {}], [{}, {}, {}, {}], [{}, {}, {}, {}]]", write!(f.buf, "[[{}, {}, {}, {}], [{}, {}, {}, {}], [{}, {}, {}, {}], [{}, {}, {}, {}]]",
self.cr(0, 0), self.cr(0, 1), self.cr(0, 2), self.cr(0, 3), self.cr(0, 0), self.cr(0, 1), self.cr(0, 2), self.cr(0, 3),

52
src/cgmath/partial_ord.rs Normal file
View file

@ -0,0 +1,52 @@
// 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;
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> : Float + ApproxEq<S> + PartOrdPrim {}
impl PartOrdFloat<f32> for f32 {}
impl PartOrdFloat<f64> for f64 {}

View file

@ -23,6 +23,7 @@ use point::{Point, Point3};
use ray::Ray3; use ray::Ray3;
use vector::{Vec3, Vec4}; use vector::{Vec3, Vec4};
use vector::{Vector, EuclideanVector}; use vector::{Vector, EuclideanVector};
use partial_ord::PartOrdFloat;
/// A 3-dimendional plane formed from the equation: `a*x + b*y + c*z - d = 0`. /// A 3-dimendional plane formed from the equation: `a*x + b*y + c*z - d = 0`.
@ -46,7 +47,7 @@ pub struct Plane<S> {
d: S, d: S,
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Plane<S> { Plane<S> {
/// Construct a plane from a normal vector and a scalar distance /// Construct a plane from a normal vector and a scalar distance
pub fn new(n: Vec3<S>, d: S) -> Plane<S> { pub fn new(n: Vec3<S>, d: S) -> Plane<S> {
@ -88,7 +89,7 @@ Plane<S> {
} }
} }
impl<S: Float> Intersect<Option<Point3<S>>> for (Plane<S>, Ray3<S>) { impl<S: PartOrdFloat<S>> Intersect<Option<Point3<S>>> for (Plane<S>, Ray3<S>) {
fn intersection(&self) -> Option<Point3<S>> { fn intersection(&self) -> Option<Point3<S>> {
match *self { match *self {
(ref p, ref r) => { (ref p, ref r) => {

View file

@ -22,6 +22,7 @@ use std::num::{one, zero};
use array::*; use array::*;
use vector::*; use vector::*;
use partial_ord::PartOrdPrim;
/// A point in 2-dimensional space. /// A point in 2-dimensional space.
#[deriving(Eq, Clone, Hash)] #[deriving(Eq, Clone, Hash)]
@ -46,7 +47,7 @@ impl<S: Num> Point3<S> {
} }
} }
impl<S: Clone + Num + Primitive> Point3<S> { impl<S: PartOrdPrim> Point3<S> {
#[inline] #[inline]
pub fn from_homogeneous(v: &Vec4<S>) -> Point3<S> { pub fn from_homogeneous(v: &Vec4<S>) -> Point3<S> {
let e = v.truncate().mul_s(one::<S>() / v.w); let e = v.truncate().mul_s(one::<S>() / v.w);
@ -62,7 +63,7 @@ impl<S: Clone + Num + Primitive> Point3<S> {
/// Specifies the numeric operations for point types. /// Specifies the numeric operations for point types.
pub trait Point pub trait Point
< <
S: Primitive, S: PartOrdPrim,
V: Vector<S, Slice>, V: Vector<S, Slice>,
Slice Slice
> >
@ -96,8 +97,8 @@ pub trait Point
array!(impl<S> Point2<S> -> [S, ..2] _2) array!(impl<S> Point2<S> -> [S, ..2] _2)
array!(impl<S> Point3<S> -> [S, ..3] _3) array!(impl<S> Point3<S> -> [S, ..3] _3)
impl<S: Primitive> Point<S, Vec2<S>, [S, ..2]> for Point2<S> {} impl<S: PartOrdPrim> Point<S, Vec2<S>, [S, ..2]> for Point2<S> {}
impl<S: Primitive> Point<S, Vec3<S>, [S, ..3]> for Point3<S> {} impl<S: PartOrdPrim> Point<S, Vec3<S>, [S, ..3]> for Point3<S> {}
impl<S: fmt::Show> fmt::Show for Point2<S> { impl<S: fmt::Show> fmt::Show for Point2<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

View file

@ -16,10 +16,10 @@
use std::num::{zero, one, cast}; use std::num::{zero, one, cast};
use angle::{Angle, tan, cot}; use angle::{Angle, tan, cot};
use approx::ApproxEq;
use frustum::Frustum; use frustum::Frustum;
use matrix::{Mat4, ToMat4}; use matrix::{Mat4, ToMat4};
use plane::Plane; use plane::Plane;
use partial_ord::PartOrdFloat;
/// Create a perspective projection matrix. /// Create a perspective projection matrix.
/// ///
@ -94,7 +94,7 @@ impl<S: Float, A: Angle<S>> PerspectiveFov<S, A> {
} }
} }
impl<S: Float + ApproxEq<S>, A: Angle<S>> impl<S: PartOrdFloat<S>, A: Angle<S>>
Projection<S> for PerspectiveFov<S, A> { Projection<S> for PerspectiveFov<S, A> {
fn to_frustum(&self) -> Frustum<S> { fn to_frustum(&self) -> Frustum<S> {
// TODO: Could this be faster? // TODO: Could this be faster?
@ -151,7 +151,7 @@ pub struct Perspective<S> {
near: S, far: S, near: S, far: S,
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Projection<S> for Perspective<S> { Projection<S> for Perspective<S> {
fn to_frustum(&self) -> Frustum<S> { fn to_frustum(&self) -> Frustum<S> {
// TODO: Could this be faster? // TODO: Could this be faster?
@ -202,7 +202,7 @@ pub struct Ortho<S> {
near: S, far: S, near: S, far: S,
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Projection<S> for Ortho<S> { Projection<S> for Ortho<S> {
fn to_frustum(&self) -> Frustum<S> { fn to_frustum(&self) -> Frustum<S> {
Frustum { Frustum {

View file

@ -23,6 +23,7 @@ use matrix::{Mat3, ToMat3, ToMat4, Mat4};
use point::{Point3}; use point::{Point3};
use rotation::{Rotation, Rotation3, Basis3, ToBasis3}; use rotation::{Rotation, Rotation3, Basis3, ToBasis3};
use vector::{Vec3, Vector, EuclideanVector}; use vector::{Vec3, Vector, EuclideanVector};
use partial_ord::PartOrdFloat;
/// A quaternion in scalar/vector form /// A quaternion in scalar/vector form
#[deriving(Clone, Eq)] #[deriving(Clone, Eq)]
@ -34,7 +35,7 @@ pub trait ToQuat<S: Float> {
fn to_quat(&self) -> Quat<S>; fn to_quat(&self) -> Quat<S>;
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Quat<S> { Quat<S> {
/// Construct a new quaternion from one scalar component and three /// Construct a new quaternion from one scalar component and three
/// imaginary components /// imaginary components
@ -173,7 +174,7 @@ Quat<S> {
} }
} }
impl<S: Float + ApproxEq<S> + Ord> impl<S: PartOrdFloat<S>>
Quat<S> { Quat<S> {
/// Spherical Linear Intoperlation /// Spherical Linear Intoperlation
/// ///
@ -279,7 +280,7 @@ ToMat4<S> for Quat<S> {
} }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Neg<Quat<S>> for Quat<S> { Neg<Quat<S>> for Quat<S> {
#[inline] #[inline]
fn neg(&self) -> Quat<S> { fn neg(&self) -> Quat<S> {
@ -299,7 +300,7 @@ impl<S: fmt::Show> fmt::Show for Quat<S> {
// Quaternion Rotation impls // Quaternion Rotation impls
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
ToBasis3<S> for Quat<S> { ToBasis3<S> for Quat<S> {
#[inline] #[inline]
fn to_rot3(&self) -> Basis3<S> { Basis3::from_quat(self) } fn to_rot3(&self) -> Basis3<S> { Basis3::from_quat(self) }
@ -310,7 +311,7 @@ impl<S: Float> ToQuat<S> for Quat<S> {
fn to_quat(&self) -> Quat<S> { self.clone() } fn to_quat(&self) -> Quat<S> { self.clone() }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Quat<S> { Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Quat<S> {
#[inline] #[inline]
fn identity() -> Quat<S> { Quat::identity() } fn identity() -> Quat<S> { Quat::identity() }
@ -343,7 +344,7 @@ Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Quat<S> {
fn invert_self(&mut self) { *self = self.invert() } fn invert_self(&mut self) { *self = self.invert() }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Rotation3<S> for Quat<S> Rotation3<S> for Quat<S>
{ {
#[inline] #[inline]

View file

@ -23,11 +23,12 @@ use point::{Point, Point2, Point3};
use quaternion::{Quat, ToQuat}; use quaternion::{Quat, ToQuat};
use ray::Ray; use ray::Ray;
use vector::{Vector, Vec2, Vec3}; use vector::{Vector, Vec2, Vec3};
use partial_ord::{PartOrdPrim, PartOrdFloat};
/// A trait for generic rotation /// A trait for generic rotation
pub trait Rotation pub trait Rotation
< <
S: Primitive, S: PartOrdPrim,
Slice, Slice,
V: Vector<S,Slice>, V: Vector<S,Slice>,
P: Point<S,V,Slice> P: Point<S,V,Slice>
@ -156,7 +157,7 @@ impl<S: Float> ToMat2<S> for Basis2<S> {
fn to_mat2(&self) -> Mat2<S> { self.mat.clone() } fn to_mat2(&self) -> Mat2<S> { self.mat.clone() }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Rotation<S, [S, ..2], Vec2<S>, Point2<S>> for Basis2<S> { Rotation<S, [S, ..2], Vec2<S>, Point2<S>> for Basis2<S> {
#[inline] #[inline]
fn identity() -> Basis2<S> { Basis2{ mat: Mat2::identity() } } fn identity() -> Basis2<S> { Basis2{ mat: Mat2::identity() } }
@ -191,7 +192,7 @@ Rotation<S, [S, ..2], Vec2<S>, Point2<S>> for Basis2<S> {
fn invert_self(&mut self) { self.mat.invert_self(); } fn invert_self(&mut self) { self.mat.invert_self(); }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
ApproxEq<S> for Basis2<S> { ApproxEq<S> for Basis2<S> {
#[inline] #[inline]
fn approx_eq_eps(&self, other: &Basis2<S>, epsilon: &S) -> bool { fn approx_eq_eps(&self, other: &Basis2<S>, epsilon: &S) -> bool {
@ -199,7 +200,7 @@ ApproxEq<S> for Basis2<S> {
} }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Rotation2<S> for Basis2<S> { Rotation2<S> for Basis2<S> {
fn from_angle(theta: Rad<S>) -> Basis2<S> { Basis2 { mat: Mat2::from_angle(theta) } } fn from_angle(theta: Rad<S>) -> Basis2<S> { Basis2 { mat: Mat2::from_angle(theta) } }
} }
@ -215,7 +216,7 @@ pub struct Basis3<S> {
priv mat: Mat3<S> priv mat: Mat3<S>
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Basis3<S> { Basis3<S> {
#[inline] #[inline]
pub fn from_quat(quat: &Quat<S>) -> Basis3<S> { Basis3 { mat: quat.to_mat3() } } pub fn from_quat(quat: &Quat<S>) -> Basis3<S> { Basis3 { mat: quat.to_mat3() } }
@ -238,13 +239,13 @@ impl<S: Float> ToMat3<S> for Basis3<S> {
fn to_mat3(&self) -> Mat3<S> { self.mat.clone() } fn to_mat3(&self) -> Mat3<S> { self.mat.clone() }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
ToQuat<S> for Basis3<S> { ToQuat<S> for Basis3<S> {
#[inline] #[inline]
fn to_quat(&self) -> Quat<S> { self.mat.to_quat() } fn to_quat(&self) -> Quat<S> { self.mat.to_quat() }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Basis3<S> { Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Basis3<S> {
#[inline] #[inline]
fn identity() -> Basis3<S> { Basis3{ mat: Mat3::identity() } } fn identity() -> Basis3<S> { Basis3{ mat: Mat3::identity() } }
@ -288,7 +289,7 @@ ApproxEq<S> for Basis3<S> {
} }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Rotation3<S> for Basis3<S> { Rotation3<S> for Basis3<S> {
fn from_axis_angle(axis: &Vec3<S>, angle: Rad<S>) -> Basis3<S> { fn from_axis_angle(axis: &Vec3<S>, angle: Rad<S>) -> Basis3<S> {
Basis3 { mat: Mat3::from_axis_angle(axis, angle) } Basis3 { mat: Mat3::from_axis_angle(axis, angle) }

View file

@ -19,6 +19,7 @@ use intersect::Intersect;
use point::{Point, Point3}; use point::{Point, Point3};
use ray::Ray3; use ray::Ray3;
use vector::Vector; use vector::Vector;
use partial_ord::PartOrdFloat;
use std::num::NumCast; use std::num::NumCast;
use std::num; use std::num;
@ -33,7 +34,7 @@ pub struct Sphere<S> {
radius: S, radius: S,
} }
impl<S: Float> Intersect<Option<Point3<S>>> for (Sphere<S>, Ray3<S>) { impl<S: PartOrdFloat<S>> Intersect<Option<Point3<S>>> for (Sphere<S>, Ray3<S>) {
fn intersection(&self) -> Option<Point3<S>> { fn intersection(&self) -> Option<Point3<S>> {
match *self { match *self {
(ref s, ref r) => { (ref s, ref r) => {

View file

@ -24,11 +24,12 @@ use ray::Ray;
use rotation::{Rotation, Rotation3}; use rotation::{Rotation, Rotation3};
use quaternion::Quat; use quaternion::Quat;
use vector::{Vector, Vec3}; use vector::{Vector, Vec3};
use partial_ord::{PartOrdPrim, PartOrdFloat};
/// A trait of affine transformation, that can be applied to points or vectors /// A trait of affine transformation, that can be applied to points or vectors
pub trait Transform pub trait Transform
< <
S: Primitive, S: PartOrdPrim,
Slice, Slice,
V: Vector<S,Slice>, V: Vector<S,Slice>,
P: Point<S,V,Slice> P: Point<S,V,Slice>
@ -77,7 +78,7 @@ pub struct Decomposed<S,V,R> {
impl impl
< <
S: Float + ApproxEq<S>, S: PartOrdFloat<S>,
Slice, Slice,
V: Vector<S, Slice>, V: Vector<S, Slice>,
P: Point<S, V, Slice>, P: Point<S, V, Slice>,
@ -145,7 +146,7 @@ pub trait Transform3<S>
+ ToMat4<S> + ToMat4<S>
{} {}
impl<S: Float + Clone + ApproxEq<S>, R: Rotation3<S>> impl<S: PartOrdFloat<S>, R: Rotation3<S>>
ToMat4<S> for Decomposed<S, Vec3<S>, R> { ToMat4<S> for Decomposed<S, Vec3<S>, R> {
fn to_mat4(&self) -> Mat4<S> { fn to_mat4(&self) -> Mat4<S> {
let mut m = self.rot.to_mat3().mul_s( self.scale.clone() ).to_mat4(); let mut m = self.rot.to_mat3().mul_s( self.scale.clone() ).to_mat4();
@ -154,7 +155,7 @@ ToMat4<S> for Decomposed<S, Vec3<S>, R> {
} }
} }
impl<S: Float + ApproxEq<S>, R: Rotation3<S>> impl<S: PartOrdFloat<S>, R: Rotation3<S>>
Transform3<S> for Decomposed<S,Vec3<S>,R> {} Transform3<S> for Decomposed<S,Vec3<S>,R> {}
impl<S: fmt::Show + Float, R: fmt::Show + Rotation3<S>> impl<S: fmt::Show + Float, R: fmt::Show + Rotation3<S>>
@ -171,7 +172,7 @@ pub struct AffineMatrix3<S> {
mat: Mat4<S>, mat: Mat4<S>,
} }
impl<S : Clone + Float + ApproxEq<S>> impl<S : PartOrdFloat<S>>
Transform<S, [S, ..3], Vec3<S>, Point3<S>> for AffineMatrix3<S> { Transform<S, [S, ..3], Vec3<S>, Point3<S>> for AffineMatrix3<S> {
#[inline] #[inline]
fn identity() -> AffineMatrix3<S> { fn identity() -> AffineMatrix3<S> {
@ -204,12 +205,12 @@ Transform<S, [S, ..3], Vec3<S>, Point3<S>> for AffineMatrix3<S> {
} }
} }
impl<S: Clone + Primitive> impl<S: PartOrdPrim>
ToMat4<S> for AffineMatrix3<S> { ToMat4<S> for AffineMatrix3<S> {
#[inline] fn to_mat4(&self) -> Mat4<S> { self.mat.clone() } #[inline] fn to_mat4(&self) -> Mat4<S> { self.mat.clone() }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
Transform3<S> for AffineMatrix3<S> {} Transform3<S> for AffineMatrix3<S> {}
@ -217,7 +218,7 @@ Transform3<S> for AffineMatrix3<S> {}
/// displacement vector and scale amount. /// displacement vector and scale amount.
pub struct Transform3D<S>( Decomposed<S,Vec3<S>,Quat<S>> ); pub struct Transform3D<S>( Decomposed<S,Vec3<S>,Quat<S>> );
impl<S: Float + ApproxEq<S>> Transform3D<S> { impl<S: PartOrdFloat<S>> Transform3D<S> {
#[inline] #[inline]
pub fn new(scale: S, rot: Quat<S>, disp: Vec3<S>) -> Transform3D<S> { pub fn new(scale: S, rot: Quat<S>, disp: Vec3<S>) -> Transform3D<S> {
Transform3D( Decomposed { scale: scale, rot: rot, disp: disp }) Transform3D( Decomposed { scale: scale, rot: rot, disp: disp })
@ -235,6 +236,6 @@ impl<S: Float + ApproxEq<S>> Transform3D<S> {
} }
} }
impl<S: Float + ApproxEq<S>> ToMat4<S> for Transform3D<S> { impl<S: PartOrdFloat<S>> ToMat4<S> for Transform3D<S> {
fn to_mat4(&self) -> Mat4<S> { self.get().to_mat4() } fn to_mat4(&self) -> Mat4<S> { self.get().to_mat4() }
} }

View file

@ -19,13 +19,14 @@ use std::num::{Zero, zero, One, one, sqrt};
use angle::{Rad, atan2, acos}; use angle::{Rad, atan2, acos};
use approx::ApproxEq; use approx::ApproxEq;
use array::{Array, build}; use array::{Array, build};
use partial_ord::{PartOrdPrim, PartOrdFloat};
/// A trait that specifies a range of numeric operations for vectors. Not all /// 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 /// of these make sense from a linear algebra point of view, but are included
/// for pragmatic reasons. /// for pragmatic reasons.
pub trait Vector pub trait Vector
< <
S: Primitive, S: PartOrdPrim,
Slice Slice
> >
: Array<S, Slice> : Array<S, Slice>
@ -74,7 +75,7 @@ pub trait 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| if *a > *b { *a } else {*b }) }
} }
#[inline] pub fn dot<S: Primitive, Slice, V: Vector<S, Slice>>(a: V, b: V) -> S { a.dot(&b) } #[inline] pub fn dot<S: PartOrdPrim, Slice, V: Vector<S, Slice>>(a: V, b: V) -> S { a.dot(&b) }
// Utility macro for generating associated functions for the vectors // Utility macro for generating associated functions for the vectors
macro_rules! vec( macro_rules! vec(
@ -103,32 +104,32 @@ macro_rules! vec(
pub fn ident() -> $Self<$S> { $Self::from_value(one()) } pub fn ident() -> $Self<$S> { $Self::from_value(one()) }
} }
impl<S: Primitive> Add<$Self<S>, $Self<S>> for $Self<S> { impl<S: PartOrdPrim> Add<$Self<S>, $Self<S>> for $Self<S> {
#[inline] fn add(&self, other: &$Self<S>) -> $Self<S> { self.add_v(other) } #[inline] fn add(&self, other: &$Self<S>) -> $Self<S> { self.add_v(other) }
} }
impl<S: Primitive> Sub<$Self<S>, $Self<S>> for $Self<S> { impl<S: PartOrdPrim> Sub<$Self<S>, $Self<S>> for $Self<S> {
#[inline] fn sub(&self, other: &$Self<S>) -> $Self<S> { self.sub_v(other) } #[inline] fn sub(&self, other: &$Self<S>) -> $Self<S> { self.sub_v(other) }
} }
impl<S: Primitive> Zero for $Self<S> { impl<S: PartOrdPrim> Zero for $Self<S> {
#[inline] fn zero() -> $Self<S> { $Self::from_value(zero()) } #[inline] fn zero() -> $Self<S> { $Self::from_value(zero()) }
#[inline] fn is_zero(&self) -> bool { *self == zero() } #[inline] fn is_zero(&self) -> bool { *self == zero() }
} }
impl<S: Primitive> Neg<$Self<S>> for $Self<S> { impl<S: PartOrdPrim> Neg<$Self<S>> for $Self<S> {
#[inline] fn neg(&self) -> $Self<S> { build(|i| self.i(i).neg()) } #[inline] fn neg(&self) -> $Self<S> { build(|i| self.i(i).neg()) }
} }
impl<S: Primitive> Mul<$Self<S>, $Self<S>> for $Self<S> { impl<S: PartOrdPrim> Mul<$Self<S>, $Self<S>> for $Self<S> {
#[inline] fn mul(&self, other: &$Self<S>) -> $Self<S> { self.mul_v(other) } #[inline] fn mul(&self, other: &$Self<S>) -> $Self<S> { self.mul_v(other) }
} }
impl<S: Primitive> One for $Self<S> { impl<S: PartOrdPrim> One for $Self<S> {
#[inline] fn one() -> $Self<S> { $Self::from_value(one()) } #[inline] fn one() -> $Self<S> { $Self::from_value(one()) }
} }
impl<S: Primitive> Vector<S, [S, ..$n]> for $Self<S> {} impl<S: PartOrdPrim> Vector<S, [S, ..$n]> for $Self<S> {}
) )
) )
@ -206,7 +207,7 @@ impl<S: Primitive> Vec4<S> {
/// 2-dimensional and 3-dimensional vectors. /// 2-dimensional and 3-dimensional vectors.
pub trait EuclideanVector pub trait EuclideanVector
< <
S: Float + ApproxEq<S>, S: PartOrdFloat<S>,
Slice Slice
> >
: Vector<S, Slice> : Vector<S, Slice>
@ -277,7 +278,7 @@ pub trait EuclideanVector
} }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
EuclideanVector<S, [S, ..2]> for Vec2<S> { EuclideanVector<S, [S, ..2]> for Vec2<S> {
#[inline] #[inline]
fn angle(&self, other: &Vec2<S>) -> Rad<S> { fn angle(&self, other: &Vec2<S>) -> Rad<S> {
@ -285,7 +286,7 @@ EuclideanVector<S, [S, ..2]> for Vec2<S> {
} }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
EuclideanVector<S, [S, ..3]> for Vec3<S> { EuclideanVector<S, [S, ..3]> for Vec3<S> {
#[inline] #[inline]
fn angle(&self, other: &Vec3<S>) -> Rad<S> { fn angle(&self, other: &Vec3<S>) -> Rad<S> {
@ -293,7 +294,7 @@ EuclideanVector<S, [S, ..3]> for Vec3<S> {
} }
} }
impl<S: Float + ApproxEq<S>> impl<S: PartOrdFloat<S>>
EuclideanVector<S, [S, ..4]> for Vec4<S> { EuclideanVector<S, [S, ..4]> for Vec4<S> {
#[inline] #[inline]
fn angle(&self, other: &Vec4<S>) -> Rad<S> { fn angle(&self, other: &Vec4<S>) -> Rad<S> {