Macro groupping.

This commit is contained in:
Sébastien Crozet 2016-07-23 20:57:28 +02:00
parent 7b4a57c224
commit 88a74ca4e5
25 changed files with 1790 additions and 2672 deletions

View File

@ -13,6 +13,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- `.set_col` -> `.set_column` - `.set_col` -> `.set_column`
- `::canonical_basis_with_dim` -> `::canonical_basis_with_dimension` - `::canonical_basis_with_dim` -> `::canonical_basis_with_dimension`
- `::from_elem` -> `::from_element` - `::from_elem` -> `::from_element`
- `DiagMut` -> `DiagonalMut`
* Added: * Added:
- Added `.exp()` and `.pow()` for quaternions. - Added `.exp()` and `.pow()` for quaternions.

View File

@ -1,6 +1,6 @@
[package] [package]
name = "nalgebra" name = "nalgebra"
version = "0.8.2" version = "0.9.0"
authors = [ "Sébastien Crozet <developer@crozet.re>" ] # FIXME: add the contributors. authors = [ "Sébastien Crozet <developer@crozet.re>" ] # FIXME: add the contributors.
description = "Linear algebra library for computer physics, computer graphics and general low-dimensional linear algebra for Rust." description = "Linear algebra library for computer physics, computer graphics and general low-dimensional linear algebra for Rust."

View File

@ -63,6 +63,13 @@ bench_unop!(_bench_vec4_normalize, Vector4<f32>, normalize);
#[cfg(feature = "generic_sizes")] #[cfg(feature = "generic_sizes")]
mod bench_vecn { mod bench_vecn {
extern crate test;
extern crate rand;
extern crate nalgebra as na;
use rand::{IsaacRng, Rng};
use test::Bencher;
use std::ops::{Add, Sub, Mul, Div};
use typenum::{U2, U3, U4}; use typenum::{U2, U3, U4};
use na::VectorN; use na::VectorN;

View File

@ -1,5 +1,5 @@
use traits::operations::{Transpose, ApproxEq}; use traits::operations::{Transpose, ApproxEq};
use traits::structure::{ColumnSlice, Eye, Indexable, Diagonal, SquareMatrix, BaseFloat, Cast}; use traits::structure::{ColumnSlice, Eye, Indexable, SquareMatrix, BaseFloat, Cast};
use traits::geometry::Norm; use traits::geometry::Norm;
use std::cmp; use std::cmp;
use std::ops::{Mul, Add, Sub}; use std::ops::{Mul, Add, Sub};

View File

@ -0,0 +1,351 @@
#![macro_use]
macro_rules! pointwise_mul(
($t: ident, $($compN: ident),+) => (
impl<N: Mul<N, Output = N>> Mul<$t<N>> for $t<N> {
type Output = $t<N>;
#[inline]
fn mul(self, right: $t<N>) -> $t<N> {
$t::new($(self.$compN * right.$compN),+)
}
}
impl<N: MulAssign<N>> MulAssign<$t<N>> for $t<N> {
#[inline]
fn mul_assign(&mut self, right: $t<N>) {
$( self.$compN *= right.$compN; )+
}
}
)
);
macro_rules! pointwise_div(
($t: ident, $($compN: ident),+) => (
impl<N: Div<N, Output = N>> Div<$t<N>> for $t<N> {
type Output = $t<N>;
#[inline]
fn div(self, right: $t<N>) -> $t<N> {
$t::new($(self.$compN / right.$compN),+)
}
}
impl<N: DivAssign<N>> DivAssign<$t<N>> for $t<N> {
#[inline]
fn div_assign(&mut self, right: $t<N>) {
$( self.$compN /= right.$compN; )+
}
}
)
);
macro_rules! pointwise_add(
($t: ident, $($compN: ident),+) => (
impl<N: Add<N, Output = N>> Add<$t<N>> for $t<N> {
type Output = $t<N>;
#[inline]
fn add(self, right: $t<N>) -> $t<N> {
$t::new($(self.$compN + right.$compN),+)
}
}
impl<N: AddAssign<N>> AddAssign<$t<N>> for $t<N> {
#[inline]
fn add_assign(&mut self, right: $t<N>) {
$( self.$compN += right.$compN; )+
}
}
)
);
macro_rules! pointwise_sub(
($t: ident, $($compN: ident),+) => (
impl<N: Sub<N, Output = N>> Sub<$t<N>> for $t<N> {
type Output = $t<N>;
#[inline]
fn sub(self, right: $t<N>) -> $t<N> {
$t::new($(self.$compN - right.$compN),+)
}
}
impl<N: SubAssign<N>> SubAssign<$t<N>> for $t<N> {
#[inline]
fn sub_assign(&mut self, right: $t<N>) {
$( self.$compN -= right.$compN; )+
}
}
)
);
macro_rules! pointwise_scalar_mul(
($t: ident, $($compN: ident),+) => (
impl<N: Copy + Mul<N, Output = N>> Mul<N> for $t<N> {
type Output = $t<N>;
#[inline]
fn mul(self, right: N) -> $t<N> {
$t::new($(self.$compN * right),+)
}
}
impl<N: Copy + MulAssign<N>> MulAssign<N> for $t<N> {
#[inline]
fn mul_assign(&mut self, right: N) {
$( self.$compN *= right; )+
}
}
impl Mul<$t<f32>> for f32 {
type Output = $t<f32>;
#[inline]
fn mul(self, right: $t<f32>) -> $t<f32> {
$t::new($(self * right.$compN),+)
}
}
impl Mul<$t<f64>> for f64 {
type Output = $t<f64>;
#[inline]
fn mul(self, right: $t<f64>) -> $t<f64> {
$t::new($(self * right.$compN),+)
}
}
)
);
macro_rules! pointwise_scalar_div(
($t: ident, $($compN: ident),+) => (
impl<N: Copy + Div<N, Output = N>> Div<N> for $t<N> {
type Output = $t<N>;
#[inline]
fn div(self, right: N) -> $t<N> {
$t::new($(self.$compN / right),+)
}
}
impl<N: Copy + DivAssign<N>> DivAssign<N> for $t<N> {
#[inline]
fn div_assign(&mut self, right: N) {
$( self.$compN /= right; )+
}
}
)
);
macro_rules! pointwise_scalar_add(
($t: ident, $($compN: ident),+) => (
impl<N: Copy + Add<N, Output = N>> Add<N> for $t<N> {
type Output = $t<N>;
#[inline]
fn add(self, right: N) -> $t<N> {
$t::new($(self.$compN + right),+)
}
}
impl<N: Copy + AddAssign<N>> AddAssign<N> for $t<N> {
#[inline]
fn add_assign(&mut self, right: N) {
$( self.$compN += right; )+
}
}
impl Add<$t<f32>> for f32 {
type Output = $t<f32>;
#[inline]
fn add(self, right: $t<f32>) -> $t<f32> {
$t::new($(self + right.$compN),+)
}
}
impl Add<$t<f64>> for f64 {
type Output = $t<f64>;
#[inline]
fn add(self, right: $t<f64>) -> $t<f64> {
$t::new($(self + right.$compN),+)
}
}
)
);
macro_rules! pointwise_scalar_sub(
($t: ident, $($compN: ident),+) => (
impl<N: Copy + Sub<N, Output = N>> Sub<N> for $t<N> {
type Output = $t<N>;
#[inline]
fn sub(self, right: N) -> $t<N> {
$t::new($(self.$compN - right),+)
}
}
impl<N: Copy + SubAssign<N>> SubAssign<N> for $t<N> {
#[inline]
fn sub_assign(&mut self, right: N) {
$( self.$compN -= right; )+
}
}
impl Sub<$t<f32>> for f32 {
type Output = $t<f32>;
#[inline]
fn sub(self, right: $t<f32>) -> $t<f32> {
$t::new($(self - right.$compN),+)
}
}
impl Sub<$t<f64>> for f64 {
type Output = $t<f64>;
#[inline]
fn sub(self, right: $t<f64>) -> $t<f64> {
$t::new($(self - right.$compN),+)
}
}
)
);
macro_rules! componentwise_neg(
($t: ident, $($compN: ident),+) => (
impl<N: Neg<Output = N> + Copy> Neg for $t<N> {
type Output = $t<N>;
#[inline]
fn neg(self) -> $t<N> {
$t::new($(-self.$compN ),+)
}
}
)
);
macro_rules! componentwise_repeat(
($t: ident, $($compN: ident),+) => (
impl<N: Copy> Repeat<N> for $t<N> {
fn repeat(val: N) -> $t<N> {
$t {
$($compN: val ),+
}
}
}
)
);
macro_rules! componentwise_absolute(
($t: ident, $($compN: ident),+) => (
impl<N: Absolute<N>> Absolute<$t<N>> for $t<N> {
#[inline]
fn abs(m: &$t<N>) -> $t<N> {
$t::new($(::abs(&m.$compN) ),+)
}
}
)
);
macro_rules! componentwise_zero(
($t: ident, $($compN: ident),+ ) => (
impl<N: Zero> Zero for $t<N> {
#[inline]
fn zero() -> $t<N> {
$t {
$($compN: ::zero() ),+
}
}
#[inline]
fn is_zero(&self) -> bool {
$(::is_zero(&self.$compN) )&&+
}
}
)
);
macro_rules! componentwise_one(
($t: ident, $($compN: ident),+ ) => (
impl<N: BaseNum> One for $t<N> {
#[inline]
fn one() -> $t<N> {
$t {
$($compN: ::one() ),+
}
}
}
)
);
// Implements Arbitrary by setting each components to Arbitrary::arbitrary.
macro_rules! componentwise_arbitrary(
($t: ident, $($compN: ident),+ ) => (
#[cfg(feature="arbitrary")]
impl<N: Arbitrary> Arbitrary for $t<N> {
#[inline]
fn arbitrary<G: Gen>(g: &mut G) -> $t<N> {
$t { $($compN: Arbitrary::arbitrary(g),)* }
}
}
)
);
// Implements Rand by setting each components to Rand::rand.
macro_rules! componentwise_rand(
($t: ident, $($compN: ident),+ ) => (
impl<N: Rand> Rand for $t<N> {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> $t<N> {
$t { $($compN: Rand::rand(rng), )* }
}
}
)
);
macro_rules! component_basis_element(
($t: ident, $($compN: ident),+ ) => (
/*
*
* Element of the canonical basis.
*
*/
impl<N: Zero + One> $t<N> {
$(
/// Create the element of the canonical basis having this component set to one and
/// all the others set to zero.
#[inline]
pub fn $compN() -> $t<N> {
let mut res: $t<N> = ::zero();
res.$compN = ::one();
res
}
)+
}
)
);
// A function to create a new element from its component values.
macro_rules! component_new(
($t: ident, $($compN: ident),+) => (
impl<N> $t<N> {
/// Creation from component values.
#[inline]
pub fn new($($compN: N ),+) -> $t<N> {
$t {
$($compN: $compN ),+
}
}
}
);
);

View File

@ -9,7 +9,8 @@ use rand::{self, Rand};
use num::{Zero, One}; use num::{Zero, One};
use structs::dvector::{DVector, DVector1, DVector2, DVector3, DVector4, DVector5, DVector6}; use structs::dvector::{DVector, DVector1, DVector2, DVector3, DVector4, DVector5, DVector6};
use traits::operations::{ApproxEq, Inverse, Transpose, Mean, Covariance}; use traits::operations::{ApproxEq, Inverse, Transpose, Mean, Covariance};
use traits::structure::{Cast, Column, ColumnSlice, Row, RowSlice, Diagonal, DiagMut, Eye, Indexable, Shape, BaseNum}; use traits::structure::{Cast, Column, ColumnSlice, Row, RowSlice, Diagonal, DiagonalMut, Eye,
Indexable, Shape, BaseNum};
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};

View File

@ -858,7 +858,7 @@ macro_rules! dmat_impl(
} }
} }
impl<N: Copy + Clone + Zero> DiagMut<$dvector<N>> for $dmatrix<N> { impl<N: Copy + Clone + Zero> DiagonalMut<$dvector<N>> for $dmatrix<N> {
#[inline] #[inline]
fn set_diagonal(&mut self, diagonal: &$dvector<N>) { fn set_diagonal(&mut self, diagonal: &$dvector<N>) {
let smallest_dim = cmp::min(self.nrows, self.ncols); let smallest_dim = cmp::min(self.nrows, self.ncols);

View File

@ -74,8 +74,8 @@ impl<N: BaseFloat> Isometry3<N> {
/// requirement of this parameter is to not be collinear to `target - eye`. /// requirement of this parameter is to not be collinear to `target - eye`.
#[inline] #[inline]
pub fn look_at_rh(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Isometry3<N> { pub fn look_at_rh(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Isometry3<N> {
let rotation = Rotation3::look_at_rh(&(*target - *eye), up); let rotation = Rotation3::look_at_rh(&(*target - *eye), up);
let trans = rotation * (-*eye); let trans = rotation * (-*eye);
Isometry3::new_with_rotation_matrix(trans.to_vector(), rotation) Isometry3::new_with_rotation_matrix(trans.to_vector(), rotation)
} }
@ -92,53 +92,15 @@ impl<N: BaseFloat> Isometry3<N> {
/// requirement of this parameter is to not be collinear to `target - eye`. /// requirement of this parameter is to not be collinear to `target - eye`.
#[inline] #[inline]
pub fn look_at_lh(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Isometry3<N> { pub fn look_at_lh(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Isometry3<N> {
let rotation = Rotation3::look_at_lh(&(*target - *eye), up); let rotation = Rotation3::look_at_lh(&(*target - *eye), up);
let trans = rotation * (-*eye); let trans = rotation * (-*eye);
Isometry3::new_with_rotation_matrix(trans.to_vector(), rotation) Isometry3::new_with_rotation_matrix(trans.to_vector(), rotation)
} }
} }
isometry_impl!(Isometry2, Rotation2, Vector2, Vector1); isometry_impl!(Isometry2, Rotation2, Vector2, Vector1, Point2, Matrix3);
rotation_matrix_impl!(Isometry2, Rotation2, Vector2, Vector1);
rotation_impl!(Isometry2, Rotation2, Vector1);
dim_impl!(Isometry2, 2); dim_impl!(Isometry2, 2);
one_impl!(Isometry2);
absolute_rotate_impl!(Isometry2, Vector2);
rand_impl!(Isometry2);
approx_eq_impl!(Isometry2);
to_homogeneous_impl!(Isometry2, Matrix3);
inverse_impl!(Isometry2);
transform_impl!(Isometry2, Point2);
transformation_impl!(Isometry2);
rotate_impl!(Isometry2, Vector2);
translation_impl!(Isometry2, Vector2);
translate_impl!(Isometry2, Point2);
isometry_mul_isometry_impl!(Isometry2);
isometry_mul_rotation_impl!(Isometry2, Rotation2);
isometry_mul_point_impl!(Isometry2, Point2);
isometry_mul_vec_impl!(Isometry2, Vector2);
arbitrary_isometry_impl!(Isometry2);
isometry_display_impl!(Isometry2);
isometry_impl!(Isometry3, Rotation3, Vector3, Vector3); isometry_impl!(Isometry3, Rotation3, Vector3, Vector3, Point3, Matrix4);
rotation_matrix_impl!(Isometry3, Rotation3, Vector3, Vector3);
rotation_impl!(Isometry3, Rotation3, Vector3);
dim_impl!(Isometry3, 3); dim_impl!(Isometry3, 3);
one_impl!(Isometry3);
absolute_rotate_impl!(Isometry3, Vector3);
rand_impl!(Isometry3);
approx_eq_impl!(Isometry3);
to_homogeneous_impl!(Isometry3, Matrix4);
inverse_impl!(Isometry3);
transform_impl!(Isometry3, Point3);
transformation_impl!(Isometry3);
rotate_impl!(Isometry3, Vector3);
translation_impl!(Isometry3, Vector3);
translate_impl!(Isometry3, Point3);
isometry_mul_isometry_impl!(Isometry3);
isometry_mul_rotation_impl!(Isometry3, Rotation3);
isometry_mul_point_impl!(Isometry3, Point3);
isometry_mul_vec_impl!(Isometry3, Vector3);
arbitrary_isometry_impl!(Isometry3);
isometry_display_impl!(Isometry3);

View File

@ -1,68 +1,63 @@
#![macro_use] #![macro_use]
macro_rules! isometry_impl( macro_rules! isometry_impl(
($t: ident, $submatrix: ident, $subvector: ident, $subrotvector: ident) => ( ($t: ident, $rotmatrix: ident, $vector: ident, $rotvector: ident, $point: ident,
$homogeneous: ident) => (
impl<N: BaseFloat> $t<N> { impl<N: BaseFloat> $t<N> {
/// Creates a new isometry from an axis-angle rotation, and a vector. /// Creates a new isometry from an axis-angle rotation, and a vector.
#[inline] #[inline]
pub fn new(translation: $subvector<N>, rotation: $subrotvector<N>) -> $t<N> { pub fn new(translation: $vector<N>, rotation: $rotvector<N>) -> $t<N> {
$t { $t {
rotation: $submatrix::new(rotation), rotation: $rotmatrix::new(rotation),
translation: translation translation: translation
} }
} }
/// 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_with_rotation_matrix(translation: $subvector<N>, rotation: $submatrix<N>) -> $t<N> { pub fn new_with_rotation_matrix(translation: $vector<N>, rotation: $rotmatrix<N>) -> $t<N> {
$t { $t {
rotation: rotation, rotation: rotation,
translation: translation translation: translation
} }
} }
} }
)
);
macro_rules! rotation_matrix_impl(
($t: ident, $trotation: ident, $tlv: ident, $tav: ident) => ( /*
*
* RotationMatrix
*
*/
impl<N: Cast<f64> + BaseFloat> impl<N: Cast<f64> + BaseFloat>
RotationMatrix<N, $tlv<N>, $tav<N>> for $t<N> { RotationMatrix<N, $vector<N>, $rotvector<N>> for $t<N> {
type Output = $trotation<N>; type Output = $rotmatrix<N>;
#[inline] #[inline]
fn to_rotation_matrix(&self) -> $trotation<N> { fn to_rotation_matrix(&self) -> $rotmatrix<N> {
self.rotation self.rotation
} }
} }
)
);
macro_rules! dim_impl( /*
($t: ident, $dimension: expr) => ( *
impl<N> Dimension for $t<N> { * One
#[inline] *
fn dimension(_: Option<$t<N>>) -> usize { */
$dimension
}
}
)
);
macro_rules! one_impl(
($t: ident) => (
impl<N: BaseFloat> One for $t<N> { impl<N: BaseFloat> One for $t<N> {
#[inline] #[inline]
fn one() -> $t<N> { fn one() -> $t<N> {
$t::new_with_rotation_matrix(::zero(), ::one()) $t::new_with_rotation_matrix(::zero(), ::one())
} }
} }
)
);
macro_rules! isometry_mul_isometry_impl(
($t: ident) => ( /*
*
* Isometry × Isometry
*
*/
impl<N: BaseFloat> Mul<$t<N>> for $t<N> { impl<N: BaseFloat> Mul<$t<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
@ -81,21 +76,23 @@ macro_rules! isometry_mul_isometry_impl(
self.rotation *= right.rotation; self.rotation *= right.rotation;
} }
} }
)
);
macro_rules! isometry_mul_rotation_impl(
($t: ident, $rotation: ident) => ( /*
impl<N: BaseFloat> Mul<$rotation<N>> for $t<N> { *
* Isometry × Rotation
*
*/
impl<N: BaseFloat> Mul<$rotmatrix<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
#[inline] #[inline]
fn mul(self, right: $rotation<N>) -> $t<N> { fn mul(self, right: $rotmatrix<N>) -> $t<N> {
$t::new_with_rotation_matrix(self.translation, self.rotation * right) $t::new_with_rotation_matrix(self.translation, self.rotation * right)
} }
} }
impl<N: BaseFloat> Mul<$t<N>> for $rotation<N> { impl<N: BaseFloat> Mul<$t<N>> for $rotmatrix<N> {
type Output = $t<N>; type Output = $t<N>;
#[inline] #[inline]
@ -106,167 +103,181 @@ macro_rules! isometry_mul_rotation_impl(
} }
} }
impl<N: BaseFloat> MulAssign<$rotation<N>> for $t<N> { impl<N: BaseFloat> MulAssign<$rotmatrix<N>> for $t<N> {
#[inline] #[inline]
fn mul_assign(&mut self, right: $rotation<N>) { fn mul_assign(&mut self, right: $rotmatrix<N>) {
self.rotation *= right self.rotation *= right
} }
} }
)
);
macro_rules! isometry_mul_point_impl(
($t: ident, $tv: ident) => ( /*
impl<N: BaseNum> Mul<$tv<N>> for $t<N> { *
type Output = $tv<N>; * Isometry × Point
*
*/
impl<N: BaseNum> Mul<$point<N>> for $t<N> {
type Output = $point<N>;
#[inline] #[inline]
fn mul(self, right: $tv<N>) -> $tv<N> { fn mul(self, right: $point<N>) -> $point<N> {
self.rotation * right + self.translation self.rotation * right + self.translation
} }
} }
)
);
macro_rules! isometry_mul_vec_impl(
($t: ident, $tv: ident) => ( /*
impl<N: BaseNum> Mul<$tv<N>> for $t<N> { *
type Output = $tv<N>; * Isometry × Vector
*
*/
impl<N: BaseNum> Mul<$vector<N>> for $t<N> {
type Output = $vector<N>;
#[inline] #[inline]
fn mul(self, right: $tv<N>) -> $tv<N> { fn mul(self, right: $vector<N>) -> $vector<N> {
self.rotation * right self.rotation * right
} }
} }
)
);
macro_rules! translation_impl(
($t: ident, $tv: ident) => ( /*
impl<N: BaseFloat> Translation<$tv<N>> for $t<N> { *
* Translation
*
*/
impl<N: BaseFloat> Translation<$vector<N>> for $t<N> {
#[inline] #[inline]
fn translation(&self) -> $tv<N> { fn translation(&self) -> $vector<N> {
self.translation self.translation
} }
#[inline] #[inline]
fn inverse_translation(&self) -> $tv<N> { fn inverse_translation(&self) -> $vector<N> {
-self.translation -self.translation
} }
#[inline] #[inline]
fn append_translation_mut(&mut self, t: &$tv<N>) { fn append_translation_mut(&mut self, t: &$vector<N>) {
self.translation = *t + self.translation self.translation = *t + self.translation
} }
#[inline] #[inline]
fn append_translation(&self, t: &$tv<N>) -> $t<N> { fn append_translation(&self, t: &$vector<N>) -> $t<N> {
$t::new_with_rotation_matrix(*t + self.translation, self.rotation) $t::new_with_rotation_matrix(*t + self.translation, self.rotation)
} }
#[inline] #[inline]
fn prepend_translation_mut(&mut self, t: &$tv<N>) { fn prepend_translation_mut(&mut self, t: &$vector<N>) {
self.translation = self.translation + self.rotation * *t self.translation = self.translation + self.rotation * *t
} }
#[inline] #[inline]
fn prepend_translation(&self, t: &$tv<N>) -> $t<N> { fn prepend_translation(&self, t: &$vector<N>) -> $t<N> {
$t::new_with_rotation_matrix(self.translation + self.rotation * *t, self.rotation) $t::new_with_rotation_matrix(self.translation + self.rotation * *t, self.rotation)
} }
#[inline] #[inline]
fn set_translation(&mut self, t: $tv<N>) { fn set_translation(&mut self, t: $vector<N>) {
self.translation = t self.translation = t
} }
} }
)
);
macro_rules! translate_impl(
($t: ident, $tv: ident) => ( /*
impl<N: Copy + Add<N, Output = N> + Sub<N, Output = N>> Translate<$tv<N>> for $t<N> { *
* Translate
*
*/
impl<N: Copy + Add<N, Output = N> + Sub<N, Output = N>> Translate<$point<N>> for $t<N> {
#[inline] #[inline]
fn translate(&self, v: &$tv<N>) -> $tv<N> { fn translate(&self, v: &$point<N>) -> $point<N> {
*v + self.translation *v + self.translation
} }
#[inline] #[inline]
fn inverse_translate(&self, v: &$tv<N>) -> $tv<N> { fn inverse_translate(&self, v: &$point<N>) -> $point<N> {
*v - self.translation *v - self.translation
} }
} }
)
);
macro_rules! rotation_impl(
($t: ident, $trotation: ident, $tav: ident) => ( /*
impl<N: Cast<f64> + BaseFloat> Rotation<$tav<N>> for $t<N> { *
* Rotation
*
*/
impl<N: Cast<f64> + BaseFloat> Rotation<$rotvector<N>> for $t<N> {
#[inline] #[inline]
fn rotation(&self) -> $tav<N> { fn rotation(&self) -> $rotvector<N> {
self.rotation.rotation() self.rotation.rotation()
} }
#[inline] #[inline]
fn inverse_rotation(&self) -> $tav<N> { fn inverse_rotation(&self) -> $rotvector<N> {
self.rotation.inverse_rotation() self.rotation.inverse_rotation()
} }
#[inline] #[inline]
fn append_rotation_mut(&mut self, rotation: &$tav<N>) { fn append_rotation_mut(&mut self, rotation: &$rotvector<N>) {
let delta = $trotation::new(*rotation); let delta = $rotmatrix::new(*rotation);
self.rotation = delta * self.rotation; self.rotation = delta * self.rotation;
self.translation = delta * self.translation; self.translation = delta * self.translation;
} }
#[inline] #[inline]
fn append_rotation(&self, rotation: &$tav<N>) -> $t<N> { fn append_rotation(&self, rotation: &$rotvector<N>) -> $t<N> {
let delta = $trotation::new(*rotation); let delta = $rotmatrix::new(*rotation);
$t::new_with_rotation_matrix(delta * self.translation, delta * self.rotation) $t::new_with_rotation_matrix(delta * self.translation, delta * self.rotation)
} }
#[inline] #[inline]
fn prepend_rotation_mut(&mut self, rotation: &$tav<N>) { fn prepend_rotation_mut(&mut self, rotation: &$rotvector<N>) {
let delta = $trotation::new(*rotation); let delta = $rotmatrix::new(*rotation);
self.rotation = self.rotation * delta; self.rotation = self.rotation * delta;
} }
#[inline] #[inline]
fn prepend_rotation(&self, rotation: &$tav<N>) -> $t<N> { fn prepend_rotation(&self, rotation: &$rotvector<N>) -> $t<N> {
let delta = $trotation::new(*rotation); let delta = $rotmatrix::new(*rotation);
$t::new_with_rotation_matrix(self.translation, self.rotation * delta) $t::new_with_rotation_matrix(self.translation, self.rotation * delta)
} }
#[inline] #[inline]
fn set_rotation(&mut self, rotation: $tav<N>) { fn set_rotation(&mut self, rotation: $rotvector<N>) {
// FIXME: should the translation be changed too? // FIXME: should the translation be changed too?
self.rotation.set_rotation(rotation) self.rotation.set_rotation(rotation)
} }
} }
)
);
macro_rules! rotate_impl(
($t: ident, $tv: ident) => ( /*
impl<N: BaseNum> Rotate<$tv<N>> for $t<N> { *
* Rotate
*
*/
impl<N: BaseNum> Rotate<$vector<N>> for $t<N> {
#[inline] #[inline]
fn rotate(&self, v: &$tv<N>) -> $tv<N> { fn rotate(&self, v: &$vector<N>) -> $vector<N> {
self.rotation.rotate(v) self.rotation.rotate(v)
} }
#[inline] #[inline]
fn inverse_rotate(&self, v: &$tv<N>) -> $tv<N> { fn inverse_rotate(&self, v: &$vector<N>) -> $vector<N> {
self.rotation.inverse_rotate(v) self.rotation.inverse_rotate(v)
} }
} }
)
);
macro_rules! transformation_impl(
($t: ident) => ( /*
*
* Transformation
*
*/
impl<N: BaseFloat> Transformation<$t<N>> for $t<N> { impl<N: BaseFloat> Transformation<$t<N>> for $t<N> {
fn transformation(&self) -> $t<N> { fn transformation(&self) -> $t<N> {
*self *self
@ -297,27 +308,31 @@ macro_rules! transformation_impl(
*self = t *self = t
} }
} }
)
);
macro_rules! transform_impl(
($t: ident, $tp: ident) => ( /*
impl<N: BaseNum> Transform<$tp<N>> for $t<N> { *
* Transform
*
*/
impl<N: BaseNum> Transform<$point<N>> for $t<N> {
#[inline] #[inline]
fn transform(&self, p: &$tp<N>) -> $tp<N> { fn transform(&self, p: &$point<N>) -> $point<N> {
self.rotation.transform(p) + self.translation self.rotation.transform(p) + self.translation
} }
#[inline] #[inline]
fn inverse_transform(&self, p: &$tp<N>) -> $tp<N> { fn inverse_transform(&self, p: &$point<N>) -> $point<N> {
self.rotation.inverse_transform(&(*p - self.translation)) self.rotation.inverse_transform(&(*p - self.translation))
} }
} }
)
);
macro_rules! inverse_impl(
($t: ident) => ( /*
*
* Inverse
*
*/
impl<N: BaseNum + Neg<Output = N>> Inverse for $t<N> { impl<N: BaseNum + Neg<Output = N>> Inverse for $t<N> {
#[inline] #[inline]
fn inverse_mut(&mut self) -> bool { fn inverse_mut(&mut self) -> bool {
@ -335,28 +350,32 @@ macro_rules! inverse_impl(
Some(res) Some(res)
} }
} }
)
);
macro_rules! to_homogeneous_impl(
($t: ident, $th: ident) => ( /*
impl<N: BaseNum> ToHomogeneous<$th<N>> for $t<N> { *
fn to_homogeneous(&self) -> $th<N> { * ToHomogeneous
*
*/
impl<N: BaseNum> ToHomogeneous<$homogeneous<N>> for $t<N> {
fn to_homogeneous(&self) -> $homogeneous<N> {
let mut res = self.rotation.to_homogeneous(); let mut res = self.rotation.to_homogeneous();
// copy the translation // copy the translation
let dimension = Dimension::dimension(None::<$th<N>>); let dimension = Dimension::dimension(None::<$homogeneous<N>>);
res.set_column(dimension - 1, self.translation.as_point().to_homogeneous().to_vector()); res.set_column(dimension - 1, self.translation.as_point().to_homogeneous().to_vector());
res res
} }
} }
)
);
macro_rules! approx_eq_impl(
($t: ident) => ( /*
*
* ApproxEq
*
*/
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> { impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
#[inline] #[inline]
fn approx_epsilon(_: Option<$t<N>>) -> N { fn approx_epsilon(_: Option<$t<N>>) -> N {
@ -380,33 +399,39 @@ macro_rules! approx_eq_impl(
ApproxEq::approx_eq_ulps(&self.translation, &other.translation, ulps) ApproxEq::approx_eq_ulps(&self.translation, &other.translation, ulps)
} }
} }
)
);
macro_rules! rand_impl(
($t: ident) => ( /*
*
* Rand
*
*/
impl<N: Rand + BaseFloat> Rand for $t<N> { impl<N: Rand + BaseFloat> 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())
} }
} }
)
);
macro_rules! absolute_rotate_impl(
($t: ident, $tv: ident) => ( /*
impl<N: BaseFloat> AbsoluteRotate<$tv<N>> for $t<N> { *
* AbsoluteRotate
*
*/
impl<N: BaseFloat> AbsoluteRotate<$vector<N>> for $t<N> {
#[inline] #[inline]
fn absolute_rotate(&self, v: &$tv<N>) -> $tv<N> { fn absolute_rotate(&self, v: &$vector<N>) -> $vector<N> {
self.rotation.absolute_rotate(v) self.rotation.absolute_rotate(v)
} }
} }
)
);
macro_rules! arbitrary_isometry_impl(
($t: ident) => ( /*
*
* Arbitrary
*
*/
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for $t<N> { impl<N: Arbitrary + BaseFloat> Arbitrary for $t<N> {
fn arbitrary<G: Gen>(g: &mut G) -> $t<N> { fn arbitrary<G: Gen>(g: &mut G) -> $t<N> {
@ -416,11 +441,13 @@ macro_rules! arbitrary_isometry_impl(
) )
} }
} }
)
);
macro_rules! isometry_display_impl(
($t: ident) => ( /*
*
* Display
*
*/
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> { impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(writeln!(f, "Isometry {{")); try!(writeln!(f, "Isometry {{"));
@ -441,3 +468,14 @@ macro_rules! isometry_display_impl(
} }
) )
); );
macro_rules! dim_impl(
($t: ident, $dimension: expr) => (
impl<N> Dimension for $t<N> {
#[inline]
fn dimension(_: Option<$t<N>>) -> usize {
$dimension
}
}
)
);

