Add points.

This adds the Pnt{1,2,3,4,5,6} structures.
This adds the traits:
  − AnyPnt
  − FloatPnt
  − PntExt
  − FloatPntExt
  − Orig (to return the zero point)
  − PntAsVec
  − VecAsPnt
This adds operator overloading:
  − Pnt + Vec
  − Pnt - Vec
  − Pnt * Scalar
  − Pnt / Scalar
  − Pnt + Scalar
  − Pnt - Scalar
  − Iso * Pnt
  − Rot * Pnt
  − Pnt * Iso
  − Pnt * Rot
This changes some behavior:
  − Iso multiplication with a Vec does not translate the vector any more.
  − ToHomogeneous adds a 0.0 at the end of a Vec and a 1.0 at the end of a Pnt.
  − FromHomogeneous performs w-normalization on a Pnt, but not on a Vec.
  − The Translate<Vec> trait is never implemented (i-e. a Vec is not to be translated).

cc #25
This commit is contained in:
Sébastien Crozet 2014-10-10 11:23:52 +02:00
parent ba18f5aa70
commit 924d8269d8
20 changed files with 1181 additions and 167 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@ doc
lib
TODO
target/
Cargo.lock

View File

@ -115,6 +115,7 @@ pub use traits::{
Absolute,
AbsoluteRotate,
AnyVec,
AnyPnt,
ApproxEq,
Basis,
Cast,
@ -128,6 +129,8 @@ pub use traits::{
Dim,
Dot,
Eye,
FloatPnt,
FloatPntExt,
FloatVec,
FloatVecExt,
FromHomogeneous,
@ -139,9 +142,13 @@ pub use traits::{
Mat,
Mean,
Norm,
Orig,
Outer,
PartialOrd,
PartialOrdering,
PntAsVec,
PntExt,
Projector,
RMul,
Rotate, Rotation, RotationMatrix, RotationWithTranslation,
Row,
@ -152,6 +159,7 @@ pub use traits::{
Translate, Translation,
Transpose,
UniformSphereSample,
VecAsPnt,
VecExt
};
@ -163,7 +171,8 @@ pub use structs::{
Mat1, Mat2, Mat3, Mat4,
Mat5, Mat6,
Rot2, Rot3, Rot4,
Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6
Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6,
Pnt0, Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6
};
pub use linalg::{
@ -337,6 +346,27 @@ pub fn one<T: One>() -> T {
//
//
/// Returns the trivial origin of an affine space.
#[inline(always)]
pub fn orig<T: Orig>() -> T {
Orig::orig()
}
/*
* FloatPnt
*/
/// Returns the distance between two points.
#[inline(always)]
pub fn dist<N: Float, P: FloatPnt<N, V>, V: Norm<N>>(a: &P, b: &P) -> N {
FloatPnt::<N, V>::dist(a, b)
}
/// Returns the squared distance between two points.
#[inline(always)]
pub fn sqdist<N: Float, P: FloatPnt<N, V>, V: Norm<N>>(a: &P, b: &P) -> N {
FloatPnt::<N, V>::sqdist(a, b)
}
/*
* Perspective
*/
@ -405,46 +435,46 @@ pub fn append_translation<V, M: Translation<V>>(m: &M, v: &V) -> M {
}
/*
* Translate<V>
* Translate<P>
*/
/// Applies a translation to a vector.
/// Applies a translation to a point.
///
/// ```rust
/// extern crate "nalgebra" as na;
/// use na::{Vec3, Iso3};
/// use na::{Pnt3, Vec3, Iso3};
///
/// fn main() {
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
/// let v = Vec3::new(2.0, 2.0, 2.0);
/// let p = Pnt3::new(2.0, 2.0, 2.0);
///
/// let tv = na::translate(&t, &v);
/// let tp = na::translate(&t, &p);
///
/// assert!(tv == Vec3::new(3.0, 3.0, 3.0))
/// assert!(tp == Pnt3::new(3.0, 3.0, 3.0))
/// }
/// ```
#[inline(always)]
pub fn translate<V, M: Translate<V>>(m: &M, v: &V) -> V {
m.translate(v)
pub fn translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
m.translate(p)
}
/// Applies an inverse translation to a vector.
/// Applies an inverse translation to a point.
///
/// ```rust
/// extern crate "nalgebra" as na;
/// use na::{Vec3, Iso3};
/// use na::{Pnt3, Vec3, Iso3};
///
/// fn main() {
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
/// let v = Vec3::new(2.0, 2.0, 2.0);
/// let p = Pnt3::new(2.0, 2.0, 2.0);
///
/// let tv = na::inv_translate(&t, &v);
/// let tp = na::inv_translate(&t, &p);
///
/// assert!(na::approx_eq(&tv, &Vec3::new(1.0, 1.0, 1.0)))
/// assert!(na::approx_eq(&tp, &Pnt3::new(1.0, 1.0, 1.0)))
/// }
#[inline(always)]
pub fn inv_translate<V, M: Translate<V>>(m: &M, v: &V) -> V {
m.inv_translate(v)
pub fn inv_translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
m.inv_translate(p)
}
/*
@ -666,12 +696,6 @@ pub fn dot<V: Dot<N>, N>(a: &V, b: &V) -> N {
Dot::dot(a, b)
}
/// Computes a subtraction followed by a dot product.
#[inline(always)]
pub fn sub_dot<V: Dot<N>, N>(a: &V, b: &V, c: &V) -> N {
Dot::sub_dot(a, b, c)
}
/*
* Norm<N>
*/

View File

@ -431,13 +431,6 @@ pub fn dot<V: Dot<N>, N>(a: &V, b: &V) -> N {
super::dot(a, b)
}
/// Computes a subtraction followed by a dot product.
#[inline(always)]
#[deprecated = "use the root module `nalgebra::` directly instead of the `nalgebra::na::` module (you may create an alias `extern crate \"nalgebra\" as na;` when importing the crate)"]
pub fn sub_dot<V: Dot<N>, N>(a: &V, b: &V, c: &V) -> N {
super::sub_dot(a, b, c)
}
/*
* Norm<N>
*/

View File

@ -220,17 +220,6 @@ macro_rules! dvec_impl(
res
}
#[inline]
fn sub_dot(a: &$dvec<N>, b: &$dvec<N>, c: &$dvec<N>) -> N {
let mut res: N = Zero::zero();
for i in range(0u, a.len()) {
res = res + unsafe { (a.unsafe_at(i) - b.unsafe_at(i)) * c.unsafe_at(i) };
}
res
}
}
impl<N: Float + Clone> Norm<N> for $dvec<N> {

View File

@ -11,6 +11,7 @@ use traits::geometry::{RotationMatrix, Rotation, Rotate, AbsoluteRotate, Transfo
Translate, Translation, ToHomogeneous};
use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec2MulRhs, Vec3MulRhs, Vec4MulRhs};
use structs::pnt::{Pnt2, Pnt3, Pnt4, Pnt2MulRhs, Pnt3MulRhs, Pnt4MulRhs};
use structs::rot::{Rot2, Rot3, Rot4};
@ -104,14 +105,16 @@ rand_impl!(Iso2)
approx_eq_impl!(Iso2)
to_homogeneous_impl!(Iso2, Mat3)
inv_impl!(Iso2)
transform_impl!(Iso2, Vec2)
transform_impl!(Iso2TransformRhs, Iso2, Vec2, Pnt2)
transformation_impl!(Iso2)
rotate_impl!(Iso2, Vec2)
translation_impl!(Iso2, Vec2)
translate_impl!(Iso2, Vec2)
translate_impl!(Iso2, Pnt2)
iso_mul_iso_impl!(Iso2, Iso2MulRhs)
iso_mul_vec_impl!(Iso2, Vec2, Iso2MulRhs)
vec_mul_iso_impl!(Iso2, Vec2, Vec2MulRhs)
iso_mul_pnt_impl!(Iso2, Pnt2, Iso2MulRhs)
pnt_mul_iso_impl!(Iso2, Pnt2, Pnt2MulRhs)
iso_impl!(Iso3, Rot3, Vec3, Vec3)
double_dispatch_binop_decl_trait!(Iso3, Iso3MulRhs)
@ -125,14 +128,16 @@ rand_impl!(Iso3)
approx_eq_impl!(Iso3)
to_homogeneous_impl!(Iso3, Mat4)
inv_impl!(Iso3)
transform_impl!(Iso3, Vec3)
transform_impl!(Iso3TransformRhs, Iso3, Vec3, Pnt3)
transformation_impl!(Iso3)
rotate_impl!(Iso3, Vec3)
translation_impl!(Iso3, Vec3)
translate_impl!(Iso3, Vec3)
translate_impl!(Iso3, Pnt3)
iso_mul_iso_impl!(Iso3, Iso3MulRhs)
iso_mul_vec_impl!(Iso3, Vec3, Iso3MulRhs)
vec_mul_iso_impl!(Iso3, Vec3, Vec3MulRhs)
iso_mul_pnt_impl!(Iso3, Pnt3, Iso3MulRhs)
pnt_mul_iso_impl!(Iso3, Pnt3, Pnt3MulRhs)
// iso_impl!(Iso4, Rot4, Vec4, Vec4)
double_dispatch_binop_decl_trait!(Iso4, Iso4MulRhs)
@ -146,11 +151,13 @@ absolute_rotate_impl!(Iso4, Vec4)
approx_eq_impl!(Iso4)
to_homogeneous_impl!(Iso4, Mat5)
inv_impl!(Iso4)
transform_impl!(Iso4, Vec4)
transform_impl!(Iso4TransformRhs, Iso4, Vec4, Pnt4)
transformation_impl!(Iso4)
rotate_impl!(Iso4, Vec4)
translation_impl!(Iso4, Vec4)
translate_impl!(Iso4, Vec4)
translate_impl!(Iso4, Pnt4)
iso_mul_iso_impl!(Iso4, Iso4MulRhs)
iso_mul_vec_impl!(Iso4, Vec4, Iso4MulRhs)
vec_mul_iso_impl!(Iso4, Vec4, Vec4MulRhs)
iso_mul_pnt_impl!(Iso4, Pnt4, Iso4MulRhs)
pnt_mul_iso_impl!(Iso4, Pnt4, Pnt4MulRhs)

View File

@ -77,13 +77,35 @@ macro_rules! iso_mul_vec_impl(
impl<N: Num + Clone> $tmul<N, $tv<N>> for $tv<N> {
#[inline]
fn binop(left: &$t<N>, right: &$tv<N>) -> $tv<N> {
left.translation + left.rotation * *right
left.rotation * *right
}
}
)
)
macro_rules! vec_mul_iso_impl(
($t: ident, $tv: ident, $tmul: ident) => (
impl<N: Clone + Num> $tmul<N, $tv<N>> for $t<N> {
#[inline]
fn binop(left: &$tv<N>, right: &$t<N>) -> $tv<N> {
left * right.rotation
}
}
)
)
macro_rules! iso_mul_pnt_impl(
($t: ident, $tv: ident, $tmul: ident) => (
impl<N: Num + Clone> $tmul<N, $tv<N>> for $tv<N> {
#[inline]
fn binop(left: &$t<N>, right: &$tv<N>) -> $tv<N> {
left.rotation * *right + left.translation
}
}
)
)
macro_rules! pnt_mul_iso_impl(
($t: ident, $tv: ident, $tmul: ident) => (
impl<N: Clone + Num> $tmul<N, $tv<N>> for $t<N> {
#[inline]
@ -254,16 +276,49 @@ macro_rules! transformation_impl(
)
macro_rules! transform_impl(
($t: ident, $tv: ident) => (
impl<N: Num + Clone> Transform<$tv<N>> for $t<N> {
($trhs: ident, $t: ident, $tv: ident, $tp: ident) => (
/*
* FIXME: we use the double dispatch trick here so that we can transform vectors _and_
* points. Remove this as soon as rust supports multidispatch.
*/
pub trait $trhs<N> {
fn transform(left: &$t<N>, right: &Self) -> Self;
fn inv_transform(left: &$t<N>, right: &Self) -> Self;
}
impl<N, V: $trhs<N>> Transform<V> for $t<N> {
#[inline(always)]
fn transform(&self, other: &V) -> V {
$trhs::transform(self, other)
}
#[inline(always)]
fn inv_transform(&self, other: &V) -> V {
$trhs::inv_transform(self, other)
}
}
impl<N: Num + Clone> $trhs<N> for $tv<N> {
#[inline]
fn transform(&self, v: &$tv<N>) -> $tv<N> {
self.rotation.transform(v) + self.translation
fn transform(t: &$t<N>, v: &$tv<N>) -> $tv<N> {
t.rotation.transform(v)
}
#[inline]
fn inv_transform(&self, v: &$tv<N>) -> $tv<N> {
self.rotation.inv_transform(&(v - self.translation))
fn inv_transform(t: &$t<N>, v: &$tv<N>) -> $tv<N> {
t.rotation.inv_transform(v)
}
}
impl<N: Num + Clone> $trhs<N> for $tp<N> {
#[inline]
fn transform(t: &$t<N>, p: &$tp<N>) -> $tp<N> {
t.rotation.transform(p) + t.translation
}
#[inline]
fn inv_transform(t: &$t<N>, p: &$tp<N>) -> $tp<N> {
t.rotation.inv_transform(&(p - t.translation))
}
}
)

View File

@ -8,12 +8,13 @@ use traits::operations::ApproxEq;
use std::slice::{Items, MutItems};
use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6,
Vec1MulRhs, Vec4MulRhs, Vec5MulRhs, Vec6MulRhs};
use structs::pnt::{Pnt1, Pnt4, Pnt5, Pnt6, Pnt1MulRhs, Pnt4MulRhs, Pnt5MulRhs, Pnt6MulRhs};
use structs::dvec::{DVec1, DVec2, DVec3, DVec4, DVec5, DVec6};
use traits::structure::{Cast, Row, Col, Iterable, IterableMut, Dim, Indexable,
Eye, ColSlice, RowSlice, Diag};
use traits::operations::{Absolute, Transpose, Inv, Outer};
use traits::geometry::{ToHomogeneous, FromHomogeneous};
use traits::geometry::{ToHomogeneous, FromHomogeneous, Orig};
/// Special identity matrix. All its operation are no-ops.
@ -112,8 +113,10 @@ dim_impl!(Mat1, 1)
indexable_impl!(Mat1, 1)
index_impl!(Mat1, Vec1, 1)
mat_mul_mat_impl!(Mat1, Mat1MulRhs, 1)
mat_mul_vec_impl!(Mat1, Vec1, Mat1MulRhs, 1)
vec_mul_mat_impl!(Mat1, Vec1, Vec1MulRhs, 1)
mat_mul_vec_impl!(Mat1, Vec1, Mat1MulRhs, 1, Zero::zero)
vec_mul_mat_impl!(Mat1, Vec1, Vec1MulRhs, 1, Zero::zero)
mat_mul_pnt_impl!(Mat1, Pnt1, Mat1MulRhs, 1, Orig::orig)
pnt_mul_mat_impl!(Mat1, Pnt1, Pnt1MulRhs, 1, Orig::orig)
// (specialized) inv_impl!(Mat1, 1)
transpose_impl!(Mat1, 1)
approx_eq_impl!(Mat1)
@ -501,8 +504,10 @@ indexable_impl!(Mat4, 4)
index_impl!(Mat4, Vec4, 4)
at_fast_impl!(Mat4, 4)
mat_mul_mat_impl!(Mat4, Mat4MulRhs, 4)
mat_mul_vec_impl!(Mat4, Vec4, Mat4MulRhs, 4)
vec_mul_mat_impl!(Mat4, Vec4, Vec4MulRhs, 4)
mat_mul_vec_impl!(Mat4, Vec4, Mat4MulRhs, 4, Zero::zero)
vec_mul_mat_impl!(Mat4, Vec4, Vec4MulRhs, 4, Zero::zero)
mat_mul_pnt_impl!(Mat4, Pnt4, Mat4MulRhs, 4, Orig::orig)
pnt_mul_mat_impl!(Mat4, Pnt4, Pnt4MulRhs, 4, Orig::orig)
inv_impl!(Mat4, 4)
transpose_impl!(Mat4, 4)
approx_eq_impl!(Mat4)
@ -686,8 +691,10 @@ indexable_impl!(Mat5, 5)
index_impl!(Mat5, Vec5, 5)
at_fast_impl!(Mat5, 5)
mat_mul_mat_impl!(Mat5, Mat5MulRhs, 5)
mat_mul_vec_impl!(Mat5, Vec5, Mat5MulRhs, 5)
vec_mul_mat_impl!(Mat5, Vec5, Vec5MulRhs, 5)
mat_mul_vec_impl!(Mat5, Vec5, Mat5MulRhs, 5, Zero::zero)
vec_mul_mat_impl!(Mat5, Vec5, Vec5MulRhs, 5, Zero::zero)
mat_mul_pnt_impl!(Mat5, Pnt5, Mat5MulRhs, 5, Orig::orig)
pnt_mul_mat_impl!(Mat5, Pnt5, Pnt5MulRhs, 5, Orig::orig)
inv_impl!(Mat5, 5)
transpose_impl!(Mat5, 5)
approx_eq_impl!(Mat5)
@ -923,8 +930,10 @@ indexable_impl!(Mat6, 6)
index_impl!(Mat6, Vec6, 6)
at_fast_impl!(Mat6, 6)
mat_mul_mat_impl!(Mat6, Mat6MulRhs, 6)
mat_mul_vec_impl!(Mat6, Vec6, Mat6MulRhs, 6)
vec_mul_mat_impl!(Mat6, Vec6, Vec6MulRhs, 6)
mat_mul_vec_impl!(Mat6, Vec6, Mat6MulRhs, 6, Zero::zero)
vec_mul_mat_impl!(Mat6, Vec6, Vec6MulRhs, 6, Zero::zero)
mat_mul_pnt_impl!(Mat6, Pnt6, Mat6MulRhs, 6, Orig::orig)
pnt_mul_mat_impl!(Mat6, Pnt6, Pnt6MulRhs, 6, Orig::orig)
inv_impl!(Mat6, 6)
transpose_impl!(Mat6, 6)
approx_eq_impl!(Mat6)

View File

@ -381,11 +381,11 @@ macro_rules! mat_mul_mat_impl(
)
macro_rules! vec_mul_mat_impl(
($t: ident, $v: ident, $trhs: ident, $dim: expr) => (
($t: ident, $v: ident, $trhs: ident, $dim: expr, $zero: expr) => (
impl<N: Clone + Num> $trhs<N, $v<N>> for $t<N> {
#[inline]
fn binop(left: &$v<N>, right: &$t<N>) -> $v<N> {
let mut res : $v<N> = Zero::zero();
let mut res : $v<N> = $zero();
for i in range(0u, $dim) {
for j in range(0u, $dim) {
@ -403,11 +403,11 @@ macro_rules! vec_mul_mat_impl(
)
macro_rules! mat_mul_vec_impl(
($t: ident, $v: ident, $trhs: ident, $dim: expr) => (
($t: ident, $v: ident, $trhs: ident, $dim: expr, $zero: expr) => (
impl<N: Clone + Num> $trhs<N, $v<N>> for $v<N> {
#[inline]
fn binop(left: &$t<N>, right: &$v<N>) -> $v<N> {
let mut res : $v<N> = Zero::zero();
let mut res : $v<N> = $zero();
for i in range(0u, $dim) {
for j in range(0u, $dim) {
@ -424,6 +424,18 @@ macro_rules! mat_mul_vec_impl(
)
)
macro_rules! pnt_mul_mat_impl(
($t: ident, $v: ident, $trhs: ident, $dim: expr, $zero: expr) => (
vec_mul_mat_impl!($t, $v, $trhs, $dim, $zero)
)
)
macro_rules! mat_mul_pnt_impl(
($t: ident, $v: ident, $trhs: ident, $dim: expr, $zero: expr) => (
mat_mul_vec_impl!($t, $v, $trhs, $dim, $zero)
)
)
macro_rules! inv_impl(
($t: ident, $dim: expr) => (
impl<N: Clone + Num>

View File

@ -3,6 +3,7 @@
pub use self::dmat::DMat;
pub use self::dvec::{DVec, DVec1, DVec2, DVec3, DVec4, DVec5, DVec6};
pub use self::vec::{Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6};
pub use self::pnt::{Pnt0, Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6};
pub use self::mat::{Identity, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6};
pub use self::rot::{Rot2, Rot3, Rot4};
pub use self::iso::{Iso2, Iso3, Iso4};
@ -22,6 +23,8 @@ mod dvec_macros;
mod dvec;
mod vec_macros;
mod vec;
mod pnt_macros;
mod pnt;
mod mat_macros;
mod mat;
mod rot_macros;

593
src/structs/pnt.rs Normal file
View File

@ -0,0 +1,593 @@
//! Points with dimensions known at compile-time.
#![allow(missing_doc)] // we allow missing to avoid having to document the vector components.
use std::mem;
use std::num::{Zero, One, Bounded};
use std::slice::{Items, MutItems};
use std::iter::{Iterator, FromIterator};
use traits::operations::{ApproxEq, PartialOrd, PartialOrdering, PartialLess, PartialEqual,
PartialGreater, NotComparable};
use traits::structure::{Cast, Dim, Indexable, Iterable, IterableMut, PntAsVec};
use traits::geometry::{Orig, FromHomogeneous, ToHomogeneous};
use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6};
/// Point of dimension 0.
#[deriving(Eq, PartialEq, Decodable, Clone, Rand, Show)]
pub struct Pnt0<N>;
impl<N> Pnt0<N> {
/// Creates a new vector.
#[inline]
pub fn new() -> Pnt0<N> {
Pnt0
}
/// Creates a new vector. The parameter is not taken in account.
#[inline]
pub fn new_repeat(_: N) -> Pnt0<N> {
Pnt0
}
}
/// Point of dimension 1.
#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Show)]
pub struct Pnt1<N> {
/// First component of the vector.
pub x: N
}
double_dispatch_binop_decl_trait!(Pnt1, Pnt1MulRhs)
double_dispatch_binop_decl_trait!(Pnt1, Pnt1DivRhs)
double_dispatch_binop_decl_trait!(Pnt1, Pnt1AddRhs)
double_dispatch_binop_decl_trait!(Pnt1, Pnt1SubRhs)
double_dispatch_cast_decl_trait!(Pnt1, Pnt1Cast)
mul_redispatch_impl!(Pnt1, Pnt1MulRhs)
div_redispatch_impl!(Pnt1, Pnt1DivRhs)
add_redispatch_impl!(Pnt1, Pnt1AddRhs)
sub_redispatch_impl!(Pnt1, Pnt1SubRhs)
cast_redispatch_impl!(Pnt1, Pnt1Cast)
new_impl!(Pnt1, x)
orig_impl!(Pnt1, x)
ord_impl!(Pnt1, x)
vec_cast_impl!(Pnt1, Pnt1Cast, x)
as_slice_impl!(Pnt1, 1)
index_impl!(Pnt1)
indexable_impl!(Pnt1, 1)
at_fast_impl!(Pnt1, 1)
new_repeat_impl!(Pnt1, val, x)
dim_impl!(Pnt1, 1)
container_impl!(Pnt1)
pnt_as_vec_impl!(Pnt1, Vec1)
pnt_sub_impl!(Pnt1, Vec1, Pnt1SubRhs)
neg_impl!(Pnt1, x)
pnt_add_vec_impl!(Pnt1, Vec1, Pnt1AddRhs, x)
pnt_sub_vec_impl!(Pnt1, Vec1, Pnt1SubRhs, x)
vec_mul_scalar_impl!(Pnt1, f64, Pnt1MulRhs, x)
vec_mul_scalar_impl!(Pnt1, f32, Pnt1MulRhs, x)
vec_mul_scalar_impl!(Pnt1, u64, Pnt1MulRhs, x)
vec_mul_scalar_impl!(Pnt1, u32, Pnt1MulRhs, x)
vec_mul_scalar_impl!(Pnt1, u16, Pnt1MulRhs, x)
vec_mul_scalar_impl!(Pnt1, u8, Pnt1MulRhs, x)
vec_mul_scalar_impl!(Pnt1, i64, Pnt1MulRhs, x)
vec_mul_scalar_impl!(Pnt1, i32, Pnt1MulRhs, x)
vec_mul_scalar_impl!(Pnt1, i16, Pnt1MulRhs, x)
vec_mul_scalar_impl!(Pnt1, i8, Pnt1MulRhs, x)
vec_mul_scalar_impl!(Pnt1, uint, Pnt1MulRhs, x)
vec_mul_scalar_impl!(Pnt1, int, Pnt1MulRhs, x)
vec_div_scalar_impl!(Pnt1, f64, Pnt1DivRhs, x)
vec_div_scalar_impl!(Pnt1, f32, Pnt1DivRhs, x)
vec_div_scalar_impl!(Pnt1, u64, Pnt1DivRhs, x)
vec_div_scalar_impl!(Pnt1, u32, Pnt1DivRhs, x)
vec_div_scalar_impl!(Pnt1, u16, Pnt1DivRhs, x)
vec_div_scalar_impl!(Pnt1, u8, Pnt1DivRhs, x)
vec_div_scalar_impl!(Pnt1, i64, Pnt1DivRhs, x)
vec_div_scalar_impl!(Pnt1, i32, Pnt1DivRhs, x)
vec_div_scalar_impl!(Pnt1, i16, Pnt1DivRhs, x)
vec_div_scalar_impl!(Pnt1, i8, Pnt1DivRhs, x)
vec_div_scalar_impl!(Pnt1, uint, Pnt1DivRhs, x)
vec_div_scalar_impl!(Pnt1, int, Pnt1DivRhs, x)
vec_add_scalar_impl!(Pnt1, f64, Pnt1AddRhs, x)
vec_add_scalar_impl!(Pnt1, f32, Pnt1AddRhs, x)
vec_add_scalar_impl!(Pnt1, u64, Pnt1AddRhs, x)
vec_add_scalar_impl!(Pnt1, u32, Pnt1AddRhs, x)
vec_add_scalar_impl!(Pnt1, u16, Pnt1AddRhs, x)
vec_add_scalar_impl!(Pnt1, u8, Pnt1AddRhs, x)
vec_add_scalar_impl!(Pnt1, i64, Pnt1AddRhs, x)
vec_add_scalar_impl!(Pnt1, i32, Pnt1AddRhs, x)
vec_add_scalar_impl!(Pnt1, i16, Pnt1AddRhs, x)
vec_add_scalar_impl!(Pnt1, i8, Pnt1AddRhs, x)
vec_add_scalar_impl!(Pnt1, uint, Pnt1AddRhs, x)
vec_add_scalar_impl!(Pnt1, int, Pnt1AddRhs, x)
vec_sub_scalar_impl!(Pnt1, f64, Pnt1SubRhs, x)
vec_sub_scalar_impl!(Pnt1, f32, Pnt1SubRhs, x)
vec_sub_scalar_impl!(Pnt1, u64, Pnt1SubRhs, x)
vec_sub_scalar_impl!(Pnt1, u32, Pnt1SubRhs, x)
vec_sub_scalar_impl!(Pnt1, u16, Pnt1SubRhs, x)
vec_sub_scalar_impl!(Pnt1, u8, Pnt1SubRhs, x)
vec_sub_scalar_impl!(Pnt1, i64, Pnt1SubRhs, x)
vec_sub_scalar_impl!(Pnt1, i32, Pnt1SubRhs, x)
vec_sub_scalar_impl!(Pnt1, i16, Pnt1SubRhs, x)
vec_sub_scalar_impl!(Pnt1, i8, Pnt1SubRhs, x)
vec_sub_scalar_impl!(Pnt1, uint, Pnt1SubRhs, x)
vec_sub_scalar_impl!(Pnt1, int, Pnt1SubRhs, x)
approx_eq_impl!(Pnt1, x)
from_iterator_impl!(Pnt1, iterator)
bounded_impl!(Pnt1, x)
iterable_impl!(Pnt1, 1)
iterable_mut_impl!(Pnt1, 1)
pnt_to_homogeneous_impl!(Pnt1, Pnt2, y, x)
pnt_from_homogeneous_impl!(Pnt1, Pnt2, y, x)
/// Point of dimension 2.
#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Show)]
pub struct Pnt2<N> {
/// First component of the vector.
pub x: N,
/// Second component of the vector.
pub y: N
}
double_dispatch_binop_decl_trait!(Pnt2, Pnt2MulRhs)
double_dispatch_binop_decl_trait!(Pnt2, Pnt2DivRhs)
double_dispatch_binop_decl_trait!(Pnt2, Pnt2AddRhs)
double_dispatch_binop_decl_trait!(Pnt2, Pnt2SubRhs)
double_dispatch_cast_decl_trait!(Pnt2, Pnt2Cast)
mul_redispatch_impl!(Pnt2, Pnt2MulRhs)
div_redispatch_impl!(Pnt2, Pnt2DivRhs)
add_redispatch_impl!(Pnt2, Pnt2AddRhs)
sub_redispatch_impl!(Pnt2, Pnt2SubRhs)
cast_redispatch_impl!(Pnt2, Pnt2Cast)
new_impl!(Pnt2, x, y)
orig_impl!(Pnt2, x, y)
ord_impl!(Pnt2, x, y)
vec_cast_impl!(Pnt2, Pnt2Cast, x, y)
as_slice_impl!(Pnt2, 2)
index_impl!(Pnt2)
indexable_impl!(Pnt2, 2)
at_fast_impl!(Pnt2, 2)
new_repeat_impl!(Pnt2, val, x, y)
dim_impl!(Pnt2, 2)
container_impl!(Pnt2)
pnt_as_vec_impl!(Pnt2, Vec2)
pnt_sub_impl!(Pnt2, Vec2, Pnt2SubRhs)
neg_impl!(Pnt2, x, y)
pnt_add_vec_impl!(Pnt2, Vec2, Pnt2AddRhs, x, y)
pnt_sub_vec_impl!(Pnt2, Vec2, Pnt2SubRhs, x, y)
vec_mul_scalar_impl!(Pnt2, f64, Pnt2MulRhs, x, y)
vec_mul_scalar_impl!(Pnt2, f32, Pnt2MulRhs, x, y)
vec_mul_scalar_impl!(Pnt2, u64, Pnt2MulRhs, x, y)
vec_mul_scalar_impl!(Pnt2, u32, Pnt2MulRhs, x, y)
vec_mul_scalar_impl!(Pnt2, u16, Pnt2MulRhs, x, y)
vec_mul_scalar_impl!(Pnt2, u8, Pnt2MulRhs, x, y)
vec_mul_scalar_impl!(Pnt2, i64, Pnt2MulRhs, x, y)
vec_mul_scalar_impl!(Pnt2, i32, Pnt2MulRhs, x, y)
vec_mul_scalar_impl!(Pnt2, i16, Pnt2MulRhs, x, y)
vec_mul_scalar_impl!(Pnt2, i8, Pnt2MulRhs, x, y)
vec_mul_scalar_impl!(Pnt2, uint, Pnt2MulRhs, x, y)
vec_mul_scalar_impl!(Pnt2, int, Pnt2MulRhs, x, y)
vec_div_scalar_impl!(Pnt2, f64, Pnt2DivRhs, x, y)
vec_div_scalar_impl!(Pnt2, f32, Pnt2DivRhs, x, y)
vec_div_scalar_impl!(Pnt2, u64, Pnt2DivRhs, x, y)
vec_div_scalar_impl!(Pnt2, u32, Pnt2DivRhs, x, y)
vec_div_scalar_impl!(Pnt2, u16, Pnt2DivRhs, x, y)
vec_div_scalar_impl!(Pnt2, u8, Pnt2DivRhs, x, y)
vec_div_scalar_impl!(Pnt2, i64, Pnt2DivRhs, x, y)
vec_div_scalar_impl!(Pnt2, i32, Pnt2DivRhs, x, y)
vec_div_scalar_impl!(Pnt2, i16, Pnt2DivRhs, x, y)
vec_div_scalar_impl!(Pnt2, i8, Pnt2DivRhs, x, y)
vec_div_scalar_impl!(Pnt2, uint, Pnt2DivRhs, x, y)
vec_div_scalar_impl!(Pnt2, int, Pnt2DivRhs, x, y)
vec_add_scalar_impl!(Pnt2, f64, Pnt2AddRhs, x, y)
vec_add_scalar_impl!(Pnt2, f32, Pnt2AddRhs, x, y)
vec_add_scalar_impl!(Pnt2, u64, Pnt2AddRhs, x, y)
vec_add_scalar_impl!(Pnt2, u32, Pnt2AddRhs, x, y)
vec_add_scalar_impl!(Pnt2, u16, Pnt2AddRhs, x, y)
vec_add_scalar_impl!(Pnt2, u8, Pnt2AddRhs, x, y)
vec_add_scalar_impl!(Pnt2, i64, Pnt2AddRhs, x, y)
vec_add_scalar_impl!(Pnt2, i32, Pnt2AddRhs, x, y)
vec_add_scalar_impl!(Pnt2, i16, Pnt2AddRhs, x, y)
vec_add_scalar_impl!(Pnt2, i8, Pnt2AddRhs, x, y)
vec_add_scalar_impl!(Pnt2, uint, Pnt2AddRhs, x, y)
vec_add_scalar_impl!(Pnt2, int, Pnt2AddRhs, x, y)
vec_sub_scalar_impl!(Pnt2, f64, Pnt2SubRhs, x, y)
vec_sub_scalar_impl!(Pnt2, f32, Pnt2SubRhs, x, y)
vec_sub_scalar_impl!(Pnt2, u64, Pnt2SubRhs, x, y)
vec_sub_scalar_impl!(Pnt2, u32, Pnt2SubRhs, x, y)
vec_sub_scalar_impl!(Pnt2, u16, Pnt2SubRhs, x, y)
vec_sub_scalar_impl!(Pnt2, u8, Pnt2SubRhs, x, y)
vec_sub_scalar_impl!(Pnt2, i64, Pnt2SubRhs, x, y)
vec_sub_scalar_impl!(Pnt2, i32, Pnt2SubRhs, x, y)
vec_sub_scalar_impl!(Pnt2, i16, Pnt2SubRhs, x, y)
vec_sub_scalar_impl!(Pnt2, i8, Pnt2SubRhs, x, y)
vec_sub_scalar_impl!(Pnt2, uint, Pnt2SubRhs, x, y)
vec_sub_scalar_impl!(Pnt2, int, Pnt2SubRhs, x, y)
approx_eq_impl!(Pnt2, x, y)
from_iterator_impl!(Pnt2, iterator, iterator)
bounded_impl!(Pnt2, x, y)
iterable_impl!(Pnt2, 2)
iterable_mut_impl!(Pnt2, 2)
pnt_to_homogeneous_impl!(Pnt2, Pnt3, z, x, y)
pnt_from_homogeneous_impl!(Pnt2, Pnt3, z, x, y)
/// Point of dimension 3.
#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Show)]
pub struct Pnt3<N> {
/// First component of the vector.
pub x: N,
/// Second component of the vector.
pub y: N,
/// Third component of the vector.
pub z: N
}
double_dispatch_binop_decl_trait!(Pnt3, Pnt3MulRhs)
double_dispatch_binop_decl_trait!(Pnt3, Pnt3DivRhs)
double_dispatch_binop_decl_trait!(Pnt3, Pnt3AddRhs)
double_dispatch_binop_decl_trait!(Pnt3, Pnt3SubRhs)
double_dispatch_cast_decl_trait!(Pnt3, Pnt3Cast)
mul_redispatch_impl!(Pnt3, Pnt3MulRhs)
div_redispatch_impl!(Pnt3, Pnt3DivRhs)
add_redispatch_impl!(Pnt3, Pnt3AddRhs)
sub_redispatch_impl!(Pnt3, Pnt3SubRhs)
cast_redispatch_impl!(Pnt3, Pnt3Cast)
new_impl!(Pnt3, x, y, z)
orig_impl!(Pnt3, x, y, z)
ord_impl!(Pnt3, x, y, z)
vec_cast_impl!(Pnt3, Pnt3Cast, x, y, z)
as_slice_impl!(Pnt3, 3)
index_impl!(Pnt3)
indexable_impl!(Pnt3, 3)
at_fast_impl!(Pnt3, 3)
new_repeat_impl!(Pnt3, val, x, y, z)
dim_impl!(Pnt3, 3)
container_impl!(Pnt3)
pnt_as_vec_impl!(Pnt3, Vec3)
pnt_sub_impl!(Pnt3, Vec3, Pnt3SubRhs)
neg_impl!(Pnt3, x, y, z)
pnt_add_vec_impl!(Pnt3, Vec3, Pnt3AddRhs, x, y, z)
pnt_sub_vec_impl!(Pnt3, Vec3, Pnt3SubRhs, x, y, z)
vec_mul_scalar_impl!(Pnt3, f64, Pnt3MulRhs, x, y, z)
vec_mul_scalar_impl!(Pnt3, f32, Pnt3MulRhs, x, y, z)
vec_mul_scalar_impl!(Pnt3, u64, Pnt3MulRhs, x, y, z)
vec_mul_scalar_impl!(Pnt3, u32, Pnt3MulRhs, x, y, z)
vec_mul_scalar_impl!(Pnt3, u16, Pnt3MulRhs, x, y, z)
vec_mul_scalar_impl!(Pnt3, u8, Pnt3MulRhs, x, y, z)
vec_mul_scalar_impl!(Pnt3, i64, Pnt3MulRhs, x, y, z)
vec_mul_scalar_impl!(Pnt3, i32, Pnt3MulRhs, x, y, z)
vec_mul_scalar_impl!(Pnt3, i16, Pnt3MulRhs, x, y, z)
vec_mul_scalar_impl!(Pnt3, i8, Pnt3MulRhs, x, y, z)
vec_mul_scalar_impl!(Pnt3, uint, Pnt3MulRhs, x, y, z)
vec_mul_scalar_impl!(Pnt3, int, Pnt3MulRhs, x, y, z)
vec_div_scalar_impl!(Pnt3, f64, Pnt3DivRhs, x, y, z)
vec_div_scalar_impl!(Pnt3, f32, Pnt3DivRhs, x, y, z)
vec_div_scalar_impl!(Pnt3, u64, Pnt3DivRhs, x, y, z)
vec_div_scalar_impl!(Pnt3, u32, Pnt3DivRhs, x, y, z)
vec_div_scalar_impl!(Pnt3, u16, Pnt3DivRhs, x, y, z)
vec_div_scalar_impl!(Pnt3, u8, Pnt3DivRhs, x, y, z)
vec_div_scalar_impl!(Pnt3, i64, Pnt3DivRhs, x, y, z)
vec_div_scalar_impl!(Pnt3, i32, Pnt3DivRhs, x, y, z)
vec_div_scalar_impl!(Pnt3, i16, Pnt3DivRhs, x, y, z)
vec_div_scalar_impl!(Pnt3, i8, Pnt3DivRhs, x, y, z)
vec_div_scalar_impl!(Pnt3, uint, Pnt3DivRhs, x, y, z)
vec_div_scalar_impl!(Pnt3, int, Pnt3DivRhs, x, y, z)
vec_add_scalar_impl!(Pnt3, f64, Pnt3AddRhs, x, y, z)
vec_add_scalar_impl!(Pnt3, f32, Pnt3AddRhs, x, y, z)
vec_add_scalar_impl!(Pnt3, u64, Pnt3AddRhs, x, y, z)
vec_add_scalar_impl!(Pnt3, u32, Pnt3AddRhs, x, y, z)
vec_add_scalar_impl!(Pnt3, u16, Pnt3AddRhs, x, y, z)
vec_add_scalar_impl!(Pnt3, u8, Pnt3AddRhs, x, y, z)
vec_add_scalar_impl!(Pnt3, i64, Pnt3AddRhs, x, y, z)
vec_add_scalar_impl!(Pnt3, i32, Pnt3AddRhs, x, y, z)
vec_add_scalar_impl!(Pnt3, i16, Pnt3AddRhs, x, y, z)
vec_add_scalar_impl!(Pnt3, i8, Pnt3AddRhs, x, y, z)
vec_add_scalar_impl!(Pnt3, uint, Pnt3AddRhs, x, y, z)
vec_add_scalar_impl!(Pnt3, int, Pnt3AddRhs, x, y, z)
vec_sub_scalar_impl!(Pnt3, f64, Pnt3SubRhs, x, y, z)
vec_sub_scalar_impl!(Pnt3, f32, Pnt3SubRhs, x, y, z)
vec_sub_scalar_impl!(Pnt3, u64, Pnt3SubRhs, x, y, z)
vec_sub_scalar_impl!(Pnt3, u32, Pnt3SubRhs, x, y, z)
vec_sub_scalar_impl!(Pnt3, u16, Pnt3SubRhs, x, y, z)
vec_sub_scalar_impl!(Pnt3, u8, Pnt3SubRhs, x, y, z)
vec_sub_scalar_impl!(Pnt3, i64, Pnt3SubRhs, x, y, z)
vec_sub_scalar_impl!(Pnt3, i32, Pnt3SubRhs, x, y, z)
vec_sub_scalar_impl!(Pnt3, i16, Pnt3SubRhs, x, y, z)
vec_sub_scalar_impl!(Pnt3, i8, Pnt3SubRhs, x, y, z)
vec_sub_scalar_impl!(Pnt3, uint, Pnt3SubRhs, x, y, z)
vec_sub_scalar_impl!(Pnt3, int, Pnt3SubRhs, x, y, z)
approx_eq_impl!(Pnt3, x, y, z)
from_iterator_impl!(Pnt3, iterator, iterator, iterator)
bounded_impl!(Pnt3, x, y, z)
iterable_impl!(Pnt3, 3)
iterable_mut_impl!(Pnt3, 3)
pnt_to_homogeneous_impl!(Pnt3, Pnt4, w, x, y, z)
pnt_from_homogeneous_impl!(Pnt3, Pnt4, w, x, y, z)
/// Point of dimension 4.
#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Show)]
pub struct Pnt4<N> {
/// First component of the vector.
pub x: N,
/// Second component of the vector.
pub y: N,
/// Third component of the vector.
pub z: N,
/// Fourth component of the vector.
pub w: N
}
double_dispatch_binop_decl_trait!(Pnt4, Pnt4MulRhs)
double_dispatch_binop_decl_trait!(Pnt4, Pnt4DivRhs)
double_dispatch_binop_decl_trait!(Pnt4, Pnt4AddRhs)
double_dispatch_binop_decl_trait!(Pnt4, Pnt4SubRhs)
double_dispatch_cast_decl_trait!(Pnt4, Pnt4Cast)
mul_redispatch_impl!(Pnt4, Pnt4MulRhs)
div_redispatch_impl!(Pnt4, Pnt4DivRhs)
add_redispatch_impl!(Pnt4, Pnt4AddRhs)
sub_redispatch_impl!(Pnt4, Pnt4SubRhs)
cast_redispatch_impl!(Pnt4, Pnt4Cast)
new_impl!(Pnt4, x, y, z, w)
orig_impl!(Pnt4, x, y, z, w)
ord_impl!(Pnt4, x, y, z, w)
vec_cast_impl!(Pnt4, Pnt4Cast, x, y, z, w)
as_slice_impl!(Pnt4, 4)
index_impl!(Pnt4)
indexable_impl!(Pnt4, 4)
at_fast_impl!(Pnt4, 4)
new_repeat_impl!(Pnt4, val, x, y, z, w)
dim_impl!(Pnt4, 4)
container_impl!(Pnt4)
pnt_as_vec_impl!(Pnt4, Vec4)
pnt_sub_impl!(Pnt4, Vec4, Pnt4SubRhs)
neg_impl!(Pnt4, x, y, z, w)
pnt_add_vec_impl!(Pnt4, Vec4, Pnt4AddRhs, x, y, z, w)
pnt_sub_vec_impl!(Pnt4, Vec4, Pnt4SubRhs, x, y, z, w)
vec_mul_scalar_impl!(Pnt4, f64, Pnt4MulRhs, x, y, z, w)
vec_mul_scalar_impl!(Pnt4, f32, Pnt4MulRhs, x, y, z, w)
vec_mul_scalar_impl!(Pnt4, u64, Pnt4MulRhs, x, y, z, w)
vec_mul_scalar_impl!(Pnt4, u32, Pnt4MulRhs, x, y, z, w)
vec_mul_scalar_impl!(Pnt4, u16, Pnt4MulRhs, x, y, z, w)
vec_mul_scalar_impl!(Pnt4, u8, Pnt4MulRhs, x, y, z, w)
vec_mul_scalar_impl!(Pnt4, i64, Pnt4MulRhs, x, y, z, w)
vec_mul_scalar_impl!(Pnt4, i32, Pnt4MulRhs, x, y, z, w)
vec_mul_scalar_impl!(Pnt4, i16, Pnt4MulRhs, x, y, z, w)
vec_mul_scalar_impl!(Pnt4, i8, Pnt4MulRhs, x, y, z, w)
vec_mul_scalar_impl!(Pnt4, uint, Pnt4MulRhs, x, y, z, w)
vec_mul_scalar_impl!(Pnt4, int, Pnt4MulRhs, x, y, z, w)
vec_div_scalar_impl!(Pnt4, f64, Pnt4DivRhs, x, y, z, w)
vec_div_scalar_impl!(Pnt4, f32, Pnt4DivRhs, x, y, z, w)
vec_div_scalar_impl!(Pnt4, u64, Pnt4DivRhs, x, y, z, w)
vec_div_scalar_impl!(Pnt4, u32, Pnt4DivRhs, x, y, z, w)
vec_div_scalar_impl!(Pnt4, u16, Pnt4DivRhs, x, y, z, w)
vec_div_scalar_impl!(Pnt4, u8, Pnt4DivRhs, x, y, z, w)
vec_div_scalar_impl!(Pnt4, i64, Pnt4DivRhs, x, y, z, w)
vec_div_scalar_impl!(Pnt4, i32, Pnt4DivRhs, x, y, z, w)
vec_div_scalar_impl!(Pnt4, i16, Pnt4DivRhs, x, y, z, w)
vec_div_scalar_impl!(Pnt4, i8, Pnt4DivRhs, x, y, z, w)
vec_div_scalar_impl!(Pnt4, uint, Pnt4DivRhs, x, y, z, w)
vec_div_scalar_impl!(Pnt4, int, Pnt4DivRhs, x, y, z, w)
vec_add_scalar_impl!(Pnt4, f64, Pnt4AddRhs, x, y, z, w)
vec_add_scalar_impl!(Pnt4, f32, Pnt4AddRhs, x, y, z, w)
vec_add_scalar_impl!(Pnt4, u64, Pnt4AddRhs, x, y, z, w)
vec_add_scalar_impl!(Pnt4, u32, Pnt4AddRhs, x, y, z, w)
vec_add_scalar_impl!(Pnt4, u16, Pnt4AddRhs, x, y, z, w)
vec_add_scalar_impl!(Pnt4, u8, Pnt4AddRhs, x, y, z, w)
vec_add_scalar_impl!(Pnt4, i64, Pnt4AddRhs, x, y, z, w)
vec_add_scalar_impl!(Pnt4, i32, Pnt4AddRhs, x, y, z, w)
vec_add_scalar_impl!(Pnt4, i16, Pnt4AddRhs, x, y, z, w)
vec_add_scalar_impl!(Pnt4, i8, Pnt4AddRhs, x, y, z, w)
vec_add_scalar_impl!(Pnt4, uint, Pnt4AddRhs, x, y, z, w)
vec_add_scalar_impl!(Pnt4, int, Pnt4AddRhs, x, y, z, w)
vec_sub_scalar_impl!(Pnt4, f64, Pnt4SubRhs, x, y, z, w)
vec_sub_scalar_impl!(Pnt4, f32, Pnt4SubRhs, x, y, z, w)
vec_sub_scalar_impl!(Pnt4, u64, Pnt4SubRhs, x, y, z, w)
vec_sub_scalar_impl!(Pnt4, u32, Pnt4SubRhs, x, y, z, w)
vec_sub_scalar_impl!(Pnt4, u16, Pnt4SubRhs, x, y, z, w)
vec_sub_scalar_impl!(Pnt4, u8, Pnt4SubRhs, x, y, z, w)
vec_sub_scalar_impl!(Pnt4, i64, Pnt4SubRhs, x, y, z, w)
vec_sub_scalar_impl!(Pnt4, i32, Pnt4SubRhs, x, y, z, w)
vec_sub_scalar_impl!(Pnt4, i16, Pnt4SubRhs, x, y, z, w)
vec_sub_scalar_impl!(Pnt4, i8, Pnt4SubRhs, x, y, z, w)
vec_sub_scalar_impl!(Pnt4, uint, Pnt4SubRhs, x, y, z, w)
vec_sub_scalar_impl!(Pnt4, int, Pnt4SubRhs, x, y, z, w)
approx_eq_impl!(Pnt4, x, y, z, w)
from_iterator_impl!(Pnt4, iterator, iterator, iterator, iterator)
bounded_impl!(Pnt4, x, y, z, w)
iterable_impl!(Pnt4, 4)
iterable_mut_impl!(Pnt4, 4)
pnt_to_homogeneous_impl!(Pnt4, Pnt5, a, x, y, z, w)
pnt_from_homogeneous_impl!(Pnt4, Pnt5, a, x, y, z, w)
/// Point of dimension 5.
#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Show)]
pub struct Pnt5<N> {
/// First component of the vector.
pub x: N,
/// Second component of the vector.
pub y: N,
/// Third component of the vector.
pub z: N,
/// Fourth component of the vector.
pub w: N,
/// Fifth of the vector.
pub a: N
}
double_dispatch_binop_decl_trait!(Pnt5, Pnt5MulRhs)
double_dispatch_binop_decl_trait!(Pnt5, Pnt5DivRhs)
double_dispatch_binop_decl_trait!(Pnt5, Pnt5AddRhs)
double_dispatch_binop_decl_trait!(Pnt5, Pnt5SubRhs)
double_dispatch_cast_decl_trait!(Pnt5, Pnt5Cast)
mul_redispatch_impl!(Pnt5, Pnt5MulRhs)
div_redispatch_impl!(Pnt5, Pnt5DivRhs)
add_redispatch_impl!(Pnt5, Pnt5AddRhs)
sub_redispatch_impl!(Pnt5, Pnt5SubRhs)
cast_redispatch_impl!(Pnt5, Pnt5Cast)
new_impl!(Pnt5, x, y, z, w, a)
orig_impl!(Pnt5, x, y, z, w, a)
ord_impl!(Pnt5, x, y, z, w, a)
vec_cast_impl!(Pnt5, Pnt5Cast, x, y, z, w, a)
as_slice_impl!(Pnt5, 5)
index_impl!(Pnt5)
indexable_impl!(Pnt5, 5)
at_fast_impl!(Pnt5, 5)
new_repeat_impl!(Pnt5, val, x, y, z, w, a)
dim_impl!(Pnt5, 5)
container_impl!(Pnt5)
pnt_as_vec_impl!(Pnt5, Vec5)
pnt_sub_impl!(Pnt5, Vec5, Pnt5SubRhs)
neg_impl!(Pnt5, x, y, z, w, a)
pnt_add_vec_impl!(Pnt5, Vec5, Pnt5AddRhs, x, y, z, w, a)
pnt_sub_vec_impl!(Pnt5, Vec5, Pnt5SubRhs, x, y, z, w, a)
vec_mul_scalar_impl!(Pnt5, f64, Pnt5MulRhs, x, y, z, w, a)
vec_mul_scalar_impl!(Pnt5, f32, Pnt5MulRhs, x, y, z, w, a)
vec_mul_scalar_impl!(Pnt5, u64, Pnt5MulRhs, x, y, z, w, a)
vec_mul_scalar_impl!(Pnt5, u32, Pnt5MulRhs, x, y, z, w, a)
vec_mul_scalar_impl!(Pnt5, u16, Pnt5MulRhs, x, y, z, w, a)
vec_mul_scalar_impl!(Pnt5, u8, Pnt5MulRhs, x, y, z, w, a)
vec_mul_scalar_impl!(Pnt5, i64, Pnt5MulRhs, x, y, z, w, a)
vec_mul_scalar_impl!(Pnt5, i32, Pnt5MulRhs, x, y, z, w, a)
vec_mul_scalar_impl!(Pnt5, i16, Pnt5MulRhs, x, y, z, w, a)
vec_mul_scalar_impl!(Pnt5, i8, Pnt5MulRhs, x, y, z, w, a)
vec_mul_scalar_impl!(Pnt5, uint, Pnt5MulRhs, x, y, z, w, a)
vec_mul_scalar_impl!(Pnt5, int, Pnt5MulRhs, x, y, z, w, a)
vec_div_scalar_impl!(Pnt5, f64, Pnt5DivRhs, x, y, z, w, a)
vec_div_scalar_impl!(Pnt5, f32, Pnt5DivRhs, x, y, z, w, a)
vec_div_scalar_impl!(Pnt5, u64, Pnt5DivRhs, x, y, z, w, a)
vec_div_scalar_impl!(Pnt5, u32, Pnt5DivRhs, x, y, z, w, a)
vec_div_scalar_impl!(Pnt5, u16, Pnt5DivRhs, x, y, z, w, a)
vec_div_scalar_impl!(Pnt5, u8, Pnt5DivRhs, x, y, z, w, a)
vec_div_scalar_impl!(Pnt5, i64, Pnt5DivRhs, x, y, z, w, a)
vec_div_scalar_impl!(Pnt5, i32, Pnt5DivRhs, x, y, z, w, a)
vec_div_scalar_impl!(Pnt5, i16, Pnt5DivRhs, x, y, z, w, a)
vec_div_scalar_impl!(Pnt5, i8, Pnt5DivRhs, x, y, z, w, a)
vec_div_scalar_impl!(Pnt5, uint, Pnt5DivRhs, x, y, z, w, a)
vec_div_scalar_impl!(Pnt5, int, Pnt5DivRhs, x, y, z, w, a)
vec_add_scalar_impl!(Pnt5, f64, Pnt5AddRhs, x, y, z, w, a)
vec_add_scalar_impl!(Pnt5, f32, Pnt5AddRhs, x, y, z, w, a)
vec_add_scalar_impl!(Pnt5, u64, Pnt5AddRhs, x, y, z, w, a)
vec_add_scalar_impl!(Pnt5, u32, Pnt5AddRhs, x, y, z, w, a)
vec_add_scalar_impl!(Pnt5, u16, Pnt5AddRhs, x, y, z, w, a)
vec_add_scalar_impl!(Pnt5, u8, Pnt5AddRhs, x, y, z, w, a)
vec_add_scalar_impl!(Pnt5, i64, Pnt5AddRhs, x, y, z, w, a)
vec_add_scalar_impl!(Pnt5, i32, Pnt5AddRhs, x, y, z, w, a)
vec_add_scalar_impl!(Pnt5, i16, Pnt5AddRhs, x, y, z, w, a)
vec_add_scalar_impl!(Pnt5, i8, Pnt5AddRhs, x, y, z, w, a)
vec_add_scalar_impl!(Pnt5, uint, Pnt5AddRhs, x, y, z, w, a)
vec_add_scalar_impl!(Pnt5, int, Pnt5AddRhs, x, y, z, w, a)
vec_sub_scalar_impl!(Pnt5, f64, Pnt5SubRhs, x, y, z, w, a)
vec_sub_scalar_impl!(Pnt5, f32, Pnt5SubRhs, x, y, z, w, a)
vec_sub_scalar_impl!(Pnt5, u64, Pnt5SubRhs, x, y, z, w, a)
vec_sub_scalar_impl!(Pnt5, u32, Pnt5SubRhs, x, y, z, w, a)
vec_sub_scalar_impl!(Pnt5, u16, Pnt5SubRhs, x, y, z, w, a)
vec_sub_scalar_impl!(Pnt5, u8, Pnt5SubRhs, x, y, z, w, a)
vec_sub_scalar_impl!(Pnt5, i64, Pnt5SubRhs, x, y, z, w, a)
vec_sub_scalar_impl!(Pnt5, i32, Pnt5SubRhs, x, y, z, w, a)
vec_sub_scalar_impl!(Pnt5, i16, Pnt5SubRhs, x, y, z, w, a)
vec_sub_scalar_impl!(Pnt5, i8, Pnt5SubRhs, x, y, z, w, a)
vec_sub_scalar_impl!(Pnt5, uint, Pnt5SubRhs, x, y, z, w, a)
vec_sub_scalar_impl!(Pnt5, int, Pnt5SubRhs, x, y, z, w, a)
approx_eq_impl!(Pnt5, x, y, z, w, a)
from_iterator_impl!(Pnt5, iterator, iterator, iterator, iterator, iterator)
bounded_impl!(Pnt5, x, y, z, w, a)
iterable_impl!(Pnt5, 5)
iterable_mut_impl!(Pnt5, 5)
pnt_to_homogeneous_impl!(Pnt5, Pnt6, b, x, y, z, w, a)
pnt_from_homogeneous_impl!(Pnt5, Pnt6, b, x, y, z, w, a)
/// Point of dimension 6.
#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Show)]
pub struct Pnt6<N> {
/// First component of the vector.
pub x: N,
/// Second component of the vector.
pub y: N,
/// Third component of the vector.
pub z: N,
/// Fourth component of the vector.
pub w: N,
/// Fifth of the vector.
pub a: N,
/// Sixth component of the vector.
pub b: N
}
double_dispatch_binop_decl_trait!(Pnt6, Pnt6MulRhs)
double_dispatch_binop_decl_trait!(Pnt6, Pnt6DivRhs)
double_dispatch_binop_decl_trait!(Pnt6, Pnt6AddRhs)
double_dispatch_binop_decl_trait!(Pnt6, Pnt6SubRhs)
double_dispatch_cast_decl_trait!(Pnt6, Pnt6Cast)
mul_redispatch_impl!(Pnt6, Pnt6MulRhs)
div_redispatch_impl!(Pnt6, Pnt6DivRhs)
add_redispatch_impl!(Pnt6, Pnt6AddRhs)
sub_redispatch_impl!(Pnt6, Pnt6SubRhs)
cast_redispatch_impl!(Pnt6, Pnt6Cast)
new_impl!(Pnt6, x, y, z, w, a, b)
orig_impl!(Pnt6, x, y, z, w, a, b)
ord_impl!(Pnt6, x, y, z, w, a, b)
vec_cast_impl!(Pnt6, Pnt6Cast, x, y, z, w, a, b)
as_slice_impl!(Pnt6, 6)
index_impl!(Pnt6)
indexable_impl!(Pnt6, 6)
at_fast_impl!(Pnt6, 6)
new_repeat_impl!(Pnt6, val, x, y, z, w, a, b)
dim_impl!(Pnt6, 6)
container_impl!(Pnt6)
pnt_as_vec_impl!(Pnt6, Vec6)
pnt_sub_impl!(Pnt6, Vec6, Pnt6SubRhs)
neg_impl!(Pnt6, x, y, z, w, a, b)
pnt_add_vec_impl!(Pnt6, Vec6, Pnt6AddRhs, x, y, z, w, a, b)
pnt_sub_vec_impl!(Pnt6, Vec6, Pnt6SubRhs, x, y, z, w, a, b)
vec_mul_scalar_impl!(Pnt6, f64, Pnt6MulRhs, x, y, z, w, a, b)
vec_mul_scalar_impl!(Pnt6, f32, Pnt6MulRhs, x, y, z, w, a, b)
vec_mul_scalar_impl!(Pnt6, u64, Pnt6MulRhs, x, y, z, w, a, b)
vec_mul_scalar_impl!(Pnt6, u32, Pnt6MulRhs, x, y, z, w, a, b)
vec_mul_scalar_impl!(Pnt6, u16, Pnt6MulRhs, x, y, z, w, a, b)
vec_mul_scalar_impl!(Pnt6, u8, Pnt6MulRhs, x, y, z, w, a, b)
vec_mul_scalar_impl!(Pnt6, i64, Pnt6MulRhs, x, y, z, w, a, b)
vec_mul_scalar_impl!(Pnt6, i32, Pnt6MulRhs, x, y, z, w, a, b)
vec_mul_scalar_impl!(Pnt6, i16, Pnt6MulRhs, x, y, z, w, a, b)
vec_mul_scalar_impl!(Pnt6, i8, Pnt6MulRhs, x, y, z, w, a, b)
vec_mul_scalar_impl!(Pnt6, uint, Pnt6MulRhs, x, y, z, w, a, b)
vec_mul_scalar_impl!(Pnt6, int, Pnt6MulRhs, x, y, z, w, a, b)
vec_div_scalar_impl!(Pnt6, f64, Pnt6DivRhs, x, y, z, w, a, b)
vec_div_scalar_impl!(Pnt6, f32, Pnt6DivRhs, x, y, z, w, a, b)
vec_div_scalar_impl!(Pnt6, u64, Pnt6DivRhs, x, y, z, w, a, b)
vec_div_scalar_impl!(Pnt6, u32, Pnt6DivRhs, x, y, z, w, a, b)
vec_div_scalar_impl!(Pnt6, u16, Pnt6DivRhs, x, y, z, w, a, b)
vec_div_scalar_impl!(Pnt6, u8, Pnt6DivRhs, x, y, z, w, a, b)
vec_div_scalar_impl!(Pnt6, i64, Pnt6DivRhs, x, y, z, w, a, b)
vec_div_scalar_impl!(Pnt6, i32, Pnt6DivRhs, x, y, z, w, a, b)
vec_div_scalar_impl!(Pnt6, i16, Pnt6DivRhs, x, y, z, w, a, b)
vec_div_scalar_impl!(Pnt6, i8, Pnt6DivRhs, x, y, z, w, a, b)
vec_div_scalar_impl!(Pnt6, uint, Pnt6DivRhs, x, y, z, w, a, b)
vec_div_scalar_impl!(Pnt6, int, Pnt6DivRhs, x, y, z, w, a, b)
vec_add_scalar_impl!(Pnt6, f64, Pnt6AddRhs, x, y, z, w, a, b)
vec_add_scalar_impl!(Pnt6, f32, Pnt6AddRhs, x, y, z, w, a, b)
vec_add_scalar_impl!(Pnt6, u64, Pnt6AddRhs, x, y, z, w, a, b)
vec_add_scalar_impl!(Pnt6, u32, Pnt6AddRhs, x, y, z, w, a, b)
vec_add_scalar_impl!(Pnt6, u16, Pnt6AddRhs, x, y, z, w, a, b)
vec_add_scalar_impl!(Pnt6, u8, Pnt6AddRhs, x, y, z, w, a, b)
vec_add_scalar_impl!(Pnt6, i64, Pnt6AddRhs, x, y, z, w, a, b)
vec_add_scalar_impl!(Pnt6, i32, Pnt6AddRhs, x, y, z, w, a, b)
vec_add_scalar_impl!(Pnt6, i16, Pnt6AddRhs, x, y, z, w, a, b)
vec_add_scalar_impl!(Pnt6, i8, Pnt6AddRhs, x, y, z, w, a, b)
vec_add_scalar_impl!(Pnt6, uint, Pnt6AddRhs, x, y, z, w, a, b)
vec_add_scalar_impl!(Pnt6, int, Pnt6AddRhs, x, y, z, w, a, b)
vec_sub_scalar_impl!(Pnt6, f64, Pnt6SubRhs, x, y, z, w, a, b)
vec_sub_scalar_impl!(Pnt6, f32, Pnt6SubRhs, x, y, z, w, a, b)
vec_sub_scalar_impl!(Pnt6, u64, Pnt6SubRhs, x, y, z, w, a, b)
vec_sub_scalar_impl!(Pnt6, u32, Pnt6SubRhs, x, y, z, w, a, b)
vec_sub_scalar_impl!(Pnt6, u16, Pnt6SubRhs, x, y, z, w, a, b)
vec_sub_scalar_impl!(Pnt6, u8, Pnt6SubRhs, x, y, z, w, a, b)
vec_sub_scalar_impl!(Pnt6, i64, Pnt6SubRhs, x, y, z, w, a, b)
vec_sub_scalar_impl!(Pnt6, i32, Pnt6SubRhs, x, y, z, w, a, b)
vec_sub_scalar_impl!(Pnt6, i16, Pnt6SubRhs, x, y, z, w, a, b)
vec_sub_scalar_impl!(Pnt6, i8, Pnt6SubRhs, x, y, z, w, a, b)
vec_sub_scalar_impl!(Pnt6, uint, Pnt6SubRhs, x, y, z, w, a, b)
vec_sub_scalar_impl!(Pnt6, int, Pnt6SubRhs, x, y, z, w, a, b)
approx_eq_impl!(Pnt6, x, y, z, w, a, b)
from_iterator_impl!(Pnt6, iterator, iterator, iterator, iterator, iterator, iterator)
iterable_impl!(Pnt6, 6)
iterable_mut_impl!(Pnt6, 6)

104
src/structs/pnt_macros.rs Normal file
View File

@ -0,0 +1,104 @@
#![macro_escape]
macro_rules! orig_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Zero> Orig for $t<N> {
#[inline]
fn orig() -> $t<N> {
$t {
$comp0: Zero::zero()
$(, $compN: Zero::zero() )*
}
}
#[inline]
fn is_orig(&self) -> bool {
self.$comp0.is_zero() $(&& self.$compN.is_zero() )*
}
}
)
)
macro_rules! pnt_sub_impl(
($t: ident, $tv: ident, $trhs: ident) => (
impl<N: Sub<N, N>> $trhs<N, $tv<N>> for $t<N> {
#[inline]
fn binop(left: &$t<N>, right: &$t<N>) -> $tv<N> {
*left.as_vec() - *right.as_vec()
}
}
)
)
macro_rules! pnt_add_vec_impl(
($t: ident, $tv: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Add<N, N>> $trhs<N, $t<N>> for $tv<N> {
#[inline]
fn binop(left: &$t<N>, right: &$tv<N>) -> $t<N> {
$t::new(left.$comp0 + right.$comp0 $(, left.$compN + right.$compN)*)
}
}
)
)
macro_rules! pnt_sub_vec_impl(
($t: ident, $tv: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Sub<N, N>> $trhs<N, $t<N>> for $tv<N> {
#[inline]
fn binop(left: &$t<N>, right: &$tv<N>) -> $t<N> {
$t::new(left.$comp0 - right.$comp0 $(, left.$compN - right.$compN)*)
}
}
)
)
macro_rules! pnt_as_vec_impl(
($t: ident, $tv: ident) => (
impl<N> $t<N> {
#[inline]
pub fn as_vec<'a>(&'a self) -> &'a $tv<N> {
unsafe {
mem::transmute(self)
}
}
}
impl<N> PntAsVec<$tv<N>> for $t<N> {
#[inline]
fn as_vec<'a>(&'a self) -> &'a $tv<N> {
self.as_vec()
}
}
)
)
macro_rules! pnt_to_homogeneous_impl(
($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + One + Zero> ToHomogeneous<$t2<N>> for $t<N> {
fn to_homogeneous(v: &$t<N>) -> $t2<N> {
let mut res: $t2<N> = Orig::orig();
res.$comp0 = v.$comp0.clone();
$( res.$compN = v.$compN.clone(); )*
res.$extra = One::one();
res
}
}
)
)
macro_rules! pnt_from_homogeneous_impl(
($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + Div<N, N> + One + Zero> FromHomogeneous<$t2<N>> for $t<N> {
fn from(v: &$t2<N>) -> $t<N> {
let mut res: $t<N> = Orig::orig();
res.$comp0 = v.$comp0.clone() / v.$extra;
$( res.$compN = v.$compN.clone() / v.$extra; )*
res
}
}
)
)

View File

@ -9,6 +9,7 @@ use traits::geometry::{Rotate, Rotation, AbsoluteRotate, RotationMatrix, Transfo
use traits::structure::{Cast, Dim, Row, Col};
use traits::operations::{Absolute, Inv, Transpose, ApproxEq};
use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec2MulRhs, Vec3MulRhs, Vec4MulRhs};
use structs::pnt::{Pnt2, Pnt3, Pnt4, Pnt2MulRhs, Pnt3MulRhs, Pnt4MulRhs};
use structs::mat::{Mat2, Mat3, Mat4, Mat5};
@ -29,8 +30,7 @@ impl<N: Clone + FloatMath + Neg<N>> Rot2<N> {
}
}
impl<N: FloatMath + Clone>
Rotation<Vec1<N>> for Rot2<N> {
impl<N: FloatMath + Clone> Rotation<Vec1<N>> for Rot2<N> {
#[inline]
fn rotation(&self) -> Vec1<N> {
Vec1::new((-self.submat.m12).atan2(self.submat.m11.clone()))
@ -353,12 +353,14 @@ Rotation<Vec4<N>> for Rot4<N> {
double_dispatch_binop_decl_trait!(Rot2, Rot2MulRhs)
mul_redispatch_impl!(Rot2, Rot2MulRhs)
submat_impl!(Rot2, Mat2)
rotate_impl!(Rot2, Vec2)
transform_impl!(Rot2, Vec2)
rotate_impl!(Rot2RotateRhs, Rot2, Vec2, Pnt2)
transform_impl!(Rot2TransformRhs, Rot2, Vec2, Pnt2)
dim_impl!(Rot2, 2)
rot_mul_rot_impl!(Rot2, Rot2MulRhs)
rot_mul_vec_impl!(Rot2, Vec2, Rot2MulRhs)
vec_mul_rot_impl!(Rot2, Vec2, Vec2MulRhs)
rot_mul_pnt_impl!(Rot2, Pnt2, Rot2MulRhs)
pnt_mul_rot_impl!(Rot2, Pnt2, Pnt2MulRhs)
one_impl!(Rot2)
rotation_matrix_impl!(Rot2, Vec2, Vec1)
col_impl!(Rot2, Vec2)
@ -373,12 +375,14 @@ approx_eq_impl!(Rot2)
double_dispatch_binop_decl_trait!(Rot3, Rot3MulRhs)
mul_redispatch_impl!(Rot3, Rot3MulRhs)
submat_impl!(Rot3, Mat3)
rotate_impl!(Rot3, Vec3)
transform_impl!(Rot3, Vec3)
rotate_impl!(Rot3RotateRhs, Rot3, Vec3, Pnt3)
transform_impl!(Rot3TransformRhs, Rot3, Vec3, Pnt3)
dim_impl!(Rot3, 3)
rot_mul_rot_impl!(Rot3, Rot3MulRhs)
rot_mul_vec_impl!(Rot3, Vec3, Rot3MulRhs)
vec_mul_rot_impl!(Rot3, Vec3, Vec3MulRhs)
rot_mul_pnt_impl!(Rot3, Pnt3, Rot3MulRhs)
pnt_mul_rot_impl!(Rot3, Pnt3, Pnt3MulRhs)
one_impl!(Rot3)
rotation_matrix_impl!(Rot3, Vec3, Vec3)
col_impl!(Rot3, Vec3)
@ -393,12 +397,14 @@ approx_eq_impl!(Rot3)
double_dispatch_binop_decl_trait!(Rot4, Rot4MulRhs)
mul_redispatch_impl!(Rot4, Rot4MulRhs)
submat_impl!(Rot4, Mat4)
rotate_impl!(Rot4, Vec4)
transform_impl!(Rot4, Vec4)
rotate_impl!(Rot4RotateRhs, Rot4, Vec4, Pnt4)
transform_impl!(Rot4TransformRhs, Rot4, Vec4, Pnt4)
dim_impl!(Rot4, 4)
rot_mul_rot_impl!(Rot4, Rot4MulRhs)
rot_mul_vec_impl!(Rot4, Vec4, Rot4MulRhs)
vec_mul_rot_impl!(Rot4, Vec4, Vec4MulRhs)
rot_mul_pnt_impl!(Rot4, Pnt4, Rot4MulRhs)
pnt_mul_rot_impl!(Rot4, Pnt4, Pnt4MulRhs)
one_impl!(Rot4)
rotation_matrix_impl!(Rot4, Vec4, Vec4)
col_impl!(Rot4, Vec4)

View File

@ -12,32 +12,98 @@ macro_rules! submat_impl(
)
macro_rules! rotate_impl(
($t: ident, $tv: ident) => (
impl<N: Num + Clone> Rotate<$tv<N>> for $t<N> {
($trhs: ident, $t: ident, $tv: ident, $tp: ident) => (
/*
* FIXME: we use the double dispatch trick here so that we can rotate vectors _and_
* points. Remove this as soon as rust supports multidispatch.
*/
pub trait $trhs<N> {
fn rotate(left: &$t<N>, right: &Self) -> Self;
fn inv_rotate(left: &$t<N>, right: &Self) -> Self;
}
impl<N, V: $trhs<N>> Rotate<V> for $t<N> {
#[inline(always)]
fn rotate(&self, other: &V) -> V {
$trhs::rotate(self, other)
}
#[inline(always)]
fn inv_rotate(&self, other: &V) -> V {
$trhs::inv_rotate(self, other)
}
}
impl<N: Num + Clone> $trhs<N> for $tv<N> {
#[inline]
fn rotate(&self, v: &$tv<N>) -> $tv<N> {
self * *v
fn rotate(t: &$t<N>, v: &$tv<N>) -> $tv<N> {
t * *v
}
#[inline]
fn inv_rotate(&self, v: &$tv<N>) -> $tv<N> {
v * *self
fn inv_rotate(t: &$t<N>, v: &$tv<N>) -> $tv<N> {
v * *t
}
}
impl<N: Num + Clone> $trhs<N> for $tp<N> {
#[inline]
fn rotate(t: &$t<N>, p: &$tp<N>) -> $tp<N> {
t * *p
}
#[inline]
fn inv_rotate(t: &$t<N>, p: &$tp<N>) -> $tp<N> {
p * *t
}
}
)
)
macro_rules! transform_impl(
($t: ident, $tv: ident) => (
impl<N: Num + Clone> Transform<$tv<N>> for $t<N> {
($trhs: ident, $t: ident, $tv: ident, $tp: ident) => (
/*
* FIXME: we use the double dispatch trick here so that we can transform vectors _and_
* points. Remove this as soon as rust supports multidispatch.
*/
pub trait $trhs<N> {
fn transform(left: &$t<N>, right: &Self) -> Self;
fn inv_transform(left: &$t<N>, right: &Self) -> Self;
}
impl<N, V: $trhs<N>> Transform<V> for $t<N> {
#[inline(always)]
fn transform(&self, other: &V) -> V {
$trhs::transform(self, other)
}
#[inline(always)]
fn inv_transform(&self, other: &V) -> V {
$trhs::inv_transform(self, other)
}
}
impl<N: Num + Clone> $trhs<N> for $tv<N> {
#[inline]
fn transform(&self, v: &$tv<N>) -> $tv<N> {
self.rotate(v)
fn transform(t: &$t<N>, v: &$tv<N>) -> $tv<N> {
t.rotate(v)
}
#[inline]
fn inv_transform(&self, v: &$tv<N>) -> $tv<N> {
self.inv_rotate(v)
fn inv_transform(t: &$t<N>, v: &$tv<N>) -> $tv<N> {
t.inv_rotate(v)
}
}
impl<N: Num + Clone> $trhs<N> for $tp<N> {
#[inline]
fn transform(t: &$t<N>, p: &$tp<N>) -> $tp<N> {
t.rotate(p)
}
#[inline]
fn inv_transform(t: &$t<N>, p: &$tp<N>) -> $tp<N> {
t.inv_rotate(p)
}
}
)
@ -99,6 +165,12 @@ macro_rules! rot_mul_vec_impl(
)
)
macro_rules! rot_mul_pnt_impl(
($t: ident, $tv: ident, $mulrhs: ident) => (
rot_mul_vec_impl!($t, $tv, $mulrhs)
)
)
macro_rules! vec_mul_rot_impl(
($t: ident, $tv: ident, $mulrhs: ident) => (
impl<N: Num + Clone> $mulrhs<N, $tv<N>> for $t<N> {
@ -110,6 +182,12 @@ macro_rules! vec_mul_rot_impl(
)
)
macro_rules! pnt_mul_rot_impl(
($t: ident, $tv: ident, $mulrhs: ident) => (
vec_mul_rot_impl!($t, $tv, $mulrhs)
)
)
macro_rules! inv_impl(
($t: ident) => (
impl<N: Clone> Inv for $t<N> {

View File

@ -1,5 +1,6 @@
use std::num::{Zero, One};
use structs::vec::{Vec2, Vec3, Vec2MulRhs, Vec3MulRhs};
use structs::pnt::{Pnt2, Pnt3, Pnt2MulRhs, Pnt3MulRhs};
use structs::mat::{Mat1, Mat2, Mat3, Mat3MulRhs, Mat2MulRhs};
use traits::operations::{Inv, Det, ApproxEq};
use traits::structure::{Row, Col};
@ -284,3 +285,45 @@ impl<N: Mul<N, N> + Add<N, N>> Mat2MulRhs<N, Vec2<N>> for Vec2<N> {
)
}
}
impl<N: Mul<N, N> + Add<N, N>> Mat3MulRhs<N, Pnt3<N>> for Pnt3<N> {
#[inline(always)]
fn binop(left: &Mat3<N>, right: &Pnt3<N>) -> Pnt3<N> {
Pnt3::new(
left.m11 * right.x + left.m12 * right.y + left.m13 * right.z,
left.m21 * right.x + left.m22 * right.y + left.m23 * right.z,
left.m31 * right.x + left.m32 * right.y + left.m33 * right.z
)
}
}
impl<N: Mul<N, N> + Add<N, N>> Pnt3MulRhs<N, Pnt3<N>> for Mat3<N> {
#[inline(always)]
fn binop(left: &Pnt3<N>, right: &Mat3<N>) -> Pnt3<N> {
Pnt3::new(
left.x * right.m11 + left.y * right.m21 + left.z * right.m31,
left.x * right.m12 + left.y * right.m22 + left.z * right.m32,
left.x * right.m13 + left.y * right.m23 + left.z * right.m33
)
}
}
impl<N: Mul<N, N> + Add<N, N>> Pnt2MulRhs<N, Pnt2<N>> for Mat2<N> {
#[inline(always)]
fn binop(left: &Pnt2<N>, right: &Mat2<N>) -> Pnt2<N> {
Pnt2::new(
left.x * right.m11 + left.y * right.m21,
left.x * right.m12 + left.y * right.m22
)
}
}
impl<N: Mul<N, N> + Add<N, N>> Mat2MulRhs<N, Pnt2<N>> for Pnt2<N> {
#[inline(always)]
fn binop(left: &Mat2<N>, right: &Pnt2<N>) -> Pnt2<N> {
Pnt2::new(
left.m11 * right.x + left.m12 * right.y,
left.m21 * right.x + left.m22 * right.y
)
}
}

View File

@ -91,11 +91,6 @@ impl<N: Num> Dot<N> for vec::Vec0<N> {
fn dot(_: &vec::Vec0<N>, _: &vec::Vec0<N>) -> N {
Zero::zero()
}
#[inline]
fn sub_dot(_: &vec::Vec0<N>, _: &vec::Vec0<N>, _: &vec::Vec0<N>) -> N {
Zero::zero()
}
}
impl<N, T> Mul<T, vec::Vec0<N>> for vec::Vec0<N> {

View File

@ -10,7 +10,8 @@ use traits::operations::{ApproxEq, PartialOrd, PartialOrdering, PartialLess, Par
PartialGreater, NotComparable};
use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm,
Translation, Translate};
use traits::structure::{Basis, Cast, Dim, Indexable, Iterable, IterableMut};
use traits::structure::{Basis, Cast, Dim, Indexable, Iterable, IterableMut, VecAsPnt};
use structs::pnt::{Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6};
/// Vector of dimension 0.
@ -124,9 +125,11 @@ iterable_impl!(Vec1, 1)
iterable_mut_impl!(Vec1, 1)
to_homogeneous_impl!(Vec1, Vec2, y, x)
from_homogeneous_impl!(Vec1, Vec2, y, x)
translate_impl!(Vec1)
translate_impl!(Vec1, Pnt1)
rotate_impl!(Vec1)
transform_impl!(Vec1)
rotate_impl!(Pnt1)
transform_impl!(Vec1, Pnt1)
vec_as_pnt_impl!(Vec1, Pnt1)
/// Vector of dimension 2.
#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Zero, Show)]
@ -223,9 +226,11 @@ iterable_impl!(Vec2, 2)
iterable_mut_impl!(Vec2, 2)
to_homogeneous_impl!(Vec2, Vec3, z, x, y)
from_homogeneous_impl!(Vec2, Vec3, z, x, y)
translate_impl!(Vec2)
translate_impl!(Vec2, Pnt2)
rotate_impl!(Vec2)
transform_impl!(Vec2)
rotate_impl!(Pnt2)
transform_impl!(Vec2, Pnt2)
vec_as_pnt_impl!(Vec2, Pnt2)
/// Vector of dimension 3.
#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Zero, Show)]
@ -327,9 +332,11 @@ iterable_impl!(Vec3, 3)
iterable_mut_impl!(Vec3, 3)
to_homogeneous_impl!(Vec3, Vec4, w, x, y, z)
from_homogeneous_impl!(Vec3, Vec4, w, x, y, z)
translate_impl!(Vec3)
translate_impl!(Vec3, Pnt3)
rotate_impl!(Vec3)
transform_impl!(Vec3)
rotate_impl!(Pnt3)
transform_impl!(Vec3, Pnt3)
vec_as_pnt_impl!(Vec3, Pnt3)
/// Vector of dimension 4.
@ -431,9 +438,11 @@ iterable_impl!(Vec4, 4)
iterable_mut_impl!(Vec4, 4)
to_homogeneous_impl!(Vec4, Vec5, a, x, y, z, w)
from_homogeneous_impl!(Vec4, Vec5, a, x, y, z, w)
translate_impl!(Vec4)
translate_impl!(Vec4, Pnt4)
rotate_impl!(Vec4)
transform_impl!(Vec4)
rotate_impl!(Pnt4)
transform_impl!(Vec4, Pnt4)
vec_as_pnt_impl!(Vec4, Pnt4)
/// Vector of dimension 5.
#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Zero, Show)]
@ -536,9 +545,11 @@ iterable_impl!(Vec5, 5)
iterable_mut_impl!(Vec5, 5)
to_homogeneous_impl!(Vec5, Vec6, b, x, y, z, w, a)
from_homogeneous_impl!(Vec5, Vec6, b, x, y, z, w, a)
translate_impl!(Vec5)
translate_impl!(Vec5, Pnt5)
rotate_impl!(Vec5)
transform_impl!(Vec5)
rotate_impl!(Pnt5)
transform_impl!(Vec5, Pnt5)
vec_as_pnt_impl!(Vec5, Pnt5)
/// Vector of dimension 6.
#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Zero, Show)]
@ -641,6 +652,8 @@ from_iterator_impl!(Vec6, iterator, iterator, iterator, iterator, iterator, iter
bounded_impl!(Vec6, x, y, z, w, a, b)
iterable_impl!(Vec6, 6)
iterable_mut_impl!(Vec6, 6)
translate_impl!(Vec6)
translate_impl!(Vec6, Pnt6)
rotate_impl!(Vec6)
transform_impl!(Vec6)
rotate_impl!(Pnt6)
transform_impl!(Vec6, Pnt6)
vec_as_pnt_impl!(Vec6, Pnt6)

View File

@ -405,11 +405,6 @@ macro_rules! dot_impl(
fn dot(a: &$t<N>, b: &$t<N>) -> N {
a.$comp0 * b.$comp0 $(+ a.$compN * b.$compN )*
}
#[inline]
fn sub_dot(a: &$t<N>, b: &$t<N>, c: &$t<N>) -> N {
(a.$comp0 - b.$comp0) * c.$comp0 $(+ (a.$compN - b.$compN) * c.$compN )*
}
}
)
)
@ -608,7 +603,7 @@ macro_rules! to_homogeneous_impl(
($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + One + Zero> ToHomogeneous<$t2<N>> for $t<N> {
fn to_homogeneous(v: &$t<N>) -> $t2<N> {
let mut res: $t2<N> = One::one();
let mut res: $t2<N> = Zero::zero();
res.$comp0 = v.$comp0.clone();
$( res.$compN = v.$compN.clone(); )*
@ -625,8 +620,8 @@ macro_rules! from_homogeneous_impl(
fn from(v: &$t2<N>) -> $t<N> {
let mut res: $t<N> = Zero::zero();
res.$comp0 = v.$comp0.clone() / v.$extra;
$( res.$compN = v.$compN.clone() / v.$extra; )*
res.$comp0 = v.$comp0.clone();
$( res.$compN = v.$compN.clone(); )*
res
}
@ -635,8 +630,8 @@ macro_rules! from_homogeneous_impl(
)
macro_rules! translate_impl(
($t: ident) => (
impl<N: Add<N, N> + Sub<N, N>> Translate<$t<N>> for $t<N> {
($tv: ident, $t: ident) => (
impl<N: Add<N, N> + Sub<N, N>> Translate<$t<N>> for $tv<N> {
fn translate(&self, other: &$t<N>) -> $t<N> {
*other + *self
}
@ -663,8 +658,8 @@ macro_rules! rotate_impl(
)
macro_rules! transform_impl(
($t: ident) => (
impl<N: Clone + Add<N, N> + Sub<N, N>> Transform<$t<N>> for $t<N> {
($tv: ident, $t: ident) => (
impl<N: Clone + Add<N, N> + Sub<N, N>> Transform<$t<N>> for $tv<N> {
fn transform(&self, other: &$t<N>) -> $t<N> {
self.translate(other)
}
@ -673,5 +668,35 @@ macro_rules! transform_impl(
self.inv_translate(other)
}
}
impl<N: Clone> Transform<$tv<N>> for $tv<N> {
fn transform(&self, other: &$tv<N>) -> $tv<N> {
other.clone()
}
fn inv_transform(&self, other: &$tv<N>) -> $tv<N> {
other.clone()
}
}
)
)
macro_rules! vec_as_pnt_impl(
($tv: ident, $t: ident) => (
impl<N> $tv<N> {
#[inline]
pub fn as_pnt<'a>(&'a self) -> &'a $t<N> {
unsafe {
mem::transmute(self)
}
}
}
impl<N> VecAsPnt<$t<N>> for $tv<N> {
#[inline]
fn as_pnt<'a>(&'a self) -> &'a $t<N> {
self.as_pnt()
}
}
)
)

View File

@ -202,19 +202,6 @@ pub trait Dot<N> {
/// Computes the dot (inner) product of two vectors.
#[inline]
fn dot(&Self, &Self) -> N;
/**
* Short-cut to compute the projection of a point on a vector, but without
* computing intermediate vectors.
* The following equation must be verified:
*
* ```.ignore
* a.sub_dot(b, c) == (a - b).dot(c)
* ```
*
*/
#[inline]
fn sub_dot(a: &Self, b: &Self, c: &Self) -> N;
}
/// Traits of objects having an euclidian norm.
@ -280,3 +267,21 @@ pub trait UniformSphereSample {
/// Iterate through the samples.
fn sample(|Self| -> ());
}
/// The zero element of a vector space, seen as an element of its embeding affine space.
// XXX: once associated types are suported, move this to the `AnyPnt` trait.
pub trait Orig {
/// The trivial origin.
fn orig() -> Self;
/// Returns true if this points is exactly the trivial origin.
fn is_orig(&self) -> bool;
}
/// Trait implemented by projectors.
// XXX: Vout should be an associated type instead of a type parameter.
pub trait Projector<Vin, Vout> {
/// Projects an element of a vector or affine space to a subspace.
///
/// This must be an indempotent operaton.
fn project(&self, &Vin) -> Vout;
}

View File

@ -1,12 +1,13 @@
//! Mathematical traits.
pub use self::geometry::{AbsoluteRotate, Cross, CrossMatrix, Dot, FromHomogeneous, Norm, Rotate,
Rotation, RotationMatrix, RotationWithTranslation, ToHomogeneous,
Transform, Transformation, Translate, Translation, UniformSphereSample};
pub use self::geometry::{AbsoluteRotate, Cross, CrossMatrix, Dot, FromHomogeneous, Norm, Orig,
Projector, Rotate, Rotation, RotationMatrix, RotationWithTranslation,
ToHomogeneous, Transform, Transformation, Translate, Translation,
UniformSphereSample};
pub use self::structure::{FloatVec, FloatVecExt, Basis, Cast, Col, Dim, Indexable,
Iterable, IterableMut, Mat, Row, AnyVec, VecExt,
ColSlice, RowSlice, Diag, Eye};
pub use self::structure::{FloatVec, FloatVecExt, FloatPnt, FloatPntExt, Basis, Cast, Col, Dim,
Indexable, Iterable, IterableMut, Mat, Row, AnyVec, VecExt, AnyPnt,
PntExt, PntAsVec, VecAsPnt, ColSlice, RowSlice, Diag, Eye};
pub use self::operations::{Absolute, ApproxEq, Cov, Det, Inv, LMul, Mean, Outer, PartialOrd, RMul,
ScalarAdd, ScalarSub, ScalarMul, ScalarDiv, Transpose};

View File

@ -3,7 +3,7 @@
use std::num::{Zero, Bounded};
use std::slice::{Items, MutItems};
use traits::operations::{RMul, LMul, ScalarAdd, ScalarSub};
use traits::geometry::{Dot, Norm, UniformSphereSample};
use traits::geometry::{Dot, Norm, UniformSphereSample, Orig};
/// Traits of objects which can be created from an object of type `T`.
pub trait Cast<T> {
@ -28,37 +28,6 @@ pub trait Eye {
// XXX: we keep ScalarAdd and ScalarSub here to avoid trait impl conflict (overriding) between the
// different Add/Sub traits. This is _so_ unfortunate…
/// Trait grouping most common operations on vectors.
pub trait AnyVec<N>: Dim + Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Zero + PartialEq + Mul<N, Self>
+ Div<N, Self> + Dot<N> {
}
/// Trait of vector with components implementing the `Float` trait.
pub trait FloatVec<N: Float>: AnyVec<N> + Norm<N> {
}
/// Trait grouping uncommon, low-level and borderline (from the mathematical point of view)
/// operations on vectors.
pub trait VecExt<N>: AnyVec<N> + Indexable<uint, N> + Iterable<N> +
UniformSphereSample + ScalarAdd<N> + ScalarSub<N> + Bounded
{ }
/// Trait grouping uncommon, low-level and borderline (from the mathematical point of view)
/// operations on vectors.
pub trait FloatVecExt<N: Float>: FloatVec<N> + VecExt<N> + Basis { }
impl<N, V: Dim + Sub<V, V> + Add<V, V> + Neg<V> + Zero + PartialEq + Mul<N, V> + Div<N, V> + Dot<N>>
AnyVec<N> for V { }
impl<N: Float, V: AnyVec<N> + Norm<N>> FloatVec<N> for V { }
impl<N,
V: AnyVec<N> + Indexable<uint, N> + Iterable<N> +
UniformSphereSample + ScalarAdd<N> + ScalarSub<N> + Bounded>
VecExt<N> for V { }
impl<N: Float, V: FloatVec<N> + VecExt<N> + Basis> FloatVecExt<N> for V { }
// FIXME: return an iterator instead
/// Traits of objects which can form a basis (typically vectors).
pub trait Basis {
@ -172,3 +141,92 @@ pub trait IterableMut<N> {
/// Gets a vector-like read-write iterator.
fn mut_iter<'l>(&'l mut self) -> MutItems<'l, N>;
}
/*
* Vec related traits.
*/
/// Trait that relates a point of an affine space to a vector of the associated vector space.
pub trait VecAsPnt<P> {
/// Converts a reference to this point to a reference to its associated vector.
fn as_pnt<'a>(&'a self) -> &'a P;
}
/// Trait grouping most common operations on vectors.
pub trait AnyVec<N>: Dim + Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Zero + PartialEq + Mul<N, Self>
+ Div<N, Self> + Dot<N> {
}
/// Trait of vector with components implementing the `Float` trait.
pub trait FloatVec<N: Float>: AnyVec<N> + Norm<N> {
}
/// Trait grouping uncommon, low-level and borderline (from the mathematical point of view)
/// operations on vectors.
pub trait VecExt<N>: AnyVec<N> + Indexable<uint, N> + Iterable<N> +
UniformSphereSample + ScalarAdd<N> + ScalarSub<N> + Bounded
{ }
/// Trait grouping uncommon, low-level and borderline (from the mathematical point of view)
/// operations on vectors.
pub trait FloatVecExt<N: Float>: FloatVec<N> + VecExt<N> + Basis { }
impl<N, V: Dim + Sub<V, V> + Add<V, V> + Neg<V> + Zero + PartialEq + Mul<N, V> + Div<N, V> + Dot<N>>
AnyVec<N> for V { }
impl<N: Float, V: AnyVec<N> + Norm<N>> FloatVec<N> for V { }
impl<N,
V: AnyVec<N> + Indexable<uint, N> + Iterable<N> +
UniformSphereSample + ScalarAdd<N> + ScalarSub<N> + Bounded>
VecExt<N> for V { }
impl<N: Float, V: FloatVec<N> + VecExt<N> + Basis> FloatVecExt<N> for V { }
/*
* Pnt related traits.
*/
/// Trait that relates a point of an affine space to a vector of the associated vector space.
pub trait PntAsVec<V> {
/// Converts a reference to this point to a reference to its associated vector.
fn as_vec<'a>(&'a self) -> &'a V;
}
/// Trait grouping most common operations on points.
// XXX: the vector space element `V` should be an associated type. Though this would prevent V from
// having bounds (they are not supported yet). So, for now, we will just use a type parameter.
pub trait AnyPnt<N, V>:
PntAsVec<V> + Dim + Sub<Self, V> + Orig + Neg<Self> + PartialEq + Mul<N, Self> + Div<N, Self> {
}
/// Trait of points with components implementing the `Float` trait.
pub trait FloatPnt<N: Float, V: Norm<N>>: AnyPnt<N, V> {
/// Computes the square distance between two points.
#[inline]
fn sqdist(a: &Self, b: &Self) -> N {
Norm::sqnorm(&(*a - *b))
}
/// Computes the distance between two points.
#[inline]
fn dist(a: &Self, b: &Self) -> N {
Norm::norm(&(*a - *b))
}
}
/// Trait grouping uncommon, low-level and borderline (from the mathematical point of view)
/// operations on points.
pub trait PntExt<N, V>: AnyPnt<N, V> + Indexable<uint, N> + Iterable<N> +
ScalarAdd<N> + ScalarSub<N> + Bounded
{ }
/// Trait grouping uncommon, low-level and borderline (from the mathematical point of view)
/// operations on points.
pub trait FloatPntExt<N: Float, V: Norm<N>> : FloatPnt<N, V> + PntExt<N, V> { }
impl<N, V, P: PntAsVec<V> + Dim + Sub<P, V> + Orig + Neg<P> + PartialEq + Mul<N, P> + Div<N, P>>
AnyPnt<N, V> for P { }
impl<N: Float, V: Norm<N>, P: AnyPnt<N, V>> FloatPnt<N, V> for P { }
impl<N, V, P: AnyPnt<N, V> + Indexable<uint, N> + Iterable<N> + ScalarAdd<N> + ScalarSub<N> + Bounded>
PntExt<N, V> for P { }
impl<N: Float, V: Norm<N>, P: FloatPnt<N, V> + PntExt<N, V>> FloatPntExt<N, V> for P { }