Update to the last Rust.

Version of rustc: 0.10-pre (b0ce960 2014-02-17 22:16:51 -0800)
This replaces uses of the `Orderable` trait by a `PartialOrd` trait: the `min` and `max` methods
are replaced by `inf` and `sup` methods.
Vectors do not implement the `Ord` trait any more.

Fix #4
This commit is contained in:
Sébastien Crozet 2014-02-18 12:13:40 +01:00
parent d9ace45141
commit becb77843e
18 changed files with 317 additions and 125 deletions

View File

@ -4,13 +4,13 @@ nalgebra_doc_path=doc
all: all:
mkdir -p $(nalgebra_lib_path) mkdir -p $(nalgebra_lib_path)
rustc src/lib.rs --out-dir $(nalgebra_lib_path) --opt-level 3 rustc src/lib.rs --out-dir $(nalgebra_lib_path) --opt-level 3
rustc src/lib.rs --out-dir $(nalgebra_lib_path) --crate-type dylib --opt-level 3
test: test:
mkdir -p $(nalgebra_lib_path) mkdir -p $(nalgebra_lib_path)
rustc --test src/lib.rs --opt-level 3 -o test~ && ./test~ rustc --test src/lib.rs --opt-level 3 -o test~ && ./test~
rm test~ rm test~
# FIXME: rustdoc --test -L lib src/lib.rs
# rustdoc --test -L lib src/lib.rs
bench: bench:
rustc --test src/lib.rs --opt-level 3 -o bench~ && ./bench~ --bench rustc --test src/lib.rs --opt-level 3 -o bench~ && ./bench~ --bench

View File