View File

@ -14,7 +14,7 @@ use structs::point::{Point1, Point4, Point5, Point6};
use structs::dvector::{DVector1, DVector2, DVector3, DVector4, DVector5, DVector6}; use structs::dvector::{DVector1, DVector2, DVector3, DVector4, DVector5, DVector6};
use traits::structure::{Cast, Row, Column, Iterable, IterableMut, Dimension, Indexable, Eye, ColumnSlice, use traits::structure::{Cast, Row, Column, Iterable, IterableMut, Dimension, Indexable, Eye, ColumnSlice,
RowSlice, Diagonal, DiagMut, Shape, BaseFloat, BaseNum, Repeat}; RowSlice, Diagonal, DiagonalMut, Shape, BaseFloat, BaseNum, Repeat};
use traits::operations::{Absolute, Transpose, Inverse, Outer, EigenQR, Mean}; use traits::operations::{Absolute, Transpose, Inverse, Outer, EigenQR, Mean};
use traits::geometry::{ToHomogeneous, FromHomogeneous, Origin}; use traits::geometry::{ToHomogeneous, FromHomogeneous, Origin};
use linalg; use linalg;
@ -50,45 +50,20 @@ pub struct Matrix1<N> {
eye_impl!(Matrix1, 1, m11); eye_impl!(Matrix1, 1, m11);
mat_impl!(Matrix1, m11); matrix_impl!(Matrix1, 1, Vector1, DVector1, m11);
repeat_impl!(Matrix1, m11);
conversion_impl!(Matrix1, 1);
mat_cast_impl!(Matrix1, m11);
add_impl!(Matrix1, m11);
sub_impl!(Matrix1, m11);
scalar_add_impl!(Matrix1, m11);
scalar_sub_impl!(Matrix1, m11);
scalar_mul_impl!(Matrix1, m11);
scalar_div_impl!(Matrix1, m11);
absolute_impl!(Matrix1, m11);
zero_impl!(Matrix1, m11);
one_impl!(Matrix1, ::one); one_impl!(Matrix1, ::one);
iterable_impl!(Matrix1, 1);
iterable_mut_impl!(Matrix1, 1);
at_fast_impl!(Matrix1, 1);
dim_impl!(Matrix1, 1); dim_impl!(Matrix1, 1);
indexable_impl!(Matrix1, 1);
index_impl!(Matrix1, 1);
mat_mul_mat_impl!(Matrix1, 1); mat_mul_mat_impl!(Matrix1, 1);
mat_mul_vec_impl!(Matrix1, Vector1, 1, ::zero); mat_mul_vec_impl!(Matrix1, Vector1, 1, ::zero);
vec_mul_mat_impl!(Matrix1, Vector1, 1, ::zero); vec_mul_mat_impl!(Matrix1, Vector1, 1, ::zero);
mat_mul_point_impl!(Matrix1, Point1, 1, Origin::origin); mat_mul_point_impl!(Matrix1, Point1, 1, Origin::origin);
point_mul_mat_impl!(Matrix1, Point1, 1, Origin::origin); point_mul_mat_impl!(Matrix1, Point1, 1, Origin::origin);
// (specialized); inverse_impl!(Matrix1, 1); // (specialized); inverse_impl!(Matrix1, 1);
transpose_impl!(Matrix1, 1);
approx_eq_impl!(Matrix1);
row_impl!(Matrix1, Vector1, 1);
column_impl!(Matrix1, Vector1, 1);
column_slice_impl!(Matrix1, Vector1, DVector1, 1);
row_slice_impl!(Matrix1, Vector1, DVector1, 1);
diag_impl!(Matrix1, Vector1, 1);
to_homogeneous_impl!(Matrix1, Matrix2, 1, 2); to_homogeneous_impl!(Matrix1, Matrix2, 1, 2);
from_homogeneous_impl!(Matrix1, Matrix2, 1, 2); from_homogeneous_impl!(Matrix1, Matrix2, 1, 2);
outer_impl!(Vector1, Matrix1);
eigen_qr_impl!(Matrix1, Vector1); eigen_qr_impl!(Matrix1, Vector1);
arbitrary_impl!(Matrix1, m11); componentwise_arbitrary!(Matrix1, m11);
rand_impl!(Matrix1, m11); componentwise_rand!(Matrix1, m11);
mean_impl!(Matrix1, Vector1, 1);
mat_display_impl!(Matrix1, 1); mat_display_impl!(Matrix1, 1);
/// Square matrix of dimension 2. /// Square matrix of dimension 2.
@ -101,49 +76,20 @@ pub struct Matrix2<N> {
eye_impl!(Matrix2, 2, m11, m22); eye_impl!(Matrix2, 2, m11, m22);
mat_impl!(Matrix2, m11, m12, matrix_impl!(Matrix2, 2, Vector2, DVector2, m11, m12,
m21, m22); m21, m22);
repeat_impl!(Matrix2, m11, m12,
m21, m22);
conversion_impl!(Matrix2, 2);
mat_cast_impl!(Matrix2, m11, m12,
m21, m22);
add_impl!(Matrix2, m11, m12, m21, m22);
sub_impl!(Matrix2, m11, m12, m21, m22);
scalar_add_impl!(Matrix2, m11, m12, m21, m22);
scalar_sub_impl!(Matrix2, m11, m12, m21, m22);
scalar_mul_impl!(Matrix2, m11, m12, m21, m22);
scalar_div_impl!(Matrix2, m11, m12, m21, m22);
absolute_impl!(Matrix2, m11, m12,
m21, m22);
zero_impl!(Matrix2, m11, m12,
m21, m22);
one_impl!(Matrix2, ::one, ::zero, one_impl!(Matrix2, ::one, ::zero,
::zero, ::one); ::zero, ::one);
iterable_impl!(Matrix2, 2);
iterable_mut_impl!(Matrix2, 2);
dim_impl!(Matrix2, 2); dim_impl!(Matrix2, 2);
indexable_impl!(Matrix2, 2);
index_impl!(Matrix2, 2);
at_fast_impl!(Matrix2, 2);
// (specialized); mul_impl!(Matrix2, 2); // (specialized); mul_impl!(Matrix2, 2);
// (specialized); rmul_impl!(Matrix2, Vector2, 2); // (specialized); rmul_impl!(Matrix2, Vector2, 2);
// (specialized); lmul_impl!(Matrix2, Vector2, 2); // (specialized); lmul_impl!(Matrix2, Vector2, 2);
// (specialized); inverse_impl!(Matrix2, 2); // (specialized); inverse_impl!(Matrix2, 2);
transpose_impl!(Matrix2, 2);
approx_eq_impl!(Matrix2);
row_impl!(Matrix2, Vector2, 2);
column_impl!(Matrix2, Vector2, 2);
column_slice_impl!(Matrix2, Vector2, DVector2, 2);
row_slice_impl!(Matrix2, Vector2, DVector2, 2);
diag_impl!(Matrix2, Vector2, 2);
to_homogeneous_impl!(Matrix2, Matrix3, 2, 3); to_homogeneous_impl!(Matrix2, Matrix3, 2, 3);
from_homogeneous_impl!(Matrix2, Matrix3, 2, 3); from_homogeneous_impl!(Matrix2, Matrix3, 2, 3);
outer_impl!(Vector2, Matrix2);
eigen_qr_impl!(Matrix2, Vector2); eigen_qr_impl!(Matrix2, Vector2);
arbitrary_impl!(Matrix2, m11, m12, m21, m22); componentwise_arbitrary!(Matrix2, m11, m12, m21, m22);
rand_impl!(Matrix2, m11, m12, m21, m22); componentwise_rand!(Matrix2, m11, m12, m21, m22);
mean_impl!(Matrix2, Vector2, 2);
mat_display_impl!(Matrix2, 2); mat_display_impl!(Matrix2, 2);
/// Square matrix of dimension 3. /// Square matrix of dimension 3.
@ -157,91 +103,30 @@ pub struct Matrix3<N> {
eye_impl!(Matrix3, 3, m11, m22, m33); eye_impl!(Matrix3, 3, m11, m22, m33);
mat_impl!(Matrix3, m11, m12, m13, matrix_impl!(Matrix3, 3, Vector3, DVector3, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33); m31, m32, m33);
repeat_impl!(Matrix3, m11, m12, m13,
m21, m22, m23,
m31, m32, m33);
conversion_impl!(Matrix3, 3);
mat_cast_impl!(Matrix3, m11, m12, m13,
m21, m22, m23,
m31, m32, m33);
add_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
sub_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
scalar_add_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
scalar_sub_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
scalar_mul_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
scalar_div_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
absolute_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
zero_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
one_impl!(Matrix3, ::one , ::zero, ::zero, one_impl!(Matrix3, ::one , ::zero, ::zero,
::zero, ::one , ::zero, ::zero, ::one , ::zero,
::zero, ::zero, ::one); ::zero, ::zero, ::one);
iterable_impl!(Matrix3, 3);
iterable_mut_impl!(Matrix3, 3);
dim_impl!(Matrix3, 3); dim_impl!(Matrix3, 3);
indexable_impl!(Matrix3, 3);
index_impl!(Matrix3, 3);
at_fast_impl!(Matrix3, 3);
// (specialized); mul_impl!(Matrix3, 3); // (specialized); mul_impl!(Matrix3, 3);
// (specialized); rmul_impl!(Matrix3, Vector3, 3); // (specialized); rmul_impl!(Matrix3, Vector3, 3);
// (specialized); lmul_impl!(Matrix3, Vector3, 3); // (specialized); lmul_impl!(Matrix3, Vector3, 3);
// (specialized); inverse_impl!(Matrix3, 3); // (specialized); inverse_impl!(Matrix3, 3);
transpose_impl!(Matrix3, 3);
approx_eq_impl!(Matrix3);
// (specialized); row_impl!(Matrix3, Vector3, 3);
// (specialized); column_impl!(Matrix3, Vector3, 3);
column_slice_impl!(Matrix3, Vector3, DVector3, 3);
row_slice_impl!(Matrix3, Vector3, DVector3, 3);
diag_impl!(Matrix3, Vector3, 3);
to_homogeneous_impl!(Matrix3, Matrix4, 3, 4); to_homogeneous_impl!(Matrix3, Matrix4, 3, 4);
from_homogeneous_impl!(Matrix3, Matrix4, 3, 4); from_homogeneous_impl!(Matrix3, Matrix4, 3, 4);
outer_impl!(Vector3, Matrix3);
eigen_qr_impl!(Matrix3, Vector3); eigen_qr_impl!(Matrix3, Vector3);
arbitrary_impl!(Matrix3, componentwise_arbitrary!(Matrix3,
m11, m12, m13, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33 m31, m32, m33
); );
rand_impl!(Matrix3, componentwise_rand!(Matrix3,
m11, m12, m13, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33 m31, m32, m33
); );
mean_impl!(Matrix3, Vector3, 3);
mat_display_impl!(Matrix3, 3); mat_display_impl!(Matrix3, 3);
/// Square matrix of dimension 4. /// Square matrix of dimension 4.
@ -256,68 +141,7 @@ pub struct Matrix4<N> {
eye_impl!(Matrix4, 4, m11, m22, m33, m44); eye_impl!(Matrix4, 4, m11, m22, m33, m44);
mat_impl!(Matrix4, matrix_impl!(Matrix4, 4, Vector4, DVector4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
repeat_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
conversion_impl!(Matrix4, 4);
mat_cast_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
add_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
sub_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
scalar_add_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
scalar_sub_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
scalar_mul_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
scalar_div_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
absolute_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
zero_impl!(Matrix4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
@ -327,42 +151,28 @@ one_impl!(Matrix4, ::one , ::zero, ::zero, ::zero,
::zero, ::one , ::zero, ::zero, ::zero, ::one , ::zero, ::zero,
::zero, ::zero, ::one , ::zero, ::zero, ::zero, ::one , ::zero,
::zero, ::zero, ::zero, ::one); ::zero, ::zero, ::zero, ::one);
iterable_impl!(Matrix4, 4);
iterable_mut_impl!(Matrix4, 4);
dim_impl!(Matrix4, 4); dim_impl!(Matrix4, 4);
indexable_impl!(Matrix4, 4);
index_impl!(Matrix4, 4);
at_fast_impl!(Matrix4, 4);
mat_mul_mat_impl!(Matrix4, 4); mat_mul_mat_impl!(Matrix4, 4);
mat_mul_vec_impl!(Matrix4, Vector4, 4, ::zero); mat_mul_vec_impl!(Matrix4, Vector4, 4, ::zero);
vec_mul_mat_impl!(Matrix4, Vector4, 4, ::zero); vec_mul_mat_impl!(Matrix4, Vector4, 4, ::zero);
mat_mul_point_impl!(Matrix4, Point4, 4, Origin::origin); mat_mul_point_impl!(Matrix4, Point4, 4, Origin::origin);
point_mul_mat_impl!(Matrix4, Point4, 4, Origin::origin); point_mul_mat_impl!(Matrix4, Point4, 4, Origin::origin);
inverse_impl!(Matrix4, 4); inverse_impl!(Matrix4, 4);
transpose_impl!(Matrix4, 4);
approx_eq_impl!(Matrix4);
row_impl!(Matrix4, Vector4, 4);
column_impl!(Matrix4, Vector4, 4);
column_slice_impl!(Matrix4, Vector4, DVector4, 4);
row_slice_impl!(Matrix4, Vector4, DVector4, 4);
diag_impl!(Matrix4, Vector4, 4);
to_homogeneous_impl!(Matrix4, Matrix5, 4, 5); to_homogeneous_impl!(Matrix4, Matrix5, 4, 5);
from_homogeneous_impl!(Matrix4, Matrix5, 4, 5); from_homogeneous_impl!(Matrix4, Matrix5, 4, 5);
outer_impl!(Vector4, Matrix4);
eigen_qr_impl!(Matrix4, Vector4); eigen_qr_impl!(Matrix4, Vector4);
arbitrary_impl!(Matrix4, componentwise_arbitrary!(Matrix4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
m41, m42, m43, m44 m41, m42, m43, m44
); );
rand_impl!(Matrix4, componentwise_rand!(Matrix4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
m41, m42, m43, m44 m41, m42, m43, m44
); );
mean_impl!(Matrix4, Vector4, 4);
mat_display_impl!(Matrix4, 4); mat_display_impl!(Matrix4, 4);
/// Square matrix of dimension 5. /// Square matrix of dimension 5.
@ -378,36 +188,7 @@ pub struct Matrix5<N> {
eye_impl!(Matrix5, 5, m11, m22, m33, m44, m55); eye_impl!(Matrix5, 5, m11, m22, m33, m44, m55);
mat_impl!(Matrix5, matrix_impl!(Matrix5, 5, Vector5, DVector5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
repeat_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
conversion_impl!(Matrix5, 5);
mat_cast_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
absolute_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
zero_impl!(Matrix5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35, m31, m32, m33, m34, m35,
@ -421,86 +202,30 @@ one_impl!(Matrix5,
::zero, ::zero, ::zero, ::one , ::zero, ::zero, ::zero, ::zero, ::one , ::zero,
::zero, ::zero, ::zero, ::zero, ::one ::zero, ::zero, ::zero, ::zero, ::one
); );
add_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
sub_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
scalar_add_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
scalar_sub_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
scalar_mul_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
scalar_div_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
iterable_impl!(Matrix5, 5);
iterable_mut_impl!(Matrix5, 5);
dim_impl!(Matrix5, 5); dim_impl!(Matrix5, 5);
indexable_impl!(Matrix5, 5);
index_impl!(Matrix5, 5);
at_fast_impl!(Matrix5, 5);
mat_mul_mat_impl!(Matrix5, 5); mat_mul_mat_impl!(Matrix5, 5);
mat_mul_vec_impl!(Matrix5, Vector5, 5, ::zero); mat_mul_vec_impl!(Matrix5, Vector5, 5, ::zero);
vec_mul_mat_impl!(Matrix5, Vector5, 5, ::zero); vec_mul_mat_impl!(Matrix5, Vector5, 5, ::zero);
mat_mul_point_impl!(Matrix5, Point5, 5, Origin::origin); mat_mul_point_impl!(Matrix5, Point5, 5, Origin::origin);
point_mul_mat_impl!(Matrix5, Point5, 5, Origin::origin); point_mul_mat_impl!(Matrix5, Point5, 5, Origin::origin);
inverse_impl!(Matrix5, 5); inverse_impl!(Matrix5, 5);
transpose_impl!(Matrix5, 5);
approx_eq_impl!(Matrix5);
row_impl!(Matrix5, Vector5, 5);
column_impl!(Matrix5, Vector5, 5);
column_slice_impl!(Matrix5, Vector5, DVector5, 5);
row_slice_impl!(Matrix5, Vector5, DVector5, 5);
diag_impl!(Matrix5, Vector5, 5);
to_homogeneous_impl!(Matrix5, Matrix6, 5, 6); to_homogeneous_impl!(Matrix5, Matrix6, 5, 6);
from_homogeneous_impl!(Matrix5, Matrix6, 5, 6); from_homogeneous_impl!(Matrix5, Matrix6, 5, 6);
outer_impl!(Vector5, Matrix5);
eigen_qr_impl!(Matrix5, Vector5); eigen_qr_impl!(Matrix5, Vector5);
arbitrary_impl!(Matrix5, componentwise_arbitrary!(Matrix5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35, m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45, m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55 m51, m52, m53, m54, m55
); );
rand_impl!(Matrix5, componentwise_rand!(Matrix5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35, m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45, m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55 m51, m52, m53, m54, m55
); );
mean_impl!(Matrix5, Vector5, 5);
mat_display_impl!(Matrix5, 5); mat_display_impl!(Matrix5, 5);
/// Square matrix of dimension 6. /// Square matrix of dimension 6.
@ -517,7 +242,7 @@ pub struct Matrix6<N> {
eye_impl!(Matrix6, 6, m11, m22, m33, m44, m55, m66); eye_impl!(Matrix6, 6, m11, m22, m33, m44, m55, m66);
mat_impl!(Matrix6, matrix_impl!(Matrix6, 6, Vector6, DVector6,
m11, m12, m13, m14, m15, m16, m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26, m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36, m31, m32, m33, m34, m35, m36,
@ -525,78 +250,6 @@ mat_impl!(Matrix6,
m51, m52, m53, m54, m55, m56, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66 m61, m62, m63, m64, m65, m66
); );
repeat_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
m41, m42, m43, m44, m45, m46,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
conversion_impl!(Matrix6, 6);
mat_cast_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
m41, m42, m43, m44, m45, m46,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
add_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
m41, m42, m43, m44, m45, m46,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
sub_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
m41, m42, m43, m44, m45, m46,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
scalar_add_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
m41, m42, m43, m44, m45, m46,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
scalar_sub_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
m41, m42, m43, m44, m45, m46,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
scalar_mul_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
m41, m42, m43, m44, m45, m46,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
scalar_div_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
m41, m42, m43, m44, m45, m46,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
absolute_impl!(Matrix6, m11, m12, m13, m14, m15, m16, m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36, m41, m42, m43, m44, m45, m46, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66);
zero_impl!(Matrix6, m11, m12, m13, m14, m15, m16, m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36, m41, m42, m43, m44, m45, m46, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66);
one_impl!(Matrix6, one_impl!(Matrix6,
::one , ::zero, ::zero, ::zero, ::zero, ::zero, ::one , ::zero, ::zero, ::zero, ::zero, ::zero,
@ -606,28 +259,15 @@ one_impl!(Matrix6,
::zero, ::zero, ::zero, ::zero, ::one , ::zero, ::zero, ::zero, ::zero, ::zero, ::one , ::zero,
::zero, ::zero, ::zero, ::zero, ::zero, ::one ::zero, ::zero, ::zero, ::zero, ::zero, ::one
); );
iterable_impl!(Matrix6, 6);
iterable_mut_impl!(Matrix6, 6);
dim_impl!(Matrix6, 6); dim_impl!(Matrix6, 6);
indexable_impl!(Matrix6, 6);
index_impl!(Matrix6, 6);
at_fast_impl!(Matrix6, 6);
mat_mul_mat_impl!(Matrix6, 6); mat_mul_mat_impl!(Matrix6, 6);
mat_mul_vec_impl!(Matrix6, Vector6, 6, ::zero); mat_mul_vec_impl!(Matrix6, Vector6, 6, ::zero);
vec_mul_mat_impl!(Matrix6, Vector6, 6, ::zero); vec_mul_mat_impl!(Matrix6, Vector6, 6, ::zero);
mat_mul_point_impl!(Matrix6, Point6, 6, Origin::origin); mat_mul_point_impl!(Matrix6, Point6, 6, Origin::origin);
point_mul_mat_impl!(Matrix6, Point6, 6, Origin::origin); point_mul_mat_impl!(Matrix6, Point6, 6, Origin::origin);
inverse_impl!(Matrix6, 6); inverse_impl!(Matrix6, 6);
transpose_impl!(Matrix6, 6);
approx_eq_impl!(Matrix6);
row_impl!(Matrix6, Vector6, 6);
column_impl!(Matrix6, Vector6, 6);
column_slice_impl!(Matrix6, Vector6, DVector6, 6);
row_slice_impl!(Matrix6, Vector6, DVector6, 6);
diag_impl!(Matrix6, Vector6, 6);
outer_impl!(Vector6, Matrix6);
eigen_qr_impl!(Matrix6, Vector6); eigen_qr_impl!(Matrix6, Vector6);
arbitrary_impl!(Matrix6, componentwise_arbitrary!(Matrix6,
m11, m12, m13, m14, m15, m16, m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26, m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36, m31, m32, m33, m34, m35, m36,
@ -635,7 +275,7 @@ arbitrary_impl!(Matrix6,
m51, m52, m53, m54, m55, m56, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66 m61, m62, m63, m64, m65, m66
); );
rand_impl!(Matrix6, componentwise_rand!(Matrix6,
m11, m12, m13, m14, m15, m16, m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26, m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36, m31, m32, m33, m34, m35, m36,
@ -643,5 +283,4 @@ rand_impl!(Matrix6,
m51, m52, m53, m54, m55, m56, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66 m61, m62, m63, m64, m65, m66
); );
mean_impl!(Matrix6, Vector6, 6);
mat_display_impl!(Matrix6, 6); mat_display_impl!(Matrix6, 6);

View File

@ -1,20 +1,22 @@
#![macro_use] #![macro_use]
macro_rules! mat_impl( macro_rules! matrix_impl(
($t: ident, $($compN: ident),+) => ( ($t: ident, $dimension: expr, $vector: ident, $dvector: ident, $($compN: ident),+) => (
impl<N> $t<N> { impl<N> $t<N> {
#[inline] #[inline]
pub fn new($($compN: N ),+) -> $t<N> { pub fn new($($compN: N ),+) -> $t<N> {
$t { $t {
$($compN: $compN ),+ $($compN: $compN ),+
}
} }
} }
}
)
);
macro_rules! conversion_impl(
($t: ident, $dimension: expr) => ( /*
*
* Conversions (AsRef, AsMut, From)
*
*/
impl<N> AsRef<[[N; $dimension]; $dimension]> for $t<N> { impl<N> AsRef<[[N; $dimension]; $dimension]> for $t<N> {
#[inline] #[inline]
fn as_ref(&self) -> &[[N; $dimension]; $dimension] { fn as_ref(&self) -> &[[N; $dimension]; $dimension] {
@ -58,11 +60,13 @@ macro_rules! conversion_impl(
tref.clone() tref.clone()
} }
} }
)
);
macro_rules! at_fast_impl(
($t: ident, $dimension: expr) => ( /*
*
* Unsafe indexing.
*
*/
impl<N: Copy> $t<N> { impl<N: Copy> $t<N> {
#[inline] #[inline]
pub unsafe fn at_fast(&self, (i, j): (usize, usize)) -> N { pub unsafe fn at_fast(&self, (i, j): (usize, usize)) -> N {
@ -76,331 +80,77 @@ macro_rules! at_fast_impl(
.get_unchecked_mut(i + j * $dimension)) = val .get_unchecked_mut(i + j * $dimension)) = val
} }
} }
)
);
macro_rules! mat_cast_impl(
($t: ident, $($compN: ident),+) => ( /*
*
* Cast
*
*/
impl<Nin: Copy, Nout: Copy + Cast<Nin>> Cast<$t<Nin>> for $t<Nout> { impl<Nin: Copy, Nout: Copy + Cast<Nin>> Cast<$t<Nin>> for $t<Nout> {
#[inline] #[inline]
fn from(v: $t<Nin>) -> $t<Nout> { fn from(v: $t<Nin>) -> $t<Nout> {
$t::new($(Cast::from(v.$compN)),+) $t::new($(Cast::from(v.$compN)),+)
} }
} }
)
);
macro_rules! add_impl(
($t: ident, $($compN: ident),+) => (
impl<N: Add<N, Output = N>> Add<$t<N>> for $t<N> {
type Output = $t<N>;
/*
*
* Iterable
*
*/
impl<N> Iterable<N> for $t<N> {
#[inline] #[inline]
fn add(self, right: $t<N>) -> $t<N> { fn iter(&self) -> Iter<N> {
$t::new($(self.$compN + right.$compN),+) unsafe {
} mem::transmute::<&$t<N>, &[N; $dimension * $dimension]>(self).iter()
}
impl<N: AddAssign<N>> AddAssign<$t<N>> for $t<N> {
#[inline]
fn add_assign(&mut self, right: $t<N>) {
$( self.$compN += right.$compN; )+
}
}
)
);
macro_rules! sub_impl(
($t: ident, $($compN: ident),+) => (
impl<N: Sub<N, Output = N>> Sub<$t<N>> for $t<N> {
type Output = $t<N>;
#[inline]
fn sub(self, right: $t<N>) -> $t<N> {
$t::new($(self.$compN - right.$compN),+)
}
}
impl<N: SubAssign<N>> SubAssign<$t<N>> for $t<N> {
#[inline]
fn sub_assign(&mut self, right: $t<N>) {
$( self.$compN -= right.$compN; )+
}
}
)
);
macro_rules! mat_mul_scalar_impl(
($t: ident, $($compN: ident),+) => (
impl<N: Mul<N, Output = N>> Mul<N> for N {
type Output = $t<N>;
#[inline]
fn mul(self, right: N) -> $t<N> {
$t::new($(self.$compN * *right),+)
}
}
impl<N: MulAssign<N>> MulAssign<N> for $t<N> {
#[inline]
fn mul_assign(&mut self, right: N) {
$( self.$compN *= *right; )+
}
}
impl Mul<$t<f32>> for f32 {
type Output = $t<f32>;
#[inline]
fn mul(self, right: $t<f32>) -> $t<f32> {
$t::new($(self * right.$compN),+)
}
}
impl Mul<$t<f64>> for f64 {
type Output = $t<f64>;
#[inline]
fn mul(self, right: $t<f64>) -> $t<f64> {
$t::new($(self * right.$compN),+)
}
}
)
);
macro_rules! mat_div_scalar_impl(
($t: ident, $($compN: ident),+) => (
impl<N: Div<N, Output = N>> Div<N> for $t<N> {
type Output = $t<N>;
#[inline]
fn div(self, right: N) -> $t<N> {
$t::new($(self.$compN / *right),+)
}
}
impl<N: DivAssign<N>> DivAssign<N> for $t<N> {
#[inline]
fn div_assign(&mut self, right: N) {
$( self.$compN /= *right; )+
}
}
)
);
macro_rules! mat_add_scalar_impl(
($t: ident, $($compN: ident),+) => (
impl<N: Add<N, Output = N>> Add<N> for $t<N> {
type Output = $t<N>;
#[inline]
fn add(self, right: N) -> $t<N> {
$t::new($(self.$compN + *right),+)
}
}
impl<N: AddAssign<N>> AddAssign<N> for $t<N> {
#[inline]
fn add_assign(&mut self, right: N) {
$( self.$compN += *right; )+
}
}
impl Add<$t<f32>> for f32 {
type Output = $t<f32>;
#[inline]
fn add(self, right: $t<f32>) -> $t<f32> {
$t::new($(self + right.$compN),+)
}
}
impl Add<$t<f64>> for f64 {
type Output = $t<f64>;
#[inline]
fn add(self, right: $t<f64>) -> $t<f64> {
$t::new($(self + right.$compN),+)
}
}
)
);
macro_rules! mat_sub_scalar_impl(
($t: ident, $($compN: ident),+) => (
impl<N: Sub<N, Output = N>> Sub<N> for $t<N> {
type Output = $t<N>;
#[inline]
fn sub(self, right: &N) -> $t<N> {
$t::new($(self.$compN - *right),+)
}
}
impl<N: SubAssign<N>> SubAssign<N> for $t<N> {
#[inline]
fn sub_assign(&mut self, right: N) {
$( self.$compN -= *right; )+
}
}
impl Sub<f32> for $t<f32> {
type Output = $t<f32>;
#[inline]
fn sub(self, right: $t<f32>) -> $t<f32> {
$t::new($(self - right.$compN),+)
}
}
impl Sub<f64> for $t<f64> {
type Output = $t<f64>;
#[inline]
fn sub(self, right: $t<f64>) -> $t<f64> {
$t::new($(self - right.$compN),+)
}
}
)
);
macro_rules! eye_impl(
($t: ident, $dimension: expr, $($comp_diagN: ident),+) => (
impl<N: Zero + One> Eye for $t<N> {
fn new_identity(dimension: usize) -> $t<N> {
assert!(dimension == $dimension);
let mut eye: $t<N> = ::zero();
$(eye.$comp_diagN = ::one();)+
eye
}
}
)
);
macro_rules! repeat_impl(
($t: ident, $($compN: ident),+) => (
impl<N: Copy> Repeat<N> for $t<N> {
fn repeat(val: N) -> $t<N> {
$t {
$($compN: val ),+
} }
} }
} }
)
);
macro_rules! absolute_impl( impl<N> IterableMut<N> for $t<N> {
($t: ident, $($compN: ident),+) => ( #[inline]
impl<N: Absolute<N>> Absolute<$t<N>> for $t<N> { fn iter_mut(& mut self) -> IterMut<N> {
#[inline] unsafe {
fn abs(m: &$t<N>) -> $t<N> { mem::transmute::<&mut $t<N>, &mut [N; $dimension * $dimension]>(self).iter_mut()
$t::new($(::abs(&m.$compN) ),+) }
}
}
)
);
macro_rules! iterable_impl(
($t: ident, $dimension: expr) => (
impl<N> Iterable<N> for $t<N> {
#[inline]
fn iter(&self) -> Iter<N> {
unsafe {
mem::transmute::<&$t<N>, &[N; $dimension * $dimension]>(self).iter()
}
}
}
)
);
macro_rules! iterable_mut_impl(
($t: ident, $dimension: expr) => (
impl<N> IterableMut<N> for $t<N> {
#[inline]
fn iter_mut(& mut self) -> IterMut<N> {
unsafe {
mem::transmute::<&mut $t<N>, &mut [N; $dimension * $dimension]>(self).iter_mut()
}
}
}
)
);
macro_rules! one_impl(
($t: ident, $($valueN: expr),+ ) => (
impl<N: Copy + BaseNum> One for $t<N> {
#[inline]
fn one() -> $t<N> {
$t::new($($valueN() ),+)
}
}
)
);
macro_rules! zero_impl(
($t: ident, $($compN: ident),+ ) => (
impl<N: Zero> Zero for $t<N> {
#[inline]
fn zero() -> $t<N> {
$t {
$($compN: ::zero() ),+
} }
} }
#[inline]
fn is_zero(&self) -> bool {
$(::is_zero(&self.$compN) )&&+
}
}
)
);
macro_rules! dim_impl( /*
($t: ident, $dimension: expr) => ( *
impl<N> Dimension for $t<N> { * Shape/Indexable/Index
#[inline] *
fn dimension(_: Option<$t<N>>) -> usize { */
$dimension impl<N> Shape<(usize, usize)> for $t<N> {
} #[inline]
} fn shape(&self) -> (usize, usize) {
) ($dimension, $dimension)
);
macro_rules! indexable_impl(
($t: ident, $dimension: expr) => (
impl<N> Shape<(usize, usize)> for $t<N> {
#[inline]
fn shape(&self) -> (usize, usize) {
($dimension, $dimension)
}
}
impl<N: Copy> Indexable<(usize, usize), N> for $t<N> {
#[inline]
fn swap(&mut self, (i1, j1): (usize, usize), (i2, j2): (usize, usize)) {
unsafe {
mem::transmute::<&mut $t<N>, &mut [N; $dimension * $dimension]>(self)
.swap(i1 + j1 * $dimension, i2 + j2 * $dimension)
} }
} }
#[inline] impl<N: Copy> Indexable<(usize, usize), N> for $t<N> {
unsafe fn unsafe_at(&self, (i, j): (usize, usize)) -> N { #[inline]
(*mem::transmute::<&$t<N>, &[N; $dimension * $dimension]>(self).get_unchecked(i + j * $dimension)) fn swap(&mut self, (i1, j1): (usize, usize), (i2, j2): (usize, usize)) {
unsafe {
mem::transmute::<&mut $t<N>, &mut [N; $dimension * $dimension]>(self)
.swap(i1 + j1 * $dimension, i2 + j2 * $dimension)
}
}
#[inline]
unsafe fn unsafe_at(&self, (i, j): (usize, usize)) -> N {
(*mem::transmute::<&$t<N>, &[N; $dimension * $dimension]>(self).get_unchecked(i + j * $dimension))
}
#[inline]
unsafe fn unsafe_set(&mut self, (i, j): (usize, usize), val: N) {
(*mem::transmute::<&mut $t<N>, &mut [N; $dimension * $dimension]>(self).get_unchecked_mut(i + j * $dimension)) = val
}
} }
#[inline]
unsafe fn unsafe_set(&mut self, (i, j): (usize, usize), val: N) {
(*mem::transmute::<&mut $t<N>, &mut [N; $dimension * $dimension]>(self).get_unchecked_mut(i + j * $dimension)) = val
}
}
)
);
macro_rules! index_impl(
($t: ident, $dimension: expr) => (
impl<N> Index<(usize, usize)> for $t<N> { impl<N> Index<(usize, usize)> for $t<N> {
type Output = N; type Output = N;
@ -418,96 +168,167 @@ macro_rules! index_impl(
} }
} }
} }
)
);
macro_rules! column_slice_impl(
($t: ident, $tv: ident, $slice: ident, $dimension: expr) => ( /*
impl<N: Clone + Copy + Zero> ColumnSlice<$slice<N>> for $t<N> { *
fn column_slice(&self, cid: usize, rstart: usize, rend: usize) -> $slice<N> { * Row/Column
*
*/
impl<N: Copy + Zero> Column<$vector<N>> for $t<N> {
#[inline]
fn ncols(&self) -> usize {
Dimension::dimension(None::<$t<N>>)
}
#[inline]
fn set_column(&mut self, column: usize, v: $vector<N>) {
for (i, e) in v.iter().enumerate() {
self[(i, column)] = *e;
}
}
#[inline]
fn column(&self, column: usize) -> $vector<N> {
let mut res: $vector<N> = ::zero();
for (i, e) in res.iter_mut().enumerate() {
*e = self[(i, column)];
}
res
}
}
impl<N: Clone + Copy + Zero> ColumnSlice<$dvector<N>> for $t<N> {
fn column_slice(&self, cid: usize, rstart: usize, rend: usize) -> $dvector<N> {
let column = self.column(cid); let column = self.column(cid);
$slice::from_slice(rend - rstart, &column.as_ref()[rstart .. rend]) $dvector::from_slice(rend - rstart, &column.as_ref()[rstart .. rend])
}
}
)
);
macro_rules! row_impl(
($t: ident, $tv: ident, $dimension: expr) => (
impl<N: Copy + Zero> Row<$tv<N>> for $t<N> {
#[inline]
fn nrows(&self) -> usize {
Dimension::dimension(None::<$t<N>>)
}
#[inline]
fn set_row(&mut self, row: usize, v: $tv<N>) {
for (i, e) in v.iter().enumerate() {
self[(row, i)] = *e;
} }
} }
#[inline] impl<N: Copy + Zero> Row<$vector<N>> for $t<N> {
fn row(&self, row: usize) -> $tv<N> { #[inline]
let mut res: $tv<N> = ::zero(); fn nrows(&self) -> usize {
Dimension::dimension(None::<$t<N>>)
for (i, e) in res.iter_mut().enumerate() {
*e = self[(row, i)];
} }
res #[inline]
} fn set_row(&mut self, row: usize, v: $vector<N>) {
} for (i, e) in v.iter().enumerate() {
) self[(row, i)] = *e;
); }
}
macro_rules! row_slice_impl( #[inline]
($t: ident, $tv: ident, $slice: ident, $dimension: expr) => ( fn row(&self, row: usize) -> $vector<N> {
impl<N: Clone + Copy + Zero> RowSlice<$slice<N>> for $t<N> { let mut res: $vector<N> = ::zero();
fn row_slice(&self, rid: usize, cstart: usize, cend: usize) -> $slice<N> {
for (i, e) in res.iter_mut().enumerate() {
*e = self[(row, i)];
}
res
}
}
impl<N: Clone + Copy + Zero> RowSlice<$dvector<N>> for $t<N> {
fn row_slice(&self, rid: usize, cstart: usize, cend: usize) -> $dvector<N> {
let row = self.row(rid); let row = self.row(rid);
$slice::from_slice(cend - cstart, &row.as_ref()[cstart .. cend]) $dvector::from_slice(cend - cstart, &row.as_ref()[cstart .. cend])
}
}
)
);
macro_rules! column_impl(
($t: ident, $tv: ident, $dimension: expr) => (
impl<N: Copy + Zero> Column<$tv<N>> for $t<N> {
#[inline]
fn ncols(&self) -> usize {
Dimension::dimension(None::<$t<N>>)
}
#[inline]
fn set_column(&mut self, column: usize, v: $tv<N>) {
for (i, e) in v.iter().enumerate() {
self[(i, column)] = *e;
} }
} }
#[inline]
fn column(&self, column: usize) -> $tv<N> {
let mut res: $tv<N> = ::zero();
for (i, e) in res.iter_mut().enumerate() { /*
*e = self[(i, column)]; *
} * Transpose
*
res */
} impl<N: Copy> Transpose for $t<N> {
}
)
);
macro_rules! diag_impl(
($t: ident, $tv: ident, $dimension: expr) => (
impl<N: Copy + Zero> Diagonal<$tv<N>> for $t<N> {
#[inline] #[inline]
fn from_diagonal(diagonal: &$tv<N>) -> $t<N> { fn transpose(&self) -> $t<N> {
let mut res = *self;
res.transpose_mut();
res
}
#[inline]
fn transpose_mut(&mut self) {
for i in 1 .. $dimension {
for j in 0 .. i {
self.swap((i, j), (j, i))
}
}
}
}
/*
*
* ApproxEq
*
*/
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
#[inline]
fn approx_epsilon(_: Option<$t<N>>) -> N {
ApproxEq::approx_epsilon(None::<N>)
}
#[inline]
fn approx_ulps(_: Option<$t<N>>) -> u32 {
ApproxEq::approx_ulps(None::<N>)
}
#[inline]
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N) -> bool {
let mut zip = self.iter().zip(other.iter());
zip.all(|(a, b)| ApproxEq::approx_eq_eps(a, b, epsilon))
}
#[inline]
fn approx_eq_ulps(&self, other: &$t<N>, ulps: u32) -> bool {
let mut zip = self.iter().zip(other.iter());
zip.all(|(a, b)| ApproxEq::approx_eq_ulps(a, b, ulps))
}
}
/*
*
* Mean
*
*/
impl<N: BaseNum + Cast<f64> + Clone> Mean<$vector<N>> for $t<N> {
fn mean(&self) -> $vector<N> {
let mut res: $vector<N> = ::zero();
let normalizer: N = Cast::from(1.0f64 / $dimension as f64);
for i in 0 .. $dimension {
for j in 0 .. $dimension {
unsafe {
let acc = res.unsafe_at(j) + self.unsafe_at((i, j)) * normalizer;
res.unsafe_set(j, acc);
}
}
}
res
}
}
/*
*
* Diagonal
*
*/
impl<N: Copy + Zero> Diagonal<$vector<N>> for $t<N> {
#[inline]
fn from_diagonal(diagonal: &$vector<N>) -> $t<N> {
let mut res: $t<N> = ::zero(); let mut res: $t<N> = ::zero();
res.set_diagonal(diagonal); res.set_diagonal(diagonal);
@ -516,8 +337,8 @@ macro_rules! diag_impl(
} }
#[inline] #[inline]
fn diagonal(&self) -> $tv<N> { fn diagonal(&self) -> $vector<N> {
let mut diagonal: $tv<N> = ::zero(); let mut diagonal: $vector<N> = ::zero();
for i in 0 .. $dimension { for i in 0 .. $dimension {
unsafe { diagonal.unsafe_set(i, self.unsafe_at((i, i))) } unsafe { diagonal.unsafe_set(i, self.unsafe_at((i, i))) }
@ -527,17 +348,61 @@ macro_rules! diag_impl(
} }
} }
impl<N: Copy + Zero> DiagMut<$tv<N>> for $t<N> { impl<N: Copy + Zero> DiagonalMut<$vector<N>> for $t<N> {
#[inline] #[inline]
fn set_diagonal(&mut self, diagonal: &$tv<N>) { fn set_diagonal(&mut self, diagonal: &$vector<N>) {
for i in 0 .. $dimension { for i in 0 .. $dimension {
unsafe { self.unsafe_set((i, i), diagonal.unsafe_at(i)) } unsafe { self.unsafe_set((i, i), diagonal.unsafe_at(i)) }
} }
} }
} }
/*
*
* Outer
*
*/
impl<N: Copy + Mul<N, Output = N> + Zero> Outer for $vector<N> {
type OuterProductType = $t<N>;
#[inline]
fn outer(&self, other: &$vector<N>) -> $t<N> {
let mut res: $t<N> = ::zero();
for i in 0 .. ::dimension::<$vector<N>>() {
for j in 0 .. ::dimension::<$vector<N>>() {
res[(i, j)] = self[i] * other[j]
}
}
res
}
}
/*
*
* Componentwise unary operations.
*
*/
componentwise_repeat!($t, $($compN),+);
componentwise_absolute!($t, $($compN),+);
componentwise_zero!($t, $($compN),+);
/*
*
* Pointwise binary operations.
*
*/
pointwise_add!($t, $($compN),+);
pointwise_sub!($t, $($compN),+);
pointwise_scalar_add!($t, $($compN),+);
pointwise_scalar_sub!($t, $($compN),+);
pointwise_scalar_div!($t, $($compN),+);
pointwise_scalar_mul!($t, $($compN),+);
) )
); );
macro_rules! mat_mul_mat_impl( macro_rules! mat_mul_mat_impl(
($t: ident, $dimension: expr) => ( ($t: ident, $dimension: expr) => (
impl<N: Copy + BaseNum> Mul<$t<N>> for $t<N> { impl<N: Copy + BaseNum> Mul<$t<N>> for $t<N> {
@ -727,56 +592,6 @@ macro_rules! inverse_impl(
) )
); );
macro_rules! transpose_impl(
($t: ident, $dimension: expr) => (
impl<N: Copy> Transpose for $t<N> {
#[inline]
fn transpose(&self) -> $t<N> {
let mut res = *self;
res.transpose_mut();
res
}
#[inline]
fn transpose_mut(&mut self) {
for i in 1 .. $dimension {
for j in 0 .. i {
self.swap((i, j), (j, i))
}
}
}
}
)
);
macro_rules! approx_eq_impl(
($t: ident) => (
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
#[inline]
fn approx_epsilon(_: Option<$t<N>>) -> N {
ApproxEq::approx_epsilon(None::<N>)
}
#[inline]
fn approx_ulps(_: Option<$t<N>>) -> u32 {
ApproxEq::approx_ulps(None::<N>)
}
#[inline]
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N) -> bool {
let mut zip = self.iter().zip(other.iter());
zip.all(|(a, b)| ApproxEq::approx_eq_eps(a, b, epsilon))
}
#[inline]
fn approx_eq_ulps(&self, other: &$t<N>, ulps: u32) -> bool {
let mut zip = self.iter().zip(other.iter());
zip.all(|(a, b)| ApproxEq::approx_eq_ulps(a, b, ulps))
}
}
)
);
macro_rules! to_homogeneous_impl( macro_rules! to_homogeneous_impl(
($t: ident, $t2: ident, $dimension: expr, $dim2: expr) => ( ($t: ident, $t2: ident, $dimension: expr, $dim2: expr) => (
@ -785,8 +600,8 @@ macro_rules! to_homogeneous_impl(
fn to_homogeneous(&self) -> $t2<N> { fn to_homogeneous(&self) -> $t2<N> {
let mut res: $t2<N> = ::one(); let mut res: $t2<N> = ::one();
for i in 0..$dimension { for i in 0 .. $dimension {
for j in 0..$dimension { for j in 0 .. $dimension {
res[(i, j)] = self[(i, j)] res[(i, j)] = self[(i, j)]
} }
} }
@ -804,8 +619,8 @@ macro_rules! from_homogeneous_impl(
fn from(m: &$t2<N>) -> $t<N> { fn from(m: &$t2<N>) -> $t<N> {
let mut res: $t<N> = ::one(); let mut res: $t<N> = ::one();
for i in 0..$dimension { for i in 0 .. $dimension {
for j in 0..$dimension { for j in 0 .. $dimension {
res[(i, j)] = m[(i, j)] res[(i, j)] = m[(i, j)]
} }
} }
@ -819,25 +634,6 @@ macro_rules! from_homogeneous_impl(
) )
); );
macro_rules! outer_impl(
($t: ident, $m: ident) => (
impl<N: Copy + Mul<N, Output = N> + Zero> Outer for $t<N> {
type OuterProductType = $m<N>;
#[inline]
fn outer(&self, other: &$t<N>) -> $m<N> {
let mut res: $m<N> = ::zero();
for i in 0 .. ::dimension::<$t<N>>() {
for j in 0 .. ::dimension::<$t<N>>() {
res[(i, j)] = self[i] * other[j]
}
}
res
}
}
)
);
macro_rules! eigen_qr_impl( macro_rules! eigen_qr_impl(
($t: ident, $v: ident) => ( ($t: ident, $v: ident) => (
@ -851,27 +647,6 @@ macro_rules! eigen_qr_impl(
); );
macro_rules! mean_impl(
($t: ident, $v: ident, $dimension: expr) => (
impl<N: BaseNum + Cast<f64> + Clone> Mean<$v<N>> for $t<N> {
fn mean(&self) -> $v<N> {
let mut res: $v<N> = ::zero();
let normalizer: N = Cast::from(1.0f64 / $dimension as f64);
for i in 0 .. $dimension {
for j in 0 .. $dimension {
unsafe {
let acc = res.unsafe_at(j) + self.unsafe_at((i, j)) * normalizer;
res.unsafe_set(j, acc);
}
}
}
res
}
}
)
);
macro_rules! mat_display_impl( macro_rules! mat_display_impl(
($t: ident, $dimension: expr) => ( ($t: ident, $dimension: expr) => (
@ -925,3 +700,39 @@ macro_rules! mat_display_impl(
} }
) )
); );
macro_rules! one_impl(
($t: ident, $($valueN: expr),+ ) => (
impl<N: Copy + BaseNum> One for $t<N> {
#[inline]
fn one() -> $t<N> {
$t::new($($valueN() ),+)
}
}
)
);
macro_rules! eye_impl(
($t: ident, $dimension: expr, $($comp_diagN: ident),+) => (
impl<N: Zero + One> Eye for $t<N> {
fn new_identity(dimension: usize) -> $t<N> {
assert!(dimension == $dimension);
let mut eye: $t<N> = ::zero();
$(eye.$comp_diagN = ::one();)+
eye
}
}
)
);
macro_rules! dim_impl(
($t: ident, $dimension: expr) => (
impl<N> Dimension for $t<N> {
#[inline]
fn dimension(_: Option<$t<N>>) -> usize {
$dimension
}
}
)
);

View File

@ -15,6 +15,7 @@ pub use self::quaternion::{Quaternion, UnitQuaternion};
#[cfg(feature="generic_sizes")] #[cfg(feature="generic_sizes")]
pub use self::vectorn::VectorN; pub use self::vectorn::VectorN;
mod common_macros;
mod dmatrix_macros; mod dmatrix_macros;
mod dmatrix; mod dmatrix;
mod vectorn_macros; mod vectorn_macros;

View File

@ -27,38 +27,9 @@ pub struct Point1<N> {
pub x: N pub x: N
} }
new_impl!(Point1, x); point_impl!(Point1, Vector1, Point2, y | x);
origin_impl!(Point1, x); vectorlike_impl!(Point1, 1, x);
pord_impl!(Point1, x,);
scalar_mul_impl!(Point1, x);
scalar_div_impl!(Point1, x);
scalar_add_impl!(Point1, x);
scalar_sub_impl!(Point1, x);
vec_cast_impl!(Point1, x);
conversion_impl!(Point1, 1);
index_impl!(Point1);
indexable_impl!(Point1, 1);
at_fast_impl!(Point1, 1);
repeat_impl!(Point1, val, x);
dim_impl!(Point1, 1);
container_impl!(Point1);
point_as_vec_impl!(Point1, Vector1, x);
point_sub_impl!(Point1, Vector1);
neg_impl!(Point1, x);
point_add_vec_impl!(Point1, Vector1, x);
point_sub_vec_impl!(Point1, Vector1, x);
approx_eq_impl!(Point1, x);
from_iterator_impl!(Point1, iterator); from_iterator_impl!(Point1, iterator);
bounded_impl!(Point1, x);
axpy_impl!(Point1, x);
iterable_impl!(Point1, 1);
iterable_mut_impl!(Point1, 1);
point_to_homogeneous_impl!(Point1, Point2, y, x);
point_from_homogeneous_impl!(Point1, Point2, y, x);
num_float_point_impl!(Point1, Vector1);
arbitrary_point_impl!(Point1, x);
rand_impl!(Point1, x);
point_display_impl!(Point1);
/// Point of dimension 2. /// Point of dimension 2.
/// ///
@ -73,38 +44,9 @@ pub struct Point2<N> {
pub y: N pub y: N
} }
new_impl!(Point2, x, y); point_impl!(Point2, Vector2, Point3, z | x, y);
origin_impl!(Point2, x, y); vectorlike_impl!(Point2, 2, x, y);
pord_impl!(Point2, x, y);
scalar_mul_impl!(Point2, x, y);
scalar_div_impl!(Point2, x, y);
scalar_add_impl!(Point2, x, y);
scalar_sub_impl!(Point2, x, y);
vec_cast_impl!(Point2, x, y);
conversion_impl!(Point2, 2);
index_impl!(Point2);
indexable_impl!(Point2, 2);
at_fast_impl!(Point2, 2);
repeat_impl!(Point2, val, x, y);
dim_impl!(Point2, 2);
container_impl!(Point2);
point_as_vec_impl!(Point2, Vector2, x, y);
point_sub_impl!(Point2, Vector2);
neg_impl!(Point2, x, y);
point_add_vec_impl!(Point2, Vector2, x, y);
point_sub_vec_impl!(Point2, Vector2, x, y);
approx_eq_impl!(Point2, x, y);
from_iterator_impl!(Point2, iterator, iterator); from_iterator_impl!(Point2, iterator, iterator);
bounded_impl!(Point2, x, y);
axpy_impl!(Point2, x, y);
iterable_impl!(Point2, 2);
iterable_mut_impl!(Point2, 2);
point_to_homogeneous_impl!(Point2, Point3, z, x, y);
point_from_homogeneous_impl!(Point2, Point3, z, x, y);
num_float_point_impl!(Point2, Vector2);
arbitrary_point_impl!(Point2, x, y);
rand_impl!(Point2, x, y);
point_display_impl!(Point2);
/// Point of dimension 3. /// Point of dimension 3.
/// ///
@ -121,38 +63,9 @@ pub struct Point3<N> {
pub z: N pub z: N
} }
new_impl!(Point3, x, y, z); point_impl!(Point3, Vector3, Point4, w | x, y, z);
origin_impl!(Point3, x, y, z); vectorlike_impl!(Point3, 3, x, y, z);
pord_impl!(Point3, x, y, z);
scalar_mul_impl!(Point3, x, y, z);
scalar_div_impl!(Point3, x, y, z);
scalar_add_impl!(Point3, x, y, z);
scalar_sub_impl!(Point3, x, y, z);
vec_cast_impl!(Point3, x, y, z);
conversion_impl!(Point3, 3);
index_impl!(Point3);
indexable_impl!(Point3, 3);
at_fast_impl!(Point3, 3);
repeat_impl!(Point3, val, x, y, z);
dim_impl!(Point3, 3);
container_impl!(Point3);
point_as_vec_impl!(Point3, Vector3, x, y, z);
point_sub_impl!(Point3, Vector3);
neg_impl!(Point3, x, y, z);
point_add_vec_impl!(Point3, Vector3, x, y, z);
point_sub_vec_impl!(Point3, Vector3, x, y, z);
approx_eq_impl!(Point3, x, y, z);
from_iterator_impl!(Point3, iterator, iterator, iterator); from_iterator_impl!(Point3, iterator, iterator, iterator);
bounded_impl!(Point3, x, y, z);
axpy_impl!(Point3, x, y, z);
iterable_impl!(Point3, 3);
iterable_mut_impl!(Point3, 3);
point_to_homogeneous_impl!(Point3, Point4, w, x, y, z);
point_from_homogeneous_impl!(Point3, Point4, w, x, y, z);
num_float_point_impl!(Point3, Vector3);
arbitrary_point_impl!(Point3, x, y, z);
rand_impl!(Point3, x, y, z);
point_display_impl!(Point3);
/// Point of dimension 4. /// Point of dimension 4.
/// ///
@ -171,38 +84,9 @@ pub struct Point4<N> {
pub w: N pub w: N
} }
new_impl!(Point4, x, y, z, w); point_impl!(Point4, Vector4, Point5, a | x, y, z, w);
origin_impl!(Point4, x, y, z, w); vectorlike_impl!(Point4, 4, x, y, z, w);
pord_impl!(Point4, x, y, z, w);
scalar_mul_impl!(Point4, x, y, z, w);
scalar_div_impl!(Point4, x, y, z, w);
scalar_add_impl!(Point4, x, y, z, w);
scalar_sub_impl!(Point4, x, y, z, w);
vec_cast_impl!(Point4, x, y, z, w);
conversion_impl!(Point4, 4);
index_impl!(Point4);
indexable_impl!(Point4, 4);
at_fast_impl!(Point4, 4);
repeat_impl!(Point4, val, x, y, z, w);
dim_impl!(Point4, 4);
container_impl!(Point4);
point_as_vec_impl!(Point4, Vector4, x, y, z, w);
point_sub_impl!(Point4, Vector4);
neg_impl!(Point4, x, y, z, w);
point_add_vec_impl!(Point4, Vector4, x, y, z, w);
point_sub_vec_impl!(Point4, Vector4, x, y, z, w);
approx_eq_impl!(Point4, x, y, z, w);
from_iterator_impl!(Point4, iterator, iterator, iterator, iterator); from_iterator_impl!(Point4, iterator, iterator, iterator, iterator);
bounded_impl!(Point4, x, y, z, w);
axpy_impl!(Point4, x, y, z, w);
iterable_impl!(Point4, 4);
iterable_mut_impl!(Point4, 4);
point_to_homogeneous_impl!(Point4, Point5, a, x, y, z, w);
point_from_homogeneous_impl!(Point4, Point5, a, x, y, z, w);
num_float_point_impl!(Point4, Vector4);
arbitrary_point_impl!(Point4, x, y, z, w);
rand_impl!(Point4, x, y, z, w);
point_display_impl!(Point4);
/// Point of dimension 5. /// Point of dimension 5.
/// ///
@ -223,38 +107,9 @@ pub struct Point5<N> {
pub a: N pub a: N
} }
new_impl!(Point5, x, y, z, w, a); point_impl!(Point5, Vector5, Point6, b | x, y, z, w, a);
origin_impl!(Point5, x, y, z, w, a); vectorlike_impl!(Point5, 5, x, y, z, w, a);
pord_impl!(Point5, x, y, z, w, a);
scalar_mul_impl!(Point5, x, y, z, w, a);
scalar_div_impl!(Point5, x, y, z, w, a);
scalar_add_impl!(Point5, x, y, z, w, a);
scalar_sub_impl!(Point5, x, y, z, w, a);
vec_cast_impl!(Point5, x, y, z, w, a);
conversion_impl!(Point5, 5);
index_impl!(Point5);
indexable_impl!(Point5, 5);
at_fast_impl!(Point5, 5);
repeat_impl!(Point5, val, x, y, z, w, a);
dim_impl!(Point5, 5);
container_impl!(Point5);
point_as_vec_impl!(Point5, Vector5, x, y, z, w, a);
point_sub_impl!(Point5, Vector5);
neg_impl!(Point5, x, y, z, w, a);
point_add_vec_impl!(Point5, Vector5, x, y, z, w, a);
point_sub_vec_impl!(Point5, Vector5, x, y, z, w, a);
approx_eq_impl!(Point5, x, y, z, w, a);
from_iterator_impl!(Point5, iterator, iterator, iterator, iterator, iterator); from_iterator_impl!(Point5, iterator, iterator, iterator, iterator, iterator);
bounded_impl!(Point5, x, y, z, w, a);
axpy_impl!(Point5, x, y, z, w, a);
iterable_impl!(Point5, 5);
iterable_mut_impl!(Point5, 5);
point_to_homogeneous_impl!(Point5, Point6, b, x, y, z, w, a);
point_from_homogeneous_impl!(Point5, Point6, b, x, y, z, w, a);
num_float_point_impl!(Point5, Vector5);
arbitrary_point_impl!(Point5, x, y, z, w, a);
rand_impl!(Point5, x, y, z, w, a);
point_display_impl!(Point5);
/// Point of dimension 6. /// Point of dimension 6.
/// ///
@ -277,33 +132,6 @@ pub struct Point6<N> {
pub b: N pub b: N
} }
new_impl!(Point6, x, y, z, w, a, b); point_impl!(Point6, Vector6 | x, y, z, w, a, b);
origin_impl!(Point6, x, y, z, w, a, b); vectorlike_impl!(Point6, 6, x, y, z, w, a, b);
pord_impl!(Point6, x, y, z, w, a, b);
scalar_mul_impl!(Point6, x, y, z, w, a, b);
scalar_div_impl!(Point6, x, y, z, w, a, b);
scalar_add_impl!(Point6, x, y, z, w, a, b);
scalar_sub_impl!(Point6, x, y, z, w, a, b);
vec_cast_impl!(Point6, x, y, z, w, a, b);
conversion_impl!(Point6, 6);
index_impl!(Point6);
indexable_impl!(Point6, 6);
at_fast_impl!(Point6, 6);
repeat_impl!(Point6, val, x, y, z, w, a, b);
dim_impl!(Point6, 6);
container_impl!(Point6);
point_as_vec_impl!(Point6, Vector6, x, y, z, w, a, b);
point_sub_impl!(Point6, Vector6);
neg_impl!(Point6, x, y, z, w, a, b);
point_add_vec_impl!(Point6, Vector6, x, y, z, w, a, b);
point_sub_vec_impl!(Point6, Vector6, x, y, z, w, a, b);
approx_eq_impl!(Point6, x, y, z, w, a, b);
from_iterator_impl!(Point6, iterator, iterator, iterator, iterator, iterator, iterator); from_iterator_impl!(Point6, iterator, iterator, iterator, iterator, iterator, iterator);
bounded_impl!(Point6, x, y, z, w, a, b);
axpy_impl!(Point6, x, y, z, w, a, b);
iterable_impl!(Point6, 6);
iterable_mut_impl!(Point6, 6);
num_float_point_impl!(Point6, Vector6);
arbitrary_point_impl!(Point6, x, y, z, w, a, b);
rand_impl!(Point6, x, y, z, w, a, b);
point_display_impl!(Point6);

View File

@ -1,7 +1,13 @@
#![macro_use] #![macro_use]
macro_rules! origin_impl( macro_rules! point_impl(
($t: ident, $($compN: ident),+) => ( ($t: ident, $tv: ident | $($compN: ident),+) => (
/*
*
* Origin.
*
*/
impl<N: Zero> Origin for $t<N> { impl<N: Zero> Origin for $t<N> {
#[inline] #[inline]
fn origin() -> $t<N> { fn origin() -> $t<N> {
@ -15,11 +21,13 @@ macro_rules! origin_impl(
$(self.$compN.is_zero() )&&+ $(self.$compN.is_zero() )&&+
} }
} }
)
);
macro_rules! point_sub_impl(
($t: ident, $tv: ident) => ( /*
*
* Point - Point
*
*/
impl<N: Copy + Sub<N, Output = N>> Sub<$t<N>> for $t<N> { impl<N: Copy + Sub<N, Output = N>> Sub<$t<N>> for $t<N> {
type Output = $tv<N>; type Output = $tv<N>;
@ -28,11 +36,13 @@ macro_rules! point_sub_impl(
*self.as_vector() - *right.as_vector() *self.as_vector() - *right.as_vector()
} }
} }
)
);
macro_rules! point_add_vec_impl(
($t: ident, $tv: ident, $($compN: ident),+) => ( /*
*
* Point + Vector
*
*/
impl<N: Copy + Add<N, Output = N>> Add<$tv<N>> for $t<N> { impl<N: Copy + Add<N, Output = N>> Add<$tv<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
@ -48,11 +58,13 @@ macro_rules! point_add_vec_impl(
$( self.$compN += right.$compN; )+ $( self.$compN += right.$compN; )+
} }
} }
)
);
macro_rules! point_sub_vec_impl(
($t: ident, $tv: ident, $($compN: ident),+) => ( /*
*
* Point - Vector
*
*/
impl<N: Copy + Sub<N, Output = N>> Sub<$tv<N>> for $t<N> { impl<N: Copy + Sub<N, Output = N>> Sub<$tv<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
@ -68,11 +80,14 @@ macro_rules! point_sub_vec_impl(
$( self.$compN -= right.$compN; )+ $( self.$compN -= right.$compN; )+
} }
} }
)
);
macro_rules! point_as_vec_impl(
($t: ident, $tv: ident, $($compN: ident),+) => (
/*
*
* Point as vector.
*
*/
impl<N> $t<N> { impl<N> $t<N> {
/// Converts this point to its associated vector. /// Converts this point to its associated vector.
#[inline] #[inline]
@ -114,40 +129,14 @@ macro_rules! point_as_vec_impl(
self.set_coords(v) self.set_coords(v)
} }
} }
)
);
macro_rules! point_to_homogeneous_impl(
($t: ident, $t2: ident, $extra: ident, $($compN: ident),+) => (
impl<N: Copy + One + Zero> ToHomogeneous<$t2<N>> for $t<N> {
fn to_homogeneous(&self) -> $t2<N> {
let mut res: $t2<N> = Origin::origin();
$( res.$compN = self.$compN; )+
res.$extra = ::one();
res /*
} *
} * NumPoint / FloatPoint
) *
); */
macro_rules! point_from_homogeneous_impl(
($t: ident, $t2: ident, $extra: ident, $($compN: ident),+) => (
impl<N: Copy + Div<N, Output = N> + One + Zero> FromHomogeneous<$t2<N>> for $t<N> {
fn from(v: &$t2<N>) -> $t<N> {
let mut res: $t<N> = Origin::origin();
$( res.$compN = v.$compN / v.$extra; )+
res
}
}
)
);
macro_rules! num_float_point_impl(
($t: ident, $tv: ident) => (
impl<N> NumPoint<N> for $t<N> impl<N> NumPoint<N> for $t<N>
where N: BaseNum { where N: BaseNum {
} }
@ -155,25 +144,13 @@ macro_rules! num_float_point_impl(
impl<N> FloatPoint<N> for $t<N> impl<N> FloatPoint<N> for $t<N>
where N: BaseFloat + ApproxEq<N> { where N: BaseFloat + ApproxEq<N> {
} }
)
);
macro_rules! arbitrary_point_impl(
($t: ident, $($compN: ident),*) => (
#[cfg(feature="arbitrary")]
impl<N: Arbitrary> Arbitrary for $t<N> {
#[inline]
fn arbitrary<G: Gen>(g: &mut G) -> $t<N> {
$t {
$($compN: Arbitrary::arbitrary(g),)*
}
}
}
)
);
macro_rules! point_display_impl( /*
($t: ident) => ( *
* Display
*
*/
impl<N: fmt::Display> fmt::Display for $t<N> { impl<N: fmt::Display> fmt::Display for $t<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// FIXME: differenciate them from vectors ? // FIXME: differenciate them from vectors ?
@ -190,5 +167,34 @@ macro_rules! point_display_impl(
write!(f, ")") write!(f, ")")
} }
} }
);
($t: ident, $tv: ident, $th: ident, $comp_extra: ident | $($compN: ident),+) => (
point_impl!($t, $tv | $($compN),+);
/*
*
* ToHomogeneous / FromHomogeneous
*
*/
impl<N: Copy + One + Zero> ToHomogeneous<$th<N>> for $t<N> {
fn to_homogeneous(&self) -> $th<N> {
let mut res: $th<N> = Origin::origin();
$( res.$compN = self.$compN; )+
res.$comp_extra = ::one();
res
}
}
impl<N: Copy + Div<N, Output = N> + One + Zero> FromHomogeneous<$th<N>> for $t<N> {
fn from(v: &$th<N>) -> $t<N> {
let mut res: $t<N> = Origin::origin();
$( res.$compN = v.$compN / v.$comp_extra; )+
res
}
}
) )
); );

View File

@ -32,17 +32,6 @@ pub struct Quaternion<N> {
} }
impl<N> Quaternion<N> { impl<N> Quaternion<N> {
/// Creates a new quaternion from its components.
#[inline]
pub fn new(w: N, i: N, j: N, k: N) -> Quaternion<N> {
Quaternion {
w: w,
i: i,
j: j,
k: k
}
}
/// The vector part `(i, j, k)` of this quaternion. /// The vector part `(i, j, k)` of this quaternion.
#[inline] #[inline]
pub fn vector(&self) -> &Vector3<N> { pub fn vector(&self) -> &Vector3<N> {
@ -176,9 +165,6 @@ impl<N: fmt::Display> fmt::Display for Quaternion<N> {
} }
} }
rand_impl!(Quaternion, w, i, j, k);
/// A unit quaternion that can represent a 3D rotation. /// A unit quaternion that can represent a 3D rotation.
#[repr(C)] #[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)] #[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
@ -557,6 +543,18 @@ impl<N: fmt::Display> fmt::Display for UnitQuaternion<N> {
} }
} }
/*
*
* Dimension
*
*/
impl<N> Dimension for UnitQuaternion<N> {
#[inline]
fn dimension(_: Option<UnitQuaternion<N>>) -> usize {
3
}
}
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for UnitQuaternion<N> { impl<N: Arbitrary + BaseFloat> Arbitrary for UnitQuaternion<N> {
fn arbitrary<G: Gen>(g: &mut G) -> UnitQuaternion<N> { fn arbitrary<G: Gen>(g: &mut G) -> UnitQuaternion<N> {
@ -592,45 +590,15 @@ impl Quaternion<f32> {
} }
} }
impl<T> Zero for Quaternion<T> where T: Zero {
fn zero() -> Self {
Quaternion::new(::zero(), ::zero(), ::zero(), ::zero())
}
fn is_zero(&self) -> bool {
self.w.is_zero() && self.i.is_zero() && self.j.is_zero() && self.k.is_zero()
}
}
impl<T> One for Quaternion<T> where T: Copy + One + Zero + Sub<T, Output = T> + Add<T, Output = T> { impl<T> One for Quaternion<T> where T: Copy + One + Zero + Sub<T, Output = T> + Add<T, Output = T> {
fn one() -> Self { fn one() -> Self {
Quaternion::new(T::one(), T::zero(), T::zero(), T::zero()) Quaternion::new(T::one(), T::zero(), T::zero(), T::zero())
} }
} }
pord_impl!(Quaternion, w, i, j, k); componentwise_zero!(Quaternion, w, i, j, k);
vec_axis_impl!(Quaternion, w, i, j, k); component_basis_element!(Quaternion, w, i, j, k);
vec_cast_impl!(Quaternion, w, i, j, k); pointwise_add!(Quaternion, w, i, j, k);
conversion_impl!(Quaternion, 4); pointwise_sub!(Quaternion, w, i, j, k);
index_impl!(Quaternion);
indexable_impl!(Quaternion, 4);
at_fast_impl!(Quaternion, 4);
repeat_impl!(Quaternion, val, w, i, j, k);
dim_impl!(Quaternion, 3);
container_impl!(Quaternion);
add_impl!(Quaternion, w, i, j, k);
sub_impl!(Quaternion, w, i, j, k);
scalar_add_impl!(Quaternion, w, i, j, k);
scalar_sub_impl!(Quaternion, w, i, j, k);
scalar_mul_impl!(Quaternion, w, i, j, k);
scalar_div_impl!(Quaternion, w, i, j, k);
neg_impl!(Quaternion, w, i, j, k);
approx_eq_impl!(Quaternion, w, i, j, k);
from_iterator_impl!(Quaternion, iterator, iterator, iterator, iterator); from_iterator_impl!(Quaternion, iterator, iterator, iterator, iterator);
bounded_impl!(Quaternion, w, i, j, k); vectorlike_impl!(Quaternion, 4, w, i, j, k);
axpy_impl!(Quaternion, w, i, j, k);
iterable_impl!(Quaternion, 4);
iterable_mut_impl!(Quaternion, 4);
arbitrary_impl!(Quaternion, w, i, j, k);
dim_impl!(UnitQuaternion, 3);

View File

@ -105,13 +105,6 @@ impl<N: BaseFloat> AbsoluteRotate<Vector2<N>> for Rotation2<N> {
} }
} }
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for Rotation2<N> {
fn arbitrary<G: Gen>(g: &mut G) -> Rotation2<N> {
Rotation2::new(Arbitrary::arbitrary(g))
}
}
/* /*
* 3d rotation * 3d rotation
@ -343,60 +336,13 @@ impl<N: BaseFloat> AbsoluteRotate<Vector3<N>> for Rotation3<N> {
} }
} }
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for Rotation3<N> {
fn arbitrary<G: Gen>(g: &mut G) -> Rotation3<N> {
Rotation3::new(Arbitrary::arbitrary(g))
}
}
/* /*
* Common implementations. * Common implementations.
*/ */
submat_impl!(Rotation2, Matrix2); rotation_impl!(Rotation2, Matrix2, Vector2, Vector1, Point2, Matrix3);
rotate_impl!(Rotation2, Vector2, Point2);
transform_impl!(Rotation2, Vector2, Point2);
dim_impl!(Rotation2, 2); dim_impl!(Rotation2, 2);
rotation_mul_rotation_impl!(Rotation2);
rotation_mul_vec_impl!(Rotation2, Vector2);
vec_mul_rotation_impl!(Rotation2, Vector2);
rotation_mul_point_impl!(Rotation2, Point2);
point_mul_rotation_impl!(Rotation2, Point2);
one_impl!(Rotation2);
eye_impl!(Rotation2);
rotation_matrix_impl!(Rotation2, Vector2, Vector1);
column_impl!(Rotation2, Vector2);
row_impl!(Rotation2, Vector2);
index_impl!(Rotation2);
absolute_impl!(Rotation2, Matrix2);
to_homogeneous_impl!(Rotation2, Matrix3);
inverse_impl!(Rotation2);
transpose_impl!(Rotation2);
approx_eq_impl!(Rotation2);
diag_impl!(Rotation2, Vector2);
rotation_display_impl!(Rotation2);
submat_impl!(Rotation3, Matrix3); rotation_impl!(Rotation3, Matrix3, Vector3, Vector3, Point3, Matrix4);
rotate_impl!(Rotation3, Vector3, Point3);
transform_impl!(Rotation3, Vector3, Point3);
dim_impl!(Rotation3, 3); dim_impl!(Rotation3, 3);
rotation_mul_rotation_impl!(Rotation3);
rotation_mul_vec_impl!(Rotation3, Vector3);
vec_mul_rotation_impl!(Rotation3, Vector3);
rotation_mul_point_impl!(Rotation3, Point3);
point_mul_rotation_impl!(Rotation3, Point3);
one_impl!(Rotation3);
eye_impl!(Rotation3);
rotation_matrix_impl!(Rotation3, Vector3, Vector3);
column_impl!(Rotation3, Vector3);
row_impl!(Rotation3, Vector3);
index_impl!(Rotation3);
absolute_impl!(Rotation3, Matrix3);
to_homogeneous_impl!(Rotation3, Matrix4);
inverse_impl!(Rotation3);
transpose_impl!(Rotation3);
approx_eq_impl!(Rotation3);
diag_impl!(Rotation3, Vector3);
rotation_display_impl!(Rotation3);

View File

@ -1,7 +1,7 @@
#![macro_use] #![macro_use]
macro_rules! submat_impl( macro_rules! rotation_impl(
($t: ident, $submatrix: ident) => ( ($t: ident, $submatrix: ident, $vector: ident, $rotvector: ident, $point: ident, $homogeneous: ident) => (
impl<N> $t<N> { impl<N> $t<N> {
/// This rotation's underlying matrix. /// This rotation's underlying matrix.
#[inline] #[inline]
@ -9,79 +9,75 @@ macro_rules! submat_impl(
&self.submatrix &self.submatrix
} }
} }
)
);
macro_rules! rotate_impl(
($t: ident, $tv: ident, $tp: ident) => ( /*
impl<N: BaseNum> Rotate<$tv<N>> for $t<N> { *
* Rotate Vector and Point
*
*/
impl<N: BaseNum> Rotate<$vector<N>> for $t<N> {
#[inline] #[inline]
fn rotate(&self, v: &$tv<N>) -> $tv<N> { fn rotate(&self, v: &$vector<N>) -> $vector<N> {
*self * *v *self * *v
} }
#[inline] #[inline]
fn inverse_rotate(&self, v: &$tv<N>) -> $tv<N> { fn inverse_rotate(&self, v: &$vector<N>) -> $vector<N> {
*v * *self *v * *self
} }
} }
impl<N: BaseNum> Rotate<$tp<N>> for $t<N> { impl<N: BaseNum> Rotate<$point<N>> for $t<N> {
#[inline] #[inline]
fn rotate(&self, p: &$tp<N>) -> $tp<N> { fn rotate(&self, p: &$point<N>) -> $point<N> {
*self * *p *self * *p
} }
#[inline] #[inline]
fn inverse_rotate(&self, p: &$tp<N>) -> $tp<N> { fn inverse_rotate(&self, p: &$point<N>) -> $point<N> {
*p * *self *p * *self
} }
} }
)
);
macro_rules! transform_impl(
($t: ident, $tv: ident, $tp: ident) => ( /*
impl<N: BaseNum> Transform<$tv<N>> for $t<N> { *
* Transform Vector and Point
*
*/
impl<N: BaseNum> Transform<$vector<N>> for $t<N> {
#[inline] #[inline]
fn transform(&self, v: &$tv<N>) -> $tv<N> { fn transform(&self, v: &$vector<N>) -> $vector<N> {
self.rotate(v) self.rotate(v)
} }
#[inline] #[inline]
fn inverse_transform(&self, v: &$tv<N>) -> $tv<N> { fn inverse_transform(&self, v: &$vector<N>) -> $vector<N> {
self.inverse_rotate(v) self.inverse_rotate(v)
} }
} }
impl<N: BaseNum> Transform<$tp<N>> for $t<N> { impl<N: BaseNum> Transform<$point<N>> for $t<N> {
#[inline] #[inline]
fn transform(&self, p: &$tp<N>) -> $tp<N> { fn transform(&self, p: &$point<N>) -> $point<N> {
self.rotate(p) self.rotate(p)
} }
#[inline] #[inline]
fn inverse_transform(&self, p: &$tp<N>) -> $tp<N> { fn inverse_transform(&self, p: &$point<N>) -> $point<N> {
self.inverse_rotate(p) self.inverse_rotate(p)
} }
} }
)
);
macro_rules! dim_impl(
($t: ident, $dimension: expr) => (
impl<N> Dimension for $t<N> {
#[inline]
fn dimension(_: Option<$t<N>>) -> usize {
$dimension
}
}
)
);
macro_rules! rotation_matrix_impl(
($t: ident, $tlv: ident, $tav: ident) => ( /*
impl<N: Zero + BaseNum + Cast<f64> + BaseFloat> RotationMatrix<N, $tlv<N>, $tav<N>> for $t<N> { *
* Rotation Matrix
*
*/
impl<N: Zero + BaseNum + Cast<f64> + BaseFloat> RotationMatrix<N, $vector<N>, $rotvector<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
#[inline] #[inline]
@ -89,22 +85,26 @@ macro_rules! rotation_matrix_impl(
self.clone() self.clone()
} }
} }
)
);
macro_rules! one_impl(
($t: ident) => ( /*
*
* One
*
*/
impl<N: BaseNum> One for $t<N> { impl<N: BaseNum> One for $t<N> {
#[inline] #[inline]
fn one() -> $t<N> { fn one() -> $t<N> {
$t { submatrix: ::one() } $t { submatrix: ::one() }
} }
} }
)
);
macro_rules! eye_impl(
($t: ident) => ( /*
*
* Eye
*
*/
impl<N: BaseNum> Eye for $t<N> { impl<N: BaseNum> Eye for $t<N> {
#[inline] #[inline]
fn new_identity(dimension: usize) -> $t<N> { fn new_identity(dimension: usize) -> $t<N> {
@ -116,27 +116,31 @@ macro_rules! eye_impl(
} }
} }
} }
)
);
macro_rules! diag_impl(
($t: ident, $tv: ident) => ( /*
impl<N: Copy + Zero> Diagonal<$tv<N>> for $t<N> { *
* Diagonal
*
*/
impl<N: Copy + Zero> Diagonal<$vector<N>> for $t<N> {
#[inline] #[inline]
fn from_diagonal(diagonal: &$tv<N>) -> $t<N> { fn from_diagonal(diagonal: &$vector<N>) -> $t<N> {
$t { submatrix: Diagonal::from_diagonal(diagonal) } $t { submatrix: Diagonal::from_diagonal(diagonal) }
} }
#[inline] #[inline]
fn diagonal(&self) -> $tv<N> { fn diagonal(&self) -> $vector<N> {
self.submatrix.diagonal() self.submatrix.diagonal()
} }
} }
)
);
macro_rules! rotation_mul_rotation_impl(
($t: ident) => ( /*
*
* Rotation * Rotation
*
*/
impl<N: BaseNum> Mul<$t<N>> for $t<N> { impl<N: BaseNum> Mul<$t<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
@ -152,56 +156,75 @@ macro_rules! rotation_mul_rotation_impl(
self.submatrix *= right.submatrix self.submatrix *= right.submatrix
} }
} }
)
);
macro_rules! rotation_mul_vec_impl(
($t: ident, $tv: ident) => ( /*
impl<N: BaseNum> Mul<$tv<N>> for $t<N> { *
type Output = $tv<N>; * Rotation * Vector
*
*/
impl<N: BaseNum> Mul<$vector<N>> for $t<N> {
type Output = $vector<N>;
#[inline] #[inline]
fn mul(self, right: $tv<N>) -> $tv<N> { fn mul(self, right: $vector<N>) -> $vector<N> {
self.submatrix * right self.submatrix * right
} }
} }
)
);
macro_rules! rotation_mul_point_impl( impl<N: BaseNum> Mul<$t<N>> for $vector<N> {
($t: ident, $tv: ident) => ( type Output = $vector<N>;
rotation_mul_vec_impl!($t, $tv);
)
);
macro_rules! vec_mul_rotation_impl(
($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$t<N>> for $tv<N> {
type Output = $tv<N>;
#[inline] #[inline]
fn mul(self, right: $t<N>) -> $tv<N> { fn mul(self, right: $t<N>) -> $vector<N> {
self * right.submatrix self * right.submatrix
} }
} }
impl<N: Copy + BaseNum> MulAssign<$t<N>> for $tv<N> { impl<N: Copy + BaseNum> MulAssign<$t<N>> for $vector<N> {
#[inline] #[inline]
fn mul_assign(&mut self, right: $t<N>) { fn mul_assign(&mut self, right: $t<N>) {
*self *= right.submatrix *self *= right.submatrix
} }
} }
)
);
macro_rules! point_mul_rotation_impl(
($t: ident, $tv: ident) => (
vec_mul_rotation_impl!($t, $tv);
)
);
macro_rules! inverse_impl( /*
($t: ident) => ( *
* Rotation * Point
*
*/
impl<N: BaseNum> Mul<$point<N>> for $t<N> {
type Output = $point<N>;
#[inline]
fn mul(self, right: $point<N>) -> $point<N> {
self.submatrix * right
}
}
impl<N: BaseNum> Mul<$t<N>> for $point<N> {
type Output = $point<N>;
#[inline]
fn mul(self, right: $t<N>) -> $point<N> {
self * right.submatrix
}
}
impl<N: Copy + BaseNum> MulAssign<$t<N>> for $point<N> {
#[inline]
fn mul_assign(&mut self, right: $t<N>) {
*self *= right.submatrix
}
}
/*
*
* Inverse
*
*/
impl<N: Copy> Inverse for $t<N> { impl<N: Copy> Inverse for $t<N> {
#[inline] #[inline]
fn inverse_mut(&mut self) -> bool { fn inverse_mut(&mut self) -> bool {
@ -217,11 +240,13 @@ macro_rules! inverse_impl(
Some(self.transpose()) Some(self.transpose())
} }
} }
)
);
macro_rules! transpose_impl(
($t: ident) => ( /*
*
* Transpose
*
*/
impl<N: Copy> Transpose for $t<N> { impl<N: Copy> Transpose for $t<N> {
#[inline] #[inline]
fn transpose(&self) -> $t<N> { fn transpose(&self) -> $t<N> {
@ -233,51 +258,57 @@ macro_rules! transpose_impl(
self.submatrix.transpose_mut() self.submatrix.transpose_mut()
} }
} }
)
);
macro_rules! row_impl(
($t: ident, $tv: ident) => ( /*
impl<N: Copy + Zero> Row<$tv<N>> for $t<N> { *
* Row
*
*/
impl<N: Copy + Zero> Row<$vector<N>> for $t<N> {
#[inline] #[inline]
fn nrows(&self) -> usize { fn nrows(&self) -> usize {
self.submatrix.nrows() self.submatrix.nrows()
} }
#[inline] #[inline]
fn row(&self, i: usize) -> $tv<N> { fn row(&self, i: usize) -> $vector<N> {
self.submatrix.row(i) self.submatrix.row(i)
} }
#[inline] #[inline]
fn set_row(&mut self, i: usize, row: $tv<N>) { fn set_row(&mut self, i: usize, row: $vector<N>) {
self.submatrix.set_row(i, row); self.submatrix.set_row(i, row);
} }
} }
)
);
macro_rules! column_impl(
($t: ident, $tv: ident) => ( /*
impl<N: Copy + Zero> Column<$tv<N>> for $t<N> { *
* Column
*
*/
impl<N: Copy + Zero> Column<$vector<N>> for $t<N> {
#[inline] #[inline]
fn ncols(&self) -> usize { fn ncols(&self) -> usize {
self.submatrix.ncols() self.submatrix.ncols()
} }
#[inline] #[inline]
fn column(&self, i: usize) -> $tv<N> { fn column(&self, i: usize) -> $vector<N> {
self.submatrix.column(i) self.submatrix.column(i)
} }
#[inline] #[inline]
fn set_column(&mut self, i: usize, column: $tv<N>) { fn set_column(&mut self, i: usize, column: $vector<N>) {
self.submatrix.set_column(i, column); self.submatrix.set_column(i, column);
} }
} }
)
);
macro_rules! index_impl(
($t: ident) => ( /*
*
* Index
*
*/
impl<N> Index<(usize, usize)> for $t<N> { impl<N> Index<(usize, usize)> for $t<N> {
type Output = N; type Output = N;
@ -285,22 +316,26 @@ macro_rules! index_impl(
&self.submatrix[i] &self.submatrix[i]
} }
} }
)
);
macro_rules! to_homogeneous_impl(
($t: ident, $tm: ident) => ( /*
impl<N: BaseNum> ToHomogeneous<$tm<N>> for $t<N> { *
* ToHomogeneous
*
*/
impl<N: BaseNum> ToHomogeneous<$homogeneous<N>> for $t<N> {
#[inline] #[inline]
fn to_homogeneous(&self) -> $tm<N> { fn to_homogeneous(&self) -> $homogeneous<N> {
self.submatrix.to_homogeneous() self.submatrix.to_homogeneous()
} }
} }
)
);
macro_rules! approx_eq_impl(
($t: ident) => ( /*
*
* ApproxEq
*
*/
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> { impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
#[inline] #[inline]
fn approx_epsilon(_: Option<$t<N>>) -> N { fn approx_epsilon(_: Option<$t<N>>) -> N {
@ -327,22 +362,27 @@ macro_rules! approx_eq_impl(
ApproxEq::approx_eq_ulps(&self.submatrix, &other.submatrix, ulps) ApproxEq::approx_eq_ulps(&self.submatrix, &other.submatrix, ulps)
} }
} }
)
);
macro_rules! absolute_impl(
($t: ident, $tm: ident) => ( /*
impl<N: Absolute<N>> Absolute<$tm<N>> for $t<N> { *
* Absolute
*
*/
impl<N: Absolute<N>> Absolute<$submatrix<N>> for $t<N> {
#[inline] #[inline]
fn abs(m: &$t<N>) -> $tm<N> { fn abs(m: &$t<N>) -> $submatrix<N> {
Absolute::abs(&m.submatrix) Absolute::abs(&m.submatrix)
} }
} }
)
);
macro_rules! rotation_display_impl(
($t: ident) => (
/*
*
* Display
*
*/
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> { impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let precision = f.precision().unwrap_or(3); let precision = f.precision().unwrap_or(3);
@ -352,5 +392,29 @@ macro_rules! rotation_display_impl(
writeln!(f, "}}") writeln!(f, "}}")
} }
} }
/*
*
* Arbitrary
*
*/
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for $t<N> {
fn arbitrary<G: Gen>(g: &mut G) -> $t<N> {
$t::new(Arbitrary::arbitrary(g))
}
}
)
);
macro_rules! dim_impl(
($t: ident, $dimension: expr) => (
impl<N> Dimension for $t<N> {
#[inline]
fn dimension(_: Option<$t<N>>) -> usize {
$dimension
}
}
) )
); );

