Add matrix traits, do lots of reorganisation/re-formatting

This commit is contained in:
Brendan Zabarauskas 2013-08-27 08:59:18 +10:00
parent caadaa669a
commit b67b31b633
18 changed files with 259 additions and 122 deletions

View file

@ -15,11 +15,20 @@
use std::num::Zero; use std::num::Zero;
use traits::alg::Field;
use traits::alg::ScalarMul; use traits::alg::ScalarMul;
use traits::alg::VectorSpace;
/// An affine space is a set of points closed under affine combinations. /// An affine space is a set of points closed under affine combinations.
pub trait AffineSpace<S,V>: Eq pub trait AffineSpace
<
S: Field,
V: VectorSpace<S>
>
: Eq
+ Zero + Zero
+ ScalarMul<S>
+ Add<V, Self> + Add<V, Self>
+ Sub<Self, V> {} + Sub<Self, V>
+ ScalarMul<S>
{
}

View file

@ -13,8 +13,16 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
pub use traits::util::Indexable; use traits::alg::Field;
pub use traits::util::Swappable; use traits::util::Indexable;
use traits::util::Swappable;
pub trait Coordinate<S, Slice>: Indexable<S, Slice> pub trait Coordinate
+ Swappable<S, Slice> {} <
S: Field,
Slice
>
: Indexable<S, Slice>
+ Swappable<S, Slice>
{
}

View file

