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`
- `::canonical_basis_with_dim` -> `::canonical_basis_with_dimension`
- `::from_elem` -> `::from_element`
- `DiagMut` -> `DiagonalMut`
* Added:
- Added `.exp()` and `.pow()` for quaternions.

View File

@ -1,6 +1,6 @@
[package]
name = "nalgebra"
version = "0.8.2"
version = "0.9.0"
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."

View File

@ -63,6 +63,13 @@ bench_unop!(_bench_vec4_normalize, Vector4<f32>, normalize);
#[cfg(feature = "generic_sizes")]
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 na::VectorN;

View File

@ -1,5 +1,5 @@
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 std::cmp;
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 structs::dvector::{DVector, DVector1, DVector2, DVector3, DVector4, DVector5, DVector6};
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")]
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]
fn set_diagonal(&mut self, diagonal: &$dvector<N>) {
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`.
#[inline]
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 trans = rotation * (-*eye);
let rotation = Rotation3::look_at_rh(&(*target - *eye), up);
let trans = rotation * (-*eye);
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`.
#[inline]
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 trans = rotation * (-*eye);
let rotation = Rotation3::look_at_lh(&(*target - *eye), up);
let trans = rotation * (-*eye);
Isometry3::new_with_rotation_matrix(trans.to_vector(), rotation)
}
}
isometry_impl!(Isometry2, Rotation2, Vector2, Vector1);
rotation_matrix_impl!(Isometry2, Rotation2, Vector2, Vector1);
rotation_impl!(Isometry2, Rotation2, Vector1);
isometry_impl!(Isometry2, Rotation2, Vector2, Vector1, Point2, Matrix3);
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);
rotation_matrix_impl!(Isometry3, Rotation3, Vector3, Vector3);
rotation_impl!(Isometry3, Rotation3, Vector3);
isometry_impl!(Isometry3, Rotation3, Vector3, Vector3, Point3, Matrix4);
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_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> {
/// Creates a new isometry from an axis-angle rotation, and a vector.
#[inline]
pub fn new(translation: $subvector<N>, rotation: $subrotvector<N>) -> $t<N> {
pub fn new(translation: $vector<N>, rotation: $rotvector<N>) -> $t<N> {
$t {
rotation: $submatrix::new(rotation),
rotation: $rotmatrix::new(rotation),
translation: translation
}
}
/// Creates a new isometry from a rotation matrix and a vector.
#[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 {
rotation: rotation,
translation: translation
}
}
}
)
);
macro_rules! rotation_matrix_impl(
($t: ident, $trotation: ident, $tlv: ident, $tav: ident) => (
/*
*
* RotationMatrix
*
*/
impl<N: Cast<f64> + BaseFloat>
RotationMatrix<N, $tlv<N>, $tav<N>> for $t<N> {
type Output = $trotation<N>;
RotationMatrix<N, $vector<N>, $rotvector<N>> for $t<N> {
type Output = $rotmatrix<N>;
#[inline]
fn to_rotation_matrix(&self) -> $trotation<N> {
fn to_rotation_matrix(&self) -> $rotmatrix<N> {
self.rotation
}
}
)
);
macro_rules! dim_impl(
($t: ident, $dimension: expr) => (
impl<N> Dimension for $t<N> {
#[inline]
fn dimension(_: Option<$t<N>>) -> usize {
$dimension
}
}
)
);
macro_rules! one_impl(
($t: ident) => (
/*
*
* One
*
*/
impl<N: BaseFloat> One for $t<N> {
#[inline]
fn one() -> $t<N> {
$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> {
type Output = $t<N>;
@ -81,21 +76,23 @@ macro_rules! isometry_mul_isometry_impl(
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>;
#[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)
}
}
impl<N: BaseFloat> Mul<$t<N>> for $rotation<N> {
impl<N: BaseFloat> Mul<$t<N>> for $rotmatrix<N> {
type Output = $t<N>;
#[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]
fn mul_assign(&mut self, right: $rotation<N>) {
fn mul_assign(&mut self, right: $rotmatrix<N>) {
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]
fn mul(self, right: $tv<N>) -> $tv<N> {
fn mul(self, right: $point<N>) -> $point<N> {
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]
fn mul(self, right: $tv<N>) -> $tv<N> {
fn mul(self, right: $vector<N>) -> $vector<N> {
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]
fn translation(&self) -> $tv<N> {
fn translation(&self) -> $vector<N> {
self.translation
}
#[inline]
fn inverse_translation(&self) -> $tv<N> {
fn inverse_translation(&self) -> $vector<N> {
-self.translation
}
#[inline]
fn append_translation_mut(&mut self, t: &$tv<N>) {
fn append_translation_mut(&mut self, t: &$vector<N>) {
self.translation = *t + self.translation
}
#[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)
}
#[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
}
#[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)
}
#[inline]
fn set_translation(&mut self, t: $tv<N>) {
fn set_translation(&mut self, t: $vector<N>) {
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]
fn translate(&self, v: &$tv<N>) -> $tv<N> {
fn translate(&self, v: &$point<N>) -> $point<N> {
*v + self.translation
}
#[inline]
fn inverse_translate(&self, v: &$tv<N>) -> $tv<N> {
fn inverse_translate(&self, v: &$point<N>) -> $point<N> {
*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]
fn rotation(&self) -> $tav<N> {
fn rotation(&self) -> $rotvector<N> {
self.rotation.rotation()
}
#[inline]
fn inverse_rotation(&self) -> $tav<N> {
fn inverse_rotation(&self) -> $rotvector<N> {
self.rotation.inverse_rotation()
}
#[inline]
fn append_rotation_mut(&mut self, rotation: &$tav<N>) {
let delta = $trotation::new(*rotation);
fn append_rotation_mut(&mut self, rotation: &$rotvector<N>) {
let delta = $rotmatrix::new(*rotation);
self.rotation = delta * self.rotation;
self.translation = delta * self.translation;
}
#[inline]
fn append_rotation(&self, rotation: &$tav<N>) -> $t<N> {
let delta = $trotation::new(*rotation);
fn append_rotation(&self, rotation: &$rotvector<N>) -> $t<N> {
let delta = $rotmatrix::new(*rotation);
$t::new_with_rotation_matrix(delta * self.translation, delta * self.rotation)
}
#[inline]
fn prepend_rotation_mut(&mut self, rotation: &$tav<N>) {
let delta = $trotation::new(*rotation);
fn prepend_rotation_mut(&mut self, rotation: &$rotvector<N>) {
let delta = $rotmatrix::new(*rotation);
self.rotation = self.rotation * delta;
}
#[inline]
fn prepend_rotation(&self, rotation: &$tav<N>) -> $t<N> {
let delta = $trotation::new(*rotation);
fn prepend_rotation(&self, rotation: &$rotvector<N>) -> $t<N> {
let delta = $rotmatrix::new(*rotation);
$t::new_with_rotation_matrix(self.translation, self.rotation * delta)
}
#[inline]
fn set_rotation(&mut self, rotation: $tav<N>) {
fn set_rotation(&mut self, rotation: $rotvector<N>) {
// FIXME: should the translation be changed too?
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]
fn rotate(&self, v: &$tv<N>) -> $tv<N> {
fn rotate(&self, v: &$vector<N>) -> $vector<N> {
self.rotation.rotate(v)
}
#[inline]
fn inverse_rotate(&self, v: &$tv<N>) -> $tv<N> {
fn inverse_rotate(&self, v: &$vector<N>) -> $vector<N> {
self.rotation.inverse_rotate(v)
}
}
)
);
macro_rules! transformation_impl(
($t: ident) => (
/*
*
* Transformation
*
*/
impl<N: BaseFloat> Transformation<$t<N>> for $t<N> {
fn transformation(&self) -> $t<N> {
*self
@ -297,27 +308,31 @@ macro_rules! transformation_impl(
*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]
fn transform(&self, p: &$tp<N>) -> $tp<N> {
fn transform(&self, p: &$point<N>) -> $point<N> {
self.rotation.transform(p) + self.translation
}
#[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))
}
}
)
);
macro_rules! inverse_impl(
($t: ident) => (
/*
*
* Inverse
*
*/
impl<N: BaseNum + Neg<Output = N>> Inverse for $t<N> {
#[inline]
fn inverse_mut(&mut self) -> bool {
@ -335,28 +350,32 @@ macro_rules! inverse_impl(
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();
// 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
}
}
)
);
macro_rules! approx_eq_impl(
($t: ident) => (
/*
*
* ApproxEq
*
*/
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
#[inline]
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)
}
}
)
);
macro_rules! rand_impl(
($t: ident) => (
/*
*
* Rand
*
*/
impl<N: Rand + BaseFloat> Rand for $t<N> {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> $t<N> {
$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]
fn absolute_rotate(&self, v: &$tv<N>) -> $tv<N> {
fn absolute_rotate(&self, v: &$vector<N>) -> $vector<N> {
self.rotation.absolute_rotate(v)
}
}
)
);
macro_rules! arbitrary_isometry_impl(
($t: ident) => (
/*
*
* Arbitrary
*
*/
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for $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> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
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 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::geometry::{ToHomogeneous, FromHomogeneous, Origin};
use linalg;
@ -50,45 +50,20 @@ pub struct Matrix1<N> {
eye_impl!(Matrix1, 1, m11);
mat_impl!(Matrix1, 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);
matrix_impl!(Matrix1, 1, Vector1, DVector1, m11);
one_impl!(Matrix1, ::one);
iterable_impl!(Matrix1, 1);
iterable_mut_impl!(Matrix1, 1);
at_fast_impl!(Matrix1, 1);
dim_impl!(Matrix1, 1);
indexable_impl!(Matrix1, 1);
index_impl!(Matrix1, 1);
mat_mul_mat_impl!(Matrix1, 1);
mat_mul_vec_impl!(Matrix1, Vector1, 1, ::zero);
vec_mul_mat_impl!(Matrix1, Vector1, 1, ::zero);
mat_mul_point_impl!(Matrix1, Point1, 1, Origin::origin);
point_mul_mat_impl!(Matrix1, Point1, 1, Origin::origin);
// (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);
from_homogeneous_impl!(Matrix1, Matrix2, 1, 2);
outer_impl!(Vector1, Matrix1);
eigen_qr_impl!(Matrix1, Vector1);
arbitrary_impl!(Matrix1, m11);
rand_impl!(Matrix1, m11);
mean_impl!(Matrix1, Vector1, 1);
componentwise_arbitrary!(Matrix1, m11);
componentwise_rand!(Matrix1, m11);
mat_display_impl!(Matrix1, 1);
/// Square matrix of dimension 2.
@ -101,49 +76,20 @@ pub struct Matrix2<N> {
eye_impl!(Matrix2, 2, m11, m22);
mat_impl!(Matrix2, m11, m12,
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);
matrix_impl!(Matrix2, 2, Vector2, DVector2, m11, m12,
m21, m22);
one_impl!(Matrix2, ::one, ::zero,
::zero, ::one);
iterable_impl!(Matrix2, 2);
iterable_mut_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); rmul_impl!(Matrix2, Vector2, 2);
// (specialized); lmul_impl!(Matrix2, Vector2, 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);
from_homogeneous_impl!(Matrix2, Matrix3, 2, 3);
outer_impl!(Vector2, Matrix2);
eigen_qr_impl!(Matrix2, Vector2);
arbitrary_impl!(Matrix2, m11, m12, m21, m22);
rand_impl!(Matrix2, m11, m12, m21, m22);
mean_impl!(Matrix2, Vector2, 2);
componentwise_arbitrary!(Matrix2, m11, m12, m21, m22);
componentwise_rand!(Matrix2, m11, m12, m21, m22);
mat_display_impl!(Matrix2, 2);
/// Square matrix of dimension 3.
@ -157,91 +103,30 @@ pub struct Matrix3<N> {
eye_impl!(Matrix3, 3, m11, m22, m33);
mat_impl!(Matrix3, m11, m12, m13,
m21, m22, m23,
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
);
matrix_impl!(Matrix3, 3, Vector3, DVector3, m11, m12, m13,
m21, m22, m23,
m31, m32, m33);
one_impl!(Matrix3, ::one , ::zero, ::zero,
::zero, ::one , ::zero,
::zero, ::zero, ::one);
iterable_impl!(Matrix3, 3);
iterable_mut_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); rmul_impl!(Matrix3, Vector3, 3);
// (specialized); lmul_impl!(Matrix3, Vector3, 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);
from_homogeneous_impl!(Matrix3, Matrix4, 3, 4);
outer_impl!(Vector3, Matrix3);
eigen_qr_impl!(Matrix3, Vector3);
arbitrary_impl!(Matrix3,
componentwise_arbitrary!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
rand_impl!(Matrix3,
componentwise_rand!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
mean_impl!(Matrix3, Vector3, 3);
mat_display_impl!(Matrix3, 3);
/// Square matrix of dimension 4.
@ -256,68 +141,7 @@ pub struct Matrix4<N> {
eye_impl!(Matrix4, 4, m11, m22, m33, m44);
mat_impl!(Matrix4,
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,
matrix_impl!(Matrix4, 4, Vector4, DVector4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
@ -327,42 +151,28 @@ one_impl!(Matrix4, ::one , ::zero, ::zero, ::zero,
::zero, ::one , ::zero, ::zero,
::zero, ::zero, ::one , ::zero,
::zero, ::zero, ::zero, ::one);
iterable_impl!(Matrix4, 4);
iterable_mut_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_vec_impl!(Matrix4, Vector4, 4, ::zero);
vec_mul_mat_impl!(Matrix4, Vector4, 4, ::zero);
mat_mul_point_impl!(Matrix4, Point4, 4, Origin::origin);
point_mul_mat_impl!(Matrix4, Point4, 4, Origin::origin);
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);
from_homogeneous_impl!(Matrix4, Matrix5, 4, 5);
outer_impl!(Vector4, Matrix4);
eigen_qr_impl!(Matrix4, Vector4);
arbitrary_impl!(Matrix4,
componentwise_arbitrary!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
rand_impl!(Matrix4,
componentwise_rand!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
mean_impl!(Matrix4, Vector4, 4);
mat_display_impl!(Matrix4, 4);
/// Square matrix of dimension 5.
@ -378,36 +188,7 @@ pub struct Matrix5<N> {
eye_impl!(Matrix5, 5, m11, m22, m33, m44, m55);
mat_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
);
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,
matrix_impl!(Matrix5, 5, Vector5, DVector5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
@ -421,86 +202,30 @@ one_impl!(Matrix5,
::zero, ::zero, ::zero, ::one , ::zero,
::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);
indexable_impl!(Matrix5, 5);
index_impl!(Matrix5, 5);
at_fast_impl!(Matrix5, 5);
mat_mul_mat_impl!(Matrix5, 5);
mat_mul_vec_impl!(Matrix5, Vector5, 5, ::zero);
vec_mul_mat_impl!(Matrix5, Vector5, 5, ::zero);
mat_mul_point_impl!(Matrix5, Point5, 5, Origin::origin);
point_mul_mat_impl!(Matrix5, Point5, 5, Origin::origin);
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);
from_homogeneous_impl!(Matrix5, Matrix6, 5, 6);
outer_impl!(Vector5, Matrix5);
eigen_qr_impl!(Matrix5, Vector5);
arbitrary_impl!(Matrix5,
componentwise_arbitrary!(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
);
rand_impl!(Matrix5,
componentwise_rand!(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
);
mean_impl!(Matrix5, Vector5, 5);
mat_display_impl!(Matrix5, 5);
/// Square matrix of dimension 6.
@ -517,7 +242,7 @@ pub struct Matrix6<N> {
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,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
@ -525,78 +250,6 @@ mat_impl!(Matrix6,
m51, m52, m53, m54, m55, m56,
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 , ::zero, ::zero, ::zero, ::zero, ::zero,
@ -606,28 +259,15 @@ one_impl!(Matrix6,
::zero, ::zero, ::zero, ::zero, ::one , ::zero,
::zero, ::zero, ::zero, ::zero, ::zero, ::one
);
iterable_impl!(Matrix6, 6);
iterable_mut_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_vec_impl!(Matrix6, Vector6, 6, ::zero);
vec_mul_mat_impl!(Matrix6, Vector6, 6, ::zero);
mat_mul_point_impl!(Matrix6, Point6, 6, Origin::origin);
point_mul_mat_impl!(Matrix6, Point6, 6, Origin::origin);
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);
arbitrary_impl!(Matrix6,
componentwise_arbitrary!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
@ -635,7 +275,7 @@ arbitrary_impl!(Matrix6,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
rand_impl!(Matrix6,
componentwise_rand!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
@ -643,5 +283,4 @@ rand_impl!(Matrix6,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
mean_impl!(Matrix6, Vector6, 6);
mat_display_impl!(Matrix6, 6);

View File

@ -1,20 +1,22 @@
#![macro_use]
macro_rules! mat_impl(
($t: ident, $($compN: ident),+) => (
impl<N> $t<N> {
#[inline]
pub fn new($($compN: N ),+) -> $t<N> {
$t {
$($compN: $compN ),+
macro_rules! matrix_impl(
($t: ident, $dimension: expr, $vector: ident, $dvector: ident, $($compN: ident),+) => (
impl<N> $t<N> {
#[inline]
pub fn new($($compN: N ),+) -> $t<N> {
$t {
$($compN: $compN ),+
}
}
}
}
)
);
macro_rules! conversion_impl(
($t: ident, $dimension: expr) => (
/*
*
* Conversions (AsRef, AsMut, From)
*
*/
impl<N> AsRef<[[N; $dimension]; $dimension]> for $t<N> {
#[inline]
fn as_ref(&self) -> &[[N; $dimension]; $dimension] {
@ -58,11 +60,13 @@ macro_rules! conversion_impl(
tref.clone()
}
}
)
);
macro_rules! at_fast_impl(
($t: ident, $dimension: expr) => (
/*
*
* Unsafe indexing.
*
*/
impl<N: Copy> $t<N> {
#[inline]
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
}
}
)
);
macro_rules! mat_cast_impl(
($t: ident, $($compN: ident),+) => (
/*
*
* Cast
*
*/
impl<Nin: Copy, Nout: Copy + Cast<Nin>> Cast<$t<Nin>> for $t<Nout> {
#[inline]
fn from(v: $t<Nin>) -> $t<Nout> {
$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]
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! 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 ),+
fn iter(&self) -> Iter<N> {
unsafe {
mem::transmute::<&$t<N>, &[N; $dimension * $dimension]>(self).iter()
}
}
}
)
);
macro_rules! absolute_impl(
($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! 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() ),+
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()
}
}
}
#[inline]
fn is_zero(&self) -> bool {
$(::is_zero(&self.$compN) )&&+
}
}
)
);
macro_rules! dim_impl(
($t: ident, $dimension: expr) => (
impl<N> Dimension for $t<N> {
#[inline]
fn dimension(_: Option<$t<N>>) -> usize {
$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)
/*
*
* Shape/Indexable/Index
*
*/
impl<N> Shape<(usize, usize)> for $t<N> {
#[inline]
fn shape(&self) -> (usize, usize) {
($dimension, $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))
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]
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> {
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);
$slice::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;
$dvector::from_slice(rend - rstart, &column.as_ref()[rstart .. rend])
}
}
#[inline]
fn row(&self, row: usize) -> $tv<N> {
let mut res: $tv<N> = ::zero();
for (i, e) in res.iter_mut().enumerate() {
*e = self[(row, i)];
impl<N: Copy + Zero> Row<$vector<N>> for $t<N> {
#[inline]
fn nrows(&self) -> usize {
Dimension::dimension(None::<$t<N>>)
}
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(
($t: ident, $tv: ident, $slice: ident, $dimension: expr) => (
impl<N: Clone + Copy + Zero> RowSlice<$slice<N>> for $t<N> {
fn row_slice(&self, rid: usize, cstart: usize, cend: usize) -> $slice<N> {
#[inline]
fn row(&self, row: usize) -> $vector<N> {
let mut res: $vector<N> = ::zero();
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);
$slice::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;
$dvector::from_slice(cend - cstart, &row.as_ref()[cstart .. cend])
}
}
#[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)];
}
res
}
}
)
);
macro_rules! diag_impl(
($t: ident, $tv: ident, $dimension: expr) => (
impl<N: Copy + Zero> Diagonal<$tv<N>> for $t<N> {
/*
*
* Transpose
*
*/
impl<N: Copy> Transpose for $t<N> {
#[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();
res.set_diagonal(diagonal);
@ -516,8 +337,8 @@ macro_rules! diag_impl(
}
#[inline]
fn diagonal(&self) -> $tv<N> {
let mut diagonal: $tv<N> = ::zero();
fn diagonal(&self) -> $vector<N> {
let mut diagonal: $vector<N> = ::zero();
for i in 0 .. $dimension {
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]
fn set_diagonal(&mut self, diagonal: &$tv<N>) {
fn set_diagonal(&mut self, diagonal: &$vector<N>) {
for i in 0 .. $dimension {
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(
($t: ident, $dimension: expr) => (
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(
($t: ident, $t2: ident, $dimension: expr, $dim2: expr) => (
@ -785,8 +600,8 @@ macro_rules! to_homogeneous_impl(
fn to_homogeneous(&self) -> $t2<N> {
let mut res: $t2<N> = ::one();
for i in 0..$dimension {
for j in 0..$dimension {
for i in 0 .. $dimension {
for j in 0 .. $dimension {
res[(i, j)] = self[(i, j)]
}
}
@ -804,8 +619,8 @@ macro_rules! from_homogeneous_impl(
fn from(m: &$t2<N>) -> $t<N> {
let mut res: $t<N> = ::one();
for i in 0..$dimension {
for j in 0..$dimension {
for i in 0 .. $dimension {
for j in 0 .. $dimension {
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(
($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(
($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")]
pub use self::vectorn::VectorN;
mod common_macros;
mod dmatrix_macros;
mod dmatrix;
mod vectorn_macros;

View File

@ -27,38 +27,9 @@ pub struct Point1<N> {
pub x: N
}
new_impl!(Point1, x);
origin_impl!(Point1, 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);
point_impl!(Point1, Vector1, Point2, y | x);
vectorlike_impl!(Point1, 1, x);
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.
///
@ -73,38 +44,9 @@ pub struct Point2<N> {
pub y: N
}
new_impl!(Point2, x, y);
origin_impl!(Point2, 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);
point_impl!(Point2, Vector2, Point3, z | x, y);
vectorlike_impl!(Point2, 2, x, y);
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.
///
@ -121,38 +63,9 @@ pub struct Point3<N> {
pub z: N
}
new_impl!(Point3, x, y, z);
origin_impl!(Point3, 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);
point_impl!(Point3, Vector3, Point4, w | x, y, z);
vectorlike_impl!(Point3, 3, x, y, z);
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.
///
@ -171,38 +84,9 @@ pub struct Point4<N> {
pub w: N
}
new_impl!(Point4, x, y, z, w);
origin_impl!(Point4, 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);
point_impl!(Point4, Vector4, Point5, a | x, y, z, w);
vectorlike_impl!(Point4, 4, x, y, z, w);
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.
///
@ -223,38 +107,9 @@ pub struct Point5<N> {
pub a: N
}
new_impl!(Point5, x, y, z, w, a);
origin_impl!(Point5, 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);
point_impl!(Point5, Vector5, Point6, b | x, y, z, w, a);
vectorlike_impl!(Point5, 5, x, y, z, w, a);
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.
///
@ -277,33 +132,6 @@ pub struct Point6<N> {
pub b: N
}
new_impl!(Point6, x, y, z, w, a, b);
origin_impl!(Point6, 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);
point_impl!(Point6, Vector6 | x, y, z, w, a, b);
vectorlike_impl!(Point6, 6, x, y, z, w, a, b);
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_rules! origin_impl(
($t: ident, $($compN: ident),+) => (
macro_rules! point_impl(
($t: ident, $tv: ident | $($compN: ident),+) => (
/*
*
* Origin.
*
*/
impl<N: Zero> Origin for $t<N> {
#[inline]
fn origin() -> $t<N> {
@ -15,11 +21,13 @@ macro_rules! origin_impl(
$(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> {
type Output = $tv<N>;
@ -28,11 +36,13 @@ macro_rules! point_sub_impl(
*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> {
type Output = $t<N>;
@ -48,11 +58,13 @@ macro_rules! point_add_vec_impl(
$( 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> {
type Output = $t<N>;
@ -68,11 +80,14 @@ macro_rules! point_sub_vec_impl(
$( self.$compN -= right.$compN; )+
}
}
)
);
macro_rules! point_as_vec_impl(
($t: ident, $tv: ident, $($compN: ident),+) => (
/*
*
* Point as vector.
*
*/
impl<N> $t<N> {
/// Converts this point to its associated vector.
#[inline]
@ -114,40 +129,14 @@ macro_rules! point_as_vec_impl(
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
}
}
)
);
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) => (
/*
*
* NumPoint / FloatPoint
*
*/
impl<N> NumPoint<N> for $t<N>
where N: BaseNum {
}
@ -155,25 +144,13 @@ macro_rules! num_float_point_impl(
impl<N> FloatPoint<N> for $t<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> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// FIXME: differenciate them from vectors ?
@ -190,5 +167,34 @@ macro_rules! point_display_impl(
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> {
/// 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.
#[inline]
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.
#[repr(C)]
#[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")]
impl<N: Arbitrary + BaseFloat> Arbitrary for 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> {
fn one() -> Self {
Quaternion::new(T::one(), T::zero(), T::zero(), T::zero())
}
}
pord_impl!(Quaternion, w, i, j, k);
vec_axis_impl!(Quaternion, w, i, j, k);
vec_cast_impl!(Quaternion, w, i, j, k);
conversion_impl!(Quaternion, 4);
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);
componentwise_zero!(Quaternion, w, i, j, k);
component_basis_element!(Quaternion, w, i, j, k);
pointwise_add!(Quaternion, w, i, j, k);
pointwise_sub!(Quaternion, w, i, j, k);
from_iterator_impl!(Quaternion, iterator, iterator, iterator, iterator);
bounded_impl!(Quaternion, 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);
vectorlike_impl!(Quaternion, 4, w, i, j, k);

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
@ -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.
*/
submat_impl!(Rotation2, Matrix2);
rotate_impl!(Rotation2, Vector2, Point2);
transform_impl!(Rotation2, Vector2, Point2);
rotation_impl!(Rotation2, Matrix2, Vector2, Vector1, Point2, Matrix3);
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);
rotate_impl!(Rotation3, Vector3, Point3);
transform_impl!(Rotation3, Vector3, Point3);
rotation_impl!(Rotation3, Matrix3, Vector3, Vector3, Point3, Matrix4);
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_rules! submat_impl(
($t: ident, $submatrix: ident) => (
macro_rules! rotation_impl(
($t: ident, $submatrix: ident, $vector: ident, $rotvector: ident, $point: ident, $homogeneous: ident) => (
impl<N> $t<N> {
/// This rotation's underlying matrix.
#[inline]
@ -9,79 +9,75 @@ macro_rules! submat_impl(
&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]
fn rotate(&self, v: &$tv<N>) -> $tv<N> {
fn rotate(&self, v: &$vector<N>) -> $vector<N> {
*self * *v
}
#[inline]
fn inverse_rotate(&self, v: &$tv<N>) -> $tv<N> {
fn inverse_rotate(&self, v: &$vector<N>) -> $vector<N> {
*v * *self
}
}
impl<N: BaseNum> Rotate<$tp<N>> for $t<N> {
impl<N: BaseNum> Rotate<$point<N>> for $t<N> {
#[inline]
fn rotate(&self, p: &$tp<N>) -> $tp<N> {
fn rotate(&self, p: &$point<N>) -> $point<N> {
*self * *p
}
#[inline]
fn inverse_rotate(&self, p: &$tp<N>) -> $tp<N> {
fn inverse_rotate(&self, p: &$point<N>) -> $point<N> {
*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]
fn transform(&self, v: &$tv<N>) -> $tv<N> {
fn transform(&self, v: &$vector<N>) -> $vector<N> {
self.rotate(v)
}
#[inline]
fn inverse_transform(&self, v: &$tv<N>) -> $tv<N> {
fn inverse_transform(&self, v: &$vector<N>) -> $vector<N> {
self.inverse_rotate(v)
}
}
impl<N: BaseNum> Transform<$tp<N>> for $t<N> {
impl<N: BaseNum> Transform<$point<N>> for $t<N> {
#[inline]
fn transform(&self, p: &$tp<N>) -> $tp<N> {
fn transform(&self, p: &$point<N>) -> $point<N> {
self.rotate(p)
}
#[inline]
fn inverse_transform(&self, p: &$tp<N>) -> $tp<N> {
fn inverse_transform(&self, p: &$point<N>) -> $point<N> {
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>;
#[inline]
@ -89,22 +85,26 @@ macro_rules! rotation_matrix_impl(
self.clone()
}
}
)
);
macro_rules! one_impl(
($t: ident) => (
/*
*
* One
*
*/
impl<N: BaseNum> One for $t<N> {
#[inline]
fn one() -> $t<N> {
$t { submatrix: ::one() }
}
}
)
);
macro_rules! eye_impl(
($t: ident) => (
/*
*
* Eye
*
*/
impl<N: BaseNum> Eye for $t<N> {
#[inline]
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]
fn from_diagonal(diagonal: &$tv<N>) -> $t<N> {
fn from_diagonal(diagonal: &$vector<N>) -> $t<N> {
$t { submatrix: Diagonal::from_diagonal(diagonal) }
}
#[inline]
fn diagonal(&self) -> $tv<N> {
fn diagonal(&self) -> $vector<N> {
self.submatrix.diagonal()
}
}
)
);
macro_rules! rotation_mul_rotation_impl(
($t: ident) => (
/*
*
* Rotation * Rotation
*
*/
impl<N: BaseNum> Mul<$t<N>> for $t<N> {
type Output = $t<N>;
@ -152,56 +156,75 @@ macro_rules! rotation_mul_rotation_impl(
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]
fn mul(self, right: $tv<N>) -> $tv<N> {
fn mul(self, right: $vector<N>) -> $vector<N> {
self.submatrix * right
}
}
)
);
macro_rules! rotation_mul_point_impl(
($t: ident, $tv: ident) => (
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>;
impl<N: BaseNum> Mul<$t<N>> for $vector<N> {
type Output = $vector<N>;
#[inline]
fn mul(self, right: $t<N>) -> $tv<N> {
fn mul(self, right: $t<N>) -> $vector<N> {
self * right.submatrix
}
}
impl<N: Copy + BaseNum> MulAssign<$t<N>> for $tv<N> {
impl<N: Copy + BaseNum> MulAssign<$t<N>> for $vector<N> {
#[inline]
fn mul_assign(&mut self, right: $t<N>) {
*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> {
#[inline]
fn inverse_mut(&mut self) -> bool {
@ -217,11 +240,13 @@ macro_rules! inverse_impl(
Some(self.transpose())
}
}
)
);
macro_rules! transpose_impl(
($t: ident) => (
/*
*
* Transpose
*
*/
impl<N: Copy> Transpose for $t<N> {
#[inline]
fn transpose(&self) -> $t<N> {
@ -233,51 +258,57 @@ macro_rules! transpose_impl(
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]
fn nrows(&self) -> usize {
self.submatrix.nrows()
}
#[inline]
fn row(&self, i: usize) -> $tv<N> {
fn row(&self, i: usize) -> $vector<N> {
self.submatrix.row(i)
}
#[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);
}
}
)
);
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]
fn ncols(&self) -> usize {
self.submatrix.ncols()
}
#[inline]
fn column(&self, i: usize) -> $tv<N> {
fn column(&self, i: usize) -> $vector<N> {
self.submatrix.column(i)
}
#[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);
}
}
)
);
macro_rules! index_impl(
($t: ident) => (
/*
*
* Index
*
*/
impl<N> Index<(usize, usize)> for $t<N> {
type Output = N;
@ -285,22 +316,26 @@ macro_rules! index_impl(
&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]
fn to_homogeneous(&self) -> $tm<N> {
fn to_homogeneous(&self) -> $homogeneous<N> {
self.submatrix.to_homogeneous()
}
}
)
);
macro_rules! approx_eq_impl(
($t: ident) => (
/*
*
* ApproxEq
*
*/
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
#[inline]
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)
}
}
)
);
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]
fn abs(m: &$t<N>) -> $tm<N> {
fn abs(m: &$t<N>) -> $submatrix<N> {
Absolute::abs(&m.submatrix)
}
}
)
);
macro_rules! rotation_display_impl(
($t: ident) => (
/*
*
* Display
*
*/
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let precision = f.precision().unwrap_or(3);
@ -352,5 +392,29 @@ macro_rules! rotation_display_impl(
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 traits::structure::{Dimension, Column, BaseFloat, BaseNum};
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::point::{Point2, Point3};
@ -49,38 +49,9 @@ pub struct Similarity3<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);
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_rules! sim_impl(
($t: ident, $isometry: ident, $rotation_matrix: ident, $subvector: ident, $subrotvector: ident) => (
macro_rules! similarity_impl(
($t: ident,
$isometry: ident, $rotation_matrix: ident,
$vector: ident, $rotvector: ident,
$point: ident,
$homogeneous_matrix: ident) => (
impl<N: BaseFloat> $t<N> {
/*
*
* Constructors.
*
*/
/// 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.
#[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.");
$t {
@ -20,7 +29,7 @@ macro_rules! sim_impl(
///
/// The scale factor may be negative but not zero.
#[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.");
$t {
@ -41,13 +50,12 @@ macro_rules! sim_impl(
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.
#[inline]
pub fn scale(&self) -> N {
@ -96,22 +104,61 @@ macro_rules! sim_scale_impl(
self.scale = s
}
}
)
);
macro_rules! sim_one_impl(
($t: ident) => (
/*
*
* One Impl.
*
*/
impl<N: BaseFloat> One for $t<N> {
#[inline]
fn one() -> $t<N> {
$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> {
type Output = $t<N>;
@ -132,16 +179,18 @@ macro_rules! sim_mul_sim_impl(
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>;
#[inline]
fn mul(self, right: $ti<N>) -> $t<N> {
fn mul(self, right: $isometry<N>) -> $t<N> {
$t::new_with_rotation_matrix(
self.isometry.translation + self.isometry.rotation * (right.translation * self.scale),
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]
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.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>;
#[inline]
@ -168,16 +217,17 @@ macro_rules! sim_mul_isometry_impl(
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>;
#[inline]
fn mul(self, right: $tr<N>) -> $t<N> {
fn mul(self, right: $rotation_matrix<N>) -> $t<N> {
$t::new_with_rotation_matrix(
self.isometry.translation,
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]
fn mul_assign(&mut self, right: $tr<N>) {
fn mul_assign(&mut self, right: $rotation_matrix<N>) {
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>;
#[inline]
@ -203,44 +253,56 @@ macro_rules! sim_mul_rotation_impl(
right.scale)
}
}
)
);
macro_rules! sim_mul_point_vec_impl(
($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$tv<N>> for $t<N> {
type Output = $tv<N>;
/*
*
* Similarity × { Point, Vector }
*
*/
impl<N: BaseNum> Mul<$vector<N>> for $t<N> {
type Output = $vector<N>;
#[inline]
fn mul(self, right: $tv<N>) -> $tv<N> {
fn mul(self, right: $vector<N>) -> $vector<N> {
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
// 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]
fn transform(&self, p: &$tp<N>) -> $tp<N> {
fn transform(&self, p: &$point<N>) -> $point<N> {
self.isometry.transform(&(*p * self.scale))
}
#[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
}
}
)
);
macro_rules! sim_inverse_impl(
($t: ident) => (
/*
*
* Inverse
*
*/
impl<N: BaseNum + Neg<Output = N>> Inverse for $t<N> {
#[inline]
fn inverse_mut(&mut self) -> bool {
@ -263,28 +325,32 @@ macro_rules! sim_inverse_impl(
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();
// 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
}
}
)
);
macro_rules! sim_approx_eq_impl(
($t: ident) => (
/*
*
* ApproxEq
*
*/
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
#[inline]
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)
}
}
)
);
macro_rules! sim_rand_impl(
($t: ident) => (
/*
*
* Rand
*
*/
impl<N: Rand + BaseFloat> Rand for $t<N> {
#[inline]
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)
}
}
)
);
macro_rules! sim_arbitrary_impl(
($t: ident) => (
/*
*
* Arbitrary
*
*/
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for $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> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(writeln!(f, "Similarity transformation {{"));

View File

@ -3,7 +3,7 @@ use structs::vector::{Vector2, Vector3};
use structs::point::{Point2, Point3};
use structs::matrix::{Matrix1, Matrix2, Matrix3};
use traits::operations::{Inverse, Determinant, ApproxEq};
use traits::structure::{Row, Column, BaseNum};
use traits::structure::BaseNum;
// some specializations:
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> {
type Output = Matrix3<N>;

View File

@ -29,50 +29,14 @@ pub struct Vector1<N> {
pub x: N
}
new_impl!(Vector1, x);
pord_impl!(Vector1, 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);
vector_impl!(Vector1, Point1, x);
vectorlike_impl!(Vector1, 1, x);
from_iterator_impl!(Vector1, iterator);
bounded_impl!(Vector1, x);
axpy_impl!(Vector1, x);
iterable_impl!(Vector1, 1);
iterable_mut_impl!(Vector1, 1);
// (specialized); basis_impl!(Vector1, 1);
vec_to_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.
///
@ -87,50 +51,14 @@ pub struct Vector2<N> {
pub y: N
}
new_impl!(Vector2, x, y);
pord_impl!(Vector2, 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);
vector_impl!(Vector2, Point2, x, y);
vectorlike_impl!(Vector2, 2, x, y);
from_iterator_impl!(Vector2, iterator, iterator);
bounded_impl!(Vector2, x, y);
axpy_impl!(Vector2, x, y);
iterable_impl!(Vector2, 2);
iterable_mut_impl!(Vector2, 2);
// (specialized); basis_impl!(Vector2, 1);
vec_to_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.
///
@ -147,50 +75,12 @@ pub struct Vector3<N> {
pub z: N
}
new_impl!(Vector3, x, y, z);
pord_impl!(Vector3, 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);
vector_impl!(Vector3, Point3, x, y, z);
vectorlike_impl!(Vector3, 3, x, y, z);
from_iterator_impl!(Vector3, iterator, iterator, iterator);
bounded_impl!(Vector3, x, y, z);
axpy_impl!(Vector3, x, y, z);
iterable_impl!(Vector3, 3);
iterable_mut_impl!(Vector3, 3);
// (specialized); basis_impl!(Vector3, 1);
vec_to_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.
@ -210,50 +100,14 @@ pub struct Vector4<N> {
pub w: N
}
new_impl!(Vector4, x, y, z, w);
pord_impl!(Vector4, 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);
vector_impl!(Vector4, Point4, x, y, z, w);
vectorlike_impl!(Vector4, 4, x, y, z, w);
from_iterator_impl!(Vector4, iterator, iterator, iterator, iterator);
bounded_impl!(Vector4, x, y, z, w);
axpy_impl!(Vector4, x, y, z, w);
iterable_impl!(Vector4, 4);
iterable_mut_impl!(Vector4, 4);
basis_impl!(Vector4, 4);
vec_to_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.
///
@ -274,50 +128,13 @@ pub struct Vector5<N> {
pub a: N
}
new_impl!(Vector5, x, y, z, w, a);
pord_impl!(Vector5, 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);
vector_impl!(Vector5, Point5, x, y, z, w, a);
vectorlike_impl!(Vector5, 5, x, y, z, w, a);
from_iterator_impl!(Vector5, iterator, iterator, iterator, iterator, iterator);
bounded_impl!(Vector5, x, y, z, w, a);
axpy_impl!(Vector5, x, y, z, w, a);
iterable_impl!(Vector5, 5);
iterable_mut_impl!(Vector5, 5);
basis_impl!(Vector5, 5);
vec_to_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.
///
@ -340,45 +157,8 @@ pub struct Vector6<N> {
pub b: N
}
new_impl!(Vector6, x, y, z, w, a, b);
pord_impl!(Vector6, 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);
vector_impl!(Vector6, Point6, x, y, z, w, a, b);
vectorlike_impl!(Vector6, 6, x, y, z, w, a, b);
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);
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);
basis_impl!(Vector6, 6);

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,
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};
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.
use std::mem;
use num::{Float, Signed};
use num::Signed;
use std::ops::Mul;
use std::cmp::Ordering;
use traits::structure::SquareMatrix;

View File

@ -176,7 +176,7 @@ pub trait Diagonal<V> {
}
/// 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.
fn set_diagonal(&mut self, diagonal: &V);
}