View File

@ -6,7 +6,7 @@ use num::One;
use structs::matrix::{Matrix3, Matrix4}; use structs::matrix::{Matrix3, Matrix4};
use traits::structure::{Dimension, Column, BaseFloat, BaseNum}; use traits::structure::{Dimension, Column, BaseFloat, BaseNum};
use traits::operations::{Inverse, ApproxEq}; use traits::operations::{Inverse, ApproxEq};
use traits::geometry::{Rotation, Transform, Transformation, Translation, ToHomogeneous}; use traits::geometry::{Transform, Transformation, ToHomogeneous};
use structs::vector::{Vector1, Vector2, Vector3}; use structs::vector::{Vector1, Vector2, Vector3};
use structs::point::{Point2, Point3}; use structs::point::{Point2, Point3};
@ -49,38 +49,9 @@ pub struct Similarity3<N> {
pub isometry: Isometry3<N> pub isometry: Isometry3<N>
} }
sim_impl!(Similarity2, Isometry2, Rotation2, Vector2, Vector1);
dim_impl!(Similarity2, 2);
sim_scale_impl!(Similarity2);
sim_one_impl!(Similarity2);
sim_mul_sim_impl!(Similarity2);
sim_mul_isometry_impl!(Similarity2, Isometry2);
sim_mul_rotation_impl!(Similarity2, Rotation2);
sim_mul_point_vec_impl!(Similarity2, Point2);
sim_mul_point_vec_impl!(Similarity2, Vector2);
transformation_impl!(Similarity2);
sim_transform_impl!(Similarity2, Point2);
sim_inverse_impl!(Similarity2);
sim_to_homogeneous_impl!(Similarity2, Matrix3);
sim_approx_eq_impl!(Similarity2);
sim_rand_impl!(Similarity2);
sim_arbitrary_impl!(Similarity2);
sim_display_impl!(Similarity2);
sim_impl!(Similarity3, Isometry3, Rotation3, Vector3, Vector3); similarity_impl!(Similarity2, Isometry2, Rotation2, Vector2, Vector1, Point2, Matrix3);
dim_impl!(Similarity2, 2);
similarity_impl!(Similarity3, Isometry3, Rotation3, Vector3, Vector3, Point3, Matrix4);
dim_impl!(Similarity3, 3); dim_impl!(Similarity3, 3);
sim_scale_impl!(Similarity3);
sim_one_impl!(Similarity3);
sim_mul_sim_impl!(Similarity3);
sim_mul_isometry_impl!(Similarity3, Isometry3);
sim_mul_rotation_impl!(Similarity3, Rotation3);
sim_mul_point_vec_impl!(Similarity3, Point3);
sim_mul_point_vec_impl!(Similarity3, Vector3);
transformation_impl!(Similarity3);
sim_transform_impl!(Similarity3, Point3);
sim_inverse_impl!(Similarity3);
sim_to_homogeneous_impl!(Similarity3, Matrix4);
sim_approx_eq_impl!(Similarity3);
sim_rand_impl!(Similarity3);
sim_arbitrary_impl!(Similarity3);
sim_display_impl!(Similarity3);