@ -18,7 +18,7 @@ out-of-place modifications.
* You can import the whole prelude using: * You can import the whole prelude using:
``` ```.ignore
use nalgebra::na::*; use nalgebra::na::*;
``` ```
@ -26,7 +26,7 @@ The preferred way to use **nalgebra** is to import types and traits explicitly,
free-functions using the `na::` prefix: free-functions using the `na::` prefix:
```.rust ```.rust
extern mod nalgebra; extern crate nalgebra;
use nalgebra::na::{Vec3, Rot3, Rotation}; use nalgebra::na::{Vec3, Rot3, Rotation};
use nalgebra::na; use nalgebra::na;
@ -57,7 +57,7 @@ and keeps an optimized set of tools for computational graphics and physics. Thos
For example, the following works: For example, the following works:
```rust ```rust
extern mod nalgebra; extern crate nalgebra;
use nalgebra::na::{Vec3, Mat3}; use nalgebra::na::{Vec3, Mat3};
use nalgebra::na; use nalgebra::na;
@ -76,13 +76,15 @@ fn main() {
You will need the last rust compiler from the master branch. You will need the last rust compiler from the master branch.
If you encounter problems, make sure you have the last version before creating an issue. If you encounter problems, make sure you have the last version before creating an issue.
git clone git://github.com/sebcrozet/nalgebra.git ```.ignore
cd nalgebra git clone git://github.com/sebcrozet/nalgebra.git
make cd nalgebra
make
```
You can build the documentation on the `doc` folder using: You can build the documentation on the `doc` folder using:
``` ```.ignore
make doc make doc
``` ```
@ -107,9 +109,9 @@ Feel free to add your project to this list if you happen to use **nalgebra**!
#[feature(macro_rules)]; #[feature(macro_rules)];
#[doc(html_root_url = "http://www.rust-ci.org/sebcrozet/nalgebra/doc")]; #[doc(html_root_url = "http://www.rust-ci.org/sebcrozet/nalgebra/doc")];
extern mod std; extern crate std;
extern mod extra; extern crate extra;
extern mod serialize; extern crate serialize;
pub mod na; pub mod na;
mod structs; mod structs;

109
src/na.rs
View File

@ -1,12 +1,14 @@
//! **nalgebra** prelude. //! **nalgebra** prelude.
use std::num::{Zero, One}; use std::num::{Zero, One};
use std::cmp;
pub use traits::{Less, Equal, Greater, NotComparable};
pub use traits::{ pub use traits::{
Absolute, Absolute,
AbsoluteRotate, AbsoluteRotate,
ApproxEq, ApproxEq,
RealVec, FloatVec,
RealVecExt, FloatVecExt,
Basis, Basis,
Cast, Cast,
Col, Col,
@ -25,6 +27,8 @@ pub use traits::{
Mean, Mean,
Norm, Norm,
Outer, Outer,
PartialOrd,
PartialOrdering,
RMul, RMul,
Rotate, Rotation, RotationMatrix, RotationWithTranslation, Rotate, Rotation, RotationMatrix, RotationWithTranslation,
Row, Row,
@ -48,6 +52,71 @@ pub use structs::{
Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6 Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6
}; };
/// Change the input value to ensure it is on the range `[min, max]`.
#[inline(always)]
pub fn clamp<T: Ord>(val: T, min: T, max: T) -> T {
if val > min {
if val < max {
val
}
else {
max
}
}
else {
min
}
}
/// Same as `cmp::max`.
#[inline(always)]
pub fn max<T: Ord>(a: T, b: T) -> T {
cmp::max(a, b)
}
/// Same as `cmp::min`.
#[inline(always)]
pub fn min<T: Ord>(a: T, b: T) -> T {
cmp::min(a, b)
}
/// Returns the infimum of `a` and `b`.
#[inline(always)]
pub fn inf<T: PartialOrd>(a: &T, b: &T) -> T {
PartialOrd::inf(a, b)
}
/// Returns the supremum of `a` and `b`.
#[inline(always)]
pub fn sup<T: PartialOrd>(a: &T, b: &T) -> T {
PartialOrd::sup(a, b)
}
/// Compare `a` and `b` using a partial ordering relation.
#[inline(always)]
pub fn partial_cmp<T: PartialOrd>(a: &T, b: &T) -> PartialOrdering {
PartialOrd::partial_cmp(a, b)
}
/// Return the minimum of `a` and `b` if they are comparable.
#[inline(always)]
pub fn partial_min<'a, T: PartialOrd>(a: &'a T, b: &'a T) -> Option<&'a T> {
PartialOrd::partial_min(a, b)
}
/// Return the maximum of `a` and `b` if they are comparable.
#[inline(always)]
pub fn partial_max<'a, T: PartialOrd>(a: &'a T, b: &'a T) -> Option<&'a T> {
PartialOrd::partial_max(a, b)
}
/// Clamp `value` between `min` and `max`. Returns `None` if `value` is not comparable to
/// `min` or `max`.
#[inline(always)]
pub fn partial_clamp<'a, T: PartialOrd>(value: &'a T, min: &'a T, max: &'a T) -> Option<&'a T> {
PartialOrd::partial_clamp(value, min, max)
}
// //
// //
// Constructors // Constructors
@ -89,7 +158,7 @@ pub fn one<T: One>() -> T {
*/ */
/// Computes a projection matrix given the frustrum near plane width, height, the field of /// Computes a projection matrix given the frustrum near plane width, height, the field of
/// view, and the distance to the clipping planes (`znear` and `zfar`). /// view, and the distance to the clipping planes (`znear` and `zfar`).
pub fn perspective3d<N: Real + Cast<f32> + Zero + One>(width: N, height: N, fov: N, znear: N, zfar: N) -> Mat4<N> { pub fn perspective3d<N: Float + Cast<f32> + Zero + One>(width: N, height: N, fov: N, znear: N, zfar: N) -> Mat4<N> {
let aspect = width / height; let aspect = width / height;
let _1: N = one(); let _1: N = one();
@ -112,7 +181,7 @@ pub fn perspective3d<N: Real + Cast<f32> + Zero + One>(width: N, height: N, fov:
/// Gets the translation applicable by `m`. /// Gets the translation applicable by `m`.
/// ///
/// ```rust /// ```rust
/// extern mod nalgebra; /// extern crate nalgebra;
/// use nalgebra::na::{Vec3, Iso3}; /// use nalgebra::na::{Vec3, Iso3};
/// use nalgebra::na; /// use nalgebra::na;
/// ///
@ -131,7 +200,7 @@ pub fn translation<V, M: Translation<V>>(m: &M) -> V {
/// Gets the inverse translation applicable by `m`. /// Gets the inverse translation applicable by `m`.
/// ///
/// ```rust /// ```rust
/// extern mod nalgebra; /// extern crate nalgebra;
/// use nalgebra::na::{Vec3, Iso3}; /// use nalgebra::na::{Vec3, Iso3};
/// use nalgebra::na; /// use nalgebra::na;
/// ///
@ -160,7 +229,7 @@ pub fn append_translation<V, M: Translation<V>>(m: &M, v: &V) -> M {
/// Applies a translation to a vector. /// Applies a translation to a vector.
/// ///
/// ```rust /// ```rust
/// extern mod nalgebra; /// extern crate nalgebra;
/// use nalgebra::na::{Vec3, Iso3}; /// use nalgebra::na::{Vec3, Iso3};
/// use nalgebra::na; /// use nalgebra::na;
/// ///
@ -181,7 +250,7 @@ pub fn translate<V, M: Translate<V>>(m: &M, v: &V) -> V {
/// Applies an inverse translation to a vector. /// Applies an inverse translation to a vector.
/// ///
/// ```rust /// ```rust
/// extern mod nalgebra; /// extern crate nalgebra;
/// use nalgebra::na::{Vec3, Iso3}; /// use nalgebra::na::{Vec3, Iso3};
/// use nalgebra::na; /// use nalgebra::na;
/// ///
@ -205,7 +274,7 @@ pub fn inv_translate<V, M: Translate<V>>(m: &M, v: &V) -> V {
/// Gets the rotation applicable by `m`. /// Gets the rotation applicable by `m`.
/// ///
/// ```rust /// ```rust
/// extern mod nalgebra; /// extern crate nalgebra;
/// use nalgebra::na::{Vec3, Rot3}; /// use nalgebra::na::{Vec3, Rot3};
/// use nalgebra::na; /// use nalgebra::na;
/// ///
@ -224,7 +293,7 @@ pub fn rotation<V, M: Rotation<V>>(m: &M) -> V {
/// Gets the inverse rotation applicable by `m`. /// Gets the inverse rotation applicable by `m`.
/// ///
/// ```rust /// ```rust
/// extern mod nalgebra; /// extern crate nalgebra;
/// use nalgebra::na::{Vec3, Rot3}; /// use nalgebra::na::{Vec3, Rot3};
/// use nalgebra::na; /// use nalgebra::na;
/// ///
@ -243,7 +312,7 @@ pub fn inv_rotation<V, M: Rotation<V>>(m: &M) -> V {
/// Applies the rotation `v` to a copy of `m`. /// Applies the rotation `v` to a copy of `m`.
/// ///
/// ```rust /// ```rust
/// extern mod nalgebra; /// extern crate nalgebra;
/// use nalgebra::na::{Vec3, Rot3}; /// use nalgebra::na::{Vec3, Rot3};
/// use nalgebra::na; /// use nalgebra::na;
/// ///
@ -264,7 +333,7 @@ pub fn append_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
/// Pre-applies the rotation `v` to a copy of `m`. /// Pre-applies the rotation `v` to a copy of `m`.
/// ///
/// ```rust /// ```rust
/// extern mod nalgebra; /// extern crate nalgebra;
/// use nalgebra::na::{Vec3, Rot3}; /// use nalgebra::na::{Vec3, Rot3};
/// use nalgebra::na; /// use nalgebra::na;
/// ///
@ -288,13 +357,13 @@ pub fn prepend_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
/// Applies a rotation to a vector. /// Applies a rotation to a vector.
/// ///
/// ```rust /// ```rust
/// extern mod nalgebra; /// extern crate nalgebra;
/// use std::num::Real; /// use std::num::Float;
/// use nalgebra::na::{Rot3, Vec3}; /// use nalgebra::na::{Rot3, Vec3};
/// use nalgebra::na; /// use nalgebra::na;
/// ///
/// fn main() { /// fn main() {
/// let t = Rot3::new(Vec3::new(0.0, 0.0, 0.5 * Real::pi())); /// let t = Rot3::new(Vec3::new(0.0, 0.0, 0.5 * Float::pi()));
/// let v = Vec3::new(1.0, 0.0, 0.0); /// let v = Vec3::new(1.0, 0.0, 0.0);
/// ///
/// let tv = na::rotate(&t, &v); /// let tv = na::rotate(&t, &v);
@ -311,13 +380,13 @@ pub fn rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
/// Applies an inverse rotation to a vector. /// Applies an inverse rotation to a vector.
/// ///
/// ```rust /// ```rust
/// extern mod nalgebra; /// extern crate nalgebra;
/// use std::num::Real; /// use std::num::Float;
/// use nalgebra::na::{Rot3, Vec3}; /// use nalgebra::na::{Rot3, Vec3};
/// use nalgebra::na; /// use nalgebra::na;
/// ///
/// fn main() { /// fn main() {
/// let t = Rot3::new(Vec3::new(0.0, 0.0, 0.5 * Real::pi())); /// let t = Rot3::new(Vec3::new(0.0, 0.0, 0.5 * Float::pi()));
/// let v = Vec3::new(1.0, 0.0, 0.0); /// let v = Vec3::new(1.0, 0.0, 0.0);
/// ///
/// let tv = na::inv_rotate(&t, &v); /// let tv = na::inv_rotate(&t, &v);
@ -435,19 +504,19 @@ pub fn sub_dot<V: Dot<N>, N>(a: &V, b: &V, c: &V) -> N {
/// Computes the L2 norm of a vector. /// Computes the L2 norm of a vector.
#[inline(always)] #[inline(always)]
pub fn norm<V: Norm<N>, N: Real>(v: &V) -> N { pub fn norm<V: Norm<N>, N: Float>(v: &V) -> N {
Norm::norm(v) Norm::norm(v)
} }
/// Computes the squared L2 norm of a vector. /// Computes the squared L2 norm of a vector.
#[inline(always)] #[inline(always)]
pub fn sqnorm<V: Norm<N>, N: Real>(v: &V) -> N { pub fn sqnorm<V: Norm<N>, N: Float>(v: &V) -> N {
Norm::sqnorm(v) Norm::sqnorm(v)
} }
/// Gets the normalized version of a vector. /// Gets the normalized version of a vector.
#[inline(always)] #[inline(always)]
pub fn normalize<V: Norm<N>, N: Real>(v: &V) -> V { pub fn normalize<V: Norm<N>, N: Float>(v: &V) -> V {
Norm::normalize_cpy(v) Norm::normalize_cpy(v)
} }

View File

@ -2,7 +2,7 @@
#[allow(missing_doc)]; // we hide doc to not have to document the $trhs double dispatch trait. #[allow(missing_doc)]; // we hide doc to not have to document the $trhs double dispatch trait.
use std::num::{Zero, One, Real}; use std::num::{Zero, One, Float};
use std::rand::Rand; use std::rand::Rand;
use std::rand; use std::rand;
use std::vec; use std::vec;
@ -177,7 +177,7 @@ impl<N> FromIterator<N> for DVec<N> {
} }
} }
impl<N: Clone + Num + Real + ApproxEq<N> + DVecMulRhs<N, DVec<N>>> DVec<N> { impl<N: Clone + Num + Float + ApproxEq<N> + DVecMulRhs<N, DVec<N>>> DVec<N> {
/// Computes the canonical basis for the given dimension. A canonical basis is a set of /// Computes the canonical basis for the given dimension. A canonical basis is a set of
/// vectors, mutually orthogonal, with all its component equal to 0.0 except one which is equal /// vectors, mutually orthogonal, with all its component equal to 0.0 except one which is equal
/// to 1.0. /// to 1.0.
@ -284,7 +284,7 @@ impl<N: Num + Clone> Dot<N> for DVec<N> {
} }
} }
impl<N: Num + Real + Clone> Norm<N> for DVec<N> { impl<N: Num + Float + Clone> Norm<N> for DVec<N> {
#[inline] #[inline]
fn sqnorm(v: &DVec<N>) -> N { fn sqnorm(v: &DVec<N>) -> N {
Dot::dot(v, v) Dot::dot(v, v)

View File

@ -51,7 +51,7 @@ pub struct Iso4<N> {
translation: Vec4<N> translation: Vec4<N>
} }
impl<N: Clone + Num + Real> Iso3<N> { impl<N: Clone + Num + Float> Iso3<N> {
/// Reorient and translate this transformation such that its local `x` axis points to a given /// Reorient and translate this transformation such that its local `x` axis points to a given
/// direction. Note that the usually known `look_at` function does the same thing but with the /// direction. Note that the usually known `look_at` function does the same thing but with the
/// `z` axis. See `look_at_z` for that. /// `z` axis. See `look_at_z` for that.

View File

@ -2,7 +2,7 @@
macro_rules! iso_impl( macro_rules! iso_impl(
($t: ident, $submat: ident, $subvec: ident, $subrotvec: ident) => ( ($t: ident, $submat: ident, $subvec: ident, $subrotvec: ident) => (
impl<N: Clone + Real + Real + Num> $t<N> { impl<N: Clone + Float + Float + Num> $t<N> {
/// Creates a new isometry from a rotation matrix and a vector. /// Creates a new isometry from a rotation matrix and a vector.
#[inline] #[inline]
pub fn new(translation: $subvec<N>, rotation: $subrotvec<N>) -> $t<N> { pub fn new(translation: $subvec<N>, rotation: $subrotvec<N>) -> $t<N> {
@ -26,7 +26,7 @@ macro_rules! iso_impl(
macro_rules! rotation_matrix_impl( macro_rules! rotation_matrix_impl(
($t: ident, $trot: ident, $tlv: ident, $tav: ident) => ( ($t: ident, $trot: ident, $tlv: ident, $tav: ident) => (
impl<N: Cast<f32> + Real + Real + Num + Clone> impl<N: Cast<f32> + Float + Float + Num + Clone>
RotationMatrix<$tlv<N>, $tav<N>, $trot<N>> for $t<N> { RotationMatrix<$tlv<N>, $tav<N>, $trot<N>> for $t<N> {
#[inline] #[inline]
fn to_rot_mat(&self) -> $trot<N> { fn to_rot_mat(&self) -> $trot<N> {
@ -50,7 +50,7 @@ macro_rules! dim_impl(
macro_rules! one_impl( macro_rules! one_impl(
($t: ident) => ( ($t: ident) => (
impl<N: Real + Real + Num + Clone> One for $t<N> { impl<N: Float + Float + Num + Clone> One for $t<N> {
#[inline] #[inline]
fn one() -> $t<N> { fn one() -> $t<N> {
$t::new_with_rotmat(Zero::zero(), One::one()) $t::new_with_rotmat(Zero::zero(), One::one())
@ -61,7 +61,7 @@ macro_rules! one_impl(
macro_rules! iso_mul_iso_impl( macro_rules! iso_mul_iso_impl(
($t: ident, $tmul: ident) => ( ($t: ident, $tmul: ident) => (
impl<N: Num + Real + Real + Clone> $tmul<N, $t<N>> for $t<N> { impl<N: Num + Float + Float + Clone> $tmul<N, $t<N>> for $t<N> {
#[inline] #[inline]
fn binop(left: &$t<N>, right: &$t<N>) -> $t<N> { fn binop(left: &$t<N>, right: &$t<N>) -> $t<N> {
$t::new_with_rotmat( $t::new_with_rotmat(
@ -96,7 +96,7 @@ macro_rules! vec_mul_iso_impl(
macro_rules! translation_impl( macro_rules! translation_impl(
($t: ident, $tv: ident) => ( ($t: ident, $tv: ident) => (
impl<N: Real + Num + Real + Clone> Translation<$tv<N>> for $t<N> { impl<N: Float + Num + Float + Clone> Translation<$tv<N>> for $t<N> {
#[inline] #[inline]
fn translation(&self) -> $tv<N> { fn translation(&self) -> $tv<N> {
self.translation.clone() self.translation.clone()
@ -153,7 +153,7 @@ macro_rules! translate_impl(
macro_rules! rotation_impl( macro_rules! rotation_impl(
($t: ident, $trot: ident, $tav: ident) => ( ($t: ident, $trot: ident, $tav: ident) => (
impl<N: Cast<f32> + Num + Real + Real + Clone> Rotation<$tav<N>> for $t<N> { impl<N: Cast<f32> + Num + Float + Float + Clone> Rotation<$tav<N>> for $t<N> {
#[inline] #[inline]
fn rotation(&self) -> $tav<N> { fn rotation(&self) -> $tav<N> {
self.rotation.rotation() self.rotation.rotation()
@ -220,7 +220,7 @@ macro_rules! rotate_impl(
macro_rules! transformation_impl( macro_rules! transformation_impl(
($t: ident) => ( ($t: ident) => (
impl<N: Num + Real + Real + Clone> Transformation<$t<N>> for $t<N> { impl<N: Num + Float + Float + Clone> Transformation<$t<N>> for $t<N> {
fn transformation(&self) -> $t<N> { fn transformation(&self) -> $t<N> {
self.clone() self.clone()
} }
@ -336,7 +336,7 @@ macro_rules! approx_eq_impl(
macro_rules! rand_impl( macro_rules! rand_impl(
($t: ident) => ( ($t: ident) => (
impl<N: Rand + Clone + Real + Real + Num> Rand for $t<N> { impl<N: Rand + Clone + Float + Float + Num> Rand for $t<N> {
#[inline] #[inline]
fn rand<R: Rng>(rng: &mut R) -> $t<N> { fn rand<R: Rng>(rng: &mut R) -> $t<N> {
$t::new(rng.gen(), rng.gen()) $t::new(rng.gen(), rng.gen())

View File

@ -20,7 +20,7 @@ pub struct Rot2<N> {
priv submat: Mat2<N> priv submat: Mat2<N>
} }
impl<N: Clone + Real + Neg<N>> Rot2<N> { impl<N: Clone + Float + Neg<N>> Rot2<N> {
/// Builds a 2 dimensional rotation matrix from an angle in radian. /// Builds a 2 dimensional rotation matrix from an angle in radian.
pub fn new(angle: Vec1<N>) -> Rot2<N> { pub fn new(angle: Vec1<N>) -> Rot2<N> {
let (sia, coa) = angle.x.sin_cos(); let (sia, coa) = angle.x.sin_cos();
@ -31,7 +31,7 @@ impl<N: Clone + Real + Neg<N>> Rot2<N> {
} }
} }
impl<N: Real + Num + Clone> impl<N: Float + Num + Clone>
Rotation<Vec1<N>> for Rot2<N> { Rotation<Vec1<N>> for Rot2<N> {
#[inline] #[inline]
fn rotation(&self) -> Vec1<N> { fn rotation(&self) -> Vec1<N> {
@ -69,7 +69,7 @@ Rotation<Vec1<N>> for Rot2<N> {
} }
} }
impl<N: Clone + Rand + Real + Neg<N>> Rand for Rot2<N> { impl<N: Clone + Rand + Float + Neg<N>> Rand for Rot2<N> {
#[inline] #[inline]
fn rand<R: Rng>(rng: &mut R) -> Rot2<N> { fn rand<R: Rng>(rng: &mut R) -> Rot2<N> {
Rot2::new(rng.gen()) Rot2::new(rng.gen())
@ -99,7 +99,7 @@ pub struct Rot3<N> {
} }
impl<N: Clone + Real + Num + Real> Rot3<N> { impl<N: Clone + Float + Num + Float> Rot3<N> {
/// Builds a 3 dimensional rotation matrix from an axis and an angle. /// Builds a 3 dimensional rotation matrix from an axis and an angle.
/// ///
/// # Arguments /// # Arguments
@ -140,7 +140,7 @@ impl<N: Clone + Real + Num + Real> Rot3<N> {
} }
} }
impl<N: Clone + Num + Real> Rot3<N> { impl<N: Clone + Num + Float> Rot3<N> {
/// Reorient this matrix such that its local `x` axis points to a given point. Note that the /// Reorient this matrix such that its local `x` axis points to a given point. Note that the
/// usually known `look_at` function does the same thing but with the `z` axis. See `look_at_z` /// usually known `look_at` function does the same thing but with the `z` axis. See `look_at_z`
/// for that. /// for that.
@ -180,7 +180,7 @@ impl<N: Clone + Num + Real> Rot3<N> {
} }
} }
impl<N: Clone + Real + Num + Real + Cast<f32>> impl<N: Clone + Float + Num + Float + Cast<f32>>
Rotation<Vec3<N>> for Rot3<N> { Rotation<Vec3<N>> for Rot3<N> {
#[inline] #[inline]
fn rotation(&self) -> Vec3<N> { fn rotation(&self) -> Vec3<N> {
@ -245,7 +245,7 @@ Rotation<Vec3<N>> for Rot3<N> {
} }
} }
impl<N: Clone + Rand + Real + Num + Real> impl<N: Clone + Rand + Float + Num + Float>
Rand for Rot3<N> { Rand for Rot3<N> {
#[inline] #[inline]
fn rand<R: Rng>(rng: &mut R) -> Rot3<N> { fn rand<R: Rng>(rng: &mut R) -> Rot3<N> {
@ -309,7 +309,7 @@ impl<N: Signed> AbsoluteRotate<Vec4<N>> for Rot4<N> {
} }
} }
impl<N: Real + Num + Clone> impl<N: Float + Num + Clone>
Rotation<Vec4<N>> for Rot4<N> { Rotation<Vec4<N>> for Rot4<N> {
#[inline] #[inline]
fn rotation(&self) -> Vec4<N> { fn rotation(&self) -> Vec4<N> {

View File

@ -56,7 +56,7 @@ macro_rules! dim_impl(
macro_rules! rotation_matrix_impl( macro_rules! rotation_matrix_impl(
($t: ident, $tlv: ident, $tav: ident) => ( ($t: ident, $tlv: ident, $tav: ident) => (
impl<N: Cast<f32> + Real + Real + Num + Clone> impl<N: Cast<f32> + Float + Float + Num + Clone>
RotationMatrix<$tlv<N>, $tav<N>, $t<N>> for $t<N> { RotationMatrix<$tlv<N>, $tav<N>, $t<N>> for $t<N> {
#[inline] #[inline]
fn to_rot_mat(&self) -> $t<N> { fn to_rot_mat(&self) -> $t<N> {

View File

@ -91,7 +91,7 @@ impl<N: Clone + One + Zero + Neg<N>> Basis for Vec2<N> {
} }
} }
impl<N: Clone + Ord + Real + Signed> Basis for Vec3<N> { impl<N: Clone + Ord + Float + Signed> Basis for Vec3<N> {
#[inline(always)] #[inline(always)]
fn canonical_basis(f: |Vec3<N>| -> bool) { fn canonical_basis(f: |Vec3<N>| -> bool) {
if !f(Vec3::new(One::one(), Zero::zero(), Zero::zero())) { return }; if !f(Vec3::new(One::one(), Zero::zero(), Zero::zero())) { return };

View File

@ -1,5 +1,5 @@
use std::cast; use std::cast;
use std::num::{Zero, One, Real, Bounded}; use std::num::{Zero, One, Float, Bounded};
use std::vec::{Items, MutItems}; use std::vec::{Items, MutItems};
use std::iter::{Iterator, FromIterator}; use std::iter::{Iterator, FromIterator};
use traits::operations::ApproxEq; use traits::operations::ApproxEq;
@ -159,7 +159,7 @@ impl<N: Clone + Add<N, N> + Neg<N>> Translation<vec::Vec0<N>> for vec::Vec0<N> {
} }
} }
impl<N: Num + Real> Norm<N> for vec::Vec0<N> { impl<N: Num + Float> Norm<N> for vec::Vec0<N> {
#[inline] #[inline]
fn sqnorm(_: &vec::Vec0<N>) -> N { fn sqnorm(_: &vec::Vec0<N>) -> N {
Zero::zero() Zero::zero()

View File

@ -3,10 +3,11 @@
#[allow(missing_doc)]; // we allow missing to avoid having to document the vector components. #[allow(missing_doc)]; // we allow missing to avoid having to document the vector components.
use std::cast; use std::cast;
use std::num::{Zero, One, Real, Bounded}; use std::cmp;
use std::num::{Zero, One, Float, Bounded};
use std::vec::{Items, MutItems}; use std::vec::{Items, MutItems};
use std::iter::{Iterator, FromIterator}; use std::iter::{Iterator, FromIterator};
use traits::operations::ApproxEq; use traits::operations::{ApproxEq, PartialOrd, PartialOrdering, Less, Equal, Greater, NotComparable};
use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm, use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm,
Translation, Translate}; Translation, Translate};
@ -38,7 +39,6 @@ sub_redispatch_impl!(Vec1, Vec1SubRhs)
cast_redispatch_impl!(Vec1, Vec1Cast) cast_redispatch_impl!(Vec1, Vec1Cast)
new_impl!(Vec1, x) new_impl!(Vec1, x)
ord_impl!(Vec1, x) ord_impl!(Vec1, x)
orderable_impl!(Vec1, x)
vec_axis_impl!(Vec1, x) vec_axis_impl!(Vec1, x)
vec_cast_impl!(Vec1, Vec1Cast, x) vec_cast_impl!(Vec1, Vec1Cast, x)
indexable_impl!(Vec1, 1) indexable_impl!(Vec1, 1)
@ -137,7 +137,6 @@ sub_redispatch_impl!(Vec2, Vec2SubRhs)
cast_redispatch_impl!(Vec2, Vec2Cast) cast_redispatch_impl!(Vec2, Vec2Cast)
new_impl!(Vec2, x, y) new_impl!(Vec2, x, y)
ord_impl!(Vec2, x, y) ord_impl!(Vec2, x, y)
orderable_impl!(Vec2, x, y)
vec_axis_impl!(Vec2, x, y) vec_axis_impl!(Vec2, x, y)
vec_cast_impl!(Vec2, Vec2Cast, x, y) vec_cast_impl!(Vec2, Vec2Cast, x, y)
indexable_impl!(Vec2, 2) indexable_impl!(Vec2, 2)
@ -238,7 +237,6 @@ sub_redispatch_impl!(Vec3, Vec3SubRhs)
cast_redispatch_impl!(Vec3, Vec3Cast) cast_redispatch_impl!(Vec3, Vec3Cast)
new_impl!(Vec3, x, y, z) new_impl!(Vec3, x, y, z)
ord_impl!(Vec3, x, y, z) ord_impl!(Vec3, x, y, z)
orderable_impl!(Vec3, x, y, z)
vec_axis_impl!(Vec3, x, y, z) vec_axis_impl!(Vec3, x, y, z)
vec_cast_impl!(Vec3, Vec3Cast, x, y, z) vec_cast_impl!(Vec3, Vec3Cast, x, y, z)
indexable_impl!(Vec3, 3) indexable_impl!(Vec3, 3)
@ -345,7 +343,6 @@ sub_redispatch_impl!(Vec4, Vec4SubRhs)
cast_redispatch_impl!(Vec4, Vec4Cast) cast_redispatch_impl!(Vec4, Vec4Cast)
new_impl!(Vec4, x, y, z, w) new_impl!(Vec4, x, y, z, w)
ord_impl!(Vec4, x, y, z, w) ord_impl!(Vec4, x, y, z, w)
orderable_impl!(Vec4, x, y, z, w)
vec_axis_impl!(Vec4, x, y, z, w) vec_axis_impl!(Vec4, x, y, z, w)
vec_cast_impl!(Vec4, Vec4Cast, x, y, z, w) vec_cast_impl!(Vec4, Vec4Cast, x, y, z, w)
indexable_impl!(Vec4, 4) indexable_impl!(Vec4, 4)
@ -450,7 +447,6 @@ sub_redispatch_impl!(Vec5, Vec5SubRhs)
cast_redispatch_impl!(Vec5, Vec5Cast) cast_redispatch_impl!(Vec5, Vec5Cast)
new_impl!(Vec5, x, y, z, w, a) new_impl!(Vec5, x, y, z, w, a)
ord_impl!(Vec5, x, y, z, w, a) ord_impl!(Vec5, x, y, z, w, a)
orderable_impl!(Vec5, x, y, z, w, a)
vec_axis_impl!(Vec5, x, y, z, w, a) vec_axis_impl!(Vec5, x, y, z, w, a)
vec_cast_impl!(Vec5, Vec5Cast, x, y, z, w, a) vec_cast_impl!(Vec5, Vec5Cast, x, y, z, w, a)
indexable_impl!(Vec5, 5) indexable_impl!(Vec5, 5)
@ -557,7 +553,6 @@ sub_redispatch_impl!(Vec6, Vec6SubRhs)
cast_redispatch_impl!(Vec6, Vec6Cast) cast_redispatch_impl!(Vec6, Vec6Cast)
new_impl!(Vec6, x, y, z, w, a, b) new_impl!(Vec6, x, y, z, w, a, b)
ord_impl!(Vec6, x, y, z, w, a, b) ord_impl!(Vec6, x, y, z, w, a, b)
orderable_impl!(Vec6, x, y, z, w, a, b)
vec_axis_impl!(Vec6, x, y, z, w, a, b) vec_axis_impl!(Vec6, x, y, z, w, a, b)
vec_cast_impl!(Vec6, Vec6Cast, x, y, z, w, a, b) vec_cast_impl!(Vec6, Vec6Cast, x, y, z, w, a, b)
indexable_impl!(Vec6, 6) indexable_impl!(Vec6, 6)

View File

@ -36,47 +36,52 @@ macro_rules! at_fast_impl(
macro_rules! ord_impl( macro_rules! ord_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Ord> Ord for $t<N> { impl<N: Ord + Eq + Clone> PartialOrd for $t<N> {
#[inline] #[inline]
fn lt(&self, other: &$t<N>) -> bool { fn inf(a: &$t<N>, b: &$t<N>) -> $t<N> {
self.$comp0 < other.$comp0 $(&& self.$compN < other.$compN)* $t::new(cmp::min(a.$comp0.clone(), b.$comp0.clone())
$(, cmp::min(a.$compN.clone(), b.$compN.clone()))*)
} }
#[inline] #[inline]
fn le(&self, other: &$t<N>) -> bool { fn sup(a: &$t<N>, b: &$t<N>) -> $t<N> {
self.$comp0 <= other.$comp0 $(&& self.$compN <= other.$compN)* $t::new(cmp::max(a.$comp0.clone(), b.$comp0.clone())
$(, cmp::max(a.$compN.clone(), b.$compN.clone()))*)
} }
#[inline] #[inline]
fn gt(&self, other: &$t<N>) -> bool { #[allow(unused_mut)] // otherwise there will be a warning for is_eq or Vec1.
self.$comp0 > other.$comp0 $(&& self.$compN > other.$compN)* fn partial_cmp(a: &$t<N>, b: &$t<N>) -> PartialOrdering {
} let is_lt = a.$comp0 < b.$comp0;
let mut is_eq = a.$comp0 == b.$comp0;
#[inline] if is_lt { // <
fn ge(&self, other: &$t<N>) -> bool { $(
self.$comp0 >= other.$comp0 $(&& self.$compN >= other.$compN)* if a.$compN > b.$compN {
} return NotComparable
} }
) )*
)
macro_rules! orderable_impl( Less
($t: ident, $comp0: ident $(,$compN: ident)*) => ( }
impl<N: Clone + Orderable> Orderable for $t<N> { else { // >=
#[inline] $(
fn max(&self, other: &$t<N>) -> $t<N> { if a.$compN < b.$compN {
$t::new(self.$comp0.max(&other.$comp0) $(, self.$compN.max(&other.$compN))*) return NotComparable
} }
else if a.$compN > b.$compN {
is_eq = false;
}
#[inline] )*
fn min(&self, other: &$t<N>) -> $t<N> {
$t::new(self.$comp0.min(&other.$comp0) $(, self.$compN.min(&other.$compN))*)
}
#[inline] if is_eq {
fn clamp(&self, min: &$t<N>, max: &$t<N>) -> $t<N> { Equal
$t::new(self.$comp0.clamp(&min.$comp0, &max.$comp0) }
$(, self.$compN.clamp(&min.$comp0, &max.$comp0))*) else {
Greater
}
}
} }
} }
) )
@ -223,7 +228,7 @@ macro_rules! container_impl(
macro_rules! basis_impl( macro_rules! basis_impl(
($t: ident, $trhs: ident, $dim: expr) => ( ($t: ident, $trhs: ident, $dim: expr) => (
impl<N: Clone + Num + Real + ApproxEq<N> + $trhs<N, $t<N>>> Basis for $t<N> { impl<N: Clone + Num + Float + ApproxEq<N> + $trhs<N, $t<N>>> Basis for $t<N> {
#[inline] #[inline]
fn canonical_basis(f: |$t<N>| -> bool) { fn canonical_basis(f: |$t<N>| -> bool) {
for i in range(0u, $dim) { for i in range(0u, $dim) {
@ -433,7 +438,7 @@ macro_rules! translation_impl(
macro_rules! norm_impl( macro_rules! norm_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + Num + Real> Norm<N> for $t<N> { impl<N: Clone + Num + Float> Norm<N> for $t<N> {
#[inline] #[inline]
fn sqnorm(v: &$t<N>) -> N { fn sqnorm(v: &$t<N>) -> N {
Dot::dot(v, v) Dot::dot(v, v)

View File

@ -1,4 +1,4 @@
use std::num::{Real, abs}; use std::num::{Float, abs};
use std::rand::random; use std::rand::random;
use na::{Vec1, Vec3, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6, Rot3, DMat, DVec, Indexable}; use na::{Vec1, Vec3, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6, Rot3, DMat, DVec, Indexable};
use na; use na;
@ -87,7 +87,7 @@ fn test_inv_mat6() {
fn test_rotation2() { fn test_rotation2() {
for _ in range(0, 10000) { for _ in range(0, 10000) {
let randmat: na::Rot2<f64> = na::one(); let randmat: na::Rot2<f64> = na::one();
let ang = Vec1::new(abs::<f64>(random()) % Real::pi()); let ang = Vec1::new(abs::<f64>(random()) % Float::pi());
assert!(na::approx_eq(&na::rotation(&na::append_rotation(&randmat, &ang)), &ang)); assert!(na::approx_eq(&na::rotation(&na::append_rotation(&randmat, &ang)), &ang));
} }
@ -105,7 +105,7 @@ fn test_inv_rotation3() {
for _ in range(0, 10000) { for _ in range(0, 10000) {
let randmat: Rot3<f64> = na::one(); let randmat: Rot3<f64> = na::one();
let dir: Vec3<f64> = random(); let dir: Vec3<f64> = random();
let ang = na::normalize(&dir) * (abs::<f64>(random()) % Real::pi()); let ang = na::normalize(&dir) * (abs::<f64>(random()) % Float::pi());
let rot = na::append_rotation(&randmat, &ang); let rot = na::append_rotation(&randmat, &ang);
assert!(na::approx_eq(&(na::transpose(&rot) * rot), &na::one())); assert!(na::approx_eq(&(na::transpose(&rot) * rot), &na::one()));

View File

@ -292,23 +292,19 @@ fn test_ord_vec3() {
assert!(Vec3::new(1.5, 0.5, 0.5) != Vec3::new(0.5, 0.5, 0.5)); assert!(Vec3::new(1.5, 0.5, 0.5) != Vec3::new(0.5, 0.5, 0.5));
// comparable // comparable
assert!(Vec3::new(0.5, 0.3, 0.3) < Vec3::new(1.0, 2.0, 1.0)); assert!(na::partial_cmp(&Vec3::new(0.5, 0.3, 0.3), &Vec3::new(1.0, 2.0, 1.0)).is_le());
assert!(Vec3::new(0.5, 0.3, 0.3) <= Vec3::new(1.0, 2.0, 1.0)); assert!(na::partial_cmp(&Vec3::new(0.5, 0.3, 0.3), &Vec3::new(1.0, 2.0, 1.0)).is_lt());
assert!(Vec3::new(2.0, 4.0, 2.0) > Vec3::new(1.0, 2.0, 1.0)); assert!(na::partial_cmp(&Vec3::new(2.0, 4.0, 2.0), &Vec3::new(1.0, 2.0, 1.0)).is_ge());
assert!(Vec3::new(2.0, 4.0, 2.0) >= Vec3::new(1.0, 2.0, 1.0)); assert!(na::partial_cmp(&Vec3::new(2.0, 4.0, 2.0), &Vec3::new(1.0, 2.0, 1.0)).is_gt());
// not comparable // not comparable
assert!(!(Vec3::new(0.0, 3.0, 0.0) < Vec3::new(1.0, 2.0, 1.0))); assert!(na::partial_cmp(&Vec3::new(0.0, 3.0, 0.0), &Vec3::new(1.0, 2.0, 1.0)).is_not_comparable());
assert!(!(Vec3::new(0.0, 3.0, 0.0) > Vec3::new(1.0, 2.0, 1.0)));
assert!(!(Vec3::new(0.0, 3.0, 0.0) <= Vec3::new(1.0, 2.0, 1.0)));
assert!(!(Vec3::new(0.0, 3.0, 0.0) >= Vec3::new(1.0, 2.0, 1.0)));
} }
#[test] #[test]
fn test_min_max_vec3() { fn test_min_max_vec3() {
assert_eq!(Vec3::new(1, 2, 3).max(&Vec3::new(3, 2, 1)), Vec3::new(3, 2, 3)); assert_eq!(na::sup(&Vec3::new(1, 2, 3), &Vec3::new(3, 2, 1)), Vec3::new(3, 2, 3));
assert_eq!(Vec3::new(1, 2, 3).min(&Vec3::new(3, 2, 1)), Vec3::new(1, 2, 1)); assert_eq!(na::inf(&Vec3::new(1, 2, 3), &Vec3::new(3, 2, 1)), Vec3::new(1, 2, 1));
assert_eq!(Vec3::new(0, 2, 4).clamp(&Vec3::new(1, 1, 1), &Vec3::new(3, 3, 3)), Vec3::new(1, 2, 3));
} }
#[test] #[test]

View File

@ -153,9 +153,9 @@ pub trait RotationMatrix<LV, AV, M: Mat<LV, LV> + Rotation<AV>> : Rotation<AV> {
pub trait AbsoluteRotate<V> { pub trait AbsoluteRotate<V> {
/// This is the same as: /// This is the same as:
/// ///
/// ~~~ /// ```.ignore
/// self.rotation_matrix().absolute().rmul(v) /// self.rotation_matrix().absolute().rmul(v)
/// ~~~ /// ```
fn absolute_rotate(&self, v: &V) -> V; fn absolute_rotate(&self, v: &V) -> V;
} }
@ -208,9 +208,9 @@ pub trait Dot<N> {
* computing intermediate vectors. * computing intermediate vectors.
* The following equation must be verified: * The following equation must be verified:
* *
* ~~~ * ```.ignore
* a.sub_dot(b, c) == (a - b).dot(c) * a.sub_dot(b, c) == (a - b).dot(c)
* ~~~ * ```
* *
*/ */
#[inline] #[inline]
@ -218,7 +218,7 @@ pub trait Dot<N> {
} }
/// Traits of objects having an euclidian norm. /// Traits of objects having an euclidian norm.
pub trait Norm<N: Real> { pub trait Norm<N: Float> {
/// Computes the norm of `self`. /// Computes the norm of `self`.
#[inline] #[inline]
fn norm(v: &Self) -> N { fn norm(v: &Self) -> N {

View File

@ -4,11 +4,12 @@ pub use self::geometry::{AbsoluteRotate, Cross, CrossMatrix, Dot, FromHomogeneou
Rotation, RotationMatrix, RotationWithTranslation, ToHomogeneous, Rotation, RotationMatrix, RotationWithTranslation, ToHomogeneous,
Transform, Transformation, Translate, Translation, UniformSphereSample}; Transform, Transformation, Translate, Translation, UniformSphereSample};
pub use self::structure::{RealVec, RealVecExt, Basis, Cast, Col, Dim, Indexable, pub use self::structure::{FloatVec, FloatVecExt, Basis, Cast, Col, Dim, Indexable,
Iterable, IterableMut, Mat, Row, Vec, VecExt}; Iterable, IterableMut, Mat, Row, Vec, VecExt};
pub use self::operations::{Absolute, ApproxEq, Cov, Inv, LMul, Mean, Outer, RMul, ScalarAdd, pub use self::operations::{Absolute, ApproxEq, Cov, Inv, LMul, Mean, Outer, PartialOrd, RMul,
ScalarSub, Transpose}; ScalarAdd, ScalarSub, Transpose};
pub use self::operations::{PartialOrdering, Less, Equal, Greater, NotComparable};
pub mod geometry; pub mod geometry;
pub mod structure; pub mod structure;

View File

@ -1,5 +1,129 @@
//! Low level operations on vectors and matrices. //! Low level operations on vectors and matrices.
use std::cmp;
/// Result of a partial ordering.
#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, ToStr, Show)]
pub enum PartialOrdering {
/// Result of a strict comparison.
Less,
/// Equality relationship.
Equal,
/// Result of a strict comparison.
Greater,
/// Result of a comparison between two objects that are not comparable.
NotComparable
}
impl PartialOrdering {
/// Returns `true` if `self` is equal to `Equal`.
pub fn is_eq(&self) -> bool {
*self == Equal
}
/// Returns `true` if `self` is equal to `Less`.
pub fn is_lt(&self) -> bool {
*self == Less
}
/// Returns `true` if `self` is equal to `Less` or `Equal`.
pub fn is_le(&self) -> bool {
*self == Less || *self == Equal
}
/// Returns `true` if `self` is equal to `Greater`.
pub fn is_gt(&self) -> bool {
*self == Greater
}
/// Returns `true` if `self` is equal to `Greater` or `Equal`.
pub fn is_ge(&self) -> bool {
*self == Greater || *self == Equal
}
/// Returns `true` if `self` is equal to `NotComparable`.
pub fn is_not_comparable(&self) -> bool {
*self == NotComparable
}
/// Creates a `PartialOrdering` from an `Ordering`.
pub fn from_ordering(ord: Ordering) -> PartialOrdering {
match ord {
cmp::Less => Less,
cmp::Equal => Equal,
cmp::Greater => Greater
}
}
/// Converts this `PartialOrdering` to an `Ordering`.
///
/// Returns `None` if `self` is `NotComparable`.
pub fn to_ordering(self) -> Option<Ordering> {
match self {
Less => Some(cmp::Less),
Equal => Some(cmp::Equal),
Greater => Some(cmp::Greater),
NotComparable => None
}
}
}
/// Pointwise ordering operations.
pub trait PartialOrd {
/// Returns the infimum of `a` and `b`.
fn inf(a: &Self, b: &Self) -> Self;
/// Returns the supremum of `a` and `b`.
fn sup(a: &Self, b: &Self) -> Self;
/// Compare `a` and `b` using a partial ordering relation.
fn partial_cmp(a: &Self, b: &Self) -> PartialOrdering;
/// Return the minimum of `a` and `b` if they are comparable.
#[inline]
fn partial_min<'a>(a: &'a Self, b: &'a Self) -> Option<&'a Self> {
match PartialOrd::partial_cmp(a, b) {
Less | Equal => Some(a),
Greater => Some(b),
NotComparable => None
}
}
/// Return the maximum of `a` and `b` if they are comparable.
#[inline]
fn partial_max<'a>(a: &'a Self, b: &'a Self) -> Option<&'a Self> {
match PartialOrd::partial_cmp(a, b) {
Greater | Equal => Some(a),
Less => Some(b),
NotComparable => None
}
}
/// Clamp `value` between `min` and `max`. Returns `None` if `value` is not comparable to
/// `min` or `max`.
#[inline]
fn partial_clamp<'a>(value: &'a Self, min: &'a Self, max: &'a Self) -> Option<&'a Self> {
let v_min = PartialOrd::partial_cmp(value, min);
let v_max = PartialOrd::partial_cmp(value, max);
if v_min.is_not_comparable() || v_max.is_not_comparable() {
None
}
else {
if v_min.is_lt() {
Some(min)
}
else if v_max.is_gt() {
Some(max)
}
else {
Some(value)
}
}
}
}
/// Trait for testing approximate equality /// Trait for testing approximate equality
pub trait ApproxEq<Eps> { pub trait ApproxEq<Eps> {
/// Default epsilon for approximation. /// Default epsilon for approximation.

View File

@ -27,31 +27,31 @@ pub trait Vec<N>: Dim + Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Zero + E
+ Div<N, Self> + Dot<N> { + Div<N, Self> + Dot<N> {
} }
/// Trait of vector with components implementing the `Real` trait. /// Trait of vector with components implementing the `Float` trait.
pub trait RealVec<N: Real>: Vec<N> + Norm<N> { pub trait FloatVec<N: Float>: Vec<N> + Norm<N> {
} }
/// Trait grouping uncommon, low-level and borderline (from the mathematical point of view) /// Trait grouping uncommon, low-level and borderline (from the mathematical point of view)
/// operations on vectors. /// operations on vectors.
pub trait VecExt<N>: Vec<N> + Indexable<uint, N> + Iterable<N> + pub trait VecExt<N>: Vec<N> + Indexable<uint, N> + Iterable<N> +
UniformSphereSample + ScalarAdd<N> + ScalarSub<N> + Bounded + Orderable UniformSphereSample + ScalarAdd<N> + ScalarSub<N> + Bounded
{ } { }
/// Trait grouping uncommon, low-level and borderline (from the mathematical point of view) /// Trait grouping uncommon, low-level and borderline (from the mathematical point of view)
/// operations on vectors. /// operations on vectors.
pub trait RealVecExt<N: Real>: RealVec<N> + VecExt<N> + Basis + Round { } pub trait FloatVecExt<N: Float>: FloatVec<N> + VecExt<N> + Basis + Round { }
impl<N, V: Dim + Sub<V, V> + Add<V, V> + Neg<V> + Zero + Eq + Mul<N, V> + Div<N, V> + Dot<N>> impl<N, V: Dim + Sub<V, V> + Add<V, V> + Neg<V> + Zero + Eq + Mul<N, V> + Div<N, V> + Dot<N>>
Vec<N> for V { } Vec<N> for V { }
impl<N: Real, V: Vec<N> + Norm<N>> RealVec<N> for V { } impl<N: Float, V: Vec<N> + Norm<N>> FloatVec<N> for V { }
impl<N, impl<N,
V: Vec<N> + Indexable<uint, N> + Iterable<N> + V: Vec<N> + Indexable<uint, N> + Iterable<N> +
UniformSphereSample + ScalarAdd<N> + ScalarSub<N> + Bounded + Orderable> UniformSphereSample + ScalarAdd<N> + ScalarSub<N> + Bounded>
VecExt<N> for V { } VecExt<N> for V { }
impl<N: Real, V: RealVec<N> + VecExt<N> + Basis + Round> RealVecExt<N> for V { } impl<N: Float, V: FloatVec<N> + VecExt<N> + Basis + Round> FloatVecExt<N> for V { }
// FIXME: return an iterator instead // FIXME: return an iterator instead
/// Traits of objects which can form a basis (typically vectors). /// Traits of objects which can form a basis (typically vectors).