@ -15,11 +15,16 @@
use std::num; use std::num;
use traits::alg::Ring; use traits::alg::Field;
use traits::alg::InnerProductSpace; use traits::alg::InnerProductSpace;
/// The Euclidean space is a vector space over the Real numbers. /// The Euclidean space is a vector space over the Real numbers.
pub trait EuclideanSpace<S:Real + Ring>: InnerProductSpace<S> { pub trait EuclideanSpace
<
S:Real + Field
>
: InnerProductSpace<S>
{
fn dot(&self, other: &Self) -> S { fn dot(&self, other: &Self) -> S {
self.inner(other) self.inner(other)
} }

View file

@ -15,23 +15,26 @@
use traits::alg::Ring; use traits::alg::Ring;
/// A ring that also requires the multiplicative inverse operation (division). /// A commutative ring that contains a multiplicative inverse.
pub trait DivisionRing: Ring pub trait Field
: Ring
+ Div<Self,Self> + Div<Self,Self>
+ Rem<Self,Self> {} + Rem<Self,Self>
{
}
// impls for concrete types // impls for concrete types
impl DivisionRing for u8; impl Field for u8;
impl DivisionRing for u16; impl Field for u16;
impl DivisionRing for u32; impl Field for u32;
impl DivisionRing for u64; impl Field for u64;
impl DivisionRing for uint; impl Field for uint;
impl DivisionRing for i8; impl Field for i8;
impl DivisionRing for i16; impl Field for i16;
impl DivisionRing for i32; impl Field for i32;
impl DivisionRing for i64; impl Field for i64;
impl DivisionRing for int; impl Field for int;
impl DivisionRing for f32; impl Field for f32;
impl DivisionRing for f64; impl Field for f64;
impl DivisionRing for float; impl Field for float;

View file

@ -13,11 +13,16 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use traits::alg::Ring; use traits::alg::Field;
use traits::alg::VectorSpace; use traits::alg::VectorSpace;
/// A vector space with the inner product operation. /// A vector space with the inner product operation.
pub trait InnerProductSpace<S: Ring>: VectorSpace<S> { pub trait InnerProductSpace
<
S: Field
>
: VectorSpace<S>
{
fn norm(&self) -> S; fn norm(&self) -> S;
fn inner(&self, other: &Self) -> S; fn inner(&self, other: &Self) -> S;
fn is_orthogonal(&self, other: &Self) -> bool; fn is_orthogonal(&self, other: &Self) -> bool;

30
src/traits/alg/matrix.rs Normal file
View file

@ -0,0 +1,30 @@
// 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 traits::alg::Field;
use traits::alg::Ring;
use traits::alg::VectorSpace;
pub trait Matrix
<
S: Field,
RV: VectorSpace<S>,
CV: VectorSpace<S>,
MT//: Matrix<S, CV, RV, Self>
>
: Ring
{
fn transpose(&self) -> MT;
}

View file

@ -15,22 +15,26 @@
pub use self::affine_space::AffineSpace; pub use self::affine_space::AffineSpace;
pub use self::coordinate::Coordinate; pub use self::coordinate::Coordinate;
pub use self::division_ring::DivisionRing;
pub use self::euclidean_space::EuclideanSpace; pub use self::euclidean_space::EuclideanSpace;
pub use self::field::Field;
pub use self::inner_product_space::InnerProductSpace; pub use self::inner_product_space::InnerProductSpace;
pub use self::matrix::Matrix;
pub use self::module::Module; pub use self::module::Module;
pub use self::ordered_ring::OrderedRing; pub use self::ordered_ring::OrderedRing;
pub use self::ring::Ring; pub use self::ring::Ring;
pub use self::scalar_mul::ScalarMul; pub use self::scalar_mul::ScalarMul;
pub use self::square_matrix::SquareMatrix;
pub use self::vector_space::VectorSpace; pub use self::vector_space::VectorSpace;
pub mod affine_space; pub mod affine_space;
pub mod coordinate; pub mod coordinate;
pub mod division_ring;
pub mod euclidean_space; pub mod euclidean_space;
pub mod field;
pub mod inner_product_space; pub mod inner_product_space;
pub mod matrix;
pub mod module; pub mod module;
pub mod ordered_ring; pub mod ordered_ring;
pub mod ring; pub mod ring;
pub mod scalar_mul; pub mod scalar_mul;
pub mod square_matrix;
pub mod vector_space; pub mod vector_space;

View file

@ -15,13 +15,20 @@
use std::num::Zero; use std::num::Zero;
// use traits::alg::Field;
use traits::alg::ScalarMul; use traits::alg::ScalarMul;
/// An algebraic structure that generalizes the notion of a vector space. /// An algebraic structure that generalizes the notion of a vector space.
pub trait Module<S>: Eq pub trait Module
<
S/*: Field*/
>
: Eq
+ Add<Self,Self> + Add<Self,Self>
+ ScalarMul<S> + ScalarMul<S>
+ Zero {} + Zero
{
}
// impls for concrete types // impls for concrete types

View file

@ -16,8 +16,11 @@
use traits::alg::Ring; use traits::alg::Ring;
/// A ring that can also be ordered. /// A ring that can also be ordered.
pub trait OrderedRing: Ring pub trait OrderedRing
+ Orderable {} : Ring
+ Orderable
{
}
// impls for concrete types // impls for concrete types

View file

@ -19,10 +19,13 @@ use traits::alg::Module;
/// A module that also requires the additive inverse operation (subtraction) /// A module that also requires the additive inverse operation (subtraction)
/// and the additive inverse. /// and the additive inverse.
pub trait Ring: Module<Self> pub trait Ring
: Module<Self>
+ Neg<Self> + Neg<Self>
+ Sub<Self,Self> + Sub<Self,Self>
+ One {} + One
{
}
// impls for concrete types // impls for concrete types

View file

@ -13,10 +13,18 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// use traits::alg::Field;
/// Enforces the multiplication of an type by a scalar. /// Enforces the multiplication of an type by a scalar.
pub trait ScalarMul<S>: Mul<S, Self> pub trait ScalarMul
<
S/*: Field*/
>
: Mul<S, Self>
+ Div<S, Self> + Div<S, Self>
+ Rem<S, Self> {} + Rem<S, Self>
{
}
// impls for concrete types // impls for concrete types

View file

@ -0,0 +1,33 @@
// 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 traits::alg::Field;
use traits::alg::Matrix;
use traits::alg::VectorSpace;
pub trait SquareMatrix
<
S: Field,
V: VectorSpace<S>
>
: Matrix<S, V, V, Self>
{
fn transpose_self(&mut self);
fn trace(&self) -> S;
fn det(&self) -> S;
fn invert(&self) -> Option<Self>;
fn invert_self(&mut self) -> Self;
fn eigenvalue(&self, v: V) -> Option<V>;
}

View file

@ -13,10 +13,17 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use traits::alg::Field;
use traits::alg::Module; use traits::alg::Module;
/// A vector space is a set that is closed under vector addition and /// A vector space is a set that is closed under vector addition and
/// scalar multiplication. /// scalar multiplication.
pub trait VectorSpace<S>: Module<S> pub trait VectorSpace
<
S: Field
>
: Module<S>
+ Neg<Self> + Neg<Self>
+ Sub<Self,Self> {} + Sub<Self,Self>
{
}

View file

@ -13,12 +13,18 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use traits::alg::Ring; use traits::alg::Field;
use traits::alg::VectorSpace; use traits::alg::VectorSpace;
use traits::util::Indexable; use traits::util::Indexable;
pub trait VectorExt<S: Ring, Slice>: VectorSpace<S> pub trait VectorExt
+ Indexable<S, Slice> { <
S: Field,
Slice
>
: VectorSpace<S>
+ Indexable<S, Slice>
{
#[inline] fn add_s(&self, s: S) -> Self { self.map(|x| x.add(&s)) } #[inline] fn add_s(&self, s: S) -> Self { self.map(|x| x.add(&s)) }
#[inline] fn sub_s(&self, s: S) -> Self { self.map(|x| x.sub(&s)) } #[inline] fn sub_s(&self, s: S) -> Self { self.map(|x| x.sub(&s)) }
#[inline] fn mul_s(&self, s: S) -> Self { self.map(|x| x.mul(&s)) } #[inline] fn mul_s(&self, s: S) -> Self { self.map(|x| x.mul(&s)) }

View file

@ -12,3 +12,9 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use types::vector::{Vec2, Vec3, Vec4};
#[deriving(Clone, Eq)] pub struct Mat2<T> { x: Vec2<T>, y: Vec2<T> }
#[deriving(Clone, Eq)] pub struct Mat3<T> { x: Vec3<T>, y: Vec3<T>, z: Vec3<T> }
#[deriving(Clone, Eq)] pub struct Mat4<T> { x: Vec4<T>, y: Vec4<T>, z: Vec4<T>, w: Vec4<T> }

View file

@ -27,14 +27,14 @@ struct Point2<S> { x: S, y: S }
#[deriving(Eq, Zero, Clone)] #[deriving(Eq, Zero, Clone)]
struct Point3<S> { x: S, y: S, z: S } struct Point3<S> { x: S, y: S, z: S }
impl<S> Point2<S> { impl<S: Field> Point2<S> {
#[inline] #[inline]
pub fn new(x: S, y: S) -> Point2<S> { pub fn new(x: S, y: S) -> Point2<S> {
Point2 { x: x, y: y } Point2 { x: x, y: y }
} }
} }
impl<S> Point3<S> { impl<S: Field> Point3<S> {
#[inline] #[inline]
pub fn new(x: S, y: S, z: S) -> Point3<S> { pub fn new(x: S, y: S, z: S) -> Point3<S> {
Point3 { x: x, y: y, z: z } Point3 { x: x, y: y, z: z }
@ -43,34 +43,34 @@ impl<S> Point3<S> {
// Operator impls // Operator impls
impl<S:Ring> Mul<S, Point2<S>> for Point2<S> { #[inline(always)] fn mul(&self, s: &S) -> Point2<S> { self.map(|x| x.mul(s)) } } impl<S: Field> Mul<S, Point2<S>> for Point2<S> { #[inline(always)] fn mul(&self, s: &S) -> Point2<S> { self.map(|x| x.mul(s)) } }
impl<S:Ring> Mul<S, Point3<S>> for Point3<S> { #[inline(always)] fn mul(&self, s: &S) -> Point3<S> { self.map(|x| x.mul(s)) } } impl<S: Field> Mul<S, Point3<S>> for Point3<S> { #[inline(always)] fn mul(&self, s: &S) -> Point3<S> { self.map(|x| x.mul(s)) } }
impl<S:Ring> Div<S, Point2<S>> for Point2<S> { #[inline(always)] fn div(&self, s: &S) -> Point2<S> { self.map(|x| x.div(s)) } } impl<S: Field> Div<S, Point2<S>> for Point2<S> { #[inline(always)] fn div(&self, s: &S) -> Point2<S> { self.map(|x| x.div(s)) } }
impl<S:Ring> Div<S, Point3<S>> for Point3<S> { #[inline(always)] fn div(&self, s: &S) -> Point3<S> { self.map(|x| x.div(s)) } } impl<S: Field> Div<S, Point3<S>> for Point3<S> { #[inline(always)] fn div(&self, s: &S) -> Point3<S> { self.map(|x| x.div(s)) } }
impl<S:Ring> Rem<S, Point2<S>> for Point2<S> { #[inline(always)] fn rem(&self, s: &S) -> Point2<S> { self.map(|x| x.rem(s)) } } impl<S: Field> Rem<S, Point2<S>> for Point2<S> { #[inline(always)] fn rem(&self, s: &S) -> Point2<S> { self.map(|x| x.rem(s)) } }
impl<S:Ring> Rem<S, Point3<S>> for Point3<S> { #[inline(always)] fn rem(&self, s: &S) -> Point3<S> { self.map(|x| x.rem(s)) } } impl<S: Field> Rem<S, Point3<S>> for Point3<S> { #[inline(always)] fn rem(&self, s: &S) -> Point3<S> { self.map(|x| x.rem(s)) } }
impl<S:Ring> Add<Vec2<S>, Point2<S>> for Point2<S> { #[inline(always)] fn add(&self, other: &Vec2<S>) -> Point2<S> { self.bimap(other, |a, b| a.add(b)) } } impl<S: Field> Add<Vec2<S>, Point2<S>> for Point2<S> { #[inline(always)] fn add(&self, other: &Vec2<S>) -> Point2<S> { self.bimap(other, |a, b| a.add(b)) } }
impl<S:Ring> Add<Vec3<S>, Point3<S>> for Point3<S> { #[inline(always)] fn add(&self, other: &Vec3<S>) -> Point3<S> { self.bimap(other, |a, b| a.add(b)) } } impl<S: Field> Add<Vec3<S>, Point3<S>> for Point3<S> { #[inline(always)] fn add(&self, other: &Vec3<S>) -> Point3<S> { self.bimap(other, |a, b| a.add(b)) } }
impl<S:Ring> Sub<Point2<S>, Vec2<S>> for Point2<S> { #[inline(always)] fn sub(&self, other: &Point2<S>) -> Vec2<S> { self.bimap(other, |a, b| a.sub(b)) } } impl<S: Field> Sub<Point2<S>, Vec2<S>> for Point2<S> { #[inline(always)] fn sub(&self, other: &Point2<S>) -> Vec2<S> { self.bimap(other, |a, b| a.sub(b)) } }
impl<S:Ring> Sub<Point3<S>, Vec3<S>> for Point3<S> { #[inline(always)] fn sub(&self, other: &Point3<S>) -> Vec3<S> { self.bimap(other, |a, b| a.sub(b)) } } impl<S: Field> Sub<Point3<S>, Vec3<S>> for Point3<S> { #[inline(always)] fn sub(&self, other: &Point3<S>) -> Vec3<S> { self.bimap(other, |a, b| a.sub(b)) } }
// Trait impls // Trait impls
impl_indexable!(Point2<T>, [T, ..2]) impl_indexable!(Point2<T>, [T, ..2])
impl_indexable!(Point3<T>, [T, ..3]) impl_indexable!(Point3<T>, [T, ..3])
impl<S: Clone> Swappable<S, [S, ..2]> for Point2<S>; impl<S: Clone + Field> Swappable<S, [S, ..2]> for Point2<S>;
impl<S: Clone> Swappable<S, [S, ..3]> for Point3<S>; impl<S: Clone + Field> Swappable<S, [S, ..3]> for Point3<S>;
impl<S: Clone> Coordinate<S, [S, ..2]> for Point2<S>; impl<S: Clone + Field> Coordinate<S, [S, ..2]> for Point2<S>;
impl<S: Clone> Coordinate<S, [S, ..3]> for Point3<S>; impl<S: Clone + Field> Coordinate<S, [S, ..3]> for Point3<S>;
impl<S: Ring> ScalarMul<S> for Point2<S>; impl<S: Field> ScalarMul<S> for Point2<S>;
impl<S: Ring> ScalarMul<S> for Point3<S>; impl<S: Field> ScalarMul<S> for Point3<S>;
impl<S: Ring> AffineSpace<S, Vec2<S>> for Point2<S>; impl<S: Field> AffineSpace<S, Vec2<S>> for Point2<S>;
impl<S: Ring> AffineSpace<S, Vec3<S>> for Point3<S>; impl<S: Field> AffineSpace<S, Vec3<S>> for Point3<S>;

View file

@ -20,7 +20,7 @@ use types::vector::Vec3;
#[deriving(Clone, Eq)] #[deriving(Clone, Eq)]
pub struct Quat<T> { s: T, v: Vec3<T> } pub struct Quat<T> { s: T, v: Vec3<T> }
impl<T: Ring> Quat<T> { impl<T: Field> Quat<T> {
/// Construct a new quaternion from one scalar component and three /// Construct a new quaternion from one scalar component and three
/// imaginary components /// imaginary components
#[inline] #[inline]

View file

@ -30,7 +30,7 @@ use traits::util::*;
macro_rules! impl_vec( macro_rules! impl_vec(
($Self:ident <$S:ident> { $($field:ident),+ }) => ( ($Self:ident <$S:ident> { $($field:ident),+ }) => (
impl<$S> $Self<$S> { impl<$S: Field> $Self<$S> {
#[inline] #[inline]
pub fn new($($field: $S),+) -> $Self<$S> { pub fn new($($field: $S),+) -> $Self<$S> {
$Self { $($field: $field),+ } $Self { $($field: $field),+ }
@ -48,7 +48,7 @@ impl_vec!(Vec6<S> { x, y, z, w, a, b })
macro_rules! impl_vec_clonable( macro_rules! impl_vec_clonable(
($Self:ident <$S:ident>) => ( ($Self:ident <$S:ident>) => (
impl<$S:Clone> $Self<$S> { impl<$S:Clone + Field> $Self<$S> {
/// Construct a vector from a single value. /// Construct a vector from a single value.
#[inline] #[inline]
pub fn from_value(value: $S) -> $Self<$S> { pub fn from_value(value: $S) -> $Self<$S> {
@ -67,7 +67,7 @@ impl_vec_clonable!(Vec6<S>)
macro_rules! impl_vec_ring( macro_rules! impl_vec_ring(
($Self:ident <$S:ident>) => ( ($Self:ident <$S:ident>) => (
impl<$S:Ring> $Self<$S> { impl<$S:Field> $Self<$S> {
/// The additive identity of the vector. /// The additive identity of the vector.
#[inline] #[inline]
pub fn zero() -> $Self<$S> { zero() } pub fn zero() -> $Self<$S> { zero() }
@ -90,32 +90,32 @@ macro_rules! impl_vec_ops(
use super::*; use super::*;
use super::super::super::traits::alg::*; use super::super::super::traits::alg::*;
impl<$S:Ring> Mul<$S, $Self<$S>> for $Self<$S> { impl<$S:Field> Mul<$S, $Self<$S>> for $Self<$S> {
#[inline(always)] #[inline(always)]
fn mul(&self, s: &$S) -> $Self<$S> { self.map(|x| x.mul(s)) } fn mul(&self, s: &$S) -> $Self<$S> { self.map(|x| x.mul(s)) }
} }
impl<$S:Ring> Div<$S, $Self<$S>> for $Self<$S> { impl<$S:Field> Div<$S, $Self<$S>> for $Self<$S> {
#[inline(always)] #[inline(always)]
fn div(&self, s: &$S) -> $Self<$S> { self.map(|x| x.div(s)) } fn div(&self, s: &$S) -> $Self<$S> { self.map(|x| x.div(s)) }
} }
impl<$S:Ring> Rem<$S, $Self<$S>> for $Self<$S> { impl<$S:Field> Rem<$S, $Self<$S>> for $Self<$S> {
#[inline(always)] #[inline(always)]
fn rem(&self, s: &$S) -> $Self<$S> { self.map(|x| x.rem(s)) } fn rem(&self, s: &$S) -> $Self<$S> { self.map(|x| x.rem(s)) }
} }
impl<$S:Ring> Add<$Self<$S>, $Self<$S>> for $Self<$S> { impl<$S:Field> Add<$Self<$S>, $Self<$S>> for $Self<$S> {
#[inline(always)] #[inline(always)]
fn add(&self, other: &$Self<$S>) -> $Self<$S> { self.bimap(other, |a, b| a.add(b)) } fn add(&self, other: &$Self<$S>) -> $Self<$S> { self.bimap(other, |a, b| a.add(b)) }
} }
impl<$S:Ring> Sub<$Self<$S>, $Self<$S>> for $Self<$S> { impl<$S:Field> Sub<$Self<$S>, $Self<$S>> for $Self<$S> {
#[inline(always)] #[inline(always)]
fn sub(&self, other: &$Self<$S>) -> $Self<$S> { self.bimap(other, |a, b| a.sub(b)) } fn sub(&self, other: &$Self<$S>) -> $Self<$S> { self.bimap(other, |a, b| a.sub(b)) }
} }
impl<$S:Ring> Neg<$Self<$S>> for $Self<$S> { impl<$S:Field> Neg<$Self<$S>> for $Self<$S> {
#[inline(always)] #[inline(always)]
fn neg(&self) -> $Self<$S> { self.map(|x| x.neg()) } fn neg(&self) -> $Self<$S> { self.map(|x| x.neg()) }
} }
@ -131,7 +131,7 @@ impl_vec_ops!(vec5_ops, Vec5<S>)
impl_vec_ops!(vec6_ops, Vec6<S>) impl_vec_ops!(vec6_ops, Vec6<S>)
/// Operations specific to two-dimensional vectors. /// Operations specific to two-dimensional vectors.
impl<S: Ring> Vec2<S> { impl<S: Field> Vec2<S> {
/// The perpendicular dot product of the vector and `other`. /// The perpendicular dot product of the vector and `other`.
pub fn perp_dot(&self, other: &Vec2<S>) -> S { pub fn perp_dot(&self, other: &Vec2<S>) -> S {
(self.x * other.y) - (self.y * other.x) (self.x * other.y) - (self.y * other.x)
@ -139,7 +139,7 @@ impl<S: Ring> Vec2<S> {
} }
/// Operations specific to three-dimensional vectors. /// Operations specific to three-dimensional vectors.
impl<S: Ring> Vec3<S> { impl<S: Field> Vec3<S> {
/// Returns the cross product of the vector and `other`. /// Returns the cross product of the vector and `other`.
pub fn cross(&self, other: &Vec3<S>) -> Vec3<S> { pub fn cross(&self, other: &Vec3<S>) -> Vec3<S> {
Vec3::new((self.y * other.z) - (self.z * other.y), Vec3::new((self.y * other.z) - (self.z * other.y),
@ -157,44 +157,44 @@ impl_indexable!(Vec4<S>, [S, ..4])
impl_indexable!(Vec5<S>, [S, ..5]) impl_indexable!(Vec5<S>, [S, ..5])
impl_indexable!(Vec6<S>, [S, ..6]) impl_indexable!(Vec6<S>, [S, ..6])
impl<S: Clone> Swappable<S, [S, ..1]> for Vec1<S>; impl<S: Clone + Field> Swappable<S, [S, ..1]> for Vec1<S>;
impl<S: Clone> Swappable<S, [S, ..2]> for Vec2<S>; impl<S: Clone + Field> Swappable<S, [S, ..2]> for Vec2<S>;
impl<S: Clone> Swappable<S, [S, ..3]> for Vec3<S>; impl<S: Clone + Field> Swappable<S, [S, ..3]> for Vec3<S>;
impl<S: Clone> Swappable<S, [S, ..4]> for Vec4<S>; impl<S: Clone + Field> Swappable<S, [S, ..4]> for Vec4<S>;
impl<S: Clone> Swappable<S, [S, ..5]> for Vec5<S>; impl<S: Clone + Field> Swappable<S, [S, ..5]> for Vec5<S>;
impl<S: Clone> Swappable<S, [S, ..6]> for Vec6<S>; impl<S: Clone + Field> Swappable<S, [S, ..6]> for Vec6<S>;
impl<S: Clone> Coordinate<S, [S, ..1]> for Vec1<S>; impl<S: Clone + Field> Coordinate<S, [S, ..1]> for Vec1<S>;
impl<S: Clone> Coordinate<S, [S, ..2]> for Vec2<S>; impl<S: Clone + Field> Coordinate<S, [S, ..2]> for Vec2<S>;
impl<S: Clone> Coordinate<S, [S, ..3]> for Vec3<S>; impl<S: Clone + Field> Coordinate<S, [S, ..3]> for Vec3<S>;
impl<S: Clone> Coordinate<S, [S, ..4]> for Vec4<S>; impl<S: Clone + Field> Coordinate<S, [S, ..4]> for Vec4<S>;
impl<S: Clone> Coordinate<S, [S, ..5]> for Vec5<S>; impl<S: Clone + Field> Coordinate<S, [S, ..5]> for Vec5<S>;
impl<S: Clone> Coordinate<S, [S, ..6]> for Vec6<S>; impl<S: Clone + Field> Coordinate<S, [S, ..6]> for Vec6<S>;
impl<S: Ring> ScalarMul<S> for Vec1<S>; impl<S: Field> ScalarMul<S> for Vec1<S>;
impl<S: Ring> ScalarMul<S> for Vec2<S>; impl<S: Field> ScalarMul<S> for Vec2<S>;
impl<S: Ring> ScalarMul<S> for Vec3<S>; impl<S: Field> ScalarMul<S> for Vec3<S>;
impl<S: Ring> ScalarMul<S> for Vec4<S>; impl<S: Field> ScalarMul<S> for Vec4<S>;
impl<S: Ring> ScalarMul<S> for Vec5<S>; impl<S: Field> ScalarMul<S> for Vec5<S>;
impl<S: Ring> ScalarMul<S> for Vec6<S>; impl<S: Field> ScalarMul<S> for Vec6<S>;
impl<S: Ring> Module<S> for Vec1<S>; impl<S: Field> Module<S> for Vec1<S>;
impl<S: Ring> Module<S> for Vec2<S>; impl<S: Field> Module<S> for Vec2<S>;
impl<S: Ring> Module<S> for Vec3<S>; impl<S: Field> Module<S> for Vec3<S>;
impl<S: Ring> Module<S> for Vec4<S>; impl<S: Field> Module<S> for Vec4<S>;
impl<S: Ring> Module<S> for Vec5<S>; impl<S: Field> Module<S> for Vec5<S>;
impl<S: Ring> Module<S> for Vec6<S>; impl<S: Field> Module<S> for Vec6<S>;
impl<S: Ring> VectorSpace<S> for Vec1<S>; impl<S: Field> VectorSpace<S> for Vec1<S>;
impl<S: Ring> VectorSpace<S> for Vec2<S>; impl<S: Field> VectorSpace<S> for Vec2<S>;
impl<S: Ring> VectorSpace<S> for Vec3<S>; impl<S: Field> VectorSpace<S> for Vec3<S>;
impl<S: Ring> VectorSpace<S> for Vec4<S>; impl<S: Field> VectorSpace<S> for Vec4<S>;
impl<S: Ring> VectorSpace<S> for Vec5<S>; impl<S: Field> VectorSpace<S> for Vec5<S>;
impl<S: Ring> VectorSpace<S> for Vec6<S>; impl<S: Field> VectorSpace<S> for Vec6<S>;
macro_rules! impl_vec_inner_product( macro_rules! impl_vec_inner_product(
($Self:ident <$S:ident>) => ( ($Self:ident <$S:ident>) => (
impl<$S:Real + Ring + ApproxEq<$S>> InnerProductSpace<$S> for $Self<$S> { impl<$S:Real + Field + ApproxEq<$S>> InnerProductSpace<$S> for $Self<$S> {
fn norm(&self) -> $S { fn norm(&self) -> $S {
num::sqrt(self.inner(self)) num::sqrt(self.inner(self))
} }
@ -220,21 +220,21 @@ impl_vec_inner_product!(Vec6<S>)
// Euclidean spaces only really make sense for 2D and 3D vector spaces // Euclidean spaces only really make sense for 2D and 3D vector spaces
impl<S:Real + Ring + ApproxEq<S>> EuclideanSpace<S> for Vec2<S> { impl<S:Real + Field + ApproxEq<S>> EuclideanSpace<S> for Vec2<S> {
fn angle(&self, other: &Vec2<S>) -> S { fn angle(&self, other: &Vec2<S>) -> S {
atan2(self.perp_dot(other), self.dot(other)) atan2(self.perp_dot(other), self.dot(other))
} }
} }
impl<S:Real + Ring + ApproxEq<S>> EuclideanSpace<S> for Vec3<S> { impl<S:Real + Field + ApproxEq<S>> EuclideanSpace<S> for Vec3<S> {
fn angle(&self, other: &Vec3<S>) -> S { fn angle(&self, other: &Vec3<S>) -> S {
atan2(self.cross(other).length(), self.dot(other)) atan2(self.cross(other).length(), self.dot(other))
} }
} }
impl<S: Ring> VectorExt<S, [S, ..1]> for Vec1<S>; impl<S: Clone + Field> VectorExt<S, [S, ..1]> for Vec1<S>;
impl<S: Ring> VectorExt<S, [S, ..2]> for Vec2<S>; impl<S: Clone + Field> VectorExt<S, [S, ..2]> for Vec2<S>;
impl<S: Ring> VectorExt<S, [S, ..3]> for Vec3<S>; impl<S: Clone + Field> VectorExt<S, [S, ..3]> for Vec3<S>;
impl<S: Ring> VectorExt<S, [S, ..4]> for Vec4<S>; impl<S: Clone + Field> VectorExt<S, [S, ..4]> for Vec4<S>;
impl<S: Ring> VectorExt<S, [S, ..5]> for Vec5<S>; impl<S: Clone + Field> VectorExt<S, [S, ..5]> for Vec5<S>;
impl<S: Ring> VectorExt<S, [S, ..6]> for Vec6<S>; impl<S: Clone + Field> VectorExt<S, [S, ..6]> for Vec6<S>;