View File

@ -1,13 +1,22 @@
#![macro_use] #![macro_use]
macro_rules! sim_impl( macro_rules! similarity_impl(
($t: ident, $isometry: ident, $rotation_matrix: ident, $subvector: ident, $subrotvector: ident) => ( ($t: ident,
$isometry: ident, $rotation_matrix: ident,
$vector: ident, $rotvector: ident,
$point: ident,
$homogeneous_matrix: ident) => (
impl<N: BaseFloat> $t<N> { impl<N: BaseFloat> $t<N> {
/*
*
* Constructors.
*
*/
/// Creates a new similarity transformation from a vector, an axis-angle rotation, and a scale factor. /// Creates a new similarity transformation from a vector, an axis-angle rotation, and a scale factor.
/// ///
/// The scale factor may be negative but not zero. /// The scale factor may be negative but not zero.
#[inline] #[inline]
pub fn new(translation: $subvector<N>, rotation: $subrotvector<N>, scale: N) -> $t<N> { pub fn new(translation: $vector<N>, rotation: $rotvector<N>, scale: N) -> $t<N> {
assert!(!scale.is_zero(), "A similarity transformation scale factor cannot be zero."); assert!(!scale.is_zero(), "A similarity transformation scale factor cannot be zero.");
$t { $t {
@ -20,7 +29,7 @@ macro_rules! sim_impl(
/// ///
/// The scale factor may be negative but not zero. /// The scale factor may be negative but not zero.
#[inline] #[inline]
pub fn new_with_rotation_matrix(translation: $subvector<N>, rotation: $rotation_matrix<N>, scale: N) -> $t<N> { pub fn new_with_rotation_matrix(translation: $vector<N>, rotation: $rotation_matrix<N>, scale: N) -> $t<N> {
assert!(!scale.is_zero(), "A similarity transformation scale factor cannot be zero."); assert!(!scale.is_zero(), "A similarity transformation scale factor cannot be zero.");
$t { $t {
@ -41,13 +50,12 @@ macro_rules! sim_impl(
isometry: isometry isometry: isometry
} }
} }
}
)
);
macro_rules! sim_scale_impl( /*
($t: ident) => ( *
impl<N: BaseFloat> $t<N> { * Methods related to scaling.
*
*/
/// The scale factor of this similarity transformation. /// The scale factor of this similarity transformation.
#[inline] #[inline]
pub fn scale(&self) -> N { pub fn scale(&self) -> N {
@ -96,22 +104,61 @@ macro_rules! sim_scale_impl(
self.scale = s self.scale = s
} }
} }
)
);
macro_rules! sim_one_impl( /*
($t: ident) => ( *
* One Impl.
*
*/
impl<N: BaseFloat> One for $t<N> { impl<N: BaseFloat> One for $t<N> {
#[inline] #[inline]
fn one() -> $t<N> { fn one() -> $t<N> {
$t::new_with_isometry(::one(), ::one()) $t::new_with_isometry(::one(), ::one())
} }
} }
)
);
macro_rules! sim_mul_sim_impl(
($t: ident) => ( /*
*
* Transformation
*
*/
impl<N: BaseFloat> Transformation<$t<N>> for $t<N> {
fn transformation(&self) -> $t<N> {
*self
}
fn inverse_transformation(&self) -> $t<N> {
// inversion will never fails
Inverse::inverse(self).unwrap()
}
fn append_transformation_mut(&mut self, t: &$t<N>) {
*self = *t * *self
}
fn append_transformation(&self, t: &$t<N>) -> $t<N> {
*t * *self
}
fn prepend_transformation_mut(&mut self, t: &$t<N>) {
*self = *self * *t
}
fn prepend_transformation(&self, t: &$t<N>) -> $t<N> {
*self * *t
}
fn set_transformation(&mut self, t: $t<N>) {
*self = t
}
}
/*
*
* Similarity × Similarity
*
*/
impl<N: BaseFloat> Mul<$t<N>> for $t<N> { impl<N: BaseFloat> Mul<$t<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
@ -132,16 +179,18 @@ macro_rules! sim_mul_sim_impl(
self.scale *= right.scale; self.scale *= right.scale;
} }
} }
)
);
macro_rules! sim_mul_isometry_impl(
($t: ident, $ti: ident) => ( /*
impl<N: BaseFloat> Mul<$ti<N>> for $t<N> { *
* Similarity × Isometry
*
*/
impl<N: BaseFloat> Mul<$isometry<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
#[inline] #[inline]
fn mul(self, right: $ti<N>) -> $t<N> { fn mul(self, right: $isometry<N>) -> $t<N> {
$t::new_with_rotation_matrix( $t::new_with_rotation_matrix(
self.isometry.translation + self.isometry.rotation * (right.translation * self.scale), self.isometry.translation + self.isometry.rotation * (right.translation * self.scale),
self.isometry.rotation * right.rotation, self.isometry.rotation * right.rotation,
@ -149,15 +198,15 @@ macro_rules! sim_mul_isometry_impl(
} }
} }
impl<N: BaseFloat> MulAssign<$ti<N>> for $t<N> { impl<N: BaseFloat> MulAssign<$isometry<N>> for $t<N> {
#[inline] #[inline]
fn mul_assign(&mut self, right: $ti<N>) { fn mul_assign(&mut self, right: $isometry<N>) {
self.isometry.translation += self.isometry.rotation * (right.translation * self.scale); self.isometry.translation += self.isometry.rotation * (right.translation * self.scale);
self.isometry.rotation *= right.rotation; self.isometry.rotation *= right.rotation;
} }
} }
impl<N: BaseFloat> Mul<$t<N>> for $ti<N> { impl<N: BaseFloat> Mul<$t<N>> for $isometry<N> {
type Output = $t<N>; type Output = $t<N>;
#[inline] #[inline]
@ -168,16 +217,17 @@ macro_rules! sim_mul_isometry_impl(
right.scale) right.scale)
} }
} }
)
);
macro_rules! sim_mul_rotation_impl( /*
($t: ident, $tr: ident) => ( *
impl<N: BaseFloat> Mul<$tr<N>> for $t<N> { * Similarity × Rotation
*
*/
impl<N: BaseFloat> Mul<$rotation_matrix<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
#[inline] #[inline]
fn mul(self, right: $tr<N>) -> $t<N> { fn mul(self, right: $rotation_matrix<N>) -> $t<N> {
$t::new_with_rotation_matrix( $t::new_with_rotation_matrix(
self.isometry.translation, self.isometry.translation,
self.isometry.rotation * right, self.isometry.rotation * right,
@ -185,14 +235,14 @@ macro_rules! sim_mul_rotation_impl(
} }
} }
impl<N: BaseFloat> MulAssign<$tr<N>> for $t<N> { impl<N: BaseFloat> MulAssign<$rotation_matrix<N>> for $t<N> {
#[inline] #[inline]
fn mul_assign(&mut self, right: $tr<N>) { fn mul_assign(&mut self, right: $rotation_matrix<N>) {
self.isometry.rotation *= right; self.isometry.rotation *= right;
} }
} }
impl<N: BaseFloat> Mul<$t<N>> for $tr<N> { impl<N: BaseFloat> Mul<$t<N>> for $rotation_matrix<N> {
type Output = $t<N>; type Output = $t<N>;
#[inline] #[inline]
@ -203,44 +253,56 @@ macro_rules! sim_mul_rotation_impl(
right.scale) right.scale)
} }
} }
)
);
macro_rules! sim_mul_point_vec_impl( /*
($t: ident, $tv: ident) => ( *
impl<N: BaseNum> Mul<$tv<N>> for $t<N> { * Similarity × { Point, Vector }
type Output = $tv<N>; *
*/
impl<N: BaseNum> Mul<$vector<N>> for $t<N> {
type Output = $vector<N>;
#[inline] #[inline]
fn mul(self, right: $tv<N>) -> $tv<N> { fn mul(self, right: $vector<N>) -> $vector<N> {
self.isometry * (right * self.scale) self.isometry * (right * self.scale)
} }
} }
impl<N: BaseNum> Mul<$point<N>> for $t<N> {
type Output = $point<N>;
#[inline]
fn mul(self, right: $point<N>) -> $point<N> {
self.isometry * (right * self.scale)
}
}
// NOTE: there is no viable pre-multiplication definition because of the translation // NOTE: there is no viable pre-multiplication definition because of the translation
// component. // component.
)
);
macro_rules! sim_transform_impl( /*
($t: ident, $tp: ident) => ( *
impl<N: BaseNum> Transform<$tp<N>> for $t<N> { * Similarity × Point
*
*/
impl<N: BaseNum> Transform<$point<N>> for $t<N> {
#[inline] #[inline]
fn transform(&self, p: &$tp<N>) -> $tp<N> { fn transform(&self, p: &$point<N>) -> $point<N> {
self.isometry.transform(&(*p * self.scale)) self.isometry.transform(&(*p * self.scale))
} }
#[inline] #[inline]
fn inverse_transform(&self, p: &$tp<N>) -> $tp<N> { fn inverse_transform(&self, p: &$point<N>) -> $point<N> {
self.isometry.inverse_transform(p) / self.scale self.isometry.inverse_transform(p) / self.scale
} }
} }
)
);
macro_rules! sim_inverse_impl(
($t: ident) => ( /*
*
* Inverse
*
*/
impl<N: BaseNum + Neg<Output = N>> Inverse for $t<N> { impl<N: BaseNum + Neg<Output = N>> Inverse for $t<N> {
#[inline] #[inline]
fn inverse_mut(&mut self) -> bool { fn inverse_mut(&mut self) -> bool {
@ -263,28 +325,32 @@ macro_rules! sim_inverse_impl(
Some(res) Some(res)
} }
} }
)
);
macro_rules! sim_to_homogeneous_impl(
($t: ident, $th: ident) => ( /*
impl<N: BaseNum> ToHomogeneous<$th<N>> for $t<N> { *
fn to_homogeneous(&self) -> $th<N> { * ToHomogeneous
*
*/
impl<N: BaseNum> ToHomogeneous<$homogeneous_matrix<N>> for $t<N> {
fn to_homogeneous(&self) -> $homogeneous_matrix<N> {
let mut res = (*self.isometry.rotation.submatrix() * self.scale).to_homogeneous(); let mut res = (*self.isometry.rotation.submatrix() * self.scale).to_homogeneous();
// copy the translation // copy the translation
let dimension = Dimension::dimension(None::<$th<N>>); let dimension = Dimension::dimension(None::<$homogeneous_matrix<N>>);
res.set_column(dimension - 1, self.isometry.translation.as_point().to_homogeneous().to_vector()); res.set_column(dimension - 1, self.isometry.translation.as_point().to_homogeneous().to_vector());
res res
} }
} }
)
);
macro_rules! sim_approx_eq_impl(
($t: ident) => ( /*
*
* ApproxEq
*
*/
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> { impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
#[inline] #[inline]
fn approx_epsilon(_: Option<$t<N>>) -> N { fn approx_epsilon(_: Option<$t<N>>) -> N {
@ -308,11 +374,13 @@ macro_rules! sim_approx_eq_impl(
ApproxEq::approx_eq_ulps(&self.isometry, &other.isometry, ulps) ApproxEq::approx_eq_ulps(&self.isometry, &other.isometry, ulps)
} }
} }
)
);
macro_rules! sim_rand_impl(
($t: ident) => ( /*
*
* Rand
*
*/
impl<N: Rand + BaseFloat> Rand for $t<N> { impl<N: Rand + BaseFloat> Rand for $t<N> {
#[inline] #[inline]
fn rand<R: Rng>(rng: &mut R) -> $t<N> { fn rand<R: Rng>(rng: &mut R) -> $t<N> {
@ -324,11 +392,13 @@ macro_rules! sim_rand_impl(
$t::new_with_isometry(rng.gen(), scale) $t::new_with_isometry(rng.gen(), scale)
} }
} }
)
);
macro_rules! sim_arbitrary_impl(
($t: ident) => ( /*
*
* Arbitrary
*
*/
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for $t<N> { impl<N: Arbitrary + BaseFloat> Arbitrary for $t<N> {
fn arbitrary<G: Gen>(g: &mut G) -> $t<N> { fn arbitrary<G: Gen>(g: &mut G) -> $t<N> {
@ -338,11 +408,13 @@ macro_rules! sim_arbitrary_impl(
) )
} }
} }
)
);
macro_rules! sim_display_impl(
($t: ident) => ( /*
*
* Display
*
*/
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> { impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(writeln!(f, "Similarity transformation {{")); try!(writeln!(f, "Similarity transformation {{"));

View File

@ -3,7 +3,7 @@ use structs::vector::{Vector2, Vector3};
use structs::point::{Point2, Point3}; use structs::point::{Point2, Point3};
use structs::matrix::{Matrix1, Matrix2, Matrix3}; use structs::matrix::{Matrix1, Matrix2, Matrix3};
use traits::operations::{Inverse, Determinant, ApproxEq}; use traits::operations::{Inverse, Determinant, ApproxEq};
use traits::structure::{Row, Column, BaseNum}; use traits::structure::BaseNum;
// some specializations: // some specializations:
impl<N: BaseNum + ApproxEq<N>> Inverse for Matrix1<N> { impl<N: BaseNum + ApproxEq<N>> Inverse for Matrix1<N> {
@ -129,85 +129,6 @@ impl<N: BaseNum> Determinant<N> for Matrix3<N> {
} }
} }
impl<N: Copy> Row<Vector3<N>> for Matrix3<N> {
#[inline]
fn nrows(&self) -> usize {
3
}
#[inline]
fn row(&self, i: usize) -> Vector3<N> {
match i {
0 => Vector3::new(self.m11, self.m12, self.m13),
1 => Vector3::new(self.m21, self.m22, self.m23),
2 => Vector3::new(self.m31, self.m32, self.m33),
_ => panic!(format!("Index out of range: 3d matrices do not have {} rows.", i))
}
}
#[inline]
fn set_row(&mut self, i: usize, r: Vector3<N>) {
match i {
0 => {
self.m11 = r.x;
self.m12 = r.y;
self.m13 = r.z;
},
1 => {
self.m21 = r.x;
self.m22 = r.y;
self.m23 = r.z;
},
2 => {
self.m31 = r.x;
self.m32 = r.y;
self.m33 = r.z;
},
_ => panic!(format!("Index out of range: 3d matrices do not have {} rows.", i))
}
}
}
impl<N: Copy> Column<Vector3<N>> for Matrix3<N> {
#[inline]
fn ncols(&self) -> usize {
3
}
#[inline]
fn column(&self, i: usize) -> Vector3<N> {
match i {
0 => Vector3::new(self.m11, self.m21, self.m31),
1 => Vector3::new(self.m12, self.m22, self.m32),
2 => Vector3::new(self.m13, self.m23, self.m33),
_ => panic!(format!("Index out of range: 3d matrices do not have {} cols.", i))
}
}
#[inline]
fn set_column(&mut self, i: usize, r: Vector3<N>) {
match i {
0 => {
self.m11 = r.x;
self.m21 = r.y;
self.m31 = r.z;
},
1 => {
self.m12 = r.x;
self.m22 = r.y;
self.m32 = r.z;
},
2 => {
self.m13 = r.x;
self.m23 = r.y;
self.m33 = r.z;
},
_ => panic!(format!("Index out of range: 3d matrices do not have {} cols.", i))
}
}
}
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Matrix3<N> { impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Matrix3<N> {
type Output = Matrix3<N>; type Output = Matrix3<N>;

View File

@ -29,50 +29,14 @@ pub struct Vector1<N> {
pub x: N pub x: N
} }
new_impl!(Vector1, x); vector_impl!(Vector1, Point1, x);
pord_impl!(Vector1, x,); vectorlike_impl!(Vector1, 1, x);
vec_axis_impl!(Vector1, x);
vec_cast_impl!(Vector1, x);
conversion_impl!(Vector1, 1);
index_impl!(Vector1);
indexable_impl!(Vector1, 1);
at_fast_impl!(Vector1, 1);
repeat_impl!(Vector1, val, x);
dim_impl!(Vector1, 1);
container_impl!(Vector1);
// (specialized); basis_impl!(Vector1, 1);
add_impl!(Vector1, x);
sub_impl!(Vector1, x);
mul_impl!(Vector1, x);
div_impl!(Vector1, x);
scalar_add_impl!(Vector1, x);
scalar_sub_impl!(Vector1, x);
scalar_mul_impl!(Vector1, x);
scalar_div_impl!(Vector1, x);
neg_impl!(Vector1, x);
dot_impl!(Vector1, x);
translation_impl!(Vector1);
norm_impl!(Vector1, x);
approx_eq_impl!(Vector1, x);
zero_one_impl!(Vector1, x);
from_iterator_impl!(Vector1, iterator); from_iterator_impl!(Vector1, iterator);
bounded_impl!(Vector1, x); // (specialized); basis_impl!(Vector1, 1);
axpy_impl!(Vector1, x);
iterable_impl!(Vector1, 1);
iterable_mut_impl!(Vector1, 1);
vec_to_homogeneous_impl!(Vector1, Vector2, y, x); vec_to_homogeneous_impl!(Vector1, Vector2, y, x);
vec_from_homogeneous_impl!(Vector1, Vector2, y, x); vec_from_homogeneous_impl!(Vector1, Vector2, y, x);
translate_impl!(Vector1, Point1);
rotate_impl!(Vector1);
rotate_impl!(Point1);
transform_impl!(Vector1, Point1);
vec_as_point_impl!(Vector1, Point1, x);
num_float_vec_impl!(Vector1);
absolute_vec_impl!(Vector1, x);
arbitrary_impl!(Vector1, x);
rand_impl!(Vector1, x);
mean_impl!(Vector1);
vec_display_impl!(Vector1);
/// Vector of dimension 2. /// Vector of dimension 2.
/// ///
@ -87,50 +51,14 @@ pub struct Vector2<N> {
pub y: N pub y: N
} }
new_impl!(Vector2, x, y); vector_impl!(Vector2, Point2, x, y);
pord_impl!(Vector2, x, y); vectorlike_impl!(Vector2, 2, x, y);
vec_axis_impl!(Vector2, x, y);
vec_cast_impl!(Vector2, x, y);
conversion_impl!(Vector2, 2);
index_impl!(Vector2);
indexable_impl!(Vector2, 2);
at_fast_impl!(Vector2, 2);
repeat_impl!(Vector2, val, x, y);
dim_impl!(Vector2, 2);
container_impl!(Vector2);
// (specialized); basis_impl!(Vector2, 1);
add_impl!(Vector2, x, y);
sub_impl!(Vector2, x, y);
mul_impl!(Vector2, x, y);
div_impl!(Vector2, x, y);
scalar_add_impl!(Vector2, x, y);
scalar_sub_impl!(Vector2, x, y);
scalar_mul_impl!(Vector2, x, y);
scalar_div_impl!(Vector2, x, y);
neg_impl!(Vector2, x, y);
dot_impl!(Vector2, x, y);
translation_impl!(Vector2);
norm_impl!(Vector2, x, y);
approx_eq_impl!(Vector2, x, y);
zero_one_impl!(Vector2, x, y);
from_iterator_impl!(Vector2, iterator, iterator); from_iterator_impl!(Vector2, iterator, iterator);
bounded_impl!(Vector2, x, y); // (specialized); basis_impl!(Vector2, 1);
axpy_impl!(Vector2, x, y);
iterable_impl!(Vector2, 2);
iterable_mut_impl!(Vector2, 2);
vec_to_homogeneous_impl!(Vector2, Vector3, z, x, y); vec_to_homogeneous_impl!(Vector2, Vector3, z, x, y);
vec_from_homogeneous_impl!(Vector2, Vector3, z, x, y); vec_from_homogeneous_impl!(Vector2, Vector3, z, x, y);
translate_impl!(Vector2, Point2);
rotate_impl!(Vector2);
rotate_impl!(Point2);
transform_impl!(Vector2, Point2);
vec_as_point_impl!(Vector2, Point2, x, y);
num_float_vec_impl!(Vector2);
absolute_vec_impl!(Vector2, x, y);
arbitrary_impl!(Vector2, x, y);
rand_impl!(Vector2, x, y);
mean_impl!(Vector2);
vec_display_impl!(Vector2);
/// Vector of dimension 3. /// Vector of dimension 3.
/// ///
@ -147,50 +75,12 @@ pub struct Vector3<N> {
pub z: N pub z: N
} }
new_impl!(Vector3, x, y, z); vector_impl!(Vector3, Point3, x, y, z);
pord_impl!(Vector3, x, y, z); vectorlike_impl!(Vector3, 3, x, y, z);
vec_axis_impl!(Vector3, x, y, z);
vec_cast_impl!(Vector3, x, y, z);
conversion_impl!(Vector3, 3);
index_impl!(Vector3);
indexable_impl!(Vector3, 3);
at_fast_impl!(Vector3, 3);
repeat_impl!(Vector3, val, x, y, z);
dim_impl!(Vector3, 3);
container_impl!(Vector3);
// (specialized); basis_impl!(Vector3, 1);
add_impl!(Vector3, x, y, z);
sub_impl!(Vector3, x, y, z);
mul_impl!(Vector3, x, y, z);
div_impl!(Vector3, x, y, z);
scalar_add_impl!(Vector3, x, y, z);
scalar_sub_impl!(Vector3, x, y, z);
scalar_mul_impl!(Vector3, x, y, z);
scalar_div_impl!(Vector3, x, y, z);
neg_impl!(Vector3, x, y, z);
dot_impl!(Vector3, x, y, z);
translation_impl!(Vector3);
norm_impl!(Vector3, x, y ,z);
approx_eq_impl!(Vector3, x, y, z);
zero_one_impl!(Vector3, x, y, z);
from_iterator_impl!(Vector3, iterator, iterator, iterator); from_iterator_impl!(Vector3, iterator, iterator, iterator);
bounded_impl!(Vector3, x, y, z); // (specialized); basis_impl!(Vector3, 1);
axpy_impl!(Vector3, x, y, z);
iterable_impl!(Vector3, 3);
iterable_mut_impl!(Vector3, 3);
vec_to_homogeneous_impl!(Vector3, Vector4, w, x, y, z); vec_to_homogeneous_impl!(Vector3, Vector4, w, x, y, z);
vec_from_homogeneous_impl!(Vector3, Vector4, w, x, y, z); vec_from_homogeneous_impl!(Vector3, Vector4, w, x, y, z);
translate_impl!(Vector3, Point3);
rotate_impl!(Vector3);
rotate_impl!(Point3);
transform_impl!(Vector3, Point3);
vec_as_point_impl!(Vector3, Point3, x, y, z);
num_float_vec_impl!(Vector3);
absolute_vec_impl!(Vector3, x, y, z);
arbitrary_impl!(Vector3, x, y, z);
rand_impl!(Vector3, x, y, z);
mean_impl!(Vector3);
vec_display_impl!(Vector3);
/// Vector of dimension 4. /// Vector of dimension 4.
@ -210,50 +100,14 @@ pub struct Vector4<N> {
pub w: N pub w: N
} }
new_impl!(Vector4, x, y, z, w); vector_impl!(Vector4, Point4, x, y, z, w);
pord_impl!(Vector4, x, y, z, w); vectorlike_impl!(Vector4, 4, x, y, z, w);
vec_axis_impl!(Vector4, x, y, z, w);
vec_cast_impl!(Vector4, x, y, z, w);
conversion_impl!(Vector4, 4);
index_impl!(Vector4);
indexable_impl!(Vector4, 4);
at_fast_impl!(Vector4, 4);
repeat_impl!(Vector4, val, x, y, z, w);
dim_impl!(Vector4, 4);
container_impl!(Vector4);
basis_impl!(Vector4, 4);
add_impl!(Vector4, x, y, z, w);
sub_impl!(Vector4, x, y, z, w);
mul_impl!(Vector4, x, y, z, w);
div_impl!(Vector4, x, y, z, w);
scalar_add_impl!(Vector4, x, y, z, w);
scalar_sub_impl!(Vector4, x, y, z, w);
scalar_mul_impl!(Vector4, x, y, z, w);
scalar_div_impl!(Vector4, x, y, z, w);
neg_impl!(Vector4, x, y, z, w);
dot_impl!(Vector4, x, y, z, w);
translation_impl!(Vector4);
norm_impl!(Vector4, x, y, z, w);
approx_eq_impl!(Vector4, x, y, z, w);
zero_one_impl!(Vector4, x, y, z, w);
from_iterator_impl!(Vector4, iterator, iterator, iterator, iterator); from_iterator_impl!(Vector4, iterator, iterator, iterator, iterator);
bounded_impl!(Vector4, x, y, z, w); basis_impl!(Vector4, 4);
axpy_impl!(Vector4, x, y, z, w);
iterable_impl!(Vector4, 4);
iterable_mut_impl!(Vector4, 4);
vec_to_homogeneous_impl!(Vector4, Vector5, a, x, y, z, w); vec_to_homogeneous_impl!(Vector4, Vector5, a, x, y, z, w);
vec_from_homogeneous_impl!(Vector4, Vector5, a, x, y, z, w); vec_from_homogeneous_impl!(Vector4, Vector5, a, x, y, z, w);
translate_impl!(Vector4, Point4);
rotate_impl!(Vector4);
rotate_impl!(Point4);
transform_impl!(Vector4, Point4);
vec_as_point_impl!(Vector4, Point4, x, y, z, w);
num_float_vec_impl!(Vector4);
absolute_vec_impl!(Vector4, x, y, z, w);
arbitrary_impl!(Vector4, x, y, z, w);
rand_impl!(Vector4, x, y, z, w);
mean_impl!(Vector4);
vec_display_impl!(Vector4);
/// Vector of dimension 5. /// Vector of dimension 5.
/// ///
@ -274,50 +128,13 @@ pub struct Vector5<N> {
pub a: N pub a: N
} }
new_impl!(Vector5, x, y, z, w, a); vector_impl!(Vector5, Point5, x, y, z, w, a);
pord_impl!(Vector5, x, y, z, w, a); vectorlike_impl!(Vector5, 5, x, y, z, w, a);
vec_axis_impl!(Vector5, x, y, z, w, a);
vec_cast_impl!(Vector5, x, y, z, w, a);
conversion_impl!(Vector5, 5);
index_impl!(Vector5);
indexable_impl!(Vector5, 5);
at_fast_impl!(Vector5, 5);
repeat_impl!(Vector5, val, x, y, z, w, a);
dim_impl!(Vector5, 5);
container_impl!(Vector5);
basis_impl!(Vector5, 5);
add_impl!(Vector5, x, y, z, w, a);
sub_impl!(Vector5, x, y, z, w, a);
mul_impl!(Vector5, x, y, z, w, a);
div_impl!(Vector5, x, y, z, w, a);
scalar_add_impl!(Vector5, x, y, z, w, a);
scalar_sub_impl!(Vector5, x, y, z, w, a);
scalar_mul_impl!(Vector5, x, y, z, w, a);
scalar_div_impl!(Vector5, x, y, z, w, a);
neg_impl!(Vector5, x, y, z, w, a);
dot_impl!(Vector5, x, y, z, w, a);
translation_impl!(Vector5);
norm_impl!(Vector5, x, y, z, w, a);
approx_eq_impl!(Vector5, x, y, z, w, a);
zero_one_impl!(Vector5, x, y, z, w, a);
from_iterator_impl!(Vector5, iterator, iterator, iterator, iterator, iterator); from_iterator_impl!(Vector5, iterator, iterator, iterator, iterator, iterator);
bounded_impl!(Vector5, x, y, z, w, a); basis_impl!(Vector5, 5);
axpy_impl!(Vector5, x, y, z, w, a);
iterable_impl!(Vector5, 5);
iterable_mut_impl!(Vector5, 5);
vec_to_homogeneous_impl!(Vector5, Vector6, b, x, y, z, w, a); vec_to_homogeneous_impl!(Vector5, Vector6, b, x, y, z, w, a);
vec_from_homogeneous_impl!(Vector5, Vector6, b, x, y, z, w, a); vec_from_homogeneous_impl!(Vector5, Vector6, b, x, y, z, w, a);
translate_impl!(Vector5, Point5);
rotate_impl!(Vector5);
rotate_impl!(Point5);
transform_impl!(Vector5, Point5);
vec_as_point_impl!(Vector5, Point5, x, y, z, w, a);
num_float_vec_impl!(Vector5);
absolute_vec_impl!(Vector5, x, y, z, w, a);
arbitrary_impl!(Vector5, x, y, z, w, a);
rand_impl!(Vector5, x, y, z, w, a);
mean_impl!(Vector5);
vec_display_impl!(Vector5);
/// Vector of dimension 6. /// Vector of dimension 6.
/// ///
@ -340,45 +157,8 @@ pub struct Vector6<N> {
pub b: N pub b: N
} }
new_impl!(Vector6, x, y, z, w, a, b); vector_impl!(Vector6, Point6, x, y, z, w, a, b);
pord_impl!(Vector6, x, y, z, w, a, b); vectorlike_impl!(Vector6, 6, x, y, z, w, a, b);
vec_axis_impl!(Vector6, x, y, z, w, a, b);
vec_cast_impl!(Vector6, x, y, z, w, a, b);
conversion_impl!(Vector6, 6);
index_impl!(Vector6);
indexable_impl!(Vector6, 6);
at_fast_impl!(Vector6, 6);
repeat_impl!(Vector6, val, x, y, z, w, a, b);
dim_impl!(Vector6, 6);
container_impl!(Vector6);
basis_impl!(Vector6, 6);
add_impl!(Vector6, x, y, z, w, a, b);
sub_impl!(Vector6, x, y, z, w, a, b);
mul_impl!(Vector6, x, y, z, w, a, b);
div_impl!(Vector6, x, y, z, w, a, b);
scalar_add_impl!(Vector6, x, y, z, w, a, b);
scalar_sub_impl!(Vector6, x, y, z, w, a, b);
scalar_mul_impl!(Vector6, x, y, z, w, a, b);
scalar_div_impl!(Vector6, x, y, z, w, a, b);
neg_impl!(Vector6, x, y, z, w, a, b);
dot_impl!(Vector6, x, y, z, w, a, b);
translation_impl!(Vector6);
norm_impl!(Vector6, x, y, z, w, a, b);
approx_eq_impl!(Vector6, x, y, z, w, a, b);
zero_one_impl!(Vector6, x, y, z, w, a, b);
from_iterator_impl!(Vector6, iterator, iterator, iterator, iterator, iterator, iterator); from_iterator_impl!(Vector6, iterator, iterator, iterator, iterator, iterator, iterator);
bounded_impl!(Vector6, x, y, z, w, a, b);
axpy_impl!(Vector6, x, y, z, w, a, b); basis_impl!(Vector6, 6);
iterable_impl!(Vector6, 6);
iterable_mut_impl!(Vector6, 6);
translate_impl!(Vector6, Point6);
rotate_impl!(Vector6);
rotate_impl!(Point6);
transform_impl!(Vector6, Point6);
vec_as_point_impl!(Vector6, Point6, x, y, z, w, a, b);
num_float_vec_impl!(Vector6);
absolute_vec_impl!(Vector6, x, y, z, w, a, b);
arbitrary_impl!(Vector6, x, y, z, w, a, b);
rand_impl!(Vector6, x, y, z, w, a, b);
mean_impl!(Vector6);
vec_display_impl!(Vector6);

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ pub use traits::geometry::{AbsoluteRotate, Cross, CrossMatrix, Dot, FromHomogene
pub use traits::structure::{FloatVector, FloatPoint, Basis, Cast, Column, Dimension, Indexable, Iterable, pub use traits::structure::{FloatVector, FloatPoint, Basis, Cast, Column, Dimension, Indexable, Iterable,
IterableMut, Matrix, SquareMatrix, Row, NumVector, NumPoint, PointAsVector, ColumnSlice, IterableMut, Matrix, SquareMatrix, Row, NumVector, NumPoint, PointAsVector, ColumnSlice,
RowSlice, Diagonal, DiagMut, Eye, Repeat, Shape, BaseFloat, BaseNum, RowSlice, Diagonal, DiagonalMut, Eye, Repeat, Shape, BaseFloat, BaseNum,
Bounded}; Bounded};
pub use traits::operations::{Absolute, ApproxEq, Axpy, Covariance, Determinant, Inverse, Mean, Outer, PartialOrder, Transpose, pub use traits::operations::{Absolute, ApproxEq, Axpy, Covariance, Determinant, Inverse, Mean, Outer, PartialOrder, Transpose,

View File

@ -1,7 +1,7 @@
//! Low level operations on vectors and matrices. //! Low level operations on vectors and matrices.
use std::mem; use std::mem;
use num::{Float, Signed}; use num::Signed;
use std::ops::Mul; use std::ops::Mul;
use std::cmp::Ordering; use std::cmp::Ordering;
use traits::structure::SquareMatrix; use traits::structure::SquareMatrix;

View File

@ -176,7 +176,7 @@ pub trait Diagonal<V> {
} }
/// Trait to set the diagonal of square matrices. /// Trait to set the diagonal of square matrices.
pub trait DiagMut<V>: Diagonal<V> { pub trait DiagonalMut<V>: Diagonal<V> {
/// Sets the diagonal of this matrix. /// Sets the diagonal of this matrix.
fn set_diagonal(&mut self, diagonal: &V); fn set_diagonal(&mut self, diagonal: &V);
} }