Use full names for everything.

Note that `sqdist` becomes `distance_squared` and `sqnorm` becomes `norm_squared`.

Fix #176.
This commit is contained in:
Sébastien Crozet 2016-04-17 17:26:58 +02:00
parent 353d36639d
commit e6156727f2
56 changed files with 4732 additions and 4732 deletions

View File

@ -10,7 +10,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
everything. everything.
### Modified ### Modified
* Points and vectors are now linked to each other with associated types * Points and vectors are now linked to each other with associated types
(on the PntAsVec trait). (on the PointAsVector trait).
## [0.6.0] ## [0.6.0]
@ -20,22 +20,22 @@ you [there](http://users.nphysics.org)!
### Added ### Added
* Added a dependency to [generic-array](https://crates.io/crates/generic-array). Feature-gated: * Added a dependency to [generic-array](https://crates.io/crates/generic-array). Feature-gated:
requires `features="generic_sizes"`. requires `features="generic_sizes"`.
* Added statically sized vectors with user-defined sizes: `VecN`. Feature-gated: requires * Added statically sized vectors with user-defined sizes: `VectorN`. Feature-gated: requires
`features="generic_sizes"`. `features="generic_sizes"`.
* Added similarity transformations (an uniform scale followed by a rotation followed by a * Added similarity transformations (an uniform scale followed by a rotation followed by a
translation): `Sim2`, `Sim3`. translation): `Similarity2`, `Similarity3`.
### Removed ### Removed
* Removed zero-sized elements `Vec0`, `Pnt0`. * Removed zero-sized elements `Vector0`, `Point0`.
* Removed 4-dimensional transformations `Rot4` and `Iso4` (which had an implementation to incomplete to be useful). * Removed 4-dimensional transformations `Rotation4` and `Isometry4` (which had an implementation to incomplete to be useful).
### Modified ### Modified
* Vectors are now multipliable with isometries. This will result into a pure rotation (this is how * Vectors are now multipliable with isometries. This will result into a pure rotation (this is how
vectors differ from point semantically: they design directions so they are not translatable). vectors differ from point semantically: they design directions so they are not translatable).
* `{Iso3, Rot3}::look_at` reimplemented and renamed to `::look_at_rh` and `::look_at_lh` to agree * `{Isometry3, Rotation3}::look_at` reimplemented and renamed to `::look_at_rh` and `::look_at_lh` to agree
with the computer graphics community (in particular, the GLM library). Use the `::look_at_rh` with the computer graphics community (in particular, the GLM library). Use the `::look_at_rh`
variant to build a view matrix that variant to build a view matrix that
may be successfully used with `Persp` and `Ortho`. may be successfully used with `Persp` and `Ortho`.
* The old `{Iso3, Rot3}::look_at` implementations are now called `::new_observer_frame`. * The old `{Isometry3, Rotation3}::look_at` implementations are now called `::new_observer_frame`.
* Rename every `fov` on `Persp` to `fovy`. * Rename every `fov` on `Persp` to `fovy`.
* Fixed the perspective and orthographic projection matrices. * Fixed the perspective and orthographic projection matrices.

View File

@ -16,22 +16,22 @@ All the functionality of **nalgebra** is grouped in one place: the root module `
module re-exports everything and includes free functions for all traits methods performing module re-exports everything and includes free functions for all traits methods performing
out-of-place operations. out-of-place operations.
* You can import the whole prelude using: Thus, you can import the whole prelude using:
```.ignore ```.ignore
use nalgebra::*; use nalgebra::*;
``` ```
The preferred way to use **nalgebra** is to import types and traits explicitly, and call However, the recommended way to use **nalgebra** is to import types and traits
free-functions using the `na::` prefix: explicitly, and call free-functions using the `na::` prefix:
```.rust ```.rust
extern crate nalgebra as na; extern crate nalgebra as na;
use na::{Vec3, Rot3, Rotation}; use na::{Vector3, Rotation3, Rotation};
fn main() { fn main() {
let a = Vec3::new(1.0f64, 1.0, 1.0); let a = Vector3::new(1.0f64, 1.0, 1.0);
let mut b = Rot3::new(na::zero()); let mut b = Rotation3::new(na::zero());
b.append_rotation_mut(&a); b.append_rotation_mut(&a);
@ -44,17 +44,17 @@ fn main() {
**nalgebra** is meant to be a general-purpose, low-dimensional, linear algebra library, with **nalgebra** is meant to be a general-purpose, low-dimensional, linear algebra library, with
an optimized set of tools for computer graphics and physics. Those features include: an optimized set of tools for computer graphics and physics. Those features include:
* Vectors with predefined static sizes: `Vec1`, `Vec2`, `Vec3`, `Vec4`, `Vec5`, `Vec6`. * Vectors with predefined static sizes: `Vector1`, `Vector2`, `Vector3`, `Vector4`, `Vector5`, `Vector6`.
* Vector with a user-defined static size: `VecN` (available only with the `generic_sizes` feature). * Vector with a user-defined static size: `VectorN` (available only with the `generic_sizes` feature).
* Points with static sizes: `Pnt1`, `Pnt2`, `Pnt3`, `Pnt4`, `Pnt5`, `Pnt6`. * Points with static sizes: `Point1`, `Point2`, `Point3`, `Point4`, `Point5`, `Point6`.
* Square matrices with static sizes: `Mat1`, `Mat2`, `Mat3`, `Mat4`, `Mat5`, `Mat6 `. * Square matrices with static sizes: `Matrix1`, `Matrix2`, `Matrix3`, `Matrix4`, `Matrix5`, `Matrix6 `.
* Rotation matrices: `Rot2`, `Rot3` * Rotation matrices: `Rotation2`, `Rotation3`
* Quaternions: `Quat`, `UnitQuat`. * Quaternions: `Quaternion`, `UnitQuaternion`.
* Isometries (translation rotation): `Iso2`, `Iso3` * Isometrymetries (translation rotation): `Isometry2`, `Isometry3`
* Similarity transformations (translation rotation uniform scale): `Sim2`, `Sim3`. * Similarity transformations (translation rotation uniform scale): `Similarity2`, `Similarity3`.
* 3D projections for computer graphics: `Persp3`, `PerspMat3`, `Ortho3`, `OrthoMat3`. * 3D projections for computer graphics: `Persp3`, `PerspMatrix3`, `Ortho3`, `OrthoMatrix3`.
* Dynamically sized heap-allocated vector: `DVec`. * Dynamically sized heap-allocated vector: `DVector`.
* Dynamically sized stack-allocated vectors with a maximum size: `DVec1` to `DVec6`. * Dynamically sized stack-allocated vectors with a maximum size: `DVector1` to `DVector6`.
* Dynamically sized heap-allocated (square or rectangular) matrix: `DMat`. * Dynamically sized heap-allocated (square or rectangular) matrix: `DMatrix`.
* Linear algebra and data analysis operators: `Cov`, `Mean`, `qr`, `cholesky`. * Linear algebra and data analysis operators: `Covariance`, `Mean`, `qr`, `cholesky`.
* Almost one trait per functionality: useful for generic programming. * Almost one trait per functionality: useful for generic programming.

View File

@ -6,14 +6,14 @@ extern crate nalgebra as na;
use rand::{IsaacRng, Rng}; use rand::{IsaacRng, Rng};
use test::Bencher; use test::Bencher;
use na::{UnitQuat, Rot2, Rot3, Vec1, Vec3}; use na::{UnitQuaternion, Rotation2, Rotation3, Vector1, Vector3};
#[path="common/macros.rs"] #[path="common/macros.rs"]
mod macros; mod macros;
bench_construction!(_bench_quat_from_axisangle, UnitQuat::new, axisangle: Vec3<f32>); bench_construction!(_bench_quaternion_from_axisangle, UnitQuaternion::new, axisangle: Vector3<f32>);
bench_construction!(_bench_rot2_from_axisangle, Rot2::new, axisangle: Vec1<f32>); bench_construction!(_bench_rot2_from_axisangle, Rotation2::new, axisangle: Vector1<f32>);
bench_construction!(_bench_rot3_from_axisangle, Rot3::new, axisangle: Vec3<f32>); bench_construction!(_bench_rot3_from_axisangle, Rotation3::new, axisangle: Vector3<f32>);
bench_construction!(_bench_quat_from_euler_angles, UnitQuat::new_with_euler_angles, roll: f32, pitch: f32, yaw: f32); bench_construction!(_bench_quaternion_from_euler_angles, UnitQuaternion::new_with_euler_angles, roll: f32, pitch: f32, yaw: f32);
bench_construction!(_bench_rot3_from_euler_angles, Rot3::new_with_euler_angles, roll: f32, pitch: f32, yaw: f32); bench_construction!(_bench_rot3_from_euler_angles, Rotation3::new_with_euler_angles, roll: f32, pitch: f32, yaw: f32);

View File

@ -4,14 +4,14 @@ extern crate test;
extern crate nalgebra as na; extern crate nalgebra as na;
use test::Bencher; use test::Bencher;
use na::{DVec, DMat}; use na::{DVector, DMatrix};
macro_rules! bench_mul_dmat( macro_rules! bench_mul_dmatrix(
($bh: expr, $nrows: expr, $ncols: expr) => { ($bh: expr, $nrows: expr, $ncols: expr) => {
{ {
$bh.iter(|| { $bh.iter(|| {
let a: DMat<f64> = DMat::new_random($nrows, $ncols); let a: DMatrix<f64> = DMatrix::new_random($nrows, $ncols);
let mut b: DMat<f64> = DMat::new_random($nrows, $ncols); let mut b: DMatrix<f64> = DMatrix::new_random($nrows, $ncols);
for _ in 0usize .. 1000 { for _ in 0usize .. 1000 {
// XXX: the clone here is highly undesirable! // XXX: the clone here is highly undesirable!
@ -24,36 +24,36 @@ macro_rules! bench_mul_dmat(
#[bench] #[bench]
fn bench_mul_dmat2(bh: &mut Bencher) { fn bench_mul_dmat2(bh: &mut Bencher) {
bench_mul_dmat!(bh, 2, 2); bench_mul_dmatrix!(bh, 2, 2);
} }
#[bench] #[bench]
fn bench_mul_dmat3(bh: &mut Bencher) { fn bench_mul_dmat3(bh: &mut Bencher) {
bench_mul_dmat!(bh, 3, 3); bench_mul_dmatrix!(bh, 3, 3);
} }
#[bench] #[bench]
fn bench_mul_dmat4(bh: &mut Bencher) { fn bench_mul_dmat4(bh: &mut Bencher) {
bench_mul_dmat!(bh, 4, 4); bench_mul_dmatrix!(bh, 4, 4);
} }
#[bench] #[bench]
fn bench_mul_dmat5(bh: &mut Bencher) { fn bench_mul_dmat5(bh: &mut Bencher) {
bench_mul_dmat!(bh, 5, 5); bench_mul_dmatrix!(bh, 5, 5);
} }
#[bench] #[bench]
fn bench_mul_dmat6(bh: &mut Bencher) { fn bench_mul_dmat6(bh: &mut Bencher) {
bench_mul_dmat!(bh, 6, 6); bench_mul_dmatrix!(bh, 6, 6);
} }
macro_rules! bench_mul_dmat_dvec( macro_rules! bench_mul_dmat_dvector(
($bh: expr, $nrows: expr, $ncols: expr) => { ($bh: expr, $nrows: expr, $ncols: expr) => {
{ {
$bh.iter(|| { $bh.iter(|| {
let m : DMat<f64> = DMat::new_random($nrows, $ncols); let m : DMatrix<f64> = DMatrix::new_random($nrows, $ncols);
let mut v : DVec<f64> = DVec::new_random($ncols); let mut v : DVector<f64> = DVector::new_random($ncols);
for _ in 0usize .. 1000 { for _ in 0usize .. 1000 {
// XXX: the clone here is highly undesirable! // XXX: the clone here is highly undesirable!
@ -66,25 +66,25 @@ macro_rules! bench_mul_dmat_dvec(
#[bench] #[bench]
fn bench_mul_dmat_dvec2(bh: &mut Bencher) { fn bench_mul_dmat_dvec2(bh: &mut Bencher) {
bench_mul_dmat_dvec!(bh, 2, 2); bench_mul_dmat_dvector!(bh, 2, 2);
} }
#[bench] #[bench]
fn bench_mul_dmat_dvec3(bh: &mut Bencher) { fn bench_mul_dmat_dvec3(bh: &mut Bencher) {
bench_mul_dmat_dvec!(bh, 3, 3); bench_mul_dmat_dvector!(bh, 3, 3);
} }
#[bench] #[bench]
fn bench_mul_dmat_dvec4(bh: &mut Bencher) { fn bench_mul_dmat_dvec4(bh: &mut Bencher) {
bench_mul_dmat_dvec!(bh, 4, 4); bench_mul_dmat_dvector!(bh, 4, 4);
} }
#[bench] #[bench]
fn bench_mul_dmat_dvec5(bh: &mut Bencher) { fn bench_mul_dmat_dvec5(bh: &mut Bencher) {
bench_mul_dmat_dvec!(bh, 5, 5); bench_mul_dmat_dvector!(bh, 5, 5);
} }
#[bench] #[bench]
fn bench_mul_dmat_dvec6(bh: &mut Bencher) { fn bench_mul_dmat_dvec6(bh: &mut Bencher) {
bench_mul_dmat_dvec!(bh, 6, 6); bench_mul_dmat_dvector!(bh, 6, 6);
} }

View File

@ -6,40 +6,40 @@ extern crate nalgebra as na;
use rand::{IsaacRng, Rng}; use rand::{IsaacRng, Rng};
use test::Bencher; use test::Bencher;
use na::{Vec2, Vec3, Vec4, Mat2, Mat3, Mat4}; use na::{Vector2, Vector3, Vector4, Matrix2, Matrix3, Matrix4};
use std::ops::{Add, Sub, Mul, Div}; use std::ops::{Add, Sub, Mul, Div};
#[path="common/macros.rs"] #[path="common/macros.rs"]
mod macros; mod macros;
bench_binop!(_bench_mat2_mul_m, Mat2<f32>, Mat2<f32>, mul); bench_binop!(_bench_mat2_mul_m, Matrix2<f32>, Matrix2<f32>, mul);
bench_binop!(_bench_mat3_mul_m, Mat3<f32>, Mat3<f32>, mul); bench_binop!(_bench_mat3_mul_m, Matrix3<f32>, Matrix3<f32>, mul);
bench_binop!(_bench_mat4_mul_m, Mat4<f32>, Mat4<f32>, mul); bench_binop!(_bench_mat4_mul_m, Matrix4<f32>, Matrix4<f32>, mul);
bench_binop!(_bench_mat2_add_m, Mat2<f32>, Mat2<f32>, add); bench_binop!(_bench_mat2_add_m, Matrix2<f32>, Matrix2<f32>, add);
bench_binop!(_bench_mat3_add_m, Mat3<f32>, Mat3<f32>, add); bench_binop!(_bench_mat3_add_m, Matrix3<f32>, Matrix3<f32>, add);
bench_binop!(_bench_mat4_add_m, Mat4<f32>, Mat4<f32>, add); bench_binop!(_bench_mat4_add_m, Matrix4<f32>, Matrix4<f32>, add);
bench_binop!(_bench_mat2_sub_m, Mat2<f32>, Mat2<f32>, sub); bench_binop!(_bench_mat2_sub_m, Matrix2<f32>, Matrix2<f32>, sub);
bench_binop!(_bench_mat3_sub_m, Mat3<f32>, Mat3<f32>, sub); bench_binop!(_bench_mat3_sub_m, Matrix3<f32>, Matrix3<f32>, sub);
bench_binop!(_bench_mat4_sub_m, Mat4<f32>, Mat4<f32>, sub); bench_binop!(_bench_mat4_sub_m, Matrix4<f32>, Matrix4<f32>, sub);
bench_binop!(_bench_mat2_mul_v, Mat2<f32>, Vec2<f32>, mul); bench_binop!(_bench_mat2_mul_v, Matrix2<f32>, Vector2<f32>, mul);
bench_binop!(_bench_mat3_mul_v, Mat3<f32>, Vec3<f32>, mul); bench_binop!(_bench_mat3_mul_v, Matrix3<f32>, Vector3<f32>, mul);
bench_binop!(_bench_mat4_mul_v, Mat4<f32>, Vec4<f32>, mul); bench_binop!(_bench_mat4_mul_v, Matrix4<f32>, Vector4<f32>, mul);
bench_binop!(_bench_mat2_mul_s, Mat2<f32>, f32, mul); bench_binop!(_bench_mat2_mul_s, Matrix2<f32>, f32, mul);
bench_binop!(_bench_mat3_mul_s, Mat3<f32>, f32, mul); bench_binop!(_bench_mat3_mul_s, Matrix3<f32>, f32, mul);
bench_binop!(_bench_mat4_mul_s, Mat4<f32>, f32, mul); bench_binop!(_bench_mat4_mul_s, Matrix4<f32>, f32, mul);
bench_binop!(_bench_mat2_div_s, Mat2<f32>, f32, div); bench_binop!(_bench_mat2_div_s, Matrix2<f32>, f32, div);
bench_binop!(_bench_mat3_div_s, Mat3<f32>, f32, div); bench_binop!(_bench_mat3_div_s, Matrix3<f32>, f32, div);
bench_binop!(_bench_mat4_div_s, Mat4<f32>, f32, div); bench_binop!(_bench_mat4_div_s, Matrix4<f32>, f32, div);
bench_unop!(_bench_mat2_inv, Mat2<f32>, inv); bench_unop!(_bench_mat2_inv, Matrix2<f32>, inverse);
bench_unop!(_bench_mat3_inv, Mat3<f32>, inv); bench_unop!(_bench_mat3_inv, Matrix3<f32>, inverse);
bench_unop!(_bench_mat4_inv, Mat4<f32>, inv); bench_unop!(_bench_mat4_inv, Matrix4<f32>, inverse);
bench_unop!(_bench_mat2_transpose, Mat2<f32>, transpose); bench_unop!(_bench_mat2_transpose, Matrix2<f32>, transpose);
bench_unop!(_bench_mat3_transpose, Mat3<f32>, transpose); bench_unop!(_bench_mat3_transpose, Matrix3<f32>, transpose);
bench_unop!(_bench_mat4_transpose, Mat4<f32>, transpose); bench_unop!(_bench_mat4_transpose, Matrix4<f32>, transpose);

View File

@ -6,19 +6,19 @@ extern crate nalgebra as na;
use rand::{IsaacRng, Rng}; use rand::{IsaacRng, Rng};
use test::Bencher; use test::Bencher;
use na::{Quat, UnitQuat, Vec3}; use na::{Quaternion, UnitQuaternion, Vector3};
use std::ops::{Add, Sub, Mul, Div}; use std::ops::{Add, Sub, Mul, Div};
#[path="common/macros.rs"] #[path="common/macros.rs"]
mod macros; mod macros;
bench_binop!(_bench_quat_add_q, Quat<f32>, Quat<f32>, add); bench_binop!(_bench_quaternion_add_q, Quaternion<f32>, Quaternion<f32>, add);
bench_binop!(_bench_quat_sub_q, Quat<f32>, Quat<f32>, sub); bench_binop!(_bench_quaternion_sub_q, Quaternion<f32>, Quaternion<f32>, sub);
bench_binop!(_bench_quat_mul_q, Quat<f32>, Quat<f32>, mul); bench_binop!(_bench_quaternion_mul_q, Quaternion<f32>, Quaternion<f32>, mul);
// bench_binop!(_bench_quat_div_q, Quat<f32>, Quat<f32>, div) // bench_binop!(_bench_quaternion_div_q, Quaternion<f32>, Quaternion<f32>, div)
bench_binop!(_bench_quat_mul_v, UnitQuat<f32>, Vec3<f32>, mul); bench_binop!(_bench_quaternion_mul_v, UnitQuaternion<f32>, Vector3<f32>, mul);
bench_binop!(_bench_quat_mul_s, Quat<f32>, f32, mul); bench_binop!(_bench_quaternion_mul_s, Quaternion<f32>, f32, mul);
bench_binop!(_bench_quat_div_s, Quat<f32>, f32, div); bench_binop!(_bench_quaternion_div_s, Quaternion<f32>, f32, div);
bench_unop!(_bench_quat_inv, Quat<f32>, inv); bench_unop!(_bench_quaternion_inv, Quaternion<f32>, inverse);
bench_unop_self!(_bench_quat_conjugate, Quat<f32>, conjugate); bench_unop_self!(_bench_quaternion_conjugate, Quaternion<f32>, conjugate);
bench_unop!(_bench_quat_normalize, Quat<f32>, normalize); bench_unop!(_bench_quaternion_normalize, Quaternion<f32>, normalize);

View File

@ -9,104 +9,104 @@ extern crate nalgebra as na;
use rand::{IsaacRng, Rng}; use rand::{IsaacRng, Rng};
use test::Bencher; use test::Bencher;
use na::{Vec2, Vec3, Vec4}; use na::{Vector2, Vector3, Vector4};
use std::ops::{Add, Sub, Mul, Div}; use std::ops::{Add, Sub, Mul, Div};
#[path="common/macros.rs"] #[path="common/macros.rs"]
mod macros; mod macros;
bench_binop!(_bench_vec2_add_v, Vec2<f32>, Vec2<f32>, add); bench_binop!(_bench_vec2_add_v, Vector2<f32>, Vector2<f32>, add);
bench_binop!(_bench_vec3_add_v, Vec3<f32>, Vec3<f32>, add); bench_binop!(_bench_vec3_add_v, Vector3<f32>, Vector3<f32>, add);
bench_binop!(_bench_vec4_add_v, Vec4<f32>, Vec4<f32>, add); bench_binop!(_bench_vec4_add_v, Vector4<f32>, Vector4<f32>, add);
bench_binop!(_bench_vec2_sub_v, Vec2<f32>, Vec2<f32>, sub); bench_binop!(_bench_vec2_sub_v, Vector2<f32>, Vector2<f32>, sub);
bench_binop!(_bench_vec3_sub_v, Vec3<f32>, Vec3<f32>, sub); bench_binop!(_bench_vec3_sub_v, Vector3<f32>, Vector3<f32>, sub);
bench_binop!(_bench_vec4_sub_v, Vec4<f32>, Vec4<f32>, sub); bench_binop!(_bench_vec4_sub_v, Vector4<f32>, Vector4<f32>, sub);
bench_binop!(_bench_vec2_mul_v, Vec2<f32>, Vec2<f32>, mul); bench_binop!(_bench_vec2_mul_v, Vector2<f32>, Vector2<f32>, mul);
bench_binop!(_bench_vec3_mul_v, Vec3<f32>, Vec3<f32>, mul); bench_binop!(_bench_vec3_mul_v, Vector3<f32>, Vector3<f32>, mul);
bench_binop!(_bench_vec4_mul_v, Vec4<f32>, Vec4<f32>, mul); bench_binop!(_bench_vec4_mul_v, Vector4<f32>, Vector4<f32>, mul);
bench_binop!(_bench_vec2_div_v, Vec2<f32>, Vec2<f32>, div); bench_binop!(_bench_vec2_div_v, Vector2<f32>, Vector2<f32>, div);
bench_binop!(_bench_vec3_div_v, Vec3<f32>, Vec3<f32>, div); bench_binop!(_bench_vec3_div_v, Vector3<f32>, Vector3<f32>, div);
bench_binop!(_bench_vec4_div_v, Vec4<f32>, Vec4<f32>, div); bench_binop!(_bench_vec4_div_v, Vector4<f32>, Vector4<f32>, div);
bench_binop!(_bench_vec2_add_s, Vec2<f32>, f32, add); bench_binop!(_bench_vec2_add_s, Vector2<f32>, f32, add);
bench_binop!(_bench_vec3_add_s, Vec3<f32>, f32, add); bench_binop!(_bench_vec3_add_s, Vector3<f32>, f32, add);
bench_binop!(_bench_vec4_add_s, Vec4<f32>, f32, add); bench_binop!(_bench_vec4_add_s, Vector4<f32>, f32, add);
bench_binop!(_bench_vec2_sub_s, Vec2<f32>, f32, sub); bench_binop!(_bench_vec2_sub_s, Vector2<f32>, f32, sub);
bench_binop!(_bench_vec3_sub_s, Vec3<f32>, f32, sub); bench_binop!(_bench_vec3_sub_s, Vector3<f32>, f32, sub);
bench_binop!(_bench_vec4_sub_s, Vec4<f32>, f32, sub); bench_binop!(_bench_vec4_sub_s, Vector4<f32>, f32, sub);
bench_binop!(_bench_vec2_mul_s, Vec2<f32>, f32, mul); bench_binop!(_bench_vec2_mul_s, Vector2<f32>, f32, mul);
bench_binop!(_bench_vec3_mul_s, Vec3<f32>, f32, mul); bench_binop!(_bench_vec3_mul_s, Vector3<f32>, f32, mul);
bench_binop!(_bench_vec4_mul_s, Vec4<f32>, f32, mul); bench_binop!(_bench_vec4_mul_s, Vector4<f32>, f32, mul);
bench_binop!(_bench_vec2_div_s, Vec2<f32>, f32, div); bench_binop!(_bench_vec2_div_s, Vector2<f32>, f32, div);
bench_binop!(_bench_vec3_div_s, Vec3<f32>, f32, div); bench_binop!(_bench_vec3_div_s, Vector3<f32>, f32, div);
bench_binop!(_bench_vec4_div_s, Vec4<f32>, f32, div); bench_binop!(_bench_vec4_div_s, Vector4<f32>, f32, div);
bench_binop_na!(_bench_vec2_dot, Vec2<f32>, Vec2<f32>, dot); bench_binop_na!(_bench_vec2_dot, Vector2<f32>, Vector2<f32>, dot);
bench_binop_na!(_bench_vec3_dot, Vec3<f32>, Vec3<f32>, dot); bench_binop_na!(_bench_vec3_dot, Vector3<f32>, Vector3<f32>, dot);
bench_binop_na!(_bench_vec4_dot, Vec4<f32>, Vec4<f32>, dot); bench_binop_na!(_bench_vec4_dot, Vector4<f32>, Vector4<f32>, dot);
bench_binop_na!(_bench_vec3_cross, Vec3<f32>, Vec3<f32>, cross); bench_binop_na!(_bench_vec3_cross, Vector3<f32>, Vector3<f32>, cross);
bench_unop!(_bench_vec2_norm, Vec2<f32>, norm); bench_unop!(_bench_vec2_norm, Vector2<f32>, norm);
bench_unop!(_bench_vec3_norm, Vec3<f32>, norm); bench_unop!(_bench_vec3_norm, Vector3<f32>, norm);
bench_unop!(_bench_vec4_norm, Vec4<f32>, norm); bench_unop!(_bench_vec4_norm, Vector4<f32>, norm);
bench_unop!(_bench_vec2_normalize, Vec2<f32>, normalize); bench_unop!(_bench_vec2_normalize, Vector2<f32>, normalize);
bench_unop!(_bench_vec3_normalize, Vec3<f32>, normalize); bench_unop!(_bench_vec3_normalize, Vector3<f32>, normalize);
bench_unop!(_bench_vec4_normalize, Vec4<f32>, normalize); bench_unop!(_bench_vec4_normalize, Vector4<f32>, normalize);
#[cfg(feature = "generic_sizes")] #[cfg(feature = "generic_sizes")]
mod bench_vecn { mod bench_vecn {
use typenum::{U2, U3, U4}; use typenum::{U2, U3, U4};
use na::VecN; use na::VectorN;
bench_binop!(_bench_vecn2_add_v, VecN<f32, U2>, VecN<f32, U2>, add); bench_binop!(_bench_vecn2_add_v, VectorN<f32, U2>, VectorN<f32, U2>, add);
bench_binop!(_bench_vecn3_add_v, VecN<f32, U3>, VecN<f32, U3>, add); bench_binop!(_bench_vecn3_add_v, VectorN<f32, U3>, VectorN<f32, U3>, add);
bench_binop!(_bench_vecn4_add_v, VecN<f32, U4>, VecN<f32, U4>, add); bench_binop!(_bench_vecn4_add_v, VectorN<f32, U4>, VectorN<f32, U4>, add);
bench_binop!(_bench_vecn2_sub_v, VecN<f32, U2>, VecN<f32, U2>, sub); bench_binop!(_bench_vecn2_sub_v, VectorN<f32, U2>, VectorN<f32, U2>, sub);
bench_binop!(_bench_vecn3_sub_v, VecN<f32, U3>, VecN<f32, U3>, sub); bench_binop!(_bench_vecn3_sub_v, VectorN<f32, U3>, VectorN<f32, U3>, sub);
bench_binop!(_bench_vecn4_sub_v, VecN<f32, U4>, VecN<f32, U4>, sub); bench_binop!(_bench_vecn4_sub_v, VectorN<f32, U4>, VectorN<f32, U4>, sub);
bench_binop!(_bench_vecn2_mul_v, VecN<f32, U2>, VecN<f32, U2>, mul); bench_binop!(_bench_vecn2_mul_v, VectorN<f32, U2>, VectorN<f32, U2>, mul);
bench_binop!(_bench_vecn3_mul_v, VecN<f32, U3>, VecN<f32, U3>, mul); bench_binop!(_bench_vecn3_mul_v, VectorN<f32, U3>, VectorN<f32, U3>, mul);
bench_binop!(_bench_vecn4_mul_v, VecN<f32, U4>, VecN<f32, U4>, mul); bench_binop!(_bench_vecn4_mul_v, VectorN<f32, U4>, VectorN<f32, U4>, mul);
bench_binop!(_bench_vecn2_div_v, VecN<f32, U2>, VecN<f32, U2>, div); bench_binop!(_bench_vecn2_div_v, VectorN<f32, U2>, VectorN<f32, U2>, div);
bench_binop!(_bench_vecn3_div_v, VecN<f32, U3>, VecN<f32, U3>, div); bench_binop!(_bench_vecn3_div_v, VectorN<f32, U3>, VectorN<f32, U3>, div);
bench_binop!(_bench_vecn4_div_v, VecN<f32, U4>, VecN<f32, U4>, div); bench_binop!(_bench_vecn4_div_v, VectorN<f32, U4>, VectorN<f32, U4>, div);
bench_binop!(_bench_vecn2_add_s, VecN<f32, U2>, f32, add); bench_binop!(_bench_vecn2_add_s, VectorN<f32, U2>, f32, add);
bench_binop!(_bench_vecn3_add_s, VecN<f32, U3>, f32, add); bench_binop!(_bench_vecn3_add_s, VectorN<f32, U3>, f32, add);
bench_binop!(_bench_vecn4_add_s, VecN<f32, U4>, f32, add); bench_binop!(_bench_vecn4_add_s, VectorN<f32, U4>, f32, add);
bench_binop!(_bench_vecn2_sub_s, VecN<f32, U2>, f32, sub); bench_binop!(_bench_vecn2_sub_s, VectorN<f32, U2>, f32, sub);
bench_binop!(_bench_vecn3_sub_s, VecN<f32, U3>, f32, sub); bench_binop!(_bench_vecn3_sub_s, VectorN<f32, U3>, f32, sub);
bench_binop!(_bench_vecn4_sub_s, VecN<f32, U4>, f32, sub); bench_binop!(_bench_vecn4_sub_s, VectorN<f32, U4>, f32, sub);
bench_binop!(_bench_vecn2_mul_s, VecN<f32, U2>, f32, mul); bench_binop!(_bench_vecn2_mul_s, VectorN<f32, U2>, f32, mul);
bench_binop!(_bench_vecn3_mul_s, VecN<f32, U3>, f32, mul); bench_binop!(_bench_vecn3_mul_s, VectorN<f32, U3>, f32, mul);
bench_binop!(_bench_vecn4_mul_s, VecN<f32, U4>, f32, mul); bench_binop!(_bench_vecn4_mul_s, VectorN<f32, U4>, f32, mul);
bench_binop!(_bench_vecn2_div_s, VecN<f32, U2>, f32, div); bench_binop!(_bench_vecn2_div_s, VectorN<f32, U2>, f32, div);
bench_binop!(_bench_vecn3_div_s, VecN<f32, U3>, f32, div); bench_binop!(_bench_vecn3_div_s, VectorN<f32, U3>, f32, div);
bench_binop!(_bench_vecn4_div_s, VecN<f32, U4>, f32, div); bench_binop!(_bench_vecn4_div_s, VectorN<f32, U4>, f32, div);
bench_binop_na!(_bench_vecn2_dot, VecN<f32, U2>, VecN<f32, U2>, dot); bench_binop_na!(_bench_vecn2_dot, VectorN<f32, U2>, VectorN<f32, U2>, dot);
bench_binop_na!(_bench_vecn3_dot, VecN<f32, U3>, VecN<f32, U3>, dot); bench_binop_na!(_bench_vecn3_dot, VectorN<f32, U3>, VectorN<f32, U3>, dot);
bench_binop_na!(_bench_vecn4_dot, VecN<f32, U4>, VecN<f32, U4>, dot); bench_binop_na!(_bench_vecn4_dot, VectorN<f32, U4>, VectorN<f32, U4>, dot);
bench_unop!(_bench_vecn2_norm, VecN<f32, U2>, norm); bench_unop!(_bench_vecn2_norm, VectorN<f32, U2>, norm);
bench_unop!(_bench_vecn3_norm, VecN<f32, U3>, norm); bench_unop!(_bench_vecn3_norm, VectorN<f32, U3>, norm);
bench_unop!(_bench_vecn4_norm, VecN<f32, U4>, norm); bench_unop!(_bench_vecn4_norm, VectorN<f32, U4>, norm);
bench_unop!(_bench_vecn2_normalize, VecN<f32, U2>, normalize); bench_unop!(_bench_vecn2_normalize, VectorN<f32, U2>, normalize);
bench_unop!(_bench_vecn3_normalize, VecN<f32, U3>, normalize); bench_unop!(_bench_vecn3_normalize, VectorN<f32, U3>, normalize);
bench_unop!(_bench_vecn4_normalize, VecN<f32, U4>, normalize); bench_unop!(_bench_vecn4_normalize, VectorN<f32, U4>, normalize);
} }

View File

@ -14,22 +14,22 @@ All the functionality of **nalgebra** is grouped in one place: the root module `
module re-exports everything and includes free functions for all traits methods performing module re-exports everything and includes free functions for all traits methods performing
out-of-place operations. out-of-place operations.
* You can import the whole prelude using: Thus, you can import the whole prelude using:
```.ignore ```.ignore
use nalgebra::*; use nalgebra::*;
``` ```
The preferred way to use **nalgebra** is to import types and traits explicitly, and call However, the recommended way to use **nalgebra** is to import types and traits explicitly, and call
free-functions using the `na::` prefix: free-functions using the `na::` prefix:
```.rust ```.rust
extern crate nalgebra as na; extern crate nalgebra as na;
use na::{Vec3, Rot3, Rotation}; use na::{Vector3, Rotation3, Rotation};
fn main() { fn main() {
let a = Vec3::new(1.0f64, 1.0, 1.0); let a = Vector3::new(1.0f64, 1.0, 1.0);
let mut b = Rot3::new(na::zero()); let mut b = Rotation3::new(na::zero());
b.append_rotation_mut(&a); b.append_rotation_mut(&a);
@ -41,19 +41,19 @@ fn main() {
**nalgebra** is meant to be a general-purpose, low-dimensional, linear algebra library, with **nalgebra** is meant to be a general-purpose, low-dimensional, linear algebra library, with
an optimized set of tools for computer graphics and physics. Those features include: an optimized set of tools for computer graphics and physics. Those features include:
* Vectors with predefined static sizes: `Vec1`, `Vec2`, `Vec3`, `Vec4`, `Vec5`, `Vec6`. * Vectors with predefined static sizes: `Vector1`, `Vector2`, `Vector3`, `Vector4`, `Vector5`, `Vector6`.
* Vector with a user-defined static size: `VecN` (available only with the `generic_sizes` feature). * Vector with a user-defined static size: `VectorN` (available only with the `generic_sizes` feature).
* Points with static sizes: `Pnt1`, `Pnt2`, `Pnt3`, `Pnt4`, `Pnt5`, `Pnt6`. * Points with static sizes: `Point1`, `Point2`, `Point3`, `Point4`, `Point5`, `Point6`.
* Square matrices with static sizes: `Mat1`, `Mat2`, `Mat3`, `Mat4`, `Mat5`, `Mat6 `. * Square matrices with static sizes: `Matrix1`, `Matrix2`, `Matrix3`, `Matrix4`, `Matrix5`, `Matrix6 `.
* Rotation matrices: `Rot2`, `Rot3` * Rotation matrices: `Rotation2`, `Rotation3`
* Quaternions: `Quat`, `UnitQuat`. * Quaternions: `Quaternion`, `UnitQuaternion`.
* Isometries (translation rotation): `Iso2`, `Iso3` * Isometrymetries (translation rotation): `Isometry2`, `Isometry3`
* Similarity transformations (translation rotation uniform scale): `Sim2`, `Sim3`. * Similarity transformations (translation rotation uniform scale): `Similarity2`, `Similarity3`.
* 3D projections for computer graphics: `Persp3`, `PerspMat3`, `Ortho3`, `OrthoMat3`. * 3D projections for computer graphics: `Perspective3`, `PerspectiveMatrix3`, `Orthographic3`, `OrthographicMatrix3`.
* Dynamically sized heap-allocated vector: `DVec`. * Dynamically sized heap-allocated vector: `DVector`.
* Dynamically sized stack-allocated vectors with a maximum size: `DVec1` to `DVec6`. * Dynamically sized stack-allocated vectors with a maximum size: `DVector1` to `DVector6`.
* Dynamically sized heap-allocated (square or rectangular) matrix: `DMat`. * Dynamically sized heap-allocated (square or rectangular) matrix: `DMatrix`.
* Linear algebra and data analysis operators: `Cov`, `Mean`, `qr`, `cholesky`. * Linear algebra and data analysis operators: `Covariance`, `Mean`, `qr`, `cholesky`.
* Almost one trait per functionality: useful for generic programming. * Almost one trait per functionality: useful for generic programming.
@ -98,39 +98,39 @@ pub use traits::{
BaseNum, BaseNum,
Bounded, Bounded,
Cast, Cast,
Col, Column,
ColSlice, RowSlice, ColumnSlice, RowSlice,
Cov, Covariance,
Cross, Cross,
CrossMatrix, CrossMatrix,
Det, Determinant,
Diag, Diagonal,
Dim, Dimension,
Dot, Dot,
EigenQR, EigenQR,
Eye, Eye,
FloatPnt, FloatPoint,
FloatVec, FloatVector,
FromHomogeneous, FromHomogeneous,
Indexable, Indexable,
Inv, Inverse,
Iterable, Iterable,
IterableMut, IterableMut,
Mat, Matrix,
Mean, Mean,
Norm, Norm,
NumPnt, NumPoint,
NumVec, NumVector,
Orig, Origin,
Outer, Outer,
POrd, PartialOrder,
POrdering, PartialOrdering,
PntAsVec, PointAsVector,
Repeat, Repeat,
Rotate, Rotation, RotationMatrix, RotationWithTranslation, RotationTo, Rotate, Rotation, RotationMatrix, RotationWithTranslation, RotationTo,
Row, Row,
Shape, Shape,
SquareMat, SquareMatrix,
ToHomogeneous, ToHomogeneous,
Transform, Transformation, Transform, Transformation,
Translate, Translation, Translate, Translation,
@ -139,22 +139,22 @@ pub use traits::{
}; };
#[cfg(feature="generic_sizes")] #[cfg(feature="generic_sizes")]
pub use structs::VecN; pub use structs::VectorN;
pub use structs::{ pub use structs::{
Identity, Identity,
DMat, DMat1, DMat2, DMat3, DMat4, DMat5, DMat6, DMatrix, DMatrix1, DMatrix2, DMatrix3, DMatrix4, DMatrix5, DMatrix6,
DVec, DVec1, DVec2, DVec3, DVec4, DVec5, DVec6, DVector, DVector1, DVector2, DVector3, DVector4, DVector5, DVector6,
Iso2, Iso3, Isometry2, Isometry3,
Sim2, Sim3, Similarity2, Similarity3,
Mat1, Mat2, Mat3, Mat4, Matrix1, Matrix2, Matrix3, Matrix4,
Mat5, Mat6, Matrix5, Matrix6,
Rot2, Rot3, Rotation2, Rotation3,
Vec1, Vec2, Vec3, Vec4, Vec5, Vec6, Vector1, Vector2, Vector3, Vector4, Vector5, Vector6,
Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6, Point1, Point2, Point3, Point4, Point5, Point6,
Persp3, PerspMat3, Perspective3, PerspectiveMatrix3,
Ortho3, OrthoMat3, Orthographic3, OrthographicMatrix3,
Quat, UnitQuat Quaternion, UnitQuaternion
}; };
pub use linalg::{ pub use linalg::{
@ -202,63 +202,63 @@ pub fn min<T: Ord>(a: T, b: T) -> T {
/// Returns the infimum of `a` and `b`. /// Returns the infimum of `a` and `b`.
#[inline(always)] #[inline(always)]
pub fn inf<T: POrd>(a: &T, b: &T) -> T { pub fn inf<T: PartialOrder>(a: &T, b: &T) -> T {
POrd::inf(a, b) PartialOrder::inf(a, b)
} }
/// Returns the supremum of `a` and `b`. /// Returns the supremum of `a` and `b`.
#[inline(always)] #[inline(always)]
pub fn sup<T: POrd>(a: &T, b: &T) -> T { pub fn sup<T: PartialOrder>(a: &T, b: &T) -> T {
POrd::sup(a, b) PartialOrder::sup(a, b)
} }
/// Compare `a` and `b` using a partial ordering relation. /// Compare `a` and `b` using a partial ordering relation.
#[inline(always)] #[inline(always)]
pub fn partial_cmp<T: POrd>(a: &T, b: &T) -> POrdering { pub fn partial_cmp<T: PartialOrder>(a: &T, b: &T) -> PartialOrdering {
POrd::partial_cmp(a, b) PartialOrder::partial_cmp(a, b)
} }
/// Returns `true` iff `a` and `b` are comparable and `a < b`. /// Returns `true` iff `a` and `b` are comparable and `a < b`.
#[inline(always)] #[inline(always)]
pub fn partial_lt<T: POrd>(a: &T, b: &T) -> bool { pub fn partial_lt<T: PartialOrder>(a: &T, b: &T) -> bool {
POrd::partial_lt(a, b) PartialOrder::partial_lt(a, b)
} }
/// Returns `true` iff `a` and `b` are comparable and `a <= b`. /// Returns `true` iff `a` and `b` are comparable and `a <= b`.
#[inline(always)] #[inline(always)]
pub fn partial_le<T: POrd>(a: &T, b: &T) -> bool { pub fn partial_le<T: PartialOrder>(a: &T, b: &T) -> bool {
POrd::partial_le(a, b) PartialOrder::partial_le(a, b)
} }
/// Returns `true` iff `a` and `b` are comparable and `a > b`. /// Returns `true` iff `a` and `b` are comparable and `a > b`.
#[inline(always)] #[inline(always)]
pub fn partial_gt<T: POrd>(a: &T, b: &T) -> bool { pub fn partial_gt<T: PartialOrder>(a: &T, b: &T) -> bool {
POrd::partial_gt(a, b) PartialOrder::partial_gt(a, b)
} }
/// Returns `true` iff `a` and `b` are comparable and `a >= b`. /// Returns `true` iff `a` and `b` are comparable and `a >= b`.
#[inline(always)] #[inline(always)]
pub fn partial_ge<T: POrd>(a: &T, b: &T) -> bool { pub fn partial_ge<T: PartialOrder>(a: &T, b: &T) -> bool {
POrd::partial_ge(a, b) PartialOrder::partial_ge(a, b)
} }
/// Return the minimum of `a` and `b` if they are comparable. /// Return the minimum of `a` and `b` if they are comparable.
#[inline(always)] #[inline(always)]
pub fn partial_min<'a, T: POrd>(a: &'a T, b: &'a T) -> Option<&'a T> { pub fn partial_min<'a, T: PartialOrder>(a: &'a T, b: &'a T) -> Option<&'a T> {
POrd::partial_min(a, b) PartialOrder::partial_min(a, b)
} }
/// Return the maximum of `a` and `b` if they are comparable. /// Return the maximum of `a` and `b` if they are comparable.
#[inline(always)] #[inline(always)]
pub fn partial_max<'a, T: POrd>(a: &'a T, b: &'a T) -> Option<&'a T> { pub fn partial_max<'a, T: PartialOrder>(a: &'a T, b: &'a T) -> Option<&'a T> {
POrd::partial_max(a, b) PartialOrder::partial_max(a, b)
} }
/// Clamp `value` between `min` and `max`. Returns `None` if `value` is not comparable to /// Clamp `value` between `min` and `max`. Returns `None` if `value` is not comparable to
/// `min` or `max`. /// `min` or `max`.
#[inline(always)] #[inline(always)]
pub fn partial_clamp<'a, T: POrd>(value: &'a T, min: &'a T, max: &'a T) -> Option<&'a T> { pub fn partial_clamp<'a, T: PartialOrder>(value: &'a T, min: &'a T, max: &'a T) -> Option<&'a T> {
POrd::partial_clamp(value, min, max) PartialOrder::partial_clamp(value, min, max)
} }
// //
@ -305,34 +305,34 @@ pub fn one<T: One>() -> T {
/// Returns the trivial origin of an affine space. /// Returns the trivial origin of an affine space.
#[inline(always)] #[inline(always)]
pub fn orig<P: Orig>() -> P { pub fn origin<P: Origin>() -> P {
Orig::orig() Origin::origin()
} }
/// Returns the center of two points. /// Returns the center of two points.
#[inline] #[inline]
pub fn center<N: BaseFloat, P: FloatPnt<N>>(a: &P, b: &P) -> P pub fn center<N: BaseFloat, P: FloatPoint<N>>(a: &P, b: &P) -> P
where <P as PntAsVec>::Vec: Norm<N> where <P as PointAsVector>::Vector: Norm<N>
{ {
let _2 = one::<N>() + one(); let _2 = one::<N>() + one();
(*a + b.to_vec()) / _2 (*a + b.to_vector()) / _2
} }
/* /*
* FloatPnt * FloatPoint
*/ */
/// Returns the distance between two points. /// Returns the distance between two points.
#[inline(always)] #[inline(always)]
pub fn dist<N: BaseFloat, P: FloatPnt<N>>(a: &P, b: &P) -> N where <P as PntAsVec>::Vec: Norm<N> { pub fn distance<N: BaseFloat, P: FloatPoint<N>>(a: &P, b: &P) -> N where <P as PointAsVector>::Vector: Norm<N> {
a.dist(b) a.distance(b)
} }
/// Returns the squared distance between two points. /// Returns the squared distance between two points.
#[inline(always)] #[inline(always)]
pub fn sqdist<N: BaseFloat, P: FloatPnt<N>>(a: &P, b: &P) -> N pub fn distance_squared<N: BaseFloat, P: FloatPoint<N>>(a: &P, b: &P) -> N
where <P as PntAsVec>::Vec: Norm<N> where <P as PointAsVector>::Vector: Norm<N>
{ {
a.sqdist(b) a.distance_squared(b)
} }
/* /*
@ -343,13 +343,13 @@ pub fn sqdist<N: BaseFloat, P: FloatPnt<N>>(a: &P, b: &P) -> N
/// ///
/// ```rust /// ```rust
/// extern crate nalgebra as na; /// extern crate nalgebra as na;
/// use na::{Vec3, Iso3}; /// use na::{Vector3, Isometry3};
/// ///
/// fn main() { /// fn main() {
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero()); /// let t = Isometry3::new(Vector3::new(1.0f64, 1.0, 1.0), na::zero());
/// let trans = na::translation(&t); /// let trans = na::translation(&t);
/// ///
/// assert!(trans == Vec3::new(1.0, 1.0, 1.0)); /// assert!(trans == Vector3::new(1.0, 1.0, 1.0));
/// } /// }
/// ``` /// ```
#[inline(always)] #[inline(always)]
@ -361,18 +361,18 @@ pub fn translation<V, M: Translation<V>>(m: &M) -> V {
/// ///
/// ```rust /// ```rust
/// extern crate nalgebra as na; /// extern crate nalgebra as na;
/// use na::{Vec3, Iso3}; /// use na::{Vector3, Isometry3};
/// ///
/// fn main() { /// fn main() {
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero()); /// let t = Isometry3::new(Vector3::new(1.0f64, 1.0, 1.0), na::zero());
/// let itrans = na::inv_translation(&t); /// let itrans = na::inverse_translation(&t);
/// ///
/// assert!(itrans == Vec3::new(-1.0, -1.0, -1.0)); /// assert!(itrans == Vector3::new(-1.0, -1.0, -1.0));
/// } /// }
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn inv_translation<V, M: Translation<V>>(m: &M) -> V { pub fn inverse_translation<V, M: Translation<V>>(m: &M) -> V {
m.inv_translation() m.inverse_translation()
} }
/// Applies the translation `v` to a copy of `m`. /// Applies the translation `v` to a copy of `m`.
@ -389,15 +389,15 @@ pub fn append_translation<V, M: Translation<V>>(m: &M, v: &V) -> M {
/// ///
/// ```rust /// ```rust
/// extern crate nalgebra as na; /// extern crate nalgebra as na;
/// use na::{Pnt3, Vec3, Iso3}; /// use na::{Point3, Vector3, Isometry3};
/// ///
/// fn main() { /// fn main() {
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero()); /// let t = Isometry3::new(Vector3::new(1.0f64, 1.0, 1.0), na::zero());
/// let p = Pnt3::new(2.0, 2.0, 2.0); /// let p = Point3::new(2.0, 2.0, 2.0);
/// ///
/// let tp = na::translate(&t, &p); /// let tp = na::translate(&t, &p);
/// ///
/// assert!(tp == Pnt3::new(3.0, 3.0, 3.0)) /// assert!(tp == Point3::new(3.0, 3.0, 3.0))
/// } /// }
/// ``` /// ```
#[inline(always)] #[inline(always)]
@ -409,19 +409,19 @@ pub fn translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
/// ///
/// ```rust /// ```rust
/// extern crate nalgebra as na; /// extern crate nalgebra as na;
/// use na::{Pnt3, Vec3, Iso3}; /// use na::{Point3, Vector3, Isometry3};
/// ///
/// fn main() { /// fn main() {
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero()); /// let t = Isometry3::new(Vector3::new(1.0f64, 1.0, 1.0), na::zero());
/// let p = Pnt3::new(2.0, 2.0, 2.0); /// let p = Point3::new(2.0, 2.0, 2.0);
/// ///
/// let tp = na::inv_translate(&t, &p); /// let tp = na::inverse_translate(&t, &p);
/// ///
/// assert!(na::approx_eq(&tp, &Pnt3::new(1.0, 1.0, 1.0))) /// assert!(na::approx_eq(&tp, &Point3::new(1.0, 1.0, 1.0)))
/// } /// }
#[inline(always)] #[inline(always)]
pub fn inv_translate<P, M: Translate<P>>(m: &M, p: &P) -> P { pub fn inverse_translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
m.inv_translate(p) m.inverse_translate(p)
} }
/* /*
@ -432,12 +432,12 @@ pub fn inv_translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
/// ///
/// ```rust /// ```rust
/// extern crate nalgebra as na; /// extern crate nalgebra as na;
/// use na::{Vec3, Rot3}; /// use na::{Vector3, Rotation3};
/// ///
/// fn main() { /// fn main() {
/// let t = Rot3::new(Vec3::new(1.0f64, 1.0, 1.0)); /// let t = Rotation3::new(Vector3::new(1.0f64, 1.0, 1.0));
/// ///
/// assert!(na::approx_eq(&na::rotation(&t), &Vec3::new(1.0, 1.0, 1.0))); /// assert!(na::approx_eq(&na::rotation(&t), &Vector3::new(1.0, 1.0, 1.0)));
/// } /// }
/// ``` /// ```
#[inline(always)] #[inline(always)]
@ -450,17 +450,17 @@ pub fn rotation<V, M: Rotation<V>>(m: &M) -> V {
/// ///
/// ```rust /// ```rust
/// extern crate nalgebra as na; /// extern crate nalgebra as na;
/// use na::{Vec3, Rot3}; /// use na::{Vector3, Rotation3};
/// ///
/// fn main() { /// fn main() {
/// let t = Rot3::new(Vec3::new(1.0f64, 1.0, 1.0)); /// let t = Rotation3::new(Vector3::new(1.0f64, 1.0, 1.0));
/// ///
/// assert!(na::approx_eq(&na::inv_rotation(&t), &Vec3::new(-1.0, -1.0, -1.0))); /// assert!(na::approx_eq(&na::inverse_rotation(&t), &Vector3::new(-1.0, -1.0, -1.0)));
/// } /// }
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn inv_rotation<V, M: Rotation<V>>(m: &M) -> V { pub fn inverse_rotation<V, M: Rotation<V>>(m: &M) -> V {
m.inv_rotation() m.inverse_rotation()
} }
// FIXME: this example is a bit shity // FIXME: this example is a bit shity
@ -468,14 +468,14 @@ pub fn inv_rotation<V, M: Rotation<V>>(m: &M) -> V {
/// ///
/// ```rust /// ```rust
/// extern crate nalgebra as na; /// extern crate nalgebra as na;
/// use na::{Vec3, Rot3}; /// use na::{Vector3, Rotation3};
/// ///
/// fn main() { /// fn main() {
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.0)); /// let t = Rotation3::new(Vector3::new(0.0f64, 0.0, 0.0));
/// let v = Vec3::new(1.0, 1.0, 1.0); /// let v = Vector3::new(1.0, 1.0, 1.0);
/// let rt = na::append_rotation(&t, &v); /// let rt = na::append_rotation(&t, &v);
/// ///
/// assert!(na::approx_eq(&na::rotation(&rt), &Vec3::new(1.0, 1.0, 1.0))) /// assert!(na::approx_eq(&na::rotation(&rt), &Vector3::new(1.0, 1.0, 1.0)))
/// } /// }
/// ``` /// ```
#[inline(always)] #[inline(always)]
@ -488,14 +488,14 @@ pub fn append_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
/// ///
/// ```rust /// ```rust
/// extern crate nalgebra as na; /// extern crate nalgebra as na;
/// use na::{Vec3, Rot3}; /// use na::{Vector3, Rotation3};
/// ///
/// fn main() { /// fn main() {
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.0)); /// let t = Rotation3::new(Vector3::new(0.0f64, 0.0, 0.0));
/// let v = Vec3::new(1.0, 1.0, 1.0); /// let v = Vector3::new(1.0, 1.0, 1.0);
/// let rt = na::prepend_rotation(&t, &v); /// let rt = na::prepend_rotation(&t, &v);
/// ///
/// assert!(na::approx_eq(&na::rotation(&rt), &Vec3::new(1.0, 1.0, 1.0))) /// assert!(na::approx_eq(&na::rotation(&rt), &Vector3::new(1.0, 1.0, 1.0)))
/// } /// }
/// ``` /// ```
#[inline(always)] #[inline(always)]
@ -511,15 +511,15 @@ pub fn prepend_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
/// ///
/// ```rust /// ```rust
/// extern crate nalgebra as na; /// extern crate nalgebra as na;
/// use na::{BaseFloat, Rot3, Vec3}; /// use na::{BaseFloat, Rotation3, Vector3};
/// ///
/// fn main() { /// fn main() {
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.5 * <f64 as BaseFloat>::pi())); /// let t = Rotation3::new(Vector3::new(0.0f64, 0.0, 0.5 * <f64 as BaseFloat>::pi()));
/// let v = Vec3::new(1.0, 0.0, 0.0); /// let v = Vector3::new(1.0, 0.0, 0.0);
/// ///
/// let tv = na::rotate(&t, &v); /// let tv = na::rotate(&t, &v);
/// ///
/// assert!(na::approx_eq(&tv, &Vec3::new(0.0, 1.0, 0.0))) /// assert!(na::approx_eq(&tv, &Vector3::new(0.0, 1.0, 0.0)))
/// } /// }
/// ``` /// ```
#[inline(always)] #[inline(always)]
@ -532,20 +532,20 @@ pub fn rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
/// ///
/// ```rust /// ```rust
/// extern crate nalgebra as na; /// extern crate nalgebra as na;
/// use na::{BaseFloat, Rot3, Vec3}; /// use na::{BaseFloat, Rotation3, Vector3};
/// ///
/// fn main() { /// fn main() {
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.5 * <f64 as BaseFloat>::pi())); /// let t = Rotation3::new(Vector3::new(0.0f64, 0.0, 0.5 * <f64 as BaseFloat>::pi()));
/// let v = Vec3::new(1.0, 0.0, 0.0); /// let v = Vector3::new(1.0, 0.0, 0.0);
/// ///
/// let tv = na::inv_rotate(&t, &v); /// let tv = na::inverse_rotate(&t, &v);
/// ///
/// assert!(na::approx_eq(&tv, &Vec3::new(0.0, -1.0, 0.0))) /// assert!(na::approx_eq(&tv, &Vector3::new(0.0, -1.0, 0.0)))
/// } /// }
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn inv_rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V { pub fn inverse_rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
m.inv_rotate(v) m.inverse_rotate(v)
} }
/* /*
@ -594,13 +594,13 @@ pub fn rotation_between<V: RotationTo>(a: &V, b: &V) -> V::DeltaRotationType {
/// Builds a rotation matrix from `r`. /// Builds a rotation matrix from `r`.
#[inline(always)] #[inline(always)]
pub fn to_rot_mat<N, LV, AV, R, M>(r: &R) -> M pub fn to_rotation_matrix<N, LV, AV, R, M>(r: &R) -> M
where R: RotationMatrix<N, LV, AV, Output = M>, where R: RotationMatrix<N, LV, AV, Output = M>,
M: SquareMat<N, LV> + Rotation<AV> + Copy, M: SquareMatrix<N, LV> + Rotation<AV> + Copy,
LV: Mul<M, Output = LV> LV: Mul<M, Output = LV>
{ {
// FIXME: rust-lang/rust#20413 // FIXME: rust-lang/rust#20413
r.to_rot_mat() r.to_rotation_matrix()
} }
/* /*
@ -625,8 +625,8 @@ pub fn transformation<T, M: Transformation<T>>(m: &M) -> T {
/// Gets the inverse transformation applicable by `m`. /// Gets the inverse transformation applicable by `m`.
#[inline(always)] #[inline(always)]
pub fn inv_transformation<T, M: Transformation<T>>(m: &M) -> T { pub fn inverse_transformation<T, M: Transformation<T>>(m: &M) -> T {
m.inv_transformation() m.inverse_transformation()
} }
/// Gets a transformed copy of `m`. /// Gets a transformed copy of `m`.
@ -647,8 +647,8 @@ pub fn transform<V, M: Transform<V>>(m: &M, v: &V) -> V {
/// Applies an inverse transformation to a vector. /// Applies an inverse transformation to a vector.
#[inline(always)] #[inline(always)]
pub fn inv_transform<V, M: Transform<V>>(m: &M, v: &V) -> V { pub fn inverse_transform<V, M: Transform<V>>(m: &M, v: &V) -> V {
m.inv_transform(v) m.inverse_transform(v)
} }
/* /*
@ -673,8 +673,8 @@ pub fn norm<V: Norm<N>, N: BaseFloat>(v: &V) -> N {
/// Computes the squared L2 norm of a vector. /// Computes the squared L2 norm of a vector.
#[inline(always)] #[inline(always)]
pub fn sqnorm<V: Norm<N>, N: BaseFloat>(v: &V) -> N { pub fn norm_squared<V: Norm<N>, N: BaseFloat>(v: &V) -> N {
Norm::sqnorm(v) Norm::norm_squared(v)
} }
/// Gets the normalized version of a vector. /// Gets the normalized version of a vector.
@ -684,12 +684,12 @@ pub fn normalize<V: Norm<N>, N: BaseFloat>(v: &V) -> V {
} }
/* /*
* Det<N> * Determinant<N>
*/ */
/// Computes the determinant of a square matrix. /// Computes the determinant of a square matrix.
#[inline(always)] #[inline(always)]
pub fn det<M: Det<N>, N>(m: &M) -> N { pub fn determinant<M: Determinant<N>, N>(m: &M) -> N {
Det::det(m) Determinant::determinant(m)
} }
/* /*
@ -780,13 +780,13 @@ pub fn abs<M: Absolute<Res>, Res>(m: &M) -> Res {
} }
/* /*
* Inv * Inverse
*/ */
/// Gets an inverted copy of a matrix. /// Gets an inverted copy of a matrix.
#[inline(always)] #[inline(always)]
pub fn inv<M: Inv>(m: &M) -> Option<M> { pub fn inverse<M: Inverse>(m: &M) -> Option<M> {
Inv::inv(m) Inverse::inverse(m)
} }
/* /*
@ -810,13 +810,13 @@ pub fn outer<V: Outer>(a: &V, b: &V) -> V::OuterProductType {
} }
/* /*
* Cov<M> * Covariance<M>
*/ */
/// Computes the covariance of a set of observations. /// Computes the covariance of a set of observations.
#[inline(always)] #[inline(always)]
pub fn cov<M: Cov<Res>, Res>(observations: &M) -> Res { pub fn covariance<M: Covariance<Res>, Res>(observations: &M) -> Res {
Cov::cov(observations) Covariance::covariance(observations)
} }
/* /*
@ -851,8 +851,8 @@ pub fn eigen_qr<N, V, M>(m: &M, eps: &N, niter: usize) -> (M, V)
*/ */
/// Construct the identity matrix for a given dimension /// Construct the identity matrix for a given dimension
#[inline(always)] #[inline(always)]
pub fn new_identity<M: Eye>(dim: usize) -> M { pub fn new_identity<M: Eye>(dimension: usize) -> M {
Eye::new_identity(dim) Eye::new_identity(dimension)
} }
@ -894,27 +894,27 @@ pub fn canonical_basis_element<V: Basis>(i: usize) -> Option<V> {
*/ */
/* /*
* Col<C> * Column<C>
*/ */
/* /*
* Diag<V> * Diagonal<V>
*/ */
/// Gets the diagonal of a square matrix. /// Gets the diagonal of a square matrix.
#[inline(always)] #[inline(always)]
pub fn diag<M: Diag<V>, V>(m: &M) -> V { pub fn diagonal<M: Diagonal<V>, V>(m: &M) -> V {
m.diag() m.diagonal()
} }
/* /*
* Dim * Dimension
*/ */
/// Gets the dimension an object lives in. /// Gets the dimension an object lives in.
/// ///
/// Same as `Dim::dim::(None::<V>)`. /// Same as `Dimension::dimension::(None::<V>)`.
#[inline(always)] #[inline(always)]
pub fn dim<V: Dim>() -> usize { pub fn dimension<V: Dimension>() -> usize {
Dim::dim(None::<V>) Dimension::dimension(None::<V>)
} }
/// Gets the indexable range of an object. /// Gets the indexable range of an object.
@ -931,10 +931,10 @@ pub fn shape<V: Shape<I>, I>(v: &V) -> I {
/// For primitive types, this is the same as the `as` keywords. /// For primitive types, this is the same as the `as` keywords.
/// The following properties are preserved by a cast: /// The following properties are preserved by a cast:
/// ///
/// * Type-level geometric invariants cannot be broken (eg. a cast from Rot3<f64> to Rot3<i64> is /// * Type-level geometric invariants cannot be broken (eg. a cast from Rotation3<f64> to Rotation3<i64> is
/// not possible) /// not possible)
/// * A cast to a type with more type-level invariants cannot be done (eg. a cast from Mat<f64> to /// * A cast to a type with more type-level invariants cannot be done (eg. a cast from Matrix<f64> to
/// Rot3<f64> is not possible) /// Rotation3<f64> is not possible)
/// * For primitive types an unbounded cast is done using the `as` keyword (this is different from /// * For primitive types an unbounded cast is done using the `as` keyword (this is different from
/// the standard library which makes bound-checking to ensure eg. that a i64 is not out of the /// the standard library which makes bound-checking to ensure eg. that a i64 is not out of the
/// range of an i32 when a cast from i64 to i32 is done). /// range of an i32 when a cast from i64 to i32 is done).

View File

@ -1,31 +1,31 @@
use traits::operations::{Transpose, ApproxEq}; use traits::operations::{Transpose, ApproxEq};
use traits::structure::{ColSlice, Eye, Indexable, Diag, SquareMat, BaseFloat, Cast}; use traits::structure::{ColumnSlice, Eye, Indexable, Diagonal, SquareMatrix, BaseFloat, Cast};
use traits::geometry::Norm; use traits::geometry::Norm;
use std::cmp; use std::cmp;
use std::ops::{Mul, Add, Sub}; use std::ops::{Mul, Add, Sub};
/// Get the householder matrix corresponding to a reflexion to the hyperplane /// Get the householder matrix corresponding to a reflexion to the hyperplane
/// defined by `vec`. It can be a reflexion contained in a subspace. /// defined by `vector`. It can be a reflexion contained in a subspace.
/// ///
/// # Arguments /// # Arguments
/// * `dim` - the dimension of the space the resulting matrix operates in /// * `dimension` - the dimension of the space the resulting matrix operates in
/// * `start` - the starting dimension of the subspace of the reflexion /// * `start` - the starting dimension of the subspace of the reflexion
/// * `vec` - the vector defining the reflection. /// * `vector` - the vector defining the reflection.
pub fn householder_matrix<N, V, M>(dim: usize, start: usize, vec: V) -> M pub fn householder_matrix<N, V, M>(dimension: usize, start: usize, vector: V) -> M
where N: BaseFloat, where N: BaseFloat,
M: Eye + Indexable<(usize, usize), N>, M: Eye + Indexable<(usize, usize), N>,
V: Indexable<usize, N> { V: Indexable<usize, N> {
let mut qk : M = Eye::new_identity(dim); let mut qk : M = Eye::new_identity(dimension);
let subdim = vec.shape(); let subdim = vector.shape();
let stop = subdim + start; let stop = subdim + start;
assert!(dim >= stop); assert!(dimension >= stop);
for j in start .. stop { for j in start .. stop {
for i in start .. stop { for i in start .. stop {
unsafe { unsafe {
let vv = vec.unsafe_at(i - start) * vec.unsafe_at(j - start); let vv = vector.unsafe_at(i - start) * vector.unsafe_at(j - start);
let qkij = qk.unsafe_at((i, j)); let qkij = qk.unsafe_at((i, j));
qk.unsafe_set((i, j), qkij - vv - vv); qk.unsafe_set((i, j), qkij - vv - vv);
} }
@ -41,7 +41,7 @@ pub fn householder_matrix<N, V, M>(dim: usize, start: usize, vec: V) -> M
pub fn qr<N, V, M>(m: &M) -> (M, M) pub fn qr<N, V, M>(m: &M) -> (M, M)
where N: BaseFloat, where N: BaseFloat,
V: Indexable<usize, N> + Norm<N>, V: Indexable<usize, N> + Norm<N>,
M: Copy + Eye + ColSlice<V> + Transpose + Indexable<(usize, usize), N> + M: Copy + Eye + ColumnSlice<V> + Transpose + Indexable<(usize, usize), N> +
Mul<M, Output = M> { Mul<M, Output = M> {
let (rows, cols) = m.shape(); let (rows, cols) = m.shape();
assert!(rows >= cols); assert!(rows >= cols);
@ -76,29 +76,29 @@ pub fn eigen_qr<N, V, VS, M>(m: &M, eps: &N, niter: usize) -> (M, V)
where N: BaseFloat, where N: BaseFloat,
V: Mul<M, Output = V>, V: Mul<M, Output = V>,
VS: Indexable<usize, N> + Norm<N>, VS: Indexable<usize, N> + Norm<N>,
M: Indexable<(usize, usize), N> + SquareMat<N, V> + Add<M, Output = M> + M: Indexable<(usize, usize), N> + SquareMatrix<N, V> + Add<M, Output = M> +
Sub<M, Output = M> + ColSlice<VS> + Sub<M, Output = M> + ColumnSlice<VS> +
ApproxEq<N> + Copy { ApproxEq<N> + Copy {
let (mut eigenvectors, mut eigenvalues) = hessenberg(m); let (mut eigenvectors, mut eigenvalues) = hessenberg(m);
// Allocate arrays for Givens rotation components // Allocate arrays for Givens rotation components
let mut c = Vec::<N>::with_capacity(::dim::<M>() - 1); let mut c = Vec::<N>::with_capacity(::dimension::<M>() - 1);
let mut s = Vec::<N>::with_capacity(::dim::<M>() - 1); let mut s = Vec::<N>::with_capacity(::dimension::<M>() - 1);
if ::dim::<M>() == 1 { if ::dimension::<M>() == 1 {
return (eigenvectors, eigenvalues.diag()); return (eigenvectors, eigenvalues.diagonal());
} }
unsafe { unsafe {
c.set_len(::dim::<M>() - 1); c.set_len(::dimension::<M>() - 1);
s.set_len(::dim::<M>() - 1); s.set_len(::dimension::<M>() - 1);
} }
let mut iter = 0; let mut iter = 0;
let mut curdim = ::dim::<M>() - 1; let mut curdim = ::dimension::<M>() - 1;
for _ in 0 .. ::dim::<M>() { for _ in 0 .. ::dimension::<M>() {
let mut stop = false; let mut stop = false;
@ -113,12 +113,12 @@ pub fn eigen_qr<N, V, VS, M>(m: &M, eps: &N, niter: usize) -> (M, V)
let d = eigenvalues.unsafe_at((curdim, curdim)); let d = eigenvalues.unsafe_at((curdim, curdim));
let trace = a + d; let trace = a + d;
let det = a * d - b * c; let determinant = a * d - b * c;
let constquarter: N = Cast::from(0.25f64); let constquarter: N = Cast::from(0.25f64);
let consthalf: N = Cast::from(0.5f64); let consthalf: N = Cast::from(0.5f64);
let e = (constquarter * trace * trace - det).sqrt(); let e = (constquarter * trace * trace - determinant).sqrt();
let lambda1 = consthalf * trace + e; let lambda1 = consthalf * trace + e;
let lambda2 = consthalf * trace - e; let lambda2 = consthalf * trace - e;
@ -207,7 +207,7 @@ pub fn eigen_qr<N, V, VS, M>(m: &M, eps: &N, niter: usize) -> (M, V)
// Givens rotation from right applied to eigenvectors // Givens rotation from right applied to eigenvectors
for k in 0 .. curdim { for k in 0 .. curdim {
for i in 0 .. ::dim::<M>() { for i in 0 .. ::dimension::<M>() {
unsafe { unsafe {
let a = eigenvectors.unsafe_at((i, k)); let a = eigenvectors.unsafe_at((i, k));
@ -254,7 +254,7 @@ pub fn eigen_qr<N, V, VS, M>(m: &M, eps: &N, niter: usize) -> (M, V)
} }
(eigenvectors, eigenvalues.diag()) (eigenvectors, eigenvalues.diagonal())
} }
/// Cholesky decomposition G of a square symmetric positive definite matrix A, such that A = G * G^T /// Cholesky decomposition G of a square symmetric positive definite matrix A, such that A = G * G^T
@ -265,8 +265,8 @@ pub fn cholesky<N, V, VS, M>(m: &M) -> Result<M, &'static str>
where N: BaseFloat, where N: BaseFloat,
V: Mul<M, Output = V>, V: Mul<M, Output = V>,
VS: Indexable<usize, N> + Norm<N>, VS: Indexable<usize, N> + Norm<N>,
M: Indexable<(usize, usize), N> + SquareMat<N, V> + Add<M, Output = M> + M: Indexable<(usize, usize), N> + SquareMatrix<N, V> + Add<M, Output = M> +
Sub<M, Output = M> + ColSlice<VS> + Sub<M, Output = M> + ColumnSlice<VS> +
ApproxEq<N> + Copy { ApproxEq<N> + Copy {
let mut out = m.clone().transpose(); let mut out = m.clone().transpose();
@ -317,7 +317,7 @@ pub fn cholesky<N, V, VS, M>(m: &M) -> Result<M, &'static str>
pub fn hessenberg<N, V, M>(m: &M) -> (M, M) pub fn hessenberg<N, V, M>(m: &M) -> (M, M)
where N: BaseFloat, where N: BaseFloat,
V: Indexable<usize, N> + Norm<N>, V: Indexable<usize, N> + Norm<N>,
M: Copy + Eye + ColSlice<V> + Transpose + Indexable<(usize, usize), N> + M: Copy + Eye + ColumnSlice<V> + Transpose + Indexable<(usize, usize), N> +
Mul<M, Output = M> { Mul<M, Output = M> {
let mut h = m.clone(); let mut h = m.clone();

View File

@ -7,41 +7,41 @@ use std::ops::{Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, Index, Index
use std::fmt::{Debug, Formatter, Result}; use std::fmt::{Debug, Formatter, Result};
use rand::{self, Rand}; use rand::{self, Rand};
use num::{Zero, One}; use num::{Zero, One};
use structs::dvec::{DVec, DVec1, DVec2, DVec3, DVec4, DVec5, DVec6}; use structs::dvector::{DVector, DVector1, DVector2, DVector3, DVector4, DVector5, DVector6};
use traits::operations::{ApproxEq, Inv, Transpose, Mean, Cov}; use traits::operations::{ApproxEq, Inverse, Transpose, Mean, Covariance};
use traits::structure::{Cast, Col, ColSlice, Row, RowSlice, Diag, DiagMut, Eye, Indexable, Shape, BaseNum}; use traits::structure::{Cast, Column, ColumnSlice, Row, RowSlice, Diagonal, DiagMut, Eye, Indexable, Shape, BaseNum};
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};
/// Matrix with dimensions unknown at compile-time. /// Matrix with dimensions unknown at compile-time.
#[derive(Eq, PartialEq, Clone)] #[derive(Eq, PartialEq, Clone)]
pub struct DMat<N> { pub struct DMatrix<N> {
nrows: usize, nrows: usize,
ncols: usize, ncols: usize,
mij: Vec<N> mij: Vec<N>
} }
impl<N> DMat<N> { impl<N> DMatrix<N> {
/// Creates an uninitialized matrix. /// Creates an uninitialized matrix.
#[inline] #[inline]
pub unsafe fn new_uninitialized(nrows: usize, ncols: usize) -> DMat<N> { pub unsafe fn new_uninitialized(nrows: usize, ncols: usize) -> DMatrix<N> {
let mut vec = Vec::with_capacity(nrows * ncols); let mut vector = Vec::with_capacity(nrows * ncols);
vec.set_len(nrows * ncols); vector.set_len(nrows * ncols);
DMat { DMatrix {
nrows: nrows, nrows: nrows,
ncols: ncols, ncols: ncols,
mij: vec mij: vector
} }
} }
} }
impl<N: Clone + Copy> DMat<N> { impl<N: Clone + Copy> DMatrix<N> {
/// Builds a matrix filled with a given constant. /// Builds a matrix filled with a given constant.
#[inline] #[inline]
pub fn from_elem(nrows: usize, ncols: usize, val: N) -> DMat<N> { pub fn from_elem(nrows: usize, ncols: usize, val: N) -> DMatrix<N> {
DMat { DMatrix {
nrows: nrows, nrows: nrows,
ncols: ncols, ncols: ncols,
mij: repeat(val).take(nrows * ncols).collect() mij: repeat(val).take(nrows * ncols).collect()
@ -50,35 +50,35 @@ impl<N: Clone + Copy> DMat<N> {
/// Builds a matrix filled with the components provided by a vector. /// Builds a matrix filled with the components provided by a vector.
/// The vector contains the matrix data in row-major order. /// The vector contains the matrix data in row-major order.
/// Note that `from_col_vec` is much faster than `from_row_vec` since a `DMat` stores its data /// Note that `from_col_vector` is much faster than `from_row_vector` since a `DMatrix` stores its data
/// in column-major order. /// in column-major order.
/// ///
/// The vector must have exactly `nrows * ncols` elements. /// The vector must have exactly `nrows * ncols` elements.
#[inline] #[inline]
pub fn from_row_vec(nrows: usize, ncols: usize, vec: &[N]) -> DMat<N> { pub fn from_row_vector(nrows: usize, ncols: usize, vector: &[N]) -> DMatrix<N> {
DMat::from_row_iter(nrows, ncols, vec.to_vec()) DMatrix::from_row_iter(nrows, ncols, vector.to_vec())
} }
/// Builds a matrix filled with the components provided by a vector. /// Builds a matrix filled with the components provided by a vector.
/// The vector contains the matrix data in column-major order. /// The vector contains the matrix data in column-major order.
/// Note that `from_col_vec` is much faster than `from_row_vec` since a `DMat` stores its data /// Note that `from_col_vector` is much faster than `from_row_vector` since a `DMatrix` stores its data
/// in column-major order. /// in column-major order.
/// ///
/// The vector must have exactly `nrows * ncols` elements. /// The vector must have exactly `nrows * ncols` elements.
#[inline] #[inline]
pub fn from_col_vec(nrows: usize, ncols: usize, vec: &[N]) -> DMat<N> { pub fn from_col_vector(nrows: usize, ncols: usize, vector: &[N]) -> DMatrix<N> {
DMat::from_col_iter(nrows, ncols, vec.to_vec()) DMatrix::from_col_iter(nrows, ncols, vector.to_vec())
} }
/// Builds a matrix filled with the components provided by a source that may be moved into an iterator. /// Builds a matrix filled with the components provided by a source that may be moved into an iterator.
/// The source contains the matrix data in row-major order. /// The source contains the matrix data in row-major order.
/// Note that `from_col_iter` is much faster than `from_row_iter` since a `DMat` stores its data /// Note that `from_col_iter` is much faster than `from_row_iter` since a `DMatrix` stores its data
/// in column-major order. /// in column-major order.
/// ///
/// The source must have exactly `nrows * ncols` elements. /// The source must have exactly `nrows * ncols` elements.
#[inline] #[inline]
pub fn from_row_iter<I: IntoIterator<Item = N>>(nrows: usize, ncols: usize, param: I) -> DMat<N> { pub fn from_row_iter<I: IntoIterator<Item = N>>(nrows: usize, ncols: usize, param: I) -> DMatrix<N> {
let mut res = DMat::from_col_iter(ncols, nrows, param); let mut res = DMatrix::from_col_iter(ncols, nrows, param);
// we transpose because the buffer is row_major // we transpose because the buffer is row_major
res.transpose_mut(); res.transpose_mut();
@ -89,17 +89,17 @@ impl<N: Clone + Copy> DMat<N> {
/// Builds a matrix filled with the components provided by a source that may be moved into an iterator. /// Builds a matrix filled with the components provided by a source that may be moved into an iterator.
/// The source contains the matrix data in column-major order. /// The source contains the matrix data in column-major order.
/// Note that `from_col_iter` is much faster than `from_row_iter` since a `DMat` stores its data /// Note that `from_col_iter` is much faster than `from_row_iter` since a `DMatrix` stores its data
/// in column-major order. /// in column-major order.
/// ///
/// The source must have exactly `nrows * ncols` elements. /// The source must have exactly `nrows * ncols` elements.
#[inline] #[inline]
pub fn from_col_iter<I: IntoIterator<Item = N>>(nrows: usize, ncols: usize, param: I) -> DMat<N> { pub fn from_col_iter<I: IntoIterator<Item = N>>(nrows: usize, ncols: usize, param: I) -> DMatrix<N> {
let mij: Vec<N> = param.into_iter().collect(); let mij: Vec<N> = param.into_iter().collect();
assert!(nrows * ncols == mij.len(), "The ammount of data provided does not matches the matrix size."); assert!(nrows * ncols == mij.len(), "The ammount of data provided does not matches the matrix size.");
DMat { DMatrix {
nrows: nrows, nrows: nrows,
ncols: ncols, ncols: ncols,
mij: mij mij: mij
@ -107,11 +107,11 @@ impl<N: Clone + Copy> DMat<N> {
} }
} }
impl<N> DMat<N> { impl<N> DMatrix<N> {
/// Builds a matrix filled with the results of a function applied to each of its component coordinates. /// Builds a matrix filled with the results of a function applied to each of its component coordinates.
#[inline(always)] #[inline(always)]
pub fn from_fn<F: FnMut(usize, usize) -> N>(nrows: usize, ncols: usize, mut f: F) -> DMat<N> { pub fn from_fn<F: FnMut(usize, usize) -> N>(nrows: usize, ncols: usize, mut f: F) -> DMatrix<N> {
DMat { DMatrix {
nrows: nrows, nrows: nrows,
ncols: ncols, ncols: ncols,
mij: (0 .. nrows * ncols).map(|i| { let m = i / nrows; f(i - m * nrows, m) }).collect() mij: (0 .. nrows * ncols).map(|i| { let m = i / nrows; f(i - m * nrows, m) }).collect()
@ -121,83 +121,83 @@ impl<N> DMat<N> {
/// Transforms this matrix into an array. This consumes the matrix and is O(1). /// Transforms this matrix into an array. This consumes the matrix and is O(1).
/// The returned vector contains the matrix data in column-major order. /// The returned vector contains the matrix data in column-major order.
#[inline] #[inline]
pub fn into_vec(self) -> Vec<N> { pub fn into_vector(self) -> Vec<N> {
self.mij self.mij
} }
} }
dmat_impl!(DMat, DVec); dmat_impl!(DMatrix, DVector);
/// A stack-allocated dynamically sized matrix with at most one row and column. /// A stack-allocated dynamically sized matrix with at most one row and column.
pub struct DMat1<N> { pub struct DMatrix1<N> {
nrows: usize, nrows: usize,
ncols: usize, ncols: usize,
mij: [N; 1 * 1], mij: [N; 1 * 1],
} }
small_dmat_impl!(DMat1, DVec1, 1, 0); small_dmat_impl!(DMatrix1, DVector1, 1, 0);
small_dmat_from_impl!(DMat1, 1, ::zero()); small_dmat_from_impl!(DMatrix1, 1, ::zero());
/// A stack-allocated dynamically sized square or rectangular matrix with at most 2 rows and columns. /// A stack-allocated dynamically sized square or rectangular matrix with at most 2 rows and columns.
pub struct DMat2<N> { pub struct DMatrix2<N> {
nrows: usize, nrows: usize,
ncols: usize, ncols: usize,
mij: [N; 2 * 2], mij: [N; 2 * 2],
} }
small_dmat_impl!(DMat2, DVec2, 2, 0, 1, small_dmat_impl!(DMatrix2, DVector2, 2, 0, 1,
2, 3); 2, 3);
small_dmat_from_impl!(DMat2, 2, ::zero(), ::zero(), small_dmat_from_impl!(DMatrix2, 2, ::zero(), ::zero(),
::zero(), ::zero()); ::zero(), ::zero());
/// A stack-allocated dynamically sized square or rectangular matrix with at most 3 rows and columns. /// A stack-allocated dynamically sized square or rectangular matrix with at most 3 rows and columns.
pub struct DMat3<N> { pub struct DMatrix3<N> {
nrows: usize, nrows: usize,
ncols: usize, ncols: usize,
mij: [N; 3 * 3], mij: [N; 3 * 3],
} }
small_dmat_impl!(DMat3, DVec3, 3, 0, 1, 2, small_dmat_impl!(DMatrix3, DVector3, 3, 0, 1, 2,
3, 4, 5, 3, 4, 5,
6, 7, 8); 6, 7, 8);
small_dmat_from_impl!(DMat3, 3, ::zero(), ::zero(), ::zero(), small_dmat_from_impl!(DMatrix3, 3, ::zero(), ::zero(), ::zero(),
::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
::zero(), ::zero(), ::zero()); ::zero(), ::zero(), ::zero());
/// A stack-allocated dynamically sized square or rectangular matrix with at most 4 rows and columns. /// A stack-allocated dynamically sized square or rectangular matrix with at most 4 rows and columns.
pub struct DMat4<N> { pub struct DMatrix4<N> {
nrows: usize, nrows: usize,
ncols: usize, ncols: usize,
mij: [N; 4 * 4], mij: [N; 4 * 4],
} }
small_dmat_impl!(DMat4, DVec4, 4, 0, 1, 2, 3, small_dmat_impl!(DMatrix4, DVector4, 4, 0, 1, 2, 3,
4, 5, 6, 7, 4, 5, 6, 7,
8, 9, 10, 11, 8, 9, 10, 11,
12, 13, 14, 15); 12, 13, 14, 15);
small_dmat_from_impl!(DMat4, 4, ::zero(), ::zero(), ::zero(), ::zero(), small_dmat_from_impl!(DMatrix4, 4, ::zero(), ::zero(), ::zero(), ::zero(),
::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
::zero(), ::zero(), ::zero(), ::zero()); ::zero(), ::zero(), ::zero(), ::zero());
/// A stack-allocated dynamically sized square or rectangular matrix with at most 5 rows and columns. /// A stack-allocated dynamically sized square or rectangular matrix with at most 5 rows and columns.
pub struct DMat5<N> { pub struct DMatrix5<N> {
nrows: usize, nrows: usize,
ncols: usize, ncols: usize,
mij: [N; 5 * 5], mij: [N; 5 * 5],
} }
small_dmat_impl!(DMat5, DVec5, 5, 0, 1, 2, 3, 4, small_dmat_impl!(DMatrix5, DVector5, 5, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24); 20, 21, 22, 23, 24);
small_dmat_from_impl!(DMat5, 5, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), small_dmat_from_impl!(DMatrix5, 5, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
@ -205,19 +205,19 @@ small_dmat_from_impl!(DMat5, 5, ::zero(), ::zero(), ::zero(), ::zero(), ::zero()
/// A stack-allocated dynamically sized square or rectangular matrix with at most 6 rows and columns. /// A stack-allocated dynamically sized square or rectangular matrix with at most 6 rows and columns.
pub struct DMat6<N> { pub struct DMatrix6<N> {
nrows: usize, nrows: usize,
ncols: usize, ncols: usize,
mij: [N; 6 * 6], mij: [N; 6 * 6],
} }
small_dmat_impl!(DMat6, DVec6, 6, 0, 1, 2, 3, 4, 5, small_dmat_impl!(DMatrix6, DVector6, 6, 0, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35); 30, 31, 32, 33, 34, 35);
small_dmat_from_impl!(DMat6, 6, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), small_dmat_from_impl!(DMatrix6, 6, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),

File diff suppressed because it is too large Load Diff

View File

@ -1,164 +0,0 @@
//! Vector with dimensions unknown at compile-time.
use std::slice::{Iter, IterMut};
use std::iter::{FromIterator, IntoIterator};
use std::iter::repeat;
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
use std::mem;
use rand::{self, Rand};
use num::{Zero, One};
use structs::DMat;
use traits::operations::{ApproxEq, Axpy, Mean, Outer};
use traits::geometry::{Dot, Norm};
use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat, BaseNum, Cast};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
/// Heap allocated, dynamically sized vector.
#[derive(Eq, PartialEq, Debug, Clone)]
pub struct DVec<N> {
/// Components of the vector. Contains as much elements as the vector dimension.
pub at: Vec<N>
}
impl<N> DVec<N> {
/// Creates an uninitialized vec.
#[inline]
pub unsafe fn new_uninitialized(dim: usize) -> DVec<N> {
let mut vec = Vec::with_capacity(dim);
vec.set_len(dim);
DVec {
at: vec
}
}
}
impl<N: Clone> DVec<N> {
/// Builds a vector filled with a constant.
#[inline]
pub fn from_elem(dim: usize, elem: N) -> DVec<N> {
DVec { at: repeat(elem).take(dim).collect() }
}
/// Builds a vector filled with the components provided by a vector.
///
/// The vector must have at least `dim` elements.
#[inline]
pub fn from_slice(dim: usize, vec: &[N]) -> DVec<N> {
assert!(dim <= vec.len());
DVec {
at: vec[.. dim].to_vec()
}
}
}
impl<N> DVec<N> {
/// Builds a vector filled with the results of a function applied to each of its component coordinates.
#[inline(always)]
pub fn from_fn<F: FnMut(usize) -> N>(dim: usize, mut f: F) -> DVec<N> {
DVec { at: (0 .. dim).map(|i| f(i)).collect() }
}
/// The vector length.
#[inline]
pub fn len(&self) -> usize {
self.at.len()
}
}
impl<N> FromIterator<N> for DVec<N> {
#[inline]
fn from_iter<I: IntoIterator<Item = N>>(param: I) -> DVec<N> {
DVec { at: param.into_iter().collect() }
}
}
impl<N: Copy + BaseNum> Outer for DVec<N> {
type OuterProductType = DMat<N>;
#[inline]
fn outer(&self, other: &DVec<N>) -> DMat<N> {
let mut res = unsafe { DMat::new_uninitialized(self.at.len(), other.at.len()) };
for i in 0 .. self.at.len() {
for j in 0 .. other.at.len() {
unsafe {
res.unsafe_set((i, j), self.unsafe_at(i) * other.unsafe_at(j));
}
}
}
res
}
}
#[cfg(feature="arbitrary")]
impl<N: Arbitrary> Arbitrary for DVec<N> {
fn arbitrary<G: Gen>(g: &mut G) -> DVec<N> {
DVec { at: Arbitrary::arbitrary(g) }
}
}
dvec_impl!(DVec);
/// Stack-allocated, dynamically sized vector with a maximum size of 1.
pub struct DVec1<N> {
at: [N; 1],
dim: usize
}
small_dvec_impl!(DVec1, 1, 0);
small_dvec_from_impl!(DVec1, 1, ::zero());
/// Stack-allocated, dynamically sized vector with a maximum size of 2.
pub struct DVec2<N> {
at: [N; 2],
dim: usize
}
small_dvec_impl!(DVec2, 2, 0, 1);
small_dvec_from_impl!(DVec2, 2, ::zero(), ::zero());
/// Stack-allocated, dynamically sized vector with a maximum size of 3.
pub struct DVec3<N> {
at: [N; 3],
dim: usize
}
small_dvec_impl!(DVec3, 3, 0, 1, 2);
small_dvec_from_impl!(DVec3, 3, ::zero(), ::zero(), ::zero());
/// Stack-allocated, dynamically sized vector with a maximum size of 4.
pub struct DVec4<N> {
at: [N; 4],
dim: usize
}
small_dvec_impl!(DVec4, 4, 0, 1, 2, 3);
small_dvec_from_impl!(DVec4, 4, ::zero(), ::zero(), ::zero(), ::zero());
/// Stack-allocated, dynamically sized vector with a maximum size of 5.
pub struct DVec5<N> {
at: [N; 5],
dim: usize
}
small_dvec_impl!(DVec5, 5, 0, 1, 2, 3, 4);
small_dvec_from_impl!(DVec5, 5, ::zero(), ::zero(), ::zero(), ::zero(), ::zero());
/// Stack-allocated, dynamically sized vector with a maximum size of 6.
pub struct DVec6<N> {
at: [N; 6],
dim: usize
}
small_dvec_impl!(DVec6, 6, 0, 1, 2, 3, 4, 5);
small_dvec_from_impl!(DVec6, 6, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero());

View File

@ -1,243 +0,0 @@
#![macro_use]
macro_rules! dvec_impl(
($dvec: ident) => (
vecn_dvec_common_impl!($dvec);
impl<N: Zero + Copy + Clone> $dvec<N> {
/// Builds a vector filled with zeros.
///
/// # Arguments
/// * `dim` - The dimension of the vector.
#[inline]
pub fn new_zeros(dim: usize) -> $dvec<N> {
$dvec::from_elem(dim, ::zero())
}
}
impl<N: One + Zero + Copy + Clone> $dvec<N> {
/// Builds a vector filled with ones.
///
/// # Arguments
/// * `dim` - The dimension of the vector.
#[inline]
pub fn new_ones(dim: usize) -> $dvec<N> {
$dvec::from_elem(dim, ::one())
}
}
impl<N: Rand + Zero> $dvec<N> {
/// Builds a vector filled with random values.
#[inline]
pub fn new_random(dim: usize) -> $dvec<N> {
$dvec::from_fn(dim, |_| rand::random())
}
}
impl<N: BaseFloat + ApproxEq<N>> $dvec<N> {
/// Computes the canonical basis for the given dimension. A canonical basis is a set of
/// vectors, mutually orthogonal, with all its component equal to 0.0 except one which is equal
/// to 1.0.
pub fn canonical_basis_with_dim(dim: usize) -> Vec<$dvec<N>> {
let mut res : Vec<$dvec<N>> = Vec::new();
for i in 0 .. dim {
let mut basis_element : $dvec<N> = $dvec::new_zeros(dim);
basis_element[i] = ::one();
res.push(basis_element);
}
res
}
/// Computes a basis of the space orthogonal to the vector. If the input vector is of dimension
/// `n`, this will return `n - 1` vectors.
pub fn orthogonal_subspace_basis(&self) -> Vec<$dvec<N>> {
// compute the basis of the orthogonal subspace using Gram-Schmidt
// orthogonalization algorithm
let dim = self.len();
let mut res : Vec<$dvec<N>> = Vec::new();
for i in 0 .. dim {
let mut basis_element : $dvec<N> = $dvec::new_zeros(self.len());
basis_element[i] = ::one();
if res.len() == dim - 1 {
break;
}
let mut elt = basis_element.clone();
elt.axpy(&-::dot(&basis_element, self), self);
for v in res.iter() {
let proj = ::dot(&elt, v);
elt.axpy(&-proj, v)
};
if !ApproxEq::approx_eq(&Norm::sqnorm(&elt), &::zero()) {
res.push(Norm::normalize(&elt));
}
}
assert!(res.len() == dim - 1);
res
}
}
)
);
macro_rules! small_dvec_impl (
($dvec: ident, $dim: expr, $($idx: expr),*) => (
dvec_impl!($dvec);
impl<N> $dvec<N> {
/// The number of elements of this vector.
#[inline]
pub fn len(&self) -> usize {
self.dim
}
/// Creates an uninitialized vec of dimension `dim`.
#[inline]
pub unsafe fn new_uninitialized(dim: usize) -> $dvec<N> {
assert!(dim <= $dim, "The chosen dimension is too high for that type of \
stack-allocated dynamic vector. Consider using the \
heap-allocated vector: DVec.");
$dvec {
at: mem::uninitialized(),
dim: dim
}
}
}
impl<N: PartialEq> PartialEq for $dvec<N> {
#[inline]
fn eq(&self, other: &$dvec<N>) -> bool {
if self.len() != other.len() {
return false; // FIXME: fail instead?
}
for (a, b) in self.as_ref().iter().zip(other.as_ref().iter()) {
if *a != *b {
return false;
}
}
true
}
}
impl<N: Clone> Clone for $dvec<N> {
fn clone(&self) -> $dvec<N> {
let at: [N; $dim] = [ $( self.at[$idx].clone(), )* ];
$dvec {
at: at,
dim: self.dim
}
}
}
)
);
macro_rules! small_dvec_from_impl (
($dvec: ident, $dim: expr, $($zeros: expr),*) => (
impl<N: Copy + Zero> $dvec<N> {
/// Builds a vector filled with a constant.
#[inline]
pub fn from_elem(dim: usize, elem: N) -> $dvec<N> {
assert!(dim <= $dim);
let mut at: [N; $dim] = [ $( $zeros, )* ];
for n in &mut at[.. dim] {
*n = elem;
}
$dvec {
at: at,
dim: dim
}
}
}
impl<N: Copy + Zero> $dvec<N> {
/// Builds a vector filled with the components provided by a vector.
///
/// The vector must have at least `dim` elements.
#[inline]
pub fn from_slice(dim: usize, vec: &[N]) -> $dvec<N> {
assert!(dim <= vec.len() && dim <= $dim);
// FIXME: not safe.
let mut at: [N; $dim] = [ $( $zeros, )* ];
for (curr, other) in vec.iter().zip(at.iter_mut()) {
*other = *curr;
}
$dvec {
at: at,
dim: dim
}
}
}
impl<N: Zero> $dvec<N> {
/// Builds a vector filled with the result of a function.
#[inline(always)]
pub fn from_fn<F: FnMut(usize) -> N>(dim: usize, mut f: F) -> $dvec<N> {
assert!(dim <= $dim);
let mut at: [N; $dim] = [ $( $zeros, )* ];
for i in 0 .. dim {
at[i] = f(i);
}
$dvec {
at: at,
dim: dim
}
}
}
impl<N: Zero> FromIterator<N> for $dvec<N> {
#[inline]
fn from_iter<I: IntoIterator<Item = N>>(param: I) -> $dvec<N> {
let mut at: [N; $dim] = [ $( $zeros, )* ];
let mut dim = 0;
for n in param.into_iter() {
if dim == $dim {
break;
}
at[dim] = n;
dim = dim + 1;
}
$dvec {
at: at,
dim: dim
}
}
}
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + Zero> Arbitrary for $dvec<N> {
#[inline]
fn arbitrary<G: Gen>(g: &mut G) -> $dvec<N> {
$dvec::from_fn(g.gen_range(0, $dim), |_| Arbitrary::arbitrary(g))
}
}
)
);

164
src/structs/dvector.rs Normal file
View File

@ -0,0 +1,164 @@
//! Vector with dimensions unknown at compile-time.
use std::slice::{Iter, IterMut};
use std::iter::{FromIterator, IntoIterator};
use std::iter::repeat;
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
use std::mem;
use rand::{self, Rand};
use num::{Zero, One};
use structs::DMatrix;
use traits::operations::{ApproxEq, Axpy, Mean, Outer};
use traits::geometry::{Dot, Norm};
use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat, BaseNum, Cast};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
/// Heap allocated, dynamically sized vector.
#[derive(Eq, PartialEq, Debug, Clone)]
pub struct DVector<N> {
/// Components of the vector. Contains as much elements as the vector dimension.
pub at: Vec<N>
}
impl<N> DVector<N> {
/// Creates an uninitialized vector.
#[inline]
pub unsafe fn new_uninitialized(dimension: usize) -> DVector<N> {
let mut vector = Vec::with_capacity(dimension);
vector.set_len(dimension);
DVector {
at: vector
}
}
}
impl<N: Clone> DVector<N> {
/// Builds a vector filled with a constant.
#[inline]
pub fn from_elem(dimension: usize, elem: N) -> DVector<N> {
DVector { at: repeat(elem).take(dimension).collect() }
}
/// Builds a vector filled with the components provided by a vector.
///
/// The vector must have at least `dimension` elements.
#[inline]
pub fn from_slice(dimension: usize, vector: &[N]) -> DVector<N> {
assert!(dimension <= vector.len());
DVector {
at: vector[.. dimension].to_vec()
}
}
}
impl<N> DVector<N> {
/// Builds a vector filled with the results of a function applied to each of its component coordinates.
#[inline(always)]
pub fn from_fn<F: FnMut(usize) -> N>(dimension: usize, mut f: F) -> DVector<N> {
DVector { at: (0 .. dimension).map(|i| f(i)).collect() }
}
/// The vector length.
#[inline]
pub fn len(&self) -> usize {
self.at.len()
}
}
impl<N> FromIterator<N> for DVector<N> {
#[inline]
fn from_iter<I: IntoIterator<Item = N>>(param: I) -> DVector<N> {
DVector { at: param.into_iter().collect() }
}
}
impl<N: Copy + BaseNum> Outer for DVector<N> {
type OuterProductType = DMatrix<N>;
#[inline]
fn outer(&self, other: &DVector<N>) -> DMatrix<N> {
let mut res = unsafe { DMatrix::new_uninitialized(self.at.len(), other.at.len()) };
for i in 0 .. self.at.len() {
for j in 0 .. other.at.len() {
unsafe {
res.unsafe_set((i, j), self.unsafe_at(i) * other.unsafe_at(j));
}
}
}
res
}
}
#[cfg(feature="arbitrary")]
impl<N: Arbitrary> Arbitrary for DVector<N> {
fn arbitrary<G: Gen>(g: &mut G) -> DVector<N> {
DVector { at: Arbitrary::arbitrary(g) }
}
}
dvec_impl!(DVector);
/// Stack-allocated, dynamically sized vector with a maximum size of 1.
pub struct DVector1<N> {
at: [N; 1],
dimension: usize
}
small_dvec_impl!(DVector1, 1, 0);
small_dvec_from_impl!(DVector1, 1, ::zero());
/// Stack-allocated, dynamically sized vector with a maximum size of 2.
pub struct DVector2<N> {
at: [N; 2],
dimension: usize
}
small_dvec_impl!(DVector2, 2, 0, 1);
small_dvec_from_impl!(DVector2, 2, ::zero(), ::zero());
/// Stack-allocated, dynamically sized vector with a maximum size of 3.
pub struct DVector3<N> {
at: [N; 3],
dimension: usize
}
small_dvec_impl!(DVector3, 3, 0, 1, 2);
small_dvec_from_impl!(DVector3, 3, ::zero(), ::zero(), ::zero());
/// Stack-allocated, dynamically sized vector with a maximum size of 4.
pub struct DVector4<N> {
at: [N; 4],
dimension: usize
}
small_dvec_impl!(DVector4, 4, 0, 1, 2, 3);
small_dvec_from_impl!(DVector4, 4, ::zero(), ::zero(), ::zero(), ::zero());
/// Stack-allocated, dynamically sized vector with a maximum size of 5.
pub struct DVector5<N> {
at: [N; 5],
dimension: usize
}
small_dvec_impl!(DVector5, 5, 0, 1, 2, 3, 4);
small_dvec_from_impl!(DVector5, 5, ::zero(), ::zero(), ::zero(), ::zero(), ::zero());
/// Stack-allocated, dynamically sized vector with a maximum size of 6.
pub struct DVector6<N> {
at: [N; 6],
dimension: usize
}
small_dvec_impl!(DVector6, 6, 0, 1, 2, 3, 4, 5);
small_dvec_from_impl!(DVector6, 6, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero());

View File

@ -0,0 +1,243 @@
#![macro_use]
macro_rules! dvec_impl(
($dvector: ident) => (
vecn_dvec_common_impl!($dvector);
impl<N: Zero + Copy + Clone> $dvector<N> {
/// Builds a vector filled with zeros.
///
/// # Arguments
/// * `dimension` - The dimension of the vector.
#[inline]
pub fn new_zeros(dimension: usize) -> $dvector<N> {
$dvector::from_elem(dimension, ::zero())
}
}
impl<N: One + Zero + Copy + Clone> $dvector<N> {
/// Builds a vector filled with ones.
///
/// # Arguments
/// * `dimension` - The dimension of the vector.
#[inline]
pub fn new_ones(dimension: usize) -> $dvector<N> {
$dvector::from_elem(dimension, ::one())
}
}
impl<N: Rand + Zero> $dvector<N> {
/// Builds a vector filled with random values.
#[inline]
pub fn new_random(dimension: usize) -> $dvector<N> {
$dvector::from_fn(dimension, |_| rand::random())
}
}
impl<N: BaseFloat + ApproxEq<N>> $dvector<N> {
/// Computes the canonical basis for the given dimension. A canonical basis is a set of
/// vectors, mutually orthogonal, with all its component equal to 0.0 except one which is equal
/// to 1.0.
pub fn canonical_basis_with_dim(dimension: usize) -> Vec<$dvector<N>> {
let mut res : Vec<$dvector<N>> = Vec::new();
for i in 0 .. dimension {
let mut basis_element : $dvector<N> = $dvector::new_zeros(dimension);
basis_element[i] = ::one();
res.push(basis_element);
}
res
}
/// Computes a basis of the space orthogonal to the vector. If the input vector is of dimension
/// `n`, this will return `n - 1` vectors.
pub fn orthogonal_subspace_basis(&self) -> Vec<$dvector<N>> {
// compute the basis of the orthogonal subspace using Gram-Schmidt
// orthogonalization algorithm
let dimension = self.len();
let mut res : Vec<$dvector<N>> = Vec::new();
for i in 0 .. dimension {
let mut basis_element : $dvector<N> = $dvector::new_zeros(self.len());
basis_element[i] = ::one();
if res.len() == dimension - 1 {
break;
}
let mut elt = basis_element.clone();
elt.axpy(&-::dot(&basis_element, self), self);
for v in res.iter() {
let proj = ::dot(&elt, v);
elt.axpy(&-proj, v)
};
if !ApproxEq::approx_eq(&Norm::norm_squared(&elt), &::zero()) {
res.push(Norm::normalize(&elt));
}
}
assert!(res.len() == dimension - 1);
res
}
}
)
);
macro_rules! small_dvec_impl (
($dvector: ident, $dimension: expr, $($idx: expr),*) => (
dvec_impl!($dvector);
impl<N> $dvector<N> {
/// The number of elements of this vector.
#[inline]
pub fn len(&self) -> usize {
self.dimension
}
/// Creates an uninitialized vector of dimension `dimension`.
#[inline]
pub unsafe fn new_uninitialized(dimension: usize) -> $dvector<N> {
assert!(dimension <= $dimension, "The chosen dimension is too high for that type of \
stack-allocated dynamic vector. Consider using the \
heap-allocated vector: DVector.");
$dvector {
at: mem::uninitialized(),
dimension: dimension
}
}
}
impl<N: PartialEq> PartialEq for $dvector<N> {
#[inline]
fn eq(&self, other: &$dvector<N>) -> bool {
if self.len() != other.len() {
return false; // FIXME: fail instead?
}
for (a, b) in self.as_ref().iter().zip(other.as_ref().iter()) {
if *a != *b {
return false;
}
}
true
}
}
impl<N: Clone> Clone for $dvector<N> {
fn clone(&self) -> $dvector<N> {
let at: [N; $dimension] = [ $( self.at[$idx].clone(), )* ];
$dvector {
at: at,
dimension: self.dimension
}
}
}
)
);
macro_rules! small_dvec_from_impl (
($dvector: ident, $dimension: expr, $($zeros: expr),*) => (
impl<N: Copy + Zero> $dvector<N> {
/// Builds a vector filled with a constant.
#[inline]
pub fn from_elem(dimension: usize, elem: N) -> $dvector<N> {
assert!(dimension <= $dimension);
let mut at: [N; $dimension] = [ $( $zeros, )* ];
for n in &mut at[.. dimension] {
*n = elem;
}
$dvector {
at: at,
dimension: dimension
}
}
}
impl<N: Copy + Zero> $dvector<N> {
/// Builds a vector filled with the components provided by a vector.
///
/// The vector must have at least `dimension` elements.
#[inline]
pub fn from_slice(dimension: usize, vector: &[N]) -> $dvector<N> {
assert!(dimension <= vector.len() && dimension <= $dimension);
// FIXME: not safe.
let mut at: [N; $dimension] = [ $( $zeros, )* ];
for (curr, other) in vector.iter().zip(at.iter_mut()) {
*other = *curr;
}
$dvector {
at: at,
dimension: dimension
}
}
}
impl<N: Zero> $dvector<N> {
/// Builds a vector filled with the result of a function.
#[inline(always)]
pub fn from_fn<F: FnMut(usize) -> N>(dimension: usize, mut f: F) -> $dvector<N> {
assert!(dimension <= $dimension);
let mut at: [N; $dimension] = [ $( $zeros, )* ];
for i in 0 .. dimension {
at[i] = f(i);
}
$dvector {
at: at,
dimension: dimension
}
}
}
impl<N: Zero> FromIterator<N> for $dvector<N> {
#[inline]
fn from_iter<I: IntoIterator<Item = N>>(param: I) -> $dvector<N> {
let mut at: [N; $dimension] = [ $( $zeros, )* ];
let mut dimension = 0;
for n in param.into_iter() {
if dimension == $dimension {
break;
}
at[dimension] = n;
dimension = dimension + 1;
}
$dvector {
at: at,
dimension: dimension
}
}
}
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + Zero> Arbitrary for $dvector<N> {
#[inline]
fn arbitrary<G: Gen>(g: &mut G) -> $dvector<N> {
$dvector::from_fn(g.gen_range(0, $dimension), |_| Arbitrary::arbitrary(g))
}
}
)
);

View File

@ -1,144 +0,0 @@
use std::fmt;
use std::ops::{Add, Sub, Mul, Neg, MulAssign};
use rand::{Rand, Rng};
use num::One;
use structs::mat::{Mat3, Mat4};
use traits::structure::{Cast, Dim, Col, BaseFloat, BaseNum};
use traits::operations::{Inv, ApproxEq};
use traits::geometry::{RotationMatrix, Rotation, Rotate, AbsoluteRotate, Transform, Transformation,
Translate, Translation, ToHomogeneous};
use structs::vec::{Vec1, Vec2, Vec3};
use structs::pnt::{Pnt2, Pnt3};
use structs::rot::{Rot2, Rot3};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
/// Two dimensional **direct** isometry.
///
/// This is the composition of a rotation followed by a translation. Vectors `Vec2` are not
/// affected by the translational component of this transformation while points `Pnt2` are.
/// Isometries conserve angles and distances, hence do not allow shearing nor scaling.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct Iso2<N> {
/// The rotation applicable by this isometry.
pub rotation: Rot2<N>,
/// The translation applicable by this isometry.
pub translation: Vec2<N>
}
/// Three dimensional **direct** isometry.
///
/// This is the composition of a rotation followed by a translation. Vectors `Vec3` are not
/// affected by the translational component of this transformation while points `Pnt3` are.
/// Isometries conserve angles and distances, hence do not allow shearing nor scaling.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct Iso3<N> {
/// The rotation applicable by this isometry.
pub rotation: Rot3<N>,
/// The translation applicable by this isometry.
pub translation: Vec3<N>
}
impl<N: Clone + BaseFloat> Iso3<N> {
/// Creates an isometry that corresponds to the local frame of an observer standing at the
/// point `eye` and looking toward `target`.
///
/// It maps the view direction `target - eye` to the positive `z` axis and the origin to the
/// `eye`.
///
/// # Arguments
/// * eye - The observer position.
/// * target - The target position.
/// * up - Vertical direction. The only requirement of this parameter is to not be collinear
/// to `eye - at`. Non-collinearity is not checked.
#[inline]
pub fn new_observer_frame(eye: &Pnt3<N>, target: &Pnt3<N>, up: &Vec3<N>) -> Iso3<N> {
let new_rotmat = Rot3::new_observer_frame(&(*target - *eye), up);
Iso3::new_with_rotmat(eye.as_vec().clone(), new_rotmat)
}
/// Builds a right-handed look-at view matrix.
///
/// This conforms to the common notion of right handed look-at matrix from the computer
/// graphics community.
///
/// # Arguments
/// * eye - The eye position.
/// * target - The target position.
/// * up - A vector approximately aligned with required the vertical axis. The only
/// requirement of this parameter is to not be collinear to `target - eye`.
#[inline]
pub fn look_at_rh(eye: &Pnt3<N>, target: &Pnt3<N>, up: &Vec3<N>) -> Iso3<N> {
let rot = Rot3::look_at_rh(&(*target - *eye), up);
let trans = rot * (-*eye);
Iso3::new_with_rotmat(trans.to_vec(), rot)
}
/// Builds a left-handed look-at view matrix.
///
/// This conforms to the common notion of left handed look-at matrix from the computer
/// graphics community.
///
/// # Arguments
/// * eye - The eye position.
/// * target - The target position.
/// * up - A vector approximately aligned with required the vertical axis. The only
/// requirement of this parameter is to not be collinear to `target - eye`.
#[inline]
pub fn look_at_lh(eye: &Pnt3<N>, target: &Pnt3<N>, up: &Vec3<N>) -> Iso3<N> {
let rot = Rot3::look_at_lh(&(*target - *eye), up);
let trans = rot * (-*eye);
Iso3::new_with_rotmat(trans.to_vec(), rot)
}
}
iso_impl!(Iso2, Rot2, Vec2, Vec1);
rotation_matrix_impl!(Iso2, Rot2, Vec2, Vec1);
rotation_impl!(Iso2, Rot2, Vec1);
dim_impl!(Iso2, 2);
one_impl!(Iso2);
absolute_rotate_impl!(Iso2, Vec2);
rand_impl!(Iso2);
approx_eq_impl!(Iso2);
to_homogeneous_impl!(Iso2, Mat3);
inv_impl!(Iso2);
transform_impl!(Iso2, Pnt2);
transformation_impl!(Iso2);
rotate_impl!(Iso2, Vec2);
translation_impl!(Iso2, Vec2);
translate_impl!(Iso2, Pnt2);
iso_mul_iso_impl!(Iso2);
iso_mul_rot_impl!(Iso2, Rot2);
iso_mul_pnt_impl!(Iso2, Pnt2);
iso_mul_vec_impl!(Iso2, Vec2);
arbitrary_iso_impl!(Iso2);
iso_display_impl!(Iso2);
iso_impl!(Iso3, Rot3, Vec3, Vec3);
rotation_matrix_impl!(Iso3, Rot3, Vec3, Vec3);
rotation_impl!(Iso3, Rot3, Vec3);
dim_impl!(Iso3, 3);
one_impl!(Iso3);
absolute_rotate_impl!(Iso3, Vec3);
rand_impl!(Iso3);
approx_eq_impl!(Iso3);
to_homogeneous_impl!(Iso3, Mat4);
inv_impl!(Iso3);
transform_impl!(Iso3, Pnt3);
transformation_impl!(Iso3);
rotate_impl!(Iso3, Vec3);
translation_impl!(Iso3, Vec3);
translate_impl!(Iso3, Pnt3);
iso_mul_iso_impl!(Iso3);
iso_mul_rot_impl!(Iso3, Rot3);
iso_mul_pnt_impl!(Iso3, Pnt3);
iso_mul_vec_impl!(Iso3, Vec3);
arbitrary_iso_impl!(Iso3);
iso_display_impl!(Iso3);

144
src/structs/isometry.rs Normal file
View File

@ -0,0 +1,144 @@
use std::fmt;
use std::ops::{Add, Sub, Mul, Neg, MulAssign};
use rand::{Rand, Rng};
use num::One;
use structs::matrix::{Matrix3, Matrix4};
use traits::structure::{Cast, Dimension, Column, BaseFloat, BaseNum};
use traits::operations::{Inverse, ApproxEq};
use traits::geometry::{RotationMatrix, Rotation, Rotate, AbsoluteRotate, Transform, Transformation,
Translate, Translation, ToHomogeneous};
use structs::vector::{Vector1, Vector2, Vector3};
use structs::point::{Point2, Point3};
use structs::rotation::{Rotation2, Rotation3};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
/// Two dimensional **direct** isometry.
///
/// This is the composition of a rotation followed by a translation. Vectors `Vector2` are not
/// affected by the translational component of this transformation while points `Point2` are.
/// Isometrymetries conserve angles and distances, hence do not allow shearing nor scaling.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct Isometry2<N> {
/// The rotation applicable by this isometry.
pub rotation: Rotation2<N>,
/// The translation applicable by this isometry.
pub translation: Vector2<N>
}
/// Three dimensional **direct** isometry.
///
/// This is the composition of a rotation followed by a translation. Vectors `Vector3` are not
/// affected by the translational component of this transformation while points `Point3` are.
/// Isometrymetries conserve angles and distances, hence do not allow shearing nor scaling.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct Isometry3<N> {
/// The rotation applicable by this isometry.
pub rotation: Rotation3<N>,
/// The translation applicable by this isometry.
pub translation: Vector3<N>
}
impl<N: Clone + BaseFloat> Isometry3<N> {
/// Creates an isometry that corresponds to the local frame of an observer standing at the
/// point `eye` and looking toward `target`.
///
/// It maps the view direction `target - eye` to the positive `z` axis and the origin to the
/// `eye`.
///
/// # Arguments
/// * eye - The observer position.
/// * target - The target position.
/// * up - Vertical direction. The only requirement of this parameter is to not be collinear
/// to `eye - at`. Non-collinearity is not checked.
#[inline]
pub fn new_observer_frame(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Isometry3<N> {
let new_rotation_matrix = Rotation3::new_observer_frame(&(*target - *eye), up);
Isometry3::new_with_rotation_matrix(eye.as_vector().clone(), new_rotation_matrix)
}
/// Builds a right-handed look-at view matrix.
///
/// This conforms to the common notion of right handed look-at matrix from the computer
/// graphics community.
///
/// # Arguments
/// * eye - The eye position.
/// * target - The target position.
/// * up - A vector approximately aligned with required the vertical axis. The only
/// 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);
Isometry3::new_with_rotation_matrix(trans.to_vector(), rotation)
}
/// Builds a left-handed look-at view matrix.
///
/// This conforms to the common notion of left handed look-at matrix from the computer
/// graphics community.
///
/// # Arguments
/// * eye - The eye position.
/// * target - The target position.
/// * up - A vector approximately aligned with required the vertical axis. The only
/// 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);
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);
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);
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,20 +1,20 @@
#![macro_use] #![macro_use]
macro_rules! iso_impl( macro_rules! isometry_impl(
($t: ident, $submat: ident, $subvec: ident, $subrotvec: ident) => ( ($t: ident, $submatrix: ident, $subvector: ident, $subrotvector: ident) => (
impl<N: BaseFloat> $t<N> { impl<N: BaseFloat> $t<N> {
/// Creates a new isometry from an axis-angle rotation, and a vector. /// Creates a new isometry from an axis-angle rotation, and a vector.
#[inline] #[inline]
pub fn new(translation: $subvec<N>, rotation: $subrotvec<N>) -> $t<N> { pub fn new(translation: $subvector<N>, rotation: $subrotvector<N>) -> $t<N> {
$t { $t {
rotation: $submat::new(rotation), rotation: $submatrix::new(rotation),
translation: translation translation: translation
} }
} }
/// Creates a new isometry from a rotation matrix and a vector. /// Creates a new isometry from a rotation matrix and a vector.
#[inline] #[inline]
pub fn new_with_rotmat(translation: $subvec<N>, rotation: $submat<N>) -> $t<N> { pub fn new_with_rotation_matrix(translation: $subvector<N>, rotation: $submatrix<N>) -> $t<N> {
$t { $t {
rotation: rotation, rotation: rotation,
translation: translation translation: translation
@ -25,13 +25,13 @@ macro_rules! iso_impl(
); );
macro_rules! rotation_matrix_impl( macro_rules! rotation_matrix_impl(
($t: ident, $trot: ident, $tlv: ident, $tav: ident) => ( ($t: ident, $trotation: ident, $tlv: ident, $tav: ident) => (
impl<N: Cast<f64> + BaseFloat> impl<N: Cast<f64> + BaseFloat>
RotationMatrix<N, $tlv<N>, $tav<N>> for $t<N> { RotationMatrix<N, $tlv<N>, $tav<N>> for $t<N> {
type Output = $trot<N>; type Output = $trotation<N>;
#[inline] #[inline]
fn to_rot_mat(&self) -> $trot<N> { fn to_rotation_matrix(&self) -> $trotation<N> {
self.rotation self.rotation
} }
} }
@ -40,11 +40,11 @@ macro_rules! rotation_matrix_impl(
macro_rules! dim_impl( macro_rules! dim_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N> Dim for $t<N> { impl<N> Dimension for $t<N> {
#[inline] #[inline]
fn dim(_: Option<$t<N>>) -> usize { fn dimension(_: Option<$t<N>>) -> usize {
$dim $dimension
} }
} }
) )
@ -55,20 +55,20 @@ macro_rules! one_impl(
impl<N: BaseFloat> One for $t<N> { impl<N: BaseFloat> One for $t<N> {
#[inline] #[inline]
fn one() -> $t<N> { fn one() -> $t<N> {
$t::new_with_rotmat(::zero(), ::one()) $t::new_with_rotation_matrix(::zero(), ::one())
} }
} }
) )
); );
macro_rules! iso_mul_iso_impl( macro_rules! isometry_mul_isometry_impl(
($t: ident) => ( ($t: ident) => (
impl<N: BaseFloat> Mul<$t<N>> for $t<N> { impl<N: BaseFloat> Mul<$t<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
#[inline] #[inline]
fn mul(self, right: $t<N>) -> $t<N> { fn mul(self, right: $t<N>) -> $t<N> {
$t::new_with_rotmat( $t::new_with_rotation_matrix(
self.translation + self.rotation * right.translation, self.translation + self.rotation * right.translation,
self.rotation * right.rotation) self.rotation * right.rotation)
} }
@ -84,38 +84,38 @@ macro_rules! iso_mul_iso_impl(
) )
); );
macro_rules! iso_mul_rot_impl( macro_rules! isometry_mul_rotation_impl(
($t: ident, $rot: ident) => ( ($t: ident, $rotation: ident) => (
impl<N: BaseFloat> Mul<$rot<N>> for $t<N> { impl<N: BaseFloat> Mul<$rotation<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
#[inline] #[inline]
fn mul(self, right: $rot<N>) -> $t<N> { fn mul(self, right: $rotation<N>) -> $t<N> {
$t::new_with_rotmat(self.translation, self.rotation * right) $t::new_with_rotation_matrix(self.translation, self.rotation * right)
} }
} }
impl<N: BaseFloat> Mul<$t<N>> for $rot<N> { impl<N: BaseFloat> Mul<$t<N>> for $rotation<N> {
type Output = $t<N>; type Output = $t<N>;
#[inline] #[inline]
fn mul(self, right: $t<N>) -> $t<N> { fn mul(self, right: $t<N>) -> $t<N> {
$t::new_with_rotmat( $t::new_with_rotation_matrix(
self * right.translation, self * right.translation,
self * right.rotation) self * right.rotation)
} }
} }
impl<N: BaseFloat> MulAssign<$rot<N>> for $t<N> { impl<N: BaseFloat> MulAssign<$rotation<N>> for $t<N> {
#[inline] #[inline]
fn mul_assign(&mut self, right: $rot<N>) { fn mul_assign(&mut self, right: $rotation<N>) {
self.rotation *= right self.rotation *= right
} }
} }
) )
); );
macro_rules! iso_mul_pnt_impl( macro_rules! isometry_mul_point_impl(
($t: ident, $tv: ident) => ( ($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$tv<N>> for $t<N> { impl<N: BaseNum> Mul<$tv<N>> for $t<N> {
type Output = $tv<N>; type Output = $tv<N>;
@ -128,7 +128,7 @@ macro_rules! iso_mul_pnt_impl(
) )
); );
macro_rules! iso_mul_vec_impl( macro_rules! isometry_mul_vec_impl(
($t: ident, $tv: ident) => ( ($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$tv<N>> for $t<N> { impl<N: BaseNum> Mul<$tv<N>> for $t<N> {
type Output = $tv<N>; type Output = $tv<N>;
@ -150,7 +150,7 @@ macro_rules! translation_impl(
} }
#[inline] #[inline]
fn inv_translation(&self) -> $tv<N> { fn inverse_translation(&self) -> $tv<N> {
-self.translation -self.translation
} }
@ -161,7 +161,7 @@ macro_rules! translation_impl(
#[inline] #[inline]
fn append_translation(&self, t: &$tv<N>) -> $t<N> { fn append_translation(&self, t: &$tv<N>) -> $t<N> {
$t::new_with_rotmat(*t + self.translation, self.rotation) $t::new_with_rotation_matrix(*t + self.translation, self.rotation)
} }
#[inline] #[inline]
@ -171,7 +171,7 @@ macro_rules! translation_impl(
#[inline] #[inline]
fn prepend_translation(&self, t: &$tv<N>) -> $t<N> { fn prepend_translation(&self, t: &$tv<N>) -> $t<N> {
$t::new_with_rotmat(self.translation + self.rotation * *t, self.rotation) $t::new_with_rotation_matrix(self.translation + self.rotation * *t, self.rotation)
} }
#[inline] #[inline]
@ -191,7 +191,7 @@ macro_rules! translate_impl(
} }
#[inline] #[inline]
fn inv_translate(&self, v: &$tv<N>) -> $tv<N> { fn inverse_translate(&self, v: &$tv<N>) -> $tv<N> {
*v - self.translation *v - self.translation
} }
} }
@ -199,7 +199,7 @@ macro_rules! translate_impl(
); );
macro_rules! rotation_impl( macro_rules! rotation_impl(
($t: ident, $trot: ident, $tav: ident) => ( ($t: ident, $trotation: ident, $tav: ident) => (
impl<N: Cast<f64> + BaseFloat> Rotation<$tav<N>> for $t<N> { impl<N: Cast<f64> + BaseFloat> Rotation<$tav<N>> for $t<N> {
#[inline] #[inline]
fn rotation(&self) -> $tav<N> { fn rotation(&self) -> $tav<N> {
@ -207,43 +207,43 @@ macro_rules! rotation_impl(
} }
#[inline] #[inline]
fn inv_rotation(&self) -> $tav<N> { fn inverse_rotation(&self) -> $tav<N> {
self.rotation.inv_rotation() self.rotation.inverse_rotation()
} }
#[inline] #[inline]
fn append_rotation_mut(&mut self, rot: &$tav<N>) { fn append_rotation_mut(&mut self, rotation: &$tav<N>) {
let delta = $trot::new(*rot); let delta = $trotation::new(*rotation);
self.rotation = delta * self.rotation; self.rotation = delta * self.rotation;
self.translation = delta * self.translation; self.translation = delta * self.translation;
} }
#[inline] #[inline]
fn append_rotation(&self, rot: &$tav<N>) -> $t<N> { fn append_rotation(&self, rotation: &$tav<N>) -> $t<N> {
let delta = $trot::new(*rot); let delta = $trotation::new(*rotation);
$t::new_with_rotmat(delta * self.translation, delta * self.rotation) $t::new_with_rotation_matrix(delta * self.translation, delta * self.rotation)
} }
#[inline] #[inline]
fn prepend_rotation_mut(&mut self, rot: &$tav<N>) { fn prepend_rotation_mut(&mut self, rotation: &$tav<N>) {
let delta = $trot::new(*rot); let delta = $trotation::new(*rotation);
self.rotation = self.rotation * delta; self.rotation = self.rotation * delta;
} }
#[inline] #[inline]
fn prepend_rotation(&self, rot: &$tav<N>) -> $t<N> { fn prepend_rotation(&self, rotation: &$tav<N>) -> $t<N> {
let delta = $trot::new(*rot); let delta = $trotation::new(*rotation);
$t::new_with_rotmat(self.translation, self.rotation * delta) $t::new_with_rotation_matrix(self.translation, self.rotation * delta)
} }
#[inline] #[inline]
fn set_rotation(&mut self, rot: $tav<N>) { fn set_rotation(&mut self, rotation: $tav<N>) {
// FIXME: should the translation be changed too? // FIXME: should the translation be changed too?
self.rotation.set_rotation(rot) self.rotation.set_rotation(rotation)
} }
} }
) )
@ -258,8 +258,8 @@ macro_rules! rotate_impl(
} }
#[inline] #[inline]
fn inv_rotate(&self, v: &$tv<N>) -> $tv<N> { fn inverse_rotate(&self, v: &$tv<N>) -> $tv<N> {
self.rotation.inv_rotate(v) self.rotation.inverse_rotate(v)
} }
} }
) )
@ -272,9 +272,9 @@ macro_rules! transformation_impl(
*self *self
} }
fn inv_transformation(&self) -> $t<N> { fn inverse_transformation(&self) -> $t<N> {
// inversion will never fails // inversion will never fails
Inv::inv(self).unwrap() Inverse::inverse(self).unwrap()
} }
fn append_transformation_mut(&mut self, t: &$t<N>) { fn append_transformation_mut(&mut self, t: &$t<N>) {
@ -309,28 +309,28 @@ macro_rules! transform_impl(
} }
#[inline] #[inline]
fn inv_transform(&self, p: &$tp<N>) -> $tp<N> { fn inverse_transform(&self, p: &$tp<N>) -> $tp<N> {
self.rotation.inv_transform(&(*p - self.translation)) self.rotation.inverse_transform(&(*p - self.translation))
} }
} }
) )
); );
macro_rules! inv_impl( macro_rules! inverse_impl(
($t: ident) => ( ($t: ident) => (
impl<N: BaseNum + Neg<Output = N>> Inv for $t<N> { impl<N: BaseNum + Neg<Output = N>> Inverse for $t<N> {
#[inline] #[inline]
fn inv_mut(&mut self) -> bool { fn inverse_mut(&mut self) -> bool {
self.rotation.inv_mut(); self.rotation.inverse_mut();
self.translation = self.rotation * -self.translation; self.translation = self.rotation * -self.translation;
// always succeed // always succeed
true true
} }
#[inline] #[inline]
fn inv(&self) -> Option<$t<N>> { fn inverse(&self) -> Option<$t<N>> {
let mut res = *self; let mut res = *self;
res.inv_mut(); res.inverse_mut();
// always succeed // always succeed
Some(res) Some(res)
} }
@ -345,9 +345,9 @@ macro_rules! to_homogeneous_impl(
let mut res = self.rotation.to_homogeneous(); let mut res = self.rotation.to_homogeneous();
// copy the translation // copy the translation
let dim = Dim::dim(None::<$th<N>>); let dimension = Dimension::dimension(None::<$th<N>>);
res.set_col(dim - 1, self.translation.as_pnt().to_homogeneous().to_vec()); res.set_col(dimension - 1, self.translation.as_point().to_homogeneous().to_vector());
res res
} }
@ -405,12 +405,12 @@ macro_rules! absolute_rotate_impl(
) )
); );
macro_rules! arbitrary_iso_impl( macro_rules! arbitrary_isometry_impl(
($t: ident) => ( ($t: ident) => (
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for $t<N> { impl<N: Arbitrary + BaseFloat> Arbitrary for $t<N> {
fn arbitrary<G: Gen>(g: &mut G) -> $t<N> { fn arbitrary<G: Gen>(g: &mut G) -> $t<N> {
$t::new_with_rotmat( $t::new_with_rotation_matrix(
Arbitrary::arbitrary(g), Arbitrary::arbitrary(g),
Arbitrary::arbitrary(g) Arbitrary::arbitrary(g)
) )
@ -419,7 +419,7 @@ macro_rules! arbitrary_iso_impl(
) )
); );
macro_rules! iso_display_impl( macro_rules! isometry_display_impl(
($t: ident) => ( ($t: ident) => (
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> { impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@ -428,12 +428,12 @@ macro_rules! iso_display_impl(
if let Some(precision) = f.precision() { if let Some(precision) = f.precision() {
try!(writeln!(f, "... translation: {:.*}", precision, self.translation)); try!(writeln!(f, "... translation: {:.*}", precision, self.translation));
try!(writeln!(f, "... rotation matrix:")); try!(writeln!(f, "... rotation matrix:"));
try!(write!(f, "{:.*}", precision, *self.rotation.submat())); try!(write!(f, "{:.*}", precision, *self.rotation.submatrix()));
} }
else { else {
try!(writeln!(f, "... translation: {}", self.translation)); try!(writeln!(f, "... translation: {}", self.translation));
try!(writeln!(f, "... rotation matrix:")); try!(writeln!(f, "... rotation matrix:"));
try!(write!(f, "{}", *self.rotation.submat())); try!(write!(f, "{}", *self.rotation.submatrix()));
} }
writeln!(f, "}}") writeln!(f, "}}")

View File

@ -1,4 +1,4 @@
//! Matrices with dimensions known at compile-time. //! Matrixrices with dimensions known at compile-time.
#![allow(missing_docs)] // we allow missing to avoid having to document the mij components. #![allow(missing_docs)] // we allow missing to avoid having to document the mij components.
@ -9,14 +9,14 @@ use std::slice::{Iter, IterMut};
use rand::{Rand, Rng}; use rand::{Rand, Rng};
use num::{Zero, One}; use num::{Zero, One};
use traits::operations::ApproxEq; use traits::operations::ApproxEq;
use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6}; use structs::vector::{Vector1, Vector2, Vector3, Vector4, Vector5, Vector6};
use structs::pnt::{Pnt1, Pnt4, Pnt5, Pnt6}; use structs::point::{Point1, Point4, Point5, Point6};
use structs::dvec::{DVec1, DVec2, DVec3, DVec4, DVec5, DVec6}; use structs::dvector::{DVector1, DVector2, DVector3, DVector4, DVector5, DVector6};
use traits::structure::{Cast, Row, Col, Iterable, IterableMut, Dim, Indexable, Eye, ColSlice, use traits::structure::{Cast, Row, Column, Iterable, IterableMut, Dimension, Indexable, Eye, ColumnSlice,
RowSlice, Diag, DiagMut, Shape, BaseFloat, BaseNum, Repeat}; RowSlice, Diagonal, DiagMut, Shape, BaseFloat, BaseNum, Repeat};
use traits::operations::{Absolute, Transpose, Inv, Outer, EigenQR, Mean}; use traits::operations::{Absolute, Transpose, Inverse, Outer, EigenQR, Mean};
use traits::geometry::{ToHomogeneous, FromHomogeneous, Orig}; use traits::geometry::{ToHomogeneous, FromHomogeneous, Origin};
use linalg; use linalg;
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};
@ -38,331 +38,331 @@ impl Identity {
/// Square matrix of dimension 1. /// Square matrix of dimension 1.
#[repr(C)] #[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)] #[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Mat1<N> { pub struct Matrix1<N> {
pub m11: N pub m11: N
} }
eye_impl!(Mat1, 1, m11); eye_impl!(Matrix1, 1, m11);
mat_impl!(Mat1, m11); mat_impl!(Matrix1, m11);
repeat_impl!(Mat1, m11); repeat_impl!(Matrix1, m11);
conversion_impl!(Mat1, 1); conversion_impl!(Matrix1, 1);
mat_cast_impl!(Mat1, m11); mat_cast_impl!(Matrix1, m11);
add_impl!(Mat1, m11); add_impl!(Matrix1, m11);
sub_impl!(Mat1, m11); sub_impl!(Matrix1, m11);
scalar_add_impl!(Mat1, m11); scalar_add_impl!(Matrix1, m11);
scalar_sub_impl!(Mat1, m11); scalar_sub_impl!(Matrix1, m11);
scalar_mul_impl!(Mat1, m11); scalar_mul_impl!(Matrix1, m11);
scalar_div_impl!(Mat1, m11); scalar_div_impl!(Matrix1, m11);
absolute_impl!(Mat1, m11); absolute_impl!(Matrix1, m11);
zero_impl!(Mat1, m11); zero_impl!(Matrix1, m11);
one_impl!(Mat1, ::one); one_impl!(Matrix1, ::one);
iterable_impl!(Mat1, 1); iterable_impl!(Matrix1, 1);
iterable_mut_impl!(Mat1, 1); iterable_mut_impl!(Matrix1, 1);
at_fast_impl!(Mat1, 1); at_fast_impl!(Matrix1, 1);
dim_impl!(Mat1, 1); dim_impl!(Matrix1, 1);
indexable_impl!(Mat1, 1); indexable_impl!(Matrix1, 1);
index_impl!(Mat1, 1); index_impl!(Matrix1, 1);
mat_mul_mat_impl!(Mat1, 1); mat_mul_mat_impl!(Matrix1, 1);
mat_mul_vec_impl!(Mat1, Vec1, 1, ::zero); mat_mul_vec_impl!(Matrix1, Vector1, 1, ::zero);
vec_mul_mat_impl!(Mat1, Vec1, 1, ::zero); vec_mul_mat_impl!(Matrix1, Vector1, 1, ::zero);
mat_mul_pnt_impl!(Mat1, Pnt1, 1, Orig::orig); mat_mul_point_impl!(Matrix1, Point1, 1, Origin::origin);
pnt_mul_mat_impl!(Mat1, Pnt1, 1, Orig::orig); point_mul_mat_impl!(Matrix1, Point1, 1, Origin::origin);
// (specialized); inv_impl!(Mat1, 1); // (specialized); inverse_impl!(Matrix1, 1);
transpose_impl!(Mat1, 1); transpose_impl!(Matrix1, 1);
approx_eq_impl!(Mat1); approx_eq_impl!(Matrix1);
row_impl!(Mat1, Vec1, 1); row_impl!(Matrix1, Vector1, 1);
col_impl!(Mat1, Vec1, 1); col_impl!(Matrix1, Vector1, 1);
col_slice_impl!(Mat1, Vec1, DVec1, 1); col_slice_impl!(Matrix1, Vector1, DVector1, 1);
row_slice_impl!(Mat1, Vec1, DVec1, 1); row_slice_impl!(Matrix1, Vector1, DVector1, 1);
diag_impl!(Mat1, Vec1, 1); diag_impl!(Matrix1, Vector1, 1);
to_homogeneous_impl!(Mat1, Mat2, 1, 2); to_homogeneous_impl!(Matrix1, Matrix2, 1, 2);
from_homogeneous_impl!(Mat1, Mat2, 1, 2); from_homogeneous_impl!(Matrix1, Matrix2, 1, 2);
outer_impl!(Vec1, Mat1); outer_impl!(Vector1, Matrix1);
eigen_qr_impl!(Mat1, Vec1); eigen_qr_impl!(Matrix1, Vector1);
arbitrary_impl!(Mat1, m11); arbitrary_impl!(Matrix1, m11);
rand_impl!(Mat1, m11); rand_impl!(Matrix1, m11);
mean_impl!(Mat1, Vec1, 1); mean_impl!(Matrix1, Vector1, 1);
mat_display_impl!(Mat1, 1); mat_display_impl!(Matrix1, 1);
/// Square matrix of dimension 2. /// Square matrix of dimension 2.
#[repr(C)] #[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)] #[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Mat2<N> { pub struct Matrix2<N> {
pub m11: N, pub m21: N, pub m11: N, pub m21: N,
pub m12: N, pub m22: N pub m12: N, pub m22: N
} }
eye_impl!(Mat2, 2, m11, m22); eye_impl!(Matrix2, 2, m11, m22);
mat_impl!(Mat2, m11, m12, mat_impl!(Matrix2, m11, m12,
m21, m22); m21, m22);
repeat_impl!(Mat2, m11, m12, repeat_impl!(Matrix2, m11, m12,
m21, m22); m21, m22);
conversion_impl!(Mat2, 2); conversion_impl!(Matrix2, 2);
mat_cast_impl!(Mat2, m11, m12, mat_cast_impl!(Matrix2, m11, m12,
m21, m22); m21, m22);
add_impl!(Mat2, m11, m12, m21, m22); add_impl!(Matrix2, m11, m12, m21, m22);
sub_impl!(Mat2, m11, m12, m21, m22); sub_impl!(Matrix2, m11, m12, m21, m22);
scalar_add_impl!(Mat2, m11, m12, m21, m22); scalar_add_impl!(Matrix2, m11, m12, m21, m22);
scalar_sub_impl!(Mat2, m11, m12, m21, m22); scalar_sub_impl!(Matrix2, m11, m12, m21, m22);
scalar_mul_impl!(Mat2, m11, m12, m21, m22); scalar_mul_impl!(Matrix2, m11, m12, m21, m22);
scalar_div_impl!(Mat2, m11, m12, m21, m22); scalar_div_impl!(Matrix2, m11, m12, m21, m22);
absolute_impl!(Mat2, m11, m12, absolute_impl!(Matrix2, m11, m12,
m21, m22); m21, m22);
zero_impl!(Mat2, m11, m12, zero_impl!(Matrix2, m11, m12,
m21, m22); m21, m22);
one_impl!(Mat2, ::one, ::zero, one_impl!(Matrix2, ::one, ::zero,
::zero, ::one); ::zero, ::one);
iterable_impl!(Mat2, 2); iterable_impl!(Matrix2, 2);
iterable_mut_impl!(Mat2, 2); iterable_mut_impl!(Matrix2, 2);
dim_impl!(Mat2, 2); dim_impl!(Matrix2, 2);
indexable_impl!(Mat2, 2); indexable_impl!(Matrix2, 2);
index_impl!(Mat2, 2); index_impl!(Matrix2, 2);
at_fast_impl!(Mat2, 2); at_fast_impl!(Matrix2, 2);
// (specialized); mul_impl!(Mat2, 2); // (specialized); mul_impl!(Matrix2, 2);
// (specialized); rmul_impl!(Mat2, Vec2, 2); // (specialized); rmul_impl!(Matrix2, Vector2, 2);
// (specialized); lmul_impl!(Mat2, Vec2, 2); // (specialized); lmul_impl!(Matrix2, Vector2, 2);
// (specialized); inv_impl!(Mat2, 2); // (specialized); inverse_impl!(Matrix2, 2);
transpose_impl!(Mat2, 2); transpose_impl!(Matrix2, 2);
approx_eq_impl!(Mat2); approx_eq_impl!(Matrix2);
row_impl!(Mat2, Vec2, 2); row_impl!(Matrix2, Vector2, 2);
col_impl!(Mat2, Vec2, 2); col_impl!(Matrix2, Vector2, 2);
col_slice_impl!(Mat2, Vec2, DVec2, 2); col_slice_impl!(Matrix2, Vector2, DVector2, 2);
row_slice_impl!(Mat2, Vec2, DVec2, 2); row_slice_impl!(Matrix2, Vector2, DVector2, 2);
diag_impl!(Mat2, Vec2, 2); diag_impl!(Matrix2, Vector2, 2);
to_homogeneous_impl!(Mat2, Mat3, 2, 3); to_homogeneous_impl!(Matrix2, Matrix3, 2, 3);
from_homogeneous_impl!(Mat2, Mat3, 2, 3); from_homogeneous_impl!(Matrix2, Matrix3, 2, 3);
outer_impl!(Vec2, Mat2); outer_impl!(Vector2, Matrix2);
eigen_qr_impl!(Mat2, Vec2); eigen_qr_impl!(Matrix2, Vector2);
arbitrary_impl!(Mat2, m11, m12, m21, m22); arbitrary_impl!(Matrix2, m11, m12, m21, m22);
rand_impl!(Mat2, m11, m12, m21, m22); rand_impl!(Matrix2, m11, m12, m21, m22);
mean_impl!(Mat2, Vec2, 2); mean_impl!(Matrix2, Vector2, 2);
mat_display_impl!(Mat2, 2); mat_display_impl!(Matrix2, 2);
/// Square matrix of dimension 3. /// Square matrix of dimension 3.
#[repr(C)] #[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)] #[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Mat3<N> { pub struct Matrix3<N> {
pub m11: N, pub m21: N, pub m31: N, pub m11: N, pub m21: N, pub m31: N,
pub m12: N, pub m22: N, pub m32: N, pub m12: N, pub m22: N, pub m32: N,
pub m13: N, pub m23: N, pub m33: N pub m13: N, pub m23: N, pub m33: N
} }
eye_impl!(Mat3, 3, m11, m22, m33); eye_impl!(Matrix3, 3, m11, m22, m33);
mat_impl!(Mat3, m11, m12, m13, mat_impl!(Matrix3, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33); m31, m32, m33);
repeat_impl!(Mat3, m11, m12, m13, repeat_impl!(Matrix3, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33); m31, m32, m33);
conversion_impl!(Mat3, 3); conversion_impl!(Matrix3, 3);
mat_cast_impl!(Mat3, m11, m12, m13, mat_cast_impl!(Matrix3, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33); m31, m32, m33);
add_impl!(Mat3, add_impl!(Matrix3,
m11, m12, m13, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33 m31, m32, m33
); );
sub_impl!(Mat3, sub_impl!(Matrix3,
m11, m12, m13, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33 m31, m32, m33
); );
scalar_add_impl!(Mat3, scalar_add_impl!(Matrix3,
m11, m12, m13, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33 m31, m32, m33
); );
scalar_sub_impl!(Mat3, scalar_sub_impl!(Matrix3,
m11, m12, m13, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33 m31, m32, m33
); );
scalar_mul_impl!(Mat3, scalar_mul_impl!(Matrix3,
m11, m12, m13, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33 m31, m32, m33
); );
scalar_div_impl!(Mat3, scalar_div_impl!(Matrix3,
m11, m12, m13, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33 m31, m32, m33
); );
absolute_impl!(Mat3, absolute_impl!(Matrix3,
m11, m12, m13, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33 m31, m32, m33
); );
zero_impl!(Mat3, zero_impl!(Matrix3,
m11, m12, m13, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33 m31, m32, m33
); );
one_impl!(Mat3, ::one , ::zero, ::zero, one_impl!(Matrix3, ::one , ::zero, ::zero,
::zero, ::one , ::zero, ::zero, ::one , ::zero,
::zero, ::zero, ::one); ::zero, ::zero, ::one);
iterable_impl!(Mat3, 3); iterable_impl!(Matrix3, 3);
iterable_mut_impl!(Mat3, 3); iterable_mut_impl!(Matrix3, 3);
dim_impl!(Mat3, 3); dim_impl!(Matrix3, 3);
indexable_impl!(Mat3, 3); indexable_impl!(Matrix3, 3);
index_impl!(Mat3, 3); index_impl!(Matrix3, 3);
at_fast_impl!(Mat3, 3); at_fast_impl!(Matrix3, 3);
// (specialized); mul_impl!(Mat3, 3); // (specialized); mul_impl!(Matrix3, 3);
// (specialized); rmul_impl!(Mat3, Vec3, 3); // (specialized); rmul_impl!(Matrix3, Vector3, 3);
// (specialized); lmul_impl!(Mat3, Vec3, 3); // (specialized); lmul_impl!(Matrix3, Vector3, 3);
// (specialized); inv_impl!(Mat3, 3); // (specialized); inverse_impl!(Matrix3, 3);
transpose_impl!(Mat3, 3); transpose_impl!(Matrix3, 3);
approx_eq_impl!(Mat3); approx_eq_impl!(Matrix3);
// (specialized); row_impl!(Mat3, Vec3, 3); // (specialized); row_impl!(Matrix3, Vector3, 3);
// (specialized); col_impl!(Mat3, Vec3, 3); // (specialized); col_impl!(Matrix3, Vector3, 3);
col_slice_impl!(Mat3, Vec3, DVec3, 3); col_slice_impl!(Matrix3, Vector3, DVector3, 3);
row_slice_impl!(Mat3, Vec3, DVec3, 3); row_slice_impl!(Matrix3, Vector3, DVector3, 3);
diag_impl!(Mat3, Vec3, 3); diag_impl!(Matrix3, Vector3, 3);
to_homogeneous_impl!(Mat3, Mat4, 3, 4); to_homogeneous_impl!(Matrix3, Matrix4, 3, 4);
from_homogeneous_impl!(Mat3, Mat4, 3, 4); from_homogeneous_impl!(Matrix3, Matrix4, 3, 4);
outer_impl!(Vec3, Mat3); outer_impl!(Vector3, Matrix3);
eigen_qr_impl!(Mat3, Vec3); eigen_qr_impl!(Matrix3, Vector3);
arbitrary_impl!(Mat3, arbitrary_impl!(Matrix3,
m11, m12, m13, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33 m31, m32, m33
); );
rand_impl!(Mat3, rand_impl!(Matrix3,
m11, m12, m13, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33 m31, m32, m33
); );
mean_impl!(Mat3, Vec3, 3); mean_impl!(Matrix3, Vector3, 3);
mat_display_impl!(Mat3, 3); mat_display_impl!(Matrix3, 3);
/// Square matrix of dimension 4. /// Square matrix of dimension 4.
#[repr(C)] #[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)] #[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Mat4<N> { pub struct Matrix4<N> {
pub m11: N, pub m21: N, pub m31: N, pub m41: N, pub m11: N, pub m21: N, pub m31: N, pub m41: N,
pub m12: N, pub m22: N, pub m32: N, pub m42: N, pub m12: N, pub m22: N, pub m32: N, pub m42: N,
pub m13: N, pub m23: N, pub m33: N, pub m43: N, pub m13: N, pub m23: N, pub m33: N, pub m43: N,
pub m14: N, pub m24: N, pub m34: N, pub m44: N pub m14: N, pub m24: N, pub m34: N, pub m44: N
} }
eye_impl!(Mat4, 4, m11, m22, m33, m44); eye_impl!(Matrix4, 4, m11, m22, m33, m44);
mat_impl!(Mat4, mat_impl!(Matrix4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
m41, m42, m43, m44 m41, m42, m43, m44
); );
repeat_impl!(Mat4, repeat_impl!(Matrix4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
m41, m42, m43, m44 m41, m42, m43, m44
); );
conversion_impl!(Mat4, 4); conversion_impl!(Matrix4, 4);
mat_cast_impl!(Mat4, mat_cast_impl!(Matrix4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
m41, m42, m43, m44 m41, m42, m43, m44
); );
add_impl!(Mat4, add_impl!(Matrix4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
m41, m42, m43, m44 m41, m42, m43, m44
); );
sub_impl!(Mat4, sub_impl!(Matrix4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
m41, m42, m43, m44 m41, m42, m43, m44
); );
scalar_add_impl!(Mat4, scalar_add_impl!(Matrix4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
m41, m42, m43, m44 m41, m42, m43, m44
); );
scalar_sub_impl!(Mat4, scalar_sub_impl!(Matrix4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
m41, m42, m43, m44 m41, m42, m43, m44
); );
scalar_mul_impl!(Mat4, scalar_mul_impl!(Matrix4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
m41, m42, m43, m44 m41, m42, m43, m44
); );
scalar_div_impl!(Mat4, scalar_div_impl!(Matrix4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
m41, m42, m43, m44 m41, m42, m43, m44
); );
absolute_impl!(Mat4, absolute_impl!(Matrix4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
m41, m42, m43, m44 m41, m42, m43, m44
); );
zero_impl!(Mat4, zero_impl!(Matrix4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
m41, m42, m43, m44 m41, m42, m43, m44
); );
one_impl!(Mat4, ::one , ::zero, ::zero, ::zero, one_impl!(Matrix4, ::one , ::zero, ::zero, ::zero,
::zero, ::one , ::zero, ::zero, ::zero, ::one , ::zero, ::zero,
::zero, ::zero, ::one , ::zero, ::zero, ::zero, ::one , ::zero,
::zero, ::zero, ::zero, ::one); ::zero, ::zero, ::zero, ::one);
iterable_impl!(Mat4, 4); iterable_impl!(Matrix4, 4);
iterable_mut_impl!(Mat4, 4); iterable_mut_impl!(Matrix4, 4);
dim_impl!(Mat4, 4); dim_impl!(Matrix4, 4);
indexable_impl!(Mat4, 4); indexable_impl!(Matrix4, 4);
index_impl!(Mat4, 4); index_impl!(Matrix4, 4);
at_fast_impl!(Mat4, 4); at_fast_impl!(Matrix4, 4);
mat_mul_mat_impl!(Mat4, 4); mat_mul_mat_impl!(Matrix4, 4);
mat_mul_vec_impl!(Mat4, Vec4, 4, ::zero); mat_mul_vec_impl!(Matrix4, Vector4, 4, ::zero);
vec_mul_mat_impl!(Mat4, Vec4, 4, ::zero); vec_mul_mat_impl!(Matrix4, Vector4, 4, ::zero);
mat_mul_pnt_impl!(Mat4, Pnt4, 4, Orig::orig); mat_mul_point_impl!(Matrix4, Point4, 4, Origin::origin);
pnt_mul_mat_impl!(Mat4, Pnt4, 4, Orig::orig); point_mul_mat_impl!(Matrix4, Point4, 4, Origin::origin);
inv_impl!(Mat4, 4); inverse_impl!(Matrix4, 4);
transpose_impl!(Mat4, 4); transpose_impl!(Matrix4, 4);
approx_eq_impl!(Mat4); approx_eq_impl!(Matrix4);
row_impl!(Mat4, Vec4, 4); row_impl!(Matrix4, Vector4, 4);
col_impl!(Mat4, Vec4, 4); col_impl!(Matrix4, Vector4, 4);
col_slice_impl!(Mat4, Vec4, DVec4, 4); col_slice_impl!(Matrix4, Vector4, DVector4, 4);
row_slice_impl!(Mat4, Vec4, DVec4, 4); row_slice_impl!(Matrix4, Vector4, DVector4, 4);
diag_impl!(Mat4, Vec4, 4); diag_impl!(Matrix4, Vector4, 4);
to_homogeneous_impl!(Mat4, Mat5, 4, 5); to_homogeneous_impl!(Matrix4, Matrix5, 4, 5);
from_homogeneous_impl!(Mat4, Mat5, 4, 5); from_homogeneous_impl!(Matrix4, Matrix5, 4, 5);
outer_impl!(Vec4, Mat4); outer_impl!(Vector4, Matrix4);
eigen_qr_impl!(Mat4, Vec4); eigen_qr_impl!(Matrix4, Vector4);
arbitrary_impl!(Mat4, arbitrary_impl!(Matrix4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
m41, m42, m43, m44 m41, m42, m43, m44
); );
rand_impl!(Mat4, rand_impl!(Matrix4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
m41, m42, m43, m44 m41, m42, m43, m44
); );
mean_impl!(Mat4, Vec4, 4); mean_impl!(Matrix4, Vector4, 4);
mat_display_impl!(Mat4, 4); mat_display_impl!(Matrix4, 4);
/// Square matrix of dimension 5. /// Square matrix of dimension 5.
#[repr(C)] #[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)] #[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Mat5<N> { pub struct Matrix5<N> {
pub m11: N, pub m21: N, pub m31: N, pub m41: N, pub m51: N, pub m11: N, pub m21: N, pub m31: N, pub m41: N, pub m51: N,
pub m12: N, pub m22: N, pub m32: N, pub m42: N, pub m52: N, pub m12: N, pub m22: N, pub m32: N, pub m42: N, pub m52: N,
pub m13: N, pub m23: N, pub m33: N, pub m43: N, pub m53: N, pub m13: N, pub m23: N, pub m33: N, pub m43: N, pub m53: N,
@ -370,137 +370,137 @@ pub struct Mat5<N> {
pub m15: N, pub m25: N, pub m35: N, pub m45: N, pub m55: N pub m15: N, pub m25: N, pub m35: N, pub m45: N, pub m55: N
} }
eye_impl!(Mat5, 5, m11, m22, m33, m44, m55); eye_impl!(Matrix5, 5, m11, m22, m33, m44, m55);
mat_impl!(Mat5, mat_impl!(Matrix5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35, m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45, m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55 m51, m52, m53, m54, m55
); );
repeat_impl!(Mat5, repeat_impl!(Matrix5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35, m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45, m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55 m51, m52, m53, m54, m55
); );
conversion_impl!(Mat5, 5); conversion_impl!(Matrix5, 5);
mat_cast_impl!(Mat5, mat_cast_impl!(Matrix5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35, m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45, m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55 m51, m52, m53, m54, m55
); );
absolute_impl!(Mat5, absolute_impl!(Matrix5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35, m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45, m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55 m51, m52, m53, m54, m55
); );
zero_impl!(Mat5, zero_impl!(Matrix5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35, m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45, m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55 m51, m52, m53, m54, m55
); );
one_impl!(Mat5, one_impl!(Matrix5,
::one , ::zero, ::zero, ::zero, ::zero, ::one , ::zero, ::zero, ::zero, ::zero,
::zero, ::one , ::zero, ::zero, ::zero, ::zero, ::one , ::zero, ::zero, ::zero,
::zero, ::zero, ::one , ::zero, ::zero, ::zero, ::zero, ::one , ::zero, ::zero,
::zero, ::zero, ::zero, ::one , ::zero, ::zero, ::zero, ::zero, ::one , ::zero,
::zero, ::zero, ::zero, ::zero, ::one ::zero, ::zero, ::zero, ::zero, ::one
); );
add_impl!(Mat5, add_impl!(Matrix5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35, m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45, m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55 m51, m52, m53, m54, m55
); );
sub_impl!(Mat5, sub_impl!(Matrix5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35, m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45, m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55 m51, m52, m53, m54, m55
); );
scalar_add_impl!(Mat5, scalar_add_impl!(Matrix5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35, m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45, m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55 m51, m52, m53, m54, m55
); );
scalar_sub_impl!(Mat5, scalar_sub_impl!(Matrix5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35, m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45, m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55 m51, m52, m53, m54, m55
); );
scalar_mul_impl!(Mat5, scalar_mul_impl!(Matrix5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35, m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45, m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55 m51, m52, m53, m54, m55
); );
scalar_div_impl!(Mat5, scalar_div_impl!(Matrix5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35, m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45, m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55 m51, m52, m53, m54, m55
); );
iterable_impl!(Mat5, 5); iterable_impl!(Matrix5, 5);
iterable_mut_impl!(Mat5, 5); iterable_mut_impl!(Matrix5, 5);
dim_impl!(Mat5, 5); dim_impl!(Matrix5, 5);
indexable_impl!(Mat5, 5); indexable_impl!(Matrix5, 5);
index_impl!(Mat5, 5); index_impl!(Matrix5, 5);
at_fast_impl!(Mat5, 5); at_fast_impl!(Matrix5, 5);
mat_mul_mat_impl!(Mat5, 5); mat_mul_mat_impl!(Matrix5, 5);
mat_mul_vec_impl!(Mat5, Vec5, 5, ::zero); mat_mul_vec_impl!(Matrix5, Vector5, 5, ::zero);
vec_mul_mat_impl!(Mat5, Vec5, 5, ::zero); vec_mul_mat_impl!(Matrix5, Vector5, 5, ::zero);
mat_mul_pnt_impl!(Mat5, Pnt5, 5, Orig::orig); mat_mul_point_impl!(Matrix5, Point5, 5, Origin::origin);
pnt_mul_mat_impl!(Mat5, Pnt5, 5, Orig::orig); point_mul_mat_impl!(Matrix5, Point5, 5, Origin::origin);
inv_impl!(Mat5, 5); inverse_impl!(Matrix5, 5);
transpose_impl!(Mat5, 5); transpose_impl!(Matrix5, 5);
approx_eq_impl!(Mat5); approx_eq_impl!(Matrix5);
row_impl!(Mat5, Vec5, 5); row_impl!(Matrix5, Vector5, 5);
col_impl!(Mat5, Vec5, 5); col_impl!(Matrix5, Vector5, 5);
col_slice_impl!(Mat5, Vec5, DVec5, 5); col_slice_impl!(Matrix5, Vector5, DVector5, 5);
row_slice_impl!(Mat5, Vec5, DVec5, 5); row_slice_impl!(Matrix5, Vector5, DVector5, 5);
diag_impl!(Mat5, Vec5, 5); diag_impl!(Matrix5, Vector5, 5);
to_homogeneous_impl!(Mat5, Mat6, 5, 6); to_homogeneous_impl!(Matrix5, Matrix6, 5, 6);
from_homogeneous_impl!(Mat5, Mat6, 5, 6); from_homogeneous_impl!(Matrix5, Matrix6, 5, 6);
outer_impl!(Vec5, Mat5); outer_impl!(Vector5, Matrix5);
eigen_qr_impl!(Mat5, Vec5); eigen_qr_impl!(Matrix5, Vector5);
arbitrary_impl!(Mat5, arbitrary_impl!(Matrix5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35, m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45, m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55 m51, m52, m53, m54, m55
); );
rand_impl!(Mat5, rand_impl!(Matrix5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35, m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45, m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55 m51, m52, m53, m54, m55
); );
mean_impl!(Mat5, Vec5, 5); mean_impl!(Matrix5, Vector5, 5);
mat_display_impl!(Mat5, 5); mat_display_impl!(Matrix5, 5);
/// Square matrix of dimension 6. /// Square matrix of dimension 6.
#[repr(C)] #[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)] #[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Mat6<N> { pub struct Matrix6<N> {
pub m11: N, pub m21: N, pub m31: N, pub m41: N, pub m51: N, pub m61: N, pub m11: N, pub m21: N, pub m31: N, pub m41: N, pub m51: N, pub m61: N,
pub m12: N, pub m22: N, pub m32: N, pub m42: N, pub m52: N, pub m62: N, pub m12: N, pub m22: N, pub m32: N, pub m42: N, pub m52: N, pub m62: N,
pub m13: N, pub m23: N, pub m33: N, pub m43: N, pub m53: N, pub m63: N, pub m13: N, pub m23: N, pub m33: N, pub m43: N, pub m53: N, pub m63: N,
@ -509,9 +509,9 @@ pub struct Mat6<N> {
pub m16: N, pub m26: N, pub m36: N, pub m46: N, pub m56: N, pub m66: N pub m16: N, pub m26: N, pub m36: N, pub m46: N, pub m56: N, pub m66: N
} }
eye_impl!(Mat6, 6, m11, m22, m33, m44, m55, m66); eye_impl!(Matrix6, 6, m11, m22, m33, m44, m55, m66);
mat_impl!(Mat6, mat_impl!(Matrix6,
m11, m12, m13, m14, m15, m16, m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26, m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36, m31, m32, m33, m34, m35, m36,
@ -519,7 +519,7 @@ mat_impl!(Mat6,
m51, m52, m53, m54, m55, m56, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66 m61, m62, m63, m64, m65, m66
); );
repeat_impl!(Mat6, repeat_impl!(Matrix6,
m11, m12, m13, m14, m15, m16, m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26, m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36, m31, m32, m33, m34, m35, m36,
@ -527,8 +527,8 @@ repeat_impl!(Mat6,
m51, m52, m53, m54, m55, m56, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66 m61, m62, m63, m64, m65, m66
); );
conversion_impl!(Mat6, 6); conversion_impl!(Matrix6, 6);
mat_cast_impl!(Mat6, mat_cast_impl!(Matrix6,
m11, m12, m13, m14, m15, m16, m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26, m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36, m31, m32, m33, m34, m35, m36,
@ -536,7 +536,7 @@ mat_cast_impl!(Mat6,
m51, m52, m53, m54, m55, m56, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66 m61, m62, m63, m64, m65, m66
); );
add_impl!(Mat6, add_impl!(Matrix6,
m11, m12, m13, m14, m15, m16, m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26, m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36, m31, m32, m33, m34, m35, m36,
@ -544,7 +544,7 @@ add_impl!(Mat6,
m51, m52, m53, m54, m55, m56, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66 m61, m62, m63, m64, m65, m66
); );
sub_impl!(Mat6, sub_impl!(Matrix6,
m11, m12, m13, m14, m15, m16, m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26, m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36, m31, m32, m33, m34, m35, m36,
@ -552,7 +552,7 @@ sub_impl!(Mat6,
m51, m52, m53, m54, m55, m56, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66 m61, m62, m63, m64, m65, m66
); );
scalar_add_impl!(Mat6, scalar_add_impl!(Matrix6,
m11, m12, m13, m14, m15, m16, m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26, m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36, m31, m32, m33, m34, m35, m36,
@ -560,7 +560,7 @@ scalar_add_impl!(Mat6,
m51, m52, m53, m54, m55, m56, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66 m61, m62, m63, m64, m65, m66
); );
scalar_sub_impl!(Mat6, scalar_sub_impl!(Matrix6,
m11, m12, m13, m14, m15, m16, m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26, m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36, m31, m32, m33, m34, m35, m36,
@ -568,7 +568,7 @@ scalar_sub_impl!(Mat6,
m51, m52, m53, m54, m55, m56, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66 m61, m62, m63, m64, m65, m66
); );
scalar_mul_impl!(Mat6, scalar_mul_impl!(Matrix6,
m11, m12, m13, m14, m15, m16, m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26, m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36, m31, m32, m33, m34, m35, m36,
@ -576,7 +576,7 @@ scalar_mul_impl!(Mat6,
m51, m52, m53, m54, m55, m56, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66 m61, m62, m63, m64, m65, m66
); );
scalar_div_impl!(Mat6, scalar_div_impl!(Matrix6,
m11, m12, m13, m14, m15, m16, m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26, m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36, m31, m32, m33, m34, m35, m36,
@ -584,15 +584,15 @@ scalar_div_impl!(Mat6,
m51, m52, m53, m54, m55, m56, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66 m61, m62, m63, m64, m65, m66
); );
absolute_impl!(Mat6, m11, m12, m13, m14, m15, m16, m21, m22, m23, m24, m25, m26, 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, m31, m32, m33, m34, m35, m36, m41, m42, m43, m44, m45, m46, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66); m61, m62, m63, m64, m65, m66);
zero_impl!(Mat6, m11, m12, m13, m14, m15, m16, m21, m22, m23, m24, m25, m26, 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, m31, m32, m33, m34, m35, m36, m41, m42, m43, m44, m45, m46, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66); m61, m62, m63, m64, m65, m66);
one_impl!(Mat6, one_impl!(Matrix6,
::one , ::zero, ::zero, ::zero, ::zero, ::zero, ::one , ::zero, ::zero, ::zero, ::zero, ::zero,
::zero, ::one , ::zero, ::zero, ::zero, ::zero, ::zero, ::one , ::zero, ::zero, ::zero, ::zero,
::zero, ::zero, ::one , ::zero, ::zero, ::zero, ::zero, ::zero, ::one , ::zero, ::zero, ::zero,
@ -600,28 +600,28 @@ one_impl!(Mat6,
::zero, ::zero, ::zero, ::zero, ::one , ::zero, ::zero, ::zero, ::zero, ::zero, ::one , ::zero,
::zero, ::zero, ::zero, ::zero, ::zero, ::one ::zero, ::zero, ::zero, ::zero, ::zero, ::one
); );
iterable_impl!(Mat6, 6); iterable_impl!(Matrix6, 6);
iterable_mut_impl!(Mat6, 6); iterable_mut_impl!(Matrix6, 6);
dim_impl!(Mat6, 6); dim_impl!(Matrix6, 6);
indexable_impl!(Mat6, 6); indexable_impl!(Matrix6, 6);
index_impl!(Mat6, 6); index_impl!(Matrix6, 6);
at_fast_impl!(Mat6, 6); at_fast_impl!(Matrix6, 6);
mat_mul_mat_impl!(Mat6, 6); mat_mul_mat_impl!(Matrix6, 6);
mat_mul_vec_impl!(Mat6, Vec6, 6, ::zero); mat_mul_vec_impl!(Matrix6, Vector6, 6, ::zero);
vec_mul_mat_impl!(Mat6, Vec6, 6, ::zero); vec_mul_mat_impl!(Matrix6, Vector6, 6, ::zero);
mat_mul_pnt_impl!(Mat6, Pnt6, 6, Orig::orig); mat_mul_point_impl!(Matrix6, Point6, 6, Origin::origin);
pnt_mul_mat_impl!(Mat6, Pnt6, 6, Orig::orig); point_mul_mat_impl!(Matrix6, Point6, 6, Origin::origin);
inv_impl!(Mat6, 6); inverse_impl!(Matrix6, 6);
transpose_impl!(Mat6, 6); transpose_impl!(Matrix6, 6);
approx_eq_impl!(Mat6); approx_eq_impl!(Matrix6);
row_impl!(Mat6, Vec6, 6); row_impl!(Matrix6, Vector6, 6);
col_impl!(Mat6, Vec6, 6); col_impl!(Matrix6, Vector6, 6);
col_slice_impl!(Mat6, Vec6, DVec6, 6); col_slice_impl!(Matrix6, Vector6, DVector6, 6);
row_slice_impl!(Mat6, Vec6, DVec6, 6); row_slice_impl!(Matrix6, Vector6, DVector6, 6);
diag_impl!(Mat6, Vec6, 6); diag_impl!(Matrix6, Vector6, 6);
outer_impl!(Vec6, Mat6); outer_impl!(Vector6, Matrix6);
eigen_qr_impl!(Mat6, Vec6); eigen_qr_impl!(Matrix6, Vector6);
arbitrary_impl!(Mat6, arbitrary_impl!(Matrix6,
m11, m12, m13, m14, m15, m16, m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26, m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36, m31, m32, m33, m34, m35, m36,
@ -629,7 +629,7 @@ arbitrary_impl!(Mat6,
m51, m52, m53, m54, m55, m56, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66 m61, m62, m63, m64, m65, m66
); );
rand_impl!(Mat6, rand_impl!(Matrix6,
m11, m12, m13, m14, m15, m16, m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26, m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36, m31, m32, m33, m34, m35, m36,
@ -637,5 +637,5 @@ rand_impl!(Mat6,
m51, m52, m53, m54, m55, m56, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66 m61, m62, m63, m64, m65, m66
); );
mean_impl!(Mat6, Vec6, 6); mean_impl!(Matrix6, Vector6, 6);
mat_display_impl!(Mat6, 6); mat_display_impl!(Matrix6, 6);

View File

@ -14,37 +14,37 @@ macro_rules! mat_impl(
); );
macro_rules! conversion_impl( macro_rules! conversion_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N> AsRef<[[N; $dim]; $dim]> for $t<N> { impl<N> AsRef<[[N; $dimension]; $dimension]> for $t<N> {
#[inline] #[inline]
fn as_ref(&self) -> &[[N; $dim]; $dim] { fn as_ref(&self) -> &[[N; $dimension]; $dimension] {
unsafe { unsafe {
mem::transmute(self) mem::transmute(self)
} }
} }
} }
impl<N> AsMut<[[N; $dim]; $dim]> for $t<N> { impl<N> AsMut<[[N; $dimension]; $dimension]> for $t<N> {
#[inline] #[inline]
fn as_mut(&mut self) -> &mut [[N; $dim]; $dim] { fn as_mut(&mut self) -> &mut [[N; $dimension]; $dimension] {
unsafe { unsafe {
mem::transmute(self) mem::transmute(self)
} }
} }
} }
impl<'a, N> From<&'a [[N; $dim]; $dim]> for &'a $t<N> { impl<'a, N> From<&'a [[N; $dimension]; $dimension]> for &'a $t<N> {
#[inline] #[inline]
fn from(arr: &'a [[N; $dim]; $dim]) -> &'a $t<N> { fn from(arr: &'a [[N; $dimension]; $dimension]) -> &'a $t<N> {
unsafe { unsafe {
mem::transmute(arr) mem::transmute(arr)
} }
} }
} }
impl<'a, N> From<&'a mut [[N; $dim]; $dim]> for &'a mut $t<N> { impl<'a, N> From<&'a mut [[N; $dimension]; $dimension]> for &'a mut $t<N> {
#[inline] #[inline]
fn from(arr: &'a mut [[N; $dim]; $dim]) -> &'a mut $t<N> { fn from(arr: &'a mut [[N; $dimension]; $dimension]) -> &'a mut $t<N> {
unsafe { unsafe {
mem::transmute(arr) mem::transmute(arr)
} }
@ -54,18 +54,18 @@ macro_rules! conversion_impl(
); );
macro_rules! at_fast_impl( macro_rules! at_fast_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N: Copy> $t<N> { impl<N: Copy> $t<N> {
#[inline] #[inline]
pub unsafe fn at_fast(&self, (i, j): (usize, usize)) -> N { pub unsafe fn at_fast(&self, (i, j): (usize, usize)) -> N {
(*mem::transmute::<&$t<N>, &[N; $dim * $dim]>(self) (*mem::transmute::<&$t<N>, &[N; $dimension * $dimension]>(self)
.get_unchecked(i + j * $dim)) .get_unchecked(i + j * $dimension))
} }
#[inline] #[inline]
pub unsafe fn set_fast(&mut self, (i, j): (usize, usize), val: N) { pub unsafe fn set_fast(&mut self, (i, j): (usize, usize), val: N) {
(*mem::transmute::<&mut $t<N>, &mut [N; $dim * $dim]>(self) (*mem::transmute::<&mut $t<N>, &mut [N; $dimension * $dimension]>(self)
.get_unchecked_mut(i + j * $dim)) = val .get_unchecked_mut(i + j * $dimension)) = val
} }
} }
) )
@ -259,10 +259,10 @@ macro_rules! mat_sub_scalar_impl(
macro_rules! eye_impl( macro_rules! eye_impl(
($t: ident, $dim: expr, $($comp_diagN: ident),+) => ( ($t: ident, $dimension: expr, $($comp_diagN: ident),+) => (
impl<N: Zero + One> Eye for $t<N> { impl<N: Zero + One> Eye for $t<N> {
fn new_identity(dim: usize) -> $t<N> { fn new_identity(dimension: usize) -> $t<N> {
assert!(dim == $dim); assert!(dimension == $dimension);
let mut eye: $t<N> = ::zero(); let mut eye: $t<N> = ::zero();
$(eye.$comp_diagN = ::one();)+ $(eye.$comp_diagN = ::one();)+
eye eye
@ -295,12 +295,12 @@ macro_rules! absolute_impl(
); );
macro_rules! iterable_impl( macro_rules! iterable_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N> Iterable<N> for $t<N> { impl<N> Iterable<N> for $t<N> {
#[inline] #[inline]
fn iter<'l>(&'l self) -> Iter<'l, N> { fn iter<'l>(&'l self) -> Iter<'l, N> {
unsafe { unsafe {
mem::transmute::<&'l $t<N>, &'l [N; $dim * $dim]>(self).iter() mem::transmute::<&'l $t<N>, &'l [N; $dimension * $dimension]>(self).iter()
} }
} }
} }
@ -308,12 +308,12 @@ macro_rules! iterable_impl(
); );
macro_rules! iterable_mut_impl( macro_rules! iterable_mut_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N> IterableMut<N> for $t<N> { impl<N> IterableMut<N> for $t<N> {
#[inline] #[inline]
fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> { fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> {
unsafe { unsafe {
mem::transmute::<&'l mut $t<N>, &'l mut [N; $dim * $dim]>(self).iter_mut() mem::transmute::<&'l mut $t<N>, &'l mut [N; $dimension * $dimension]>(self).iter_mut()
} }
} }
} }
@ -350,22 +350,22 @@ macro_rules! zero_impl(
); );
macro_rules! dim_impl( macro_rules! dim_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N> Dim for $t<N> { impl<N> Dimension for $t<N> {
#[inline] #[inline]
fn dim(_: Option<$t<N>>) -> usize { fn dimension(_: Option<$t<N>>) -> usize {
$dim $dimension
} }
} }
) )
); );
macro_rules! indexable_impl( macro_rules! indexable_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N> Shape<(usize, usize)> for $t<N> { impl<N> Shape<(usize, usize)> for $t<N> {
#[inline] #[inline]
fn shape(&self) -> (usize, usize) { fn shape(&self) -> (usize, usize) {
($dim, $dim) ($dimension, $dimension)
} }
} }
@ -373,32 +373,32 @@ macro_rules! indexable_impl(
#[inline] #[inline]
fn swap(&mut self, (i1, j1): (usize, usize), (i2, j2): (usize, usize)) { fn swap(&mut self, (i1, j1): (usize, usize), (i2, j2): (usize, usize)) {
unsafe { unsafe {
mem::transmute::<&mut $t<N>, &mut [N; $dim * $dim]>(self) mem::transmute::<&mut $t<N>, &mut [N; $dimension * $dimension]>(self)
.swap(i1 + j1 * $dim, i2 + j2 * $dim) .swap(i1 + j1 * $dimension, i2 + j2 * $dimension)
} }
} }
#[inline] #[inline]
unsafe fn unsafe_at(&self, (i, j): (usize, usize)) -> N { unsafe fn unsafe_at(&self, (i, j): (usize, usize)) -> N {
(*mem::transmute::<&$t<N>, &[N; $dim * $dim]>(self).get_unchecked(i + j * $dim)) (*mem::transmute::<&$t<N>, &[N; $dimension * $dimension]>(self).get_unchecked(i + j * $dimension))
} }
#[inline] #[inline]
unsafe fn unsafe_set(&mut self, (i, j): (usize, usize), val: N) { unsafe fn unsafe_set(&mut self, (i, j): (usize, usize), val: N) {
(*mem::transmute::<&mut $t<N>, &mut [N; $dim * $dim]>(self).get_unchecked_mut(i + j * $dim)) = val (*mem::transmute::<&mut $t<N>, &mut [N; $dimension * $dimension]>(self).get_unchecked_mut(i + j * $dimension)) = val
} }
} }
) )
); );
macro_rules! index_impl( macro_rules! index_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N> Index<(usize, usize)> for $t<N> { impl<N> Index<(usize, usize)> for $t<N> {
type Output = N; type Output = N;
fn index(&self, (i, j): (usize, usize)) -> &N { fn index(&self, (i, j): (usize, usize)) -> &N {
unsafe { unsafe {
&mem::transmute::<&$t<N>, & [N; $dim * $dim]>(self)[i + j * $dim] &mem::transmute::<&$t<N>, & [N; $dimension * $dimension]>(self)[i + j * $dimension]
} }
} }
} }
@ -406,7 +406,7 @@ macro_rules! index_impl(
impl<N> IndexMut<(usize, usize)> for $t<N> { impl<N> IndexMut<(usize, usize)> for $t<N> {
fn index_mut(&mut self, (i, j): (usize, usize)) -> &mut N { fn index_mut(&mut self, (i, j): (usize, usize)) -> &mut N {
unsafe { unsafe {
&mut mem::transmute::<&mut $t<N>, &mut [N; $dim * $dim]>(self)[i + j * $dim] &mut mem::transmute::<&mut $t<N>, &mut [N; $dimension * $dimension]>(self)[i + j * $dimension]
} }
} }
} }
@ -414,23 +414,23 @@ macro_rules! index_impl(
); );
macro_rules! col_slice_impl( macro_rules! col_slice_impl(
($t: ident, $tv: ident, $slice: ident, $dim: expr) => ( ($t: ident, $tv: ident, $slice: ident, $dimension: expr) => (
impl<N: Clone + Copy + Zero> ColSlice<$slice<N>> for $t<N> { impl<N: Clone + Copy + Zero> ColumnSlice<$slice<N>> for $t<N> {
fn col_slice(&self, cid: usize, rstart: usize, rend: usize) -> $slice<N> { fn col_slice(&self, cid: usize, rstart: usize, rend: usize) -> $slice<N> {
let col = self.col(cid); let column = self.column(cid);
$slice::from_slice(rend - rstart, &col.as_ref()[rstart .. rend]) $slice::from_slice(rend - rstart, &column.as_ref()[rstart .. rend])
} }
} }
) )
); );
macro_rules! row_impl( macro_rules! row_impl(
($t: ident, $tv: ident, $dim: expr) => ( ($t: ident, $tv: ident, $dimension: expr) => (
impl<N: Copy + Zero> Row<$tv<N>> for $t<N> { impl<N: Copy + Zero> Row<$tv<N>> for $t<N> {
#[inline] #[inline]
fn nrows(&self) -> usize { fn nrows(&self) -> usize {
Dim::dim(None::<$t<N>>) Dimension::dimension(None::<$t<N>>)
} }
#[inline] #[inline]
@ -455,7 +455,7 @@ macro_rules! row_impl(
); );
macro_rules! row_slice_impl( macro_rules! row_slice_impl(
($t: ident, $tv: ident, $slice: ident, $dim: expr) => ( ($t: ident, $tv: ident, $slice: ident, $dimension: expr) => (
impl<N: Clone + Copy + Zero> RowSlice<$slice<N>> for $t<N> { impl<N: Clone + Copy + Zero> RowSlice<$slice<N>> for $t<N> {
fn row_slice(&self, rid: usize, cstart: usize, cend: usize) -> $slice<N> { fn row_slice(&self, rid: usize, cstart: usize, cend: usize) -> $slice<N> {
let row = self.row(rid); let row = self.row(rid);
@ -467,26 +467,26 @@ macro_rules! row_slice_impl(
); );
macro_rules! col_impl( macro_rules! col_impl(
($t: ident, $tv: ident, $dim: expr) => ( ($t: ident, $tv: ident, $dimension: expr) => (
impl<N: Copy + Zero> Col<$tv<N>> for $t<N> { impl<N: Copy + Zero> Column<$tv<N>> for $t<N> {
#[inline] #[inline]
fn ncols(&self) -> usize { fn ncols(&self) -> usize {
Dim::dim(None::<$t<N>>) Dimension::dimension(None::<$t<N>>)
} }
#[inline] #[inline]
fn set_col(&mut self, col: usize, v: $tv<N>) { fn set_col(&mut self, column: usize, v: $tv<N>) {
for (i, e) in v.iter().enumerate() { for (i, e) in v.iter().enumerate() {
self[(i, col)] = *e; self[(i, column)] = *e;
} }
} }
#[inline] #[inline]
fn col(&self, col: usize) -> $tv<N> { fn column(&self, column: usize) -> $tv<N> {
let mut res: $tv<N> = ::zero(); let mut res: $tv<N> = ::zero();
for (i, e) in res.iter_mut().enumerate() { for (i, e) in res.iter_mut().enumerate() {
*e = self[(i, col)]; *e = self[(i, column)];
} }
res res
@ -496,34 +496,34 @@ macro_rules! col_impl(
); );
macro_rules! diag_impl( macro_rules! diag_impl(
($t: ident, $tv: ident, $dim: expr) => ( ($t: ident, $tv: ident, $dimension: expr) => (
impl<N: Copy + Zero> Diag<$tv<N>> for $t<N> { impl<N: Copy + Zero> Diagonal<$tv<N>> for $t<N> {
#[inline] #[inline]
fn from_diag(diag: &$tv<N>) -> $t<N> { fn from_diag(diagonal: &$tv<N>) -> $t<N> {
let mut res: $t<N> = ::zero(); let mut res: $t<N> = ::zero();
res.set_diag(diag); res.set_diag(diagonal);
res res
} }
#[inline] #[inline]
fn diag(&self) -> $tv<N> { fn diagonal(&self) -> $tv<N> {
let mut diag: $tv<N> = ::zero(); let mut diagonal: $tv<N> = ::zero();
for i in 0 .. $dim { for i in 0 .. $dimension {
unsafe { diag.unsafe_set(i, self.unsafe_at((i, i))) } unsafe { diagonal.unsafe_set(i, self.unsafe_at((i, i))) }
} }
diag diagonal
} }
} }
impl<N: Copy + Zero> DiagMut<$tv<N>> for $t<N> { impl<N: Copy + Zero> DiagMut<$tv<N>> for $t<N> {
#[inline] #[inline]
fn set_diag(&mut self, diag: &$tv<N>) { fn set_diag(&mut self, diagonal: &$tv<N>) {
for i in 0 .. $dim { for i in 0 .. $dimension {
unsafe { self.unsafe_set((i, i), diag.unsafe_at(i)) } unsafe { self.unsafe_set((i, i), diagonal.unsafe_at(i)) }
} }
} }
} }
@ -531,19 +531,19 @@ macro_rules! diag_impl(
); );
macro_rules! mat_mul_mat_impl( macro_rules! mat_mul_mat_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N: Copy + BaseNum> Mul<$t<N>> for $t<N> { impl<N: Copy + BaseNum> Mul<$t<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
#[inline] #[inline]
fn mul(self, right: $t<N>) -> $t<N> { fn mul(self, right: $t<N>) -> $t<N> {
let mut res: $t<N> = ::zero(); let mut res: $t<N> = ::zero();
for i in 0 .. $dim { for i in 0 .. $dimension {
for j in 0 .. $dim { for j in 0 .. $dimension {
let mut acc: N = ::zero(); let mut acc: N = ::zero();
unsafe { unsafe {
for k in 0 .. $dim { for k in 0 .. $dimension {
acc = acc + self.at_fast((i, k)) * right.at_fast((k, j)); acc = acc + self.at_fast((i, k)) * right.at_fast((k, j));
} }
@ -568,7 +568,7 @@ macro_rules! mat_mul_mat_impl(
); );
macro_rules! vec_mul_mat_impl( macro_rules! vec_mul_mat_impl(
($t: ident, $v: ident, $dim: expr, $zero: expr) => ( ($t: ident, $v: ident, $dimension: expr, $zero: expr) => (
impl<N: Copy + BaseNum> Mul<$t<N>> for $v<N> { impl<N: Copy + BaseNum> Mul<$t<N>> for $v<N> {
type Output = $v<N>; type Output = $v<N>;
@ -576,8 +576,8 @@ macro_rules! vec_mul_mat_impl(
fn mul(self, right: $t<N>) -> $v<N> { fn mul(self, right: $t<N>) -> $v<N> {
let mut res : $v<N> = $zero(); let mut res : $v<N> = $zero();
for i in 0..$dim { for i in 0..$dimension {
for j in 0..$dim { for j in 0..$dimension {
unsafe { unsafe {
let val = res.at_fast(i) + self.at_fast(j) * right.at_fast((j, i)); let val = res.at_fast(i) + self.at_fast(j) * right.at_fast((j, i));
res.set_fast(i, val) res.set_fast(i, val)
@ -601,7 +601,7 @@ macro_rules! vec_mul_mat_impl(
); );
macro_rules! mat_mul_vec_impl( macro_rules! mat_mul_vec_impl(
($t: ident, $v: ident, $dim: expr, $zero: expr) => ( ($t: ident, $v: ident, $dimension: expr, $zero: expr) => (
impl<N: Copy + BaseNum> Mul<$v<N>> for $t<N> { impl<N: Copy + BaseNum> Mul<$v<N>> for $t<N> {
type Output = $v<N>; type Output = $v<N>;
@ -609,8 +609,8 @@ macro_rules! mat_mul_vec_impl(
fn mul(self, right: $v<N>) -> $v<N> { fn mul(self, right: $v<N>) -> $v<N> {
let mut res : $v<N> = $zero(); let mut res : $v<N> = $zero();
for i in 0 .. $dim { for i in 0 .. $dimension {
for j in 0 .. $dim { for j in 0 .. $dimension {
unsafe { unsafe {
let val = res.at_fast(i) + self.at_fast((i, j)) * right.at_fast(j); let val = res.at_fast(i) + self.at_fast((i, j)) * right.at_fast(j);
res.set_fast(i, val) res.set_fast(i, val)
@ -624,26 +624,26 @@ macro_rules! mat_mul_vec_impl(
) )
); );
macro_rules! pnt_mul_mat_impl( macro_rules! point_mul_mat_impl(
($t: ident, $v: ident, $dim: expr, $zero: expr) => ( ($t: ident, $v: ident, $dimension: expr, $zero: expr) => (
vec_mul_mat_impl!($t, $v, $dim, $zero); vec_mul_mat_impl!($t, $v, $dimension, $zero);
) )
); );
macro_rules! mat_mul_pnt_impl( macro_rules! mat_mul_point_impl(
($t: ident, $v: ident, $dim: expr, $zero: expr) => ( ($t: ident, $v: ident, $dimension: expr, $zero: expr) => (
mat_mul_vec_impl!($t, $v, $dim, $zero); mat_mul_vec_impl!($t, $v, $dimension, $zero);
) )
); );
macro_rules! inv_impl( macro_rules! inverse_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N: Copy + BaseNum> impl<N: Copy + BaseNum>
Inv for $t<N> { Inverse for $t<N> {
#[inline] #[inline]
fn inv(&self) -> Option<$t<N>> { fn inverse(&self) -> Option<$t<N>> {
let mut res : $t<N> = *self; let mut res : $t<N> = *self;
if res.inv_mut() { if res.inverse_mut() {
Some(res) Some(res)
} }
else { else {
@ -651,18 +651,18 @@ macro_rules! inv_impl(
} }
} }
fn inv_mut(&mut self) -> bool { fn inverse_mut(&mut self) -> bool {
let mut res: $t<N> = ::one(); let mut res: $t<N> = ::one();
// inversion using Gauss-Jordan elimination // inversion using Gauss-Jordan elimination
for k in 0..$dim { for k in 0..$dimension {
// search a non-zero value on the k-th column // search a non-zero value on the k-th column
// FIXME: would it be worth it to spend some more time searching for the // FIXME: would it be worth it to spend some more time searching for the
// max instead? // max instead?
let mut n0 = k; // index of a non-zero entry let mut n0 = k; // index of a non-zero entry
while n0 != $dim { while n0 != $dimension {
if self[(n0, k)] != ::zero() { if self[(n0, k)] != ::zero() {
break; break;
} }
@ -670,13 +670,13 @@ macro_rules! inv_impl(
n0 = n0 + 1; n0 = n0 + 1;
} }
if n0 == $dim { if n0 == $dimension {
return false return false
} }
// swap pivot line // swap pivot line
if n0 != k { if n0 != k {
for j in 0..$dim { for j in 0..$dimension {
self.swap((n0, j), (k, j)); self.swap((n0, j), (k, j));
res.swap((n0, j), (k, j)); res.swap((n0, j), (k, j));
} }
@ -684,26 +684,26 @@ macro_rules! inv_impl(
let pivot = self[(k, k)]; let pivot = self[(k, k)];
for j in k..$dim { for j in k..$dimension {
let selfval = self[(k, j)] / pivot; let selfval = self[(k, j)] / pivot;
self[(k, j)] = selfval; self[(k, j)] = selfval;
} }
for j in 0..$dim { for j in 0..$dimension {
let resval = res[(k, j)] / pivot; let resval = res[(k, j)] / pivot;
res[(k, j)] = resval; res[(k, j)] = resval;
} }
for l in 0..$dim { for l in 0..$dimension {
if l != k { if l != k {
let normalizer = self[(l, k)]; let normalizer = self[(l, k)];
for j in k..$dim { for j in k..$dimension {
let selfval = self[(l, j)] - self[(k, j)] * normalizer; let selfval = self[(l, j)] - self[(k, j)] * normalizer;
self[(l, j)] = selfval; self[(l, j)] = selfval;
} }
for j in 0..$dim { for j in 0..$dimension {
let resval = res[(l, j)] - res[(k, j)] * normalizer; let resval = res[(l, j)] - res[(k, j)] * normalizer;
res[(l, j)] = resval; res[(l, j)] = resval;
} }
@ -720,7 +720,7 @@ macro_rules! inv_impl(
); );
macro_rules! transpose_impl( macro_rules! transpose_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N: Copy> Transpose for $t<N> { impl<N: Copy> Transpose for $t<N> {
#[inline] #[inline]
fn transpose(&self) -> $t<N> { fn transpose(&self) -> $t<N> {
@ -732,7 +732,7 @@ macro_rules! transpose_impl(
#[inline] #[inline]
fn transpose_mut(&mut self) { fn transpose_mut(&mut self) {
for i in 1..$dim { for i in 1..$dimension {
for j in 0..i { for j in 0..i {
self.swap((i, j), (j, i)) self.swap((i, j), (j, i))
} }
@ -771,14 +771,14 @@ macro_rules! approx_eq_impl(
); );
macro_rules! to_homogeneous_impl( macro_rules! to_homogeneous_impl(
($t: ident, $t2: ident, $dim: expr, $dim2: expr) => ( ($t: ident, $t2: ident, $dimension: expr, $dim2: expr) => (
impl<N: BaseNum + Copy> ToHomogeneous<$t2<N>> for $t<N> { impl<N: BaseNum + Copy> ToHomogeneous<$t2<N>> for $t<N> {
#[inline] #[inline]
fn to_homogeneous(&self) -> $t2<N> { fn to_homogeneous(&self) -> $t2<N> {
let mut res: $t2<N> = ::one(); let mut res: $t2<N> = ::one();
for i in 0..$dim { for i in 0..$dimension {
for j in 0..$dim { for j in 0..$dimension {
res[(i, j)] = self[(i, j)] res[(i, j)] = self[(i, j)]
} }
} }
@ -790,14 +790,14 @@ macro_rules! to_homogeneous_impl(
); );
macro_rules! from_homogeneous_impl( macro_rules! from_homogeneous_impl(
($t: ident, $t2: ident, $dim: expr, $dim2: expr) => ( ($t: ident, $t2: ident, $dimension: expr, $dim2: expr) => (
impl<N: BaseNum + Copy> FromHomogeneous<$t2<N>> for $t<N> { impl<N: BaseNum + Copy> FromHomogeneous<$t2<N>> for $t<N> {
#[inline] #[inline]
fn from(m: &$t2<N>) -> $t<N> { fn from(m: &$t2<N>) -> $t<N> {
let mut res: $t<N> = ::one(); let mut res: $t<N> = ::one();
for i in 0..$dim { for i in 0..$dimension {
for j in 0..$dim { for j in 0..$dimension {
res[(i, j)] = m[(i, j)] res[(i, j)] = m[(i, j)]
} }
} }
@ -819,8 +819,8 @@ macro_rules! outer_impl(
#[inline] #[inline]
fn outer(&self, other: &$t<N>) -> $m<N> { fn outer(&self, other: &$t<N>) -> $m<N> {
let mut res: $m<N> = ::zero(); let mut res: $m<N> = ::zero();
for i in 0..Dim::dim(None::<$t<N>>) { for i in 0..Dimension::dimension(None::<$t<N>>) {
for j in 0..Dim::dim(None::<$t<N>>) { for j in 0..Dimension::dimension(None::<$t<N>>) {
res[(i, j)] = self[i] * other[j] res[(i, j)] = self[i] * other[j]
} }
} }
@ -843,14 +843,14 @@ macro_rules! eigen_qr_impl(
macro_rules! mean_impl( macro_rules! mean_impl(
($t: ident, $v: ident, $dim: expr) => ( ($t: ident, $v: ident, $dimension: expr) => (
impl<N: BaseNum + Cast<f64> + Clone> Mean<$v<N>> for $t<N> { impl<N: BaseNum + Cast<f64> + Clone> Mean<$v<N>> for $t<N> {
fn mean(&self) -> $v<N> { fn mean(&self) -> $v<N> {
let mut res: $v<N> = ::zero(); let mut res: $v<N> = ::zero();
let normalizer: N = Cast::from(1.0f64 / $dim as f64); let normalizer: N = Cast::from(1.0f64 / $dimension as f64);
for i in 0 .. $dim { for i in 0 .. $dimension {
for j in 0 .. $dim { for j in 0 .. $dimension {
unsafe { unsafe {
let acc = res.unsafe_at(j) + self.unsafe_at((i, j)) * normalizer; let acc = res.unsafe_at(j) + self.unsafe_at((i, j)) * normalizer;
res.unsafe_set(j, acc); res.unsafe_set(j, acc);
@ -865,7 +865,7 @@ macro_rules! mean_impl(
); );
macro_rules! mat_display_impl( macro_rules! mat_display_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> { impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
// XXX: will will not always work correctly due to rounding errors. // XXX: will will not always work correctly due to rounding errors.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@ -888,8 +888,8 @@ macro_rules! mat_display_impl(
let mut max_decimal_length = 0; let mut max_decimal_length = 0;
let mut decimal_lengths: $t<usize> = ::zero(); let mut decimal_lengths: $t<usize> = ::zero();
for i in 0 .. $dim { for i in 0 .. $dimension {
for j in 0 .. $dim { for j in 0 .. $dimension {
decimal_lengths[(i, j)] = integral_length(&self[(i, j)].clone()); decimal_lengths[(i, j)] = integral_length(&self[(i, j)].clone());
max_decimal_length = ::max(max_decimal_length, decimal_lengths[(i, j)]); max_decimal_length = ::max(max_decimal_length, decimal_lengths[(i, j)]);
} }
@ -898,11 +898,11 @@ macro_rules! mat_display_impl(
let precision = f.precision().unwrap_or(3); let precision = f.precision().unwrap_or(3);
let max_number_length = max_decimal_length + precision + 1; let max_number_length = max_decimal_length + precision + 1;
try!(writeln!(f, " ┌ {:>width$} ┐", "", width = max_number_length * $dim + $dim - 1)); try!(writeln!(f, " ┌ {:>width$} ┐", "", width = max_number_length * $dimension + $dimension - 1));
for i in 0 .. $dim { for i in 0 .. $dimension {
try!(write!(f, "")); try!(write!(f, ""));
for j in 0 .. $dim { for j in 0 .. $dimension {
let number_length = decimal_lengths[(i, j)] + precision + 1; let number_length = decimal_lengths[(i, j)] + precision + 1;
let pad = max_number_length - number_length; let pad = max_number_length - number_length;
try!(write!(f, " {:>thepad$}", "", thepad = pad)); try!(write!(f, " {:>thepad$}", "", thepad = pad));
@ -911,7 +911,7 @@ macro_rules! mat_display_impl(
try!(writeln!(f, "")); try!(writeln!(f, ""));
} }
writeln!(f, " └ {:>width$} ┘", "", width = max_number_length * $dim + $dim - 1) writeln!(f, " └ {:>width$} ┘", "", width = max_number_length * $dimension + $dimension - 1)
} }
} }
) )

View File

@ -1,49 +1,49 @@
//! Data structures and implementations. //! Data structures and implementations.
pub use self::dmat::{DMat, DMat1, DMat2, DMat3, DMat4, DMat5, DMat6}; pub use self::dmatrix::{DMatrix, DMatrix1, DMatrix2, DMatrix3, DMatrix4, DMatrix5, DMatrix6};
pub use self::dvec::{DVec, DVec1, DVec2, DVec3, DVec4, DVec5, DVec6}; pub use self::dvector::{DVector, DVector1, DVector2, DVector3, DVector4, DVector5, DVector6};
pub use self::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6}; pub use self::vector::{Vector1, Vector2, Vector3, Vector4, Vector5, Vector6};
pub use self::pnt::{Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6}; pub use self::point::{Point1, Point2, Point3, Point4, Point5, Point6};
pub use self::mat::{Identity, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6}; pub use self::matrix::{Identity, Matrix1, Matrix2, Matrix3, Matrix4, Matrix5, Matrix6};
pub use self::rot::{Rot2, Rot3}; pub use self::rotation::{Rotation2, Rotation3};
pub use self::iso::{Iso2, Iso3}; pub use self::isometry::{Isometry2, Isometry3};
pub use self::sim::{Sim2, Sim3}; pub use self::similarity::{Similarity2, Similarity3};
pub use self::persp::{Persp3, PerspMat3}; pub use self::perspective::{Perspective3, PerspectiveMatrix3};
pub use self::ortho::{Ortho3, OrthoMat3}; pub use self::orthographic::{Orthographic3, OrthographicMatrix3};
pub use self::quat::{Quat, UnitQuat}; pub use self::quaternion::{Quaternion, UnitQuaternion};
#[cfg(feature="generic_sizes")] #[cfg(feature="generic_sizes")]
pub use self::vecn::VecN; pub use self::vectorn::VectorN;
mod dmat_macros; mod dmatrix_macros;
mod dmat; mod dmatrix;
mod vecn_macros; mod vectorn_macros;
#[cfg(feature="generic_sizes")] #[cfg(feature="generic_sizes")]
mod vecn; mod vectorn;
mod dvec_macros; mod dvector_macros;
mod dvec; mod dvector;
mod vec_macros; mod vector_macros;
mod vec; mod vector;
mod pnt_macros; mod point_macros;
mod pnt; mod point;
mod quat; mod quaternion;
mod mat_macros; mod matrix_macros;
mod mat; mod matrix;
mod rot_macros; mod rotation_macros;
mod rot; mod rotation;
mod iso_macros; mod isometry_macros;
mod iso; mod isometry;
mod sim_macros; mod similarity_macros;
mod sim; mod similarity;
mod persp; mod perspective;
mod ortho; mod orthographic;
// Specialization for some 1d, 2d and 3d operations. // Specialization for some 1d, 2d and 3d operations.
#[doc(hidden)] #[doc(hidden)]
mod spec { mod specializations {
mod identity; mod identity;
mod mat; mod matrix;
mod vec; mod vector;
mod primitives; mod primitives;
// mod complex; // mod complex;
} }

View File

@ -1,5 +1,5 @@
use traits::structure::{BaseFloat, Cast}; use traits::structure::{BaseFloat, Cast};
use structs::{Pnt3, Vec3, Mat4}; use structs::{Point3, Vector3, Matrix4};
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};
@ -11,7 +11,7 @@ use quickcheck::{Arbitrary, Gen};
/// `(-1, -1, -1)` to `(1, 1, 1)`. Reading or modifying its individual properties is cheap but /// `(-1, -1, -1)` to `(1, 1, 1)`. Reading or modifying its individual properties is cheap but
/// applying the transformation is costly. /// applying the transformation is costly.
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)] #[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct Ortho3<N> { pub struct Orthographic3<N> {
left: N, left: N,
right: N, right: N,
bottom: N, bottom: N,
@ -26,18 +26,18 @@ pub struct Ortho3<N> {
/// `(-1, -1, -1)` to `(1, 1, 1)`. Reading or modifying its individual properties is costly but /// `(-1, -1, -1)` to `(1, 1, 1)`. Reading or modifying its individual properties is costly but
/// applying the transformation is cheap. /// applying the transformation is cheap.
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)] #[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct OrthoMat3<N> { pub struct OrthographicMatrix3<N> {
mat: Mat4<N> matrix: Matrix4<N>
} }
impl<N: BaseFloat> Ortho3<N> { impl<N: BaseFloat> Orthographic3<N> {
/// Creates a new 3D orthographic projection. /// Creates a new 3D orthographic projection.
pub fn new(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Ortho3<N> { pub fn new(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Orthographic3<N> {
assert!(!::is_zero(&(zfar - znear))); assert!(!::is_zero(&(zfar - znear)));
assert!(!::is_zero(&(left - right))); assert!(!::is_zero(&(left - right)));
assert!(!::is_zero(&(top - bottom))); assert!(!::is_zero(&(top - bottom)));
Ortho3 { Orthographic3 {
left: left, left: left,
right: right, right: right,
bottom: bottom, bottom: bottom,
@ -48,30 +48,30 @@ impl<N: BaseFloat> Ortho3<N> {
} }
/// Builds a 4D projection matrix (using homogeneous coordinates) for this projection. /// Builds a 4D projection matrix (using homogeneous coordinates) for this projection.
pub fn to_mat(&self) -> Mat4<N> { pub fn to_matrix(&self) -> Matrix4<N> {
self.to_persp_mat().mat self.to_orthographic_matrix().matrix
} }
/// Build a `OrthoMat3` representing this projection. /// Build a `OrthographicMatrix3` representing this projection.
pub fn to_persp_mat(&self) -> OrthoMat3<N> { pub fn to_orthographic_matrix(&self) -> OrthographicMatrix3<N> {
OrthoMat3::new(self.left, self.right, self.bottom, self.top, self.znear, self.zfar) OrthographicMatrix3::new(self.left, self.right, self.bottom, self.top, self.znear, self.zfar)
} }
} }
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for Ortho3<N> { impl<N: Arbitrary + BaseFloat> Arbitrary for Orthographic3<N> {
fn arbitrary<G: Gen>(g: &mut G) -> Ortho3<N> { fn arbitrary<G: Gen>(g: &mut G) -> Orthographic3<N> {
let left = Arbitrary::arbitrary(g); let left = Arbitrary::arbitrary(g);
let right = reject(g, |x: &N| *x > left); let right = reject(g, |x: &N| *x > left);
let bottom = Arbitrary::arbitrary(g); let bottom = Arbitrary::arbitrary(g);
let top = reject(g, |x: &N| *x > bottom); let top = reject(g, |x: &N| *x > bottom);
let znear = Arbitrary::arbitrary(g); let znear = Arbitrary::arbitrary(g);
let zfar = reject(g, |x: &N| *x > znear); let zfar = reject(g, |x: &N| *x > znear);
Ortho3::new(left, right, bottom, top, znear, zfar) Orthographic3::new(left, right, bottom, top, znear, zfar)
} }
} }
impl<N: BaseFloat + Clone> Ortho3<N> { impl<N: BaseFloat + Clone> Orthographic3<N> {
/// The smallest x-coordinate of the view cuboid. /// The smallest x-coordinate of the view cuboid.
#[inline] #[inline]
pub fn left(&self) -> N { pub fn left(&self) -> N {
@ -152,29 +152,29 @@ impl<N: BaseFloat + Clone> Ortho3<N> {
/// Projects a point. /// Projects a point.
#[inline] #[inline]
pub fn project_pnt(&self, p: &Pnt3<N>) -> Pnt3<N> { pub fn project_point(&self, p: &Point3<N>) -> Point3<N> {
// FIXME: optimize that // FIXME: optimize that
self.to_persp_mat().project_pnt(p) self.to_orthographic_matrix().project_point(p)
} }
/// Projects a vector. /// Projects a vector.
#[inline] #[inline]
pub fn project_vec(&self, p: &Vec3<N>) -> Vec3<N> { pub fn project_vector(&self, p: &Vector3<N>) -> Vector3<N> {
// FIXME: optimize that // FIXME: optimize that
self.to_persp_mat().project_vec(p) self.to_orthographic_matrix().project_vector(p)
} }
} }
impl<N: BaseFloat> OrthoMat3<N> { impl<N: BaseFloat> OrthographicMatrix3<N> {
/// Creates a new orthographic projection matrix. /// Creates a new orthographic projection matrix.
pub fn new(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> OrthoMat3<N> { pub fn new(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> OrthographicMatrix3<N> {
assert!(left < right, "The left corner must be farther than the right corner."); assert!(left < right, "The left corner must be farther than the right corner.");
assert!(bottom < top, "The top corner must be higher than the bottom corner."); assert!(bottom < top, "The top corner must be higher than the bottom corner.");
assert!(znear < zfar, "The far plane must be farther than the near plane."); assert!(znear < zfar, "The far plane must be farther than the near plane.");
let mat: Mat4<N> = ::one(); let matrix: Matrix4<N> = ::one();
let mut res = OrthoMat3 { mat: mat }; let mut res = OrthographicMatrix3 { matrix: matrix };
res.set_left_and_right(left, right); res.set_left_and_right(left, right);
res.set_bottom_and_top(bottom, top); res.set_bottom_and_top(bottom, top);
res.set_znear_and_zfar(znear, zfar); res.set_znear_and_zfar(znear, zfar);
@ -183,7 +183,7 @@ impl<N: BaseFloat> OrthoMat3<N> {
} }
/// Creates a new orthographic projection matrix from an aspect ratio and the vertical field of view. /// Creates a new orthographic projection matrix from an aspect ratio and the vertical field of view.
pub fn new_with_fov(aspect: N, vfov: N, znear: N, zfar: N) -> OrthoMat3<N> { pub fn new_with_fov(aspect: N, vfov: N, znear: N, zfar: N) -> OrthographicMatrix3<N> {
assert!(znear < zfar, "The far plane must be farther than the near plane."); assert!(znear < zfar, "The far plane must be farther than the near plane.");
assert!(!::is_zero(&aspect)); assert!(!::is_zero(&aspect));
@ -192,59 +192,59 @@ impl<N: BaseFloat> OrthoMat3<N> {
let width = zfar * (vfov / _2).tan(); let width = zfar * (vfov / _2).tan();
let height = width / aspect; let height = width / aspect;
OrthoMat3::new(-width / _2, width / _2, -height / _2, height / _2, znear, zfar) OrthographicMatrix3::new(-width / _2, width / _2, -height / _2, height / _2, znear, zfar)
} }
/// Creates a new orthographic matrix from a 4D matrix. /// Creates a new orthographic matrix from a 4D matrix.
/// ///
/// This is unsafe because the input matrix is not checked to be a orthographic projection. /// This is unsafe because the input matrix is not checked to be a orthographic projection.
#[inline] #[inline]
pub unsafe fn new_with_mat(mat: Mat4<N>) -> OrthoMat3<N> { pub unsafe fn new_with_matrix(matrix: Matrix4<N>) -> OrthographicMatrix3<N> {
OrthoMat3 { OrthographicMatrix3 {
mat: mat matrix: matrix
} }
} }
/// Returns a reference to the 4D matrix (using homogeneous coordinates) of this projection. /// Returns a reference to the 4D matrix (using homogeneous coordinates) of this projection.
#[inline] #[inline]
pub fn as_mat<'a>(&'a self) -> &'a Mat4<N> { pub fn as_matrix<'a>(&'a self) -> &'a Matrix4<N> {
&self.mat &self.matrix
} }
/// The smallest x-coordinate of the view cuboid. /// The smallest x-coordinate of the view cuboid.
#[inline] #[inline]
pub fn left(&self) -> N { pub fn left(&self) -> N {
(-::one::<N>() - self.mat.m14) / self.mat.m11 (-::one::<N>() - self.matrix.m14) / self.matrix.m11
} }
/// The largest x-coordinate of the view cuboid. /// The largest x-coordinate of the view cuboid.
#[inline] #[inline]
pub fn right(&self) -> N { pub fn right(&self) -> N {
(::one::<N>() - self.mat.m14) / self.mat.m11 (::one::<N>() - self.matrix.m14) / self.matrix.m11
} }
/// The smallest y-coordinate of the view cuboid. /// The smallest y-coordinate of the view cuboid.
#[inline] #[inline]
pub fn bottom(&self) -> N { pub fn bottom(&self) -> N {
(-::one::<N>() - self.mat.m24) / self.mat.m22 (-::one::<N>() - self.matrix.m24) / self.matrix.m22
} }
/// The largest y-coordinate of the view cuboid. /// The largest y-coordinate of the view cuboid.
#[inline] #[inline]
pub fn top(&self) -> N { pub fn top(&self) -> N {
(::one::<N>() - self.mat.m24) / self.mat.m22 (::one::<N>() - self.matrix.m24) / self.matrix.m22
} }
/// The near plane offset of the view cuboid. /// The near plane offset of the view cuboid.
#[inline] #[inline]
pub fn znear(&self) -> N { pub fn znear(&self) -> N {
(::one::<N>() + self.mat.m34) / self.mat.m33 (::one::<N>() + self.matrix.m34) / self.matrix.m33
} }
/// The far plane offset of the view cuboid. /// The far plane offset of the view cuboid.
#[inline] #[inline]
pub fn zfar(&self) -> N { pub fn zfar(&self) -> N {
(-::one::<N>() + self.mat.m34) / self.mat.m33 (-::one::<N>() + self.matrix.m34) / self.matrix.m33
} }
/// Sets the smallest x-coordinate of the view cuboid. /// Sets the smallest x-coordinate of the view cuboid.
@ -293,65 +293,65 @@ impl<N: BaseFloat> OrthoMat3<N> {
#[inline] #[inline]
pub fn set_left_and_right(&mut self, left: N, right: N) { pub fn set_left_and_right(&mut self, left: N, right: N) {
assert!(left < right, "The left corner must be farther than the right corner."); assert!(left < right, "The left corner must be farther than the right corner.");
self.mat.m11 = <N as Cast<f64>>::from(2.0) / (right - left); self.matrix.m11 = <N as Cast<f64>>::from(2.0) / (right - left);
self.mat.m14 = -(right + left) / (right - left); self.matrix.m14 = -(right + left) / (right - left);
} }
/// Sets the view cuboid coordinates along the `y` axis. /// Sets the view cuboid coordinates along the `y` axis.
#[inline] #[inline]
pub fn set_bottom_and_top(&mut self, bottom: N, top: N) { pub fn set_bottom_and_top(&mut self, bottom: N, top: N) {
assert!(bottom < top, "The top corner must be higher than the bottom corner."); assert!(bottom < top, "The top corner must be higher than the bottom corner.");
self.mat.m22 = <N as Cast<f64>>::from(2.0) / (top - bottom); self.matrix.m22 = <N as Cast<f64>>::from(2.0) / (top - bottom);
self.mat.m24 = -(top + bottom) / (top - bottom); self.matrix.m24 = -(top + bottom) / (top - bottom);
} }
/// Sets the near and far plane offsets of the view cuboid. /// Sets the near and far plane offsets of the view cuboid.
#[inline] #[inline]
pub fn set_znear_and_zfar(&mut self, znear: N, zfar: N) { pub fn set_znear_and_zfar(&mut self, znear: N, zfar: N) {
assert!(!::is_zero(&(zfar - znear))); assert!(!::is_zero(&(zfar - znear)));
self.mat.m33 = -<N as Cast<f64>>::from(2.0) / (zfar - znear); self.matrix.m33 = -<N as Cast<f64>>::from(2.0) / (zfar - znear);
self.mat.m34 = -(zfar + znear) / (zfar - znear); self.matrix.m34 = -(zfar + znear) / (zfar - znear);
} }
/// Projects a point. /// Projects a point.
#[inline] #[inline]
pub fn project_pnt(&self, p: &Pnt3<N>) -> Pnt3<N> { pub fn project_point(&self, p: &Point3<N>) -> Point3<N> {
Pnt3::new( Point3::new(
self.mat.m11 * p.x + self.mat.m14, self.matrix.m11 * p.x + self.matrix.m14,
self.mat.m22 * p.y + self.mat.m24, self.matrix.m22 * p.y + self.matrix.m24,
self.mat.m33 * p.z + self.mat.m34 self.matrix.m33 * p.z + self.matrix.m34
) )
} }
/// Projects a vector. /// Projects a vector.
#[inline] #[inline]
pub fn project_vec(&self, p: &Vec3<N>) -> Vec3<N> { pub fn project_vector(&self, p: &Vector3<N>) -> Vector3<N> {
Vec3::new( Vector3::new(
self.mat.m11 * p.x, self.matrix.m11 * p.x,
self.mat.m22 * p.y, self.matrix.m22 * p.y,
self.mat.m33 * p.z self.matrix.m33 * p.z
) )
} }
} }
impl<N: BaseFloat + Clone> OrthoMat3<N> { impl<N: BaseFloat + Clone> OrthographicMatrix3<N> {
/// Returns the 4D matrix (using homogeneous coordinates) of this projection. /// Returns the 4D matrix (using homogeneous coordinates) of this projection.
#[inline] #[inline]
pub fn to_mat<'a>(&'a self) -> Mat4<N> { pub fn to_matrix<'a>(&'a self) -> Matrix4<N> {
self.mat.clone() self.matrix.clone()
} }
} }
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for OrthoMat3<N> { impl<N: Arbitrary + BaseFloat> Arbitrary for OrthographicMatrix3<N> {
fn arbitrary<G: Gen>(g: &mut G) -> OrthoMat3<N> { fn arbitrary<G: Gen>(g: &mut G) -> OrthographicMatrix3<N> {
let x: Ortho3<N> = Arbitrary::arbitrary(g); let x: Orthographic3<N> = Arbitrary::arbitrary(g);
x.to_persp_mat() x.to_orthographic_matrix()
} }
} }
/// Simple helper function for rejection sampling /// Similarityple helper function for rejection sampling
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
#[inline] #[inline]
pub fn reject<G: Gen, F: FnMut(&T) -> bool, T: Arbitrary>(g: &mut G, f: F) -> T { pub fn reject<G: Gen, F: FnMut(&T) -> bool, T: Arbitrary>(g: &mut G, f: F) -> T {

View File

@ -1,5 +1,5 @@
use traits::structure::BaseFloat; use traits::structure::BaseFloat;
use structs::{Pnt3, Vec3, Mat4}; use structs::{Point3, Vector3, Matrix4};
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};
@ -11,9 +11,9 @@ use quickcheck::{Arbitrary, Gen};
/// `(1, 1, 1)`. Reading or modifying its individual properties is cheap but applying the /// `(1, 1, 1)`. Reading or modifying its individual properties is cheap but applying the
/// transformation is costly. /// transformation is costly.
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)] #[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct Persp3<N> { pub struct Perspective3<N> {
aspect: N, aspect: N,
fovy: N, fovy: N,
znear: N, znear: N,
zfar: N zfar: N
} }
@ -24,46 +24,46 @@ pub struct Persp3<N> {
/// `(1, 1, 1)`. Reading or modifying its individual properties is costly but applying the /// `(1, 1, 1)`. Reading or modifying its individual properties is costly but applying the
/// transformation is cheap. /// transformation is cheap.
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)] #[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct PerspMat3<N> { pub struct PerspectiveMatrix3<N> {
mat: Mat4<N> matrix: Matrix4<N>
} }
impl<N: BaseFloat> Persp3<N> { impl<N: BaseFloat> Perspective3<N> {
/// Creates a new 3D perspective projection. /// Creates a new 3D perspective projection.
pub fn new(aspect: N, fovy: N, znear: N, zfar: N) -> Persp3<N> { pub fn new(aspect: N, fovy: N, znear: N, zfar: N) -> Perspective3<N> {
assert!(!::is_zero(&(zfar - znear))); assert!(!::is_zero(&(zfar - znear)));
assert!(!::is_zero(&aspect)); assert!(!::is_zero(&aspect));
Persp3 { Perspective3 {
aspect: aspect, aspect: aspect,
fovy: fovy, fovy: fovy,
znear: znear, znear: znear,
zfar: zfar zfar: zfar
} }
} }
/// Builds a 4D projection matrix (using homogeneous coordinates) for this projection. /// Builds a 4D projection matrix (using homogeneous coordinates) for this projection.
pub fn to_mat(&self) -> Mat4<N> { pub fn to_matrix(&self) -> Matrix4<N> {
self.to_persp_mat().mat self.to_perspective_matrix().matrix
} }
/// Build a `PerspMat3` representing this projection. /// Build a `PerspectiveMatrix3` representing this projection.
pub fn to_persp_mat(&self) -> PerspMat3<N> { pub fn to_perspective_matrix(&self) -> PerspectiveMatrix3<N> {
PerspMat3::new(self.aspect, self.fovy, self.znear, self.zfar) PerspectiveMatrix3::new(self.aspect, self.fovy, self.znear, self.zfar)
} }
} }
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for Persp3<N> { impl<N: Arbitrary + BaseFloat> Arbitrary for Perspective3<N> {
fn arbitrary<G: Gen>(g: &mut G) -> Persp3<N> { fn arbitrary<G: Gen>(g: &mut G) -> Perspective3<N> {
use structs::ortho::reject; use structs::orthographic::reject;
let znear = Arbitrary::arbitrary(g); let znear = Arbitrary::arbitrary(g);
let zfar = reject(g, |&x: &N| !::is_zero(&(x - znear))); let zfar = reject(g, |&x: &N| !::is_zero(&(x - znear)));
Persp3::new(Arbitrary::arbitrary(g), Arbitrary::arbitrary(g), znear, zfar) Perspective3::new(Arbitrary::arbitrary(g), Arbitrary::arbitrary(g), znear, zfar)
} }
} }
impl<N: BaseFloat + Clone> Persp3<N> { impl<N: BaseFloat + Clone> Perspective3<N> {
/// Gets the `width / height` aspect ratio. /// Gets the `width / height` aspect ratio.
#[inline] #[inline]
pub fn aspect(&self) -> N { pub fn aspect(&self) -> N {
@ -122,33 +122,33 @@ impl<N: BaseFloat + Clone> Persp3<N> {
/// Projects a point. /// Projects a point.
#[inline] #[inline]
pub fn project_pnt(&self, p: &Pnt3<N>) -> Pnt3<N> { pub fn project_point(&self, p: &Point3<N>) -> Point3<N> {
// FIXME: optimize that // FIXME: optimize that
self.to_persp_mat().project_pnt(p) self.to_perspective_matrix().project_point(p)
} }
/// Projects a vector. /// Projects a vector.
#[inline] #[inline]
pub fn project_vec(&self, p: &Vec3<N>) -> Vec3<N> { pub fn project_vector(&self, p: &Vector3<N>) -> Vector3<N> {
// FIXME: optimize that // FIXME: optimize that
self.to_persp_mat().project_vec(p) self.to_perspective_matrix().project_vector(p)
} }
} }
impl<N: BaseFloat> PerspMat3<N> { impl<N: BaseFloat> PerspectiveMatrix3<N> {
/// Creates a new perspective matrix from the aspect ratio, y field of view, and near/far planes. /// Creates a new perspective matrix from the aspect ratio, y field of view, and near/far planes.
pub fn new(aspect: N, fovy: N, znear: N, zfar: N) -> PerspMat3<N> { pub fn new(aspect: N, fovy: N, znear: N, zfar: N) -> PerspectiveMatrix3<N> {
assert!(!::is_zero(&(znear - zfar))); assert!(!::is_zero(&(znear - zfar)));
assert!(!::is_zero(&aspect)); assert!(!::is_zero(&aspect));
let mat: Mat4<N> = ::one(); let matrix: Matrix4<N> = ::one();
let mut res = PerspMat3 { mat: mat }; let mut res = PerspectiveMatrix3 { matrix: matrix };
res.set_fovy(fovy); res.set_fovy(fovy);
res.set_aspect(aspect); res.set_aspect(aspect);
res.set_znear_and_zfar(znear, zfar); res.set_znear_and_zfar(znear, zfar);
res.mat.m44 = ::zero(); res.matrix.m44 = ::zero();
res.mat.m43 = -::one::<N>(); res.matrix.m43 = -::one::<N>();
res res
} }
@ -157,22 +157,22 @@ impl<N: BaseFloat> PerspMat3<N> {
/// ///
/// This is unsafe because the input matrix is not checked to be a perspective projection. /// This is unsafe because the input matrix is not checked to be a perspective projection.
#[inline] #[inline]
pub unsafe fn new_with_mat(mat: Mat4<N>) -> PerspMat3<N> { pub unsafe fn new_with_matrix(matrix: Matrix4<N>) -> PerspectiveMatrix3<N> {
PerspMat3 { PerspectiveMatrix3 {
mat: mat matrix: matrix
} }
} }
/// Returns a reference to the 4D matrix (using homogeneous coordinates) of this projection. /// Returns a reference to the 4D matrix (using homogeneous coordinates) of this projection.
#[inline] #[inline]
pub fn as_mat<'a>(&'a self) -> &'a Mat4<N> { pub fn as_matrix<'a>(&'a self) -> &'a Matrix4<N> {
&self.mat &self.matrix
} }
/// Gets the `width / height` aspect ratio of the view frustrum. /// Gets the `width / height` aspect ratio of the view frustrum.
#[inline] #[inline]
pub fn aspect(&self) -> N { pub fn aspect(&self) -> N {
self.mat.m22 / self.mat.m11 self.matrix.m22 / self.matrix.m11
} }
/// Gets the y field of view of the view frustrum. /// Gets the y field of view of the view frustrum.
@ -181,7 +181,7 @@ impl<N: BaseFloat> PerspMat3<N> {
let _1: N = ::one(); let _1: N = ::one();
let _2 = _1 + _1; let _2 = _1 + _1;
(_1 / self.mat.m22).atan() * _2 (_1 / self.matrix.m22).atan() * _2
} }
/// Gets the near plane offset of the view frustrum. /// Gets the near plane offset of the view frustrum.
@ -189,9 +189,9 @@ impl<N: BaseFloat> PerspMat3<N> {
pub fn znear(&self) -> N { pub fn znear(&self) -> N {
let _1: N = ::one(); let _1: N = ::one();
let _2 = _1 + _1; let _2 = _1 + _1;
let ratio = (-self.mat.m33 + _1) / (-self.mat.m33 - _1); let ratio = (-self.matrix.m33 + _1) / (-self.matrix.m33 - _1);
self.mat.m34 / (_2 * ratio) - self.mat.m34 / _2 self.matrix.m34 / (_2 * ratio) - self.matrix.m34 / _2
} }
/// Gets the far plane offset of the view frustrum. /// Gets the far plane offset of the view frustrum.
@ -199,9 +199,9 @@ impl<N: BaseFloat> PerspMat3<N> {
pub fn zfar(&self) -> N { pub fn zfar(&self) -> N {
let _1: N = ::one(); let _1: N = ::one();
let _2 = _1 + _1; let _2 = _1 + _1;
let ratio = (-self.mat.m33 + _1) / (-self.mat.m33 - _1); let ratio = (-self.matrix.m33 + _1) / (-self.matrix.m33 - _1);
(self.mat.m34 - ratio * self.mat.m34) / _2 (self.matrix.m34 - ratio * self.matrix.m34) / _2
} }
// FIXME: add a method to retrieve znear and zfar simultaneously? // FIXME: add a method to retrieve znear and zfar simultaneously?
@ -211,7 +211,7 @@ impl<N: BaseFloat> PerspMat3<N> {
#[inline] #[inline]
pub fn set_aspect(&mut self, aspect: N) { pub fn set_aspect(&mut self, aspect: N) {
assert!(!::is_zero(&aspect)); assert!(!::is_zero(&aspect));
self.mat.m11 = self.mat.m22 / aspect; self.matrix.m11 = self.matrix.m22 / aspect;
} }
/// Updates this projection with a new y field of view of the view frustrum. /// Updates this projection with a new y field of view of the view frustrum.
@ -220,9 +220,9 @@ impl<N: BaseFloat> PerspMat3<N> {
let _1: N = ::one(); let _1: N = ::one();
let _2 = _1 + _1; let _2 = _1 + _1;
let old_m22 = self.mat.m22.clone(); let old_m22 = self.matrix.m22.clone();
self.mat.m22 = _1 / (fovy / _2).tan(); self.matrix.m22 = _1 / (fovy / _2).tan();
self.mat.m11 = self.mat.m11 * (self.mat.m22 / old_m22); self.matrix.m11 = self.matrix.m11 * (self.matrix.m22 / old_m22);
} }
/// Updates this projection matrix with a new near plane offset of the view frustrum. /// Updates this projection matrix with a new near plane offset of the view frustrum.
@ -245,47 +245,47 @@ impl<N: BaseFloat> PerspMat3<N> {
let _1: N = ::one(); let _1: N = ::one();
let _2 = _1 + _1; let _2 = _1 + _1;
self.mat.m33 = (zfar + znear) / (znear - zfar); self.matrix.m33 = (zfar + znear) / (znear - zfar);
self.mat.m34 = zfar * znear * _2 / (znear - zfar); self.matrix.m34 = zfar * znear * _2 / (znear - zfar);
} }
/// Projects a point. /// Projects a point.
#[inline] #[inline]
pub fn project_pnt(&self, p: &Pnt3<N>) -> Pnt3<N> { pub fn project_point(&self, p: &Point3<N>) -> Point3<N> {
let _1: N = ::one(); let _1: N = ::one();
let inv_denom = -_1 / p.z; let inverse_denom = -_1 / p.z;
Pnt3::new( Point3::new(
self.mat.m11 * p.x * inv_denom, self.matrix.m11 * p.x * inverse_denom,
self.mat.m22 * p.y * inv_denom, self.matrix.m22 * p.y * inverse_denom,
(self.mat.m33 * p.z + self.mat.m34) * inv_denom (self.matrix.m33 * p.z + self.matrix.m34) * inverse_denom
) )
} }
/// Projects a vector. /// Projects a vector.
#[inline] #[inline]
pub fn project_vec(&self, p: &Vec3<N>) -> Vec3<N> { pub fn project_vector(&self, p: &Vector3<N>) -> Vector3<N> {
let _1: N = ::one(); let _1: N = ::one();
let inv_denom = -_1 / p.z; let inverse_denom = -_1 / p.z;
Vec3::new( Vector3::new(
self.mat.m11 * p.x * inv_denom, self.matrix.m11 * p.x * inverse_denom,
self.mat.m22 * p.y * inv_denom, self.matrix.m22 * p.y * inverse_denom,
self.mat.m33 self.matrix.m33
) )
} }
} }
impl<N: BaseFloat + Clone> PerspMat3<N> { impl<N: BaseFloat + Clone> PerspectiveMatrix3<N> {
/// Returns the 4D matrix (using homogeneous coordinates) of this projection. /// Returns the 4D matrix (using homogeneous coordinates) of this projection.
#[inline] #[inline]
pub fn to_mat<'a>(&'a self) -> Mat4<N> { pub fn to_matrix<'a>(&'a self) -> Matrix4<N> {
self.mat.clone() self.matrix.clone()
} }
} }
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for PerspMat3<N> { impl<N: Arbitrary + BaseFloat> Arbitrary for PerspectiveMatrix3<N> {
fn arbitrary<G: Gen>(g: &mut G) -> PerspMat3<N> { fn arbitrary<G: Gen>(g: &mut G) -> PerspectiveMatrix3<N> {
let x: Persp3<N> = Arbitrary::arbitrary(g); let x: Perspective3<N> = Arbitrary::arbitrary(g);
x.to_persp_mat() x.to_perspective_matrix()
} }
} }

View File

@ -1,309 +0,0 @@
//! Points with dimension known at compile-time.
use std::mem;
use std::fmt;
use std::slice::{Iter, IterMut};
use std::iter::{Iterator, FromIterator, IntoIterator};
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
use rand::{Rand, Rng};
use num::{Zero, One};
use traits::operations::{ApproxEq, POrd, POrdering, Axpy};
use traits::structure::{Cast, Dim, Indexable, Iterable, IterableMut, PntAsVec, Shape,
NumPnt, FloatPnt, BaseFloat, BaseNum, Bounded, Repeat};
use traits::geometry::{Orig, FromHomogeneous, ToHomogeneous};
use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
/// Point of dimension 1.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Pnt1<N> {
/// First component of the point.
pub x: N
}
new_impl!(Pnt1, x);
orig_impl!(Pnt1, x);
pord_impl!(Pnt1, x,);
scalar_mul_impl!(Pnt1, x);
scalar_div_impl!(Pnt1, x);
scalar_add_impl!(Pnt1, x);
scalar_sub_impl!(Pnt1, x);
vec_cast_impl!(Pnt1, x);
conversion_impl!(Pnt1, 1);
index_impl!(Pnt1);
indexable_impl!(Pnt1, 1);
at_fast_impl!(Pnt1, 1);
repeat_impl!(Pnt1, val, x);
dim_impl!(Pnt1, 1);
container_impl!(Pnt1);
pnt_as_vec_impl!(Pnt1, Vec1, x);
pnt_sub_impl!(Pnt1, Vec1);
neg_impl!(Pnt1, x);
pnt_add_vec_impl!(Pnt1, Vec1, x);
pnt_sub_vec_impl!(Pnt1, Vec1, x);
approx_eq_impl!(Pnt1, x);
from_iterator_impl!(Pnt1, iterator);
bounded_impl!(Pnt1, x);
axpy_impl!(Pnt1, x);
iterable_impl!(Pnt1, 1);
iterable_mut_impl!(Pnt1, 1);
pnt_to_homogeneous_impl!(Pnt1, Pnt2, y, x);
pnt_from_homogeneous_impl!(Pnt1, Pnt2, y, x);
num_float_pnt_impl!(Pnt1, Vec1);
arbitrary_pnt_impl!(Pnt1, x);
rand_impl!(Pnt1, x);
pnt_display_impl!(Pnt1);
/// Point of dimension 2.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Pnt2<N> {
/// First component of the point.
pub x: N,
/// Second component of the point.
pub y: N
}
new_impl!(Pnt2, x, y);
orig_impl!(Pnt2, x, y);
pord_impl!(Pnt2, x, y);
scalar_mul_impl!(Pnt2, x, y);
scalar_div_impl!(Pnt2, x, y);
scalar_add_impl!(Pnt2, x, y);
scalar_sub_impl!(Pnt2, x, y);
vec_cast_impl!(Pnt2, x, y);
conversion_impl!(Pnt2, 2);
index_impl!(Pnt2);
indexable_impl!(Pnt2, 2);
at_fast_impl!(Pnt2, 2);
repeat_impl!(Pnt2, val, x, y);
dim_impl!(Pnt2, 2);
container_impl!(Pnt2);
pnt_as_vec_impl!(Pnt2, Vec2, x, y);
pnt_sub_impl!(Pnt2, Vec2);
neg_impl!(Pnt2, x, y);
pnt_add_vec_impl!(Pnt2, Vec2, x, y);
pnt_sub_vec_impl!(Pnt2, Vec2, x, y);
approx_eq_impl!(Pnt2, x, y);
from_iterator_impl!(Pnt2, iterator, iterator);
bounded_impl!(Pnt2, x, y);
axpy_impl!(Pnt2, x, y);
iterable_impl!(Pnt2, 2);
iterable_mut_impl!(Pnt2, 2);
pnt_to_homogeneous_impl!(Pnt2, Pnt3, z, x, y);
pnt_from_homogeneous_impl!(Pnt2, Pnt3, z, x, y);
num_float_pnt_impl!(Pnt2, Vec2);
arbitrary_pnt_impl!(Pnt2, x, y);
rand_impl!(Pnt2, x, y);
pnt_display_impl!(Pnt2);
/// Point of dimension 3.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Pnt3<N> {
/// First component of the point.
pub x: N,
/// Second component of the point.
pub y: N,
/// Third component of the point.
pub z: N
}
new_impl!(Pnt3, x, y, z);
orig_impl!(Pnt3, x, y, z);
pord_impl!(Pnt3, x, y, z);
scalar_mul_impl!(Pnt3, x, y, z);
scalar_div_impl!(Pnt3, x, y, z);
scalar_add_impl!(Pnt3, x, y, z);
scalar_sub_impl!(Pnt3, x, y, z);
vec_cast_impl!(Pnt3, x, y, z);
conversion_impl!(Pnt3, 3);
index_impl!(Pnt3);
indexable_impl!(Pnt3, 3);
at_fast_impl!(Pnt3, 3);
repeat_impl!(Pnt3, val, x, y, z);
dim_impl!(Pnt3, 3);
container_impl!(Pnt3);
pnt_as_vec_impl!(Pnt3, Vec3, x, y, z);
pnt_sub_impl!(Pnt3, Vec3);
neg_impl!(Pnt3, x, y, z);
pnt_add_vec_impl!(Pnt3, Vec3, x, y, z);
pnt_sub_vec_impl!(Pnt3, Vec3, x, y, z);
approx_eq_impl!(Pnt3, x, y, z);
from_iterator_impl!(Pnt3, iterator, iterator, iterator);
bounded_impl!(Pnt3, x, y, z);
axpy_impl!(Pnt3, x, y, z);
iterable_impl!(Pnt3, 3);
iterable_mut_impl!(Pnt3, 3);
pnt_to_homogeneous_impl!(Pnt3, Pnt4, w, x, y, z);
pnt_from_homogeneous_impl!(Pnt3, Pnt4, w, x, y, z);
num_float_pnt_impl!(Pnt3, Vec3);
arbitrary_pnt_impl!(Pnt3, x, y, z);
rand_impl!(Pnt3, x, y, z);
pnt_display_impl!(Pnt3);
/// Point of dimension 4.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Pnt4<N> {
/// First component of the point.
pub x: N,
/// Second component of the point.
pub y: N,
/// Third component of the point.
pub z: N,
/// Fourth component of the point.
pub w: N
}
new_impl!(Pnt4, x, y, z, w);
orig_impl!(Pnt4, x, y, z, w);
pord_impl!(Pnt4, x, y, z, w);
scalar_mul_impl!(Pnt4, x, y, z, w);
scalar_div_impl!(Pnt4, x, y, z, w);
scalar_add_impl!(Pnt4, x, y, z, w);
scalar_sub_impl!(Pnt4, x, y, z, w);
vec_cast_impl!(Pnt4, x, y, z, w);
conversion_impl!(Pnt4, 4);
index_impl!(Pnt4);
indexable_impl!(Pnt4, 4);
at_fast_impl!(Pnt4, 4);
repeat_impl!(Pnt4, val, x, y, z, w);
dim_impl!(Pnt4, 4);
container_impl!(Pnt4);
pnt_as_vec_impl!(Pnt4, Vec4, x, y, z, w);
pnt_sub_impl!(Pnt4, Vec4);
neg_impl!(Pnt4, x, y, z, w);
pnt_add_vec_impl!(Pnt4, Vec4, x, y, z, w);
pnt_sub_vec_impl!(Pnt4, Vec4, x, y, z, w);
approx_eq_impl!(Pnt4, x, y, z, w);
from_iterator_impl!(Pnt4, iterator, iterator, iterator, iterator);
bounded_impl!(Pnt4, x, y, z, w);
axpy_impl!(Pnt4, x, y, z, w);
iterable_impl!(Pnt4, 4);
iterable_mut_impl!(Pnt4, 4);
pnt_to_homogeneous_impl!(Pnt4, Pnt5, a, x, y, z, w);
pnt_from_homogeneous_impl!(Pnt4, Pnt5, a, x, y, z, w);
num_float_pnt_impl!(Pnt4, Vec4);
arbitrary_pnt_impl!(Pnt4, x, y, z, w);
rand_impl!(Pnt4, x, y, z, w);
pnt_display_impl!(Pnt4);
/// Point of dimension 5.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Pnt5<N> {
/// First component of the point.
pub x: N,
/// Second component of the point.
pub y: N,
/// Third component of the point.
pub z: N,
/// Fourth component of the point.
pub w: N,
/// Fifth of the point.
pub a: N
}
new_impl!(Pnt5, x, y, z, w, a);
orig_impl!(Pnt5, x, y, z, w, a);
pord_impl!(Pnt5, x, y, z, w, a);
scalar_mul_impl!(Pnt5, x, y, z, w, a);
scalar_div_impl!(Pnt5, x, y, z, w, a);
scalar_add_impl!(Pnt5, x, y, z, w, a);
scalar_sub_impl!(Pnt5, x, y, z, w, a);
vec_cast_impl!(Pnt5, x, y, z, w, a);
conversion_impl!(Pnt5, 5);
index_impl!(Pnt5);
indexable_impl!(Pnt5, 5);
at_fast_impl!(Pnt5, 5);
repeat_impl!(Pnt5, val, x, y, z, w, a);
dim_impl!(Pnt5, 5);
container_impl!(Pnt5);
pnt_as_vec_impl!(Pnt5, Vec5, x, y, z, w, a);
pnt_sub_impl!(Pnt5, Vec5);
neg_impl!(Pnt5, x, y, z, w, a);
pnt_add_vec_impl!(Pnt5, Vec5, x, y, z, w, a);
pnt_sub_vec_impl!(Pnt5, Vec5, x, y, z, w, a);
approx_eq_impl!(Pnt5, x, y, z, w, a);
from_iterator_impl!(Pnt5, iterator, iterator, iterator, iterator, iterator);
bounded_impl!(Pnt5, x, y, z, w, a);
axpy_impl!(Pnt5, x, y, z, w, a);
iterable_impl!(Pnt5, 5);
iterable_mut_impl!(Pnt5, 5);
pnt_to_homogeneous_impl!(Pnt5, Pnt6, b, x, y, z, w, a);
pnt_from_homogeneous_impl!(Pnt5, Pnt6, b, x, y, z, w, a);
num_float_pnt_impl!(Pnt5, Vec5);
arbitrary_pnt_impl!(Pnt5, x, y, z, w, a);
rand_impl!(Pnt5, x, y, z, w, a);
pnt_display_impl!(Pnt5);
/// Point of dimension 6.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Pnt6<N> {
/// First component of the point.
pub x: N,
/// Second component of the point.
pub y: N,
/// Third component of the point.
pub z: N,
/// Fourth component of the point.
pub w: N,
/// Fifth of the point.
pub a: N,
/// Sixth component of the point.
pub b: N
}
new_impl!(Pnt6, x, y, z, w, a, b);
orig_impl!(Pnt6, x, y, z, w, a, b);
pord_impl!(Pnt6, x, y, z, w, a, b);
scalar_mul_impl!(Pnt6, x, y, z, w, a, b);
scalar_div_impl!(Pnt6, x, y, z, w, a, b);
scalar_add_impl!(Pnt6, x, y, z, w, a, b);
scalar_sub_impl!(Pnt6, x, y, z, w, a, b);
vec_cast_impl!(Pnt6, x, y, z, w, a, b);
conversion_impl!(Pnt6, 6);
index_impl!(Pnt6);
indexable_impl!(Pnt6, 6);
at_fast_impl!(Pnt6, 6);
repeat_impl!(Pnt6, val, x, y, z, w, a, b);
dim_impl!(Pnt6, 6);
container_impl!(Pnt6);
pnt_as_vec_impl!(Pnt6, Vec6, x, y, z, w, a, b);
pnt_sub_impl!(Pnt6, Vec6);
neg_impl!(Pnt6, x, y, z, w, a, b);
pnt_add_vec_impl!(Pnt6, Vec6, x, y, z, w, a, b);
pnt_sub_vec_impl!(Pnt6, Vec6, x, y, z, w, a, b);
approx_eq_impl!(Pnt6, x, y, z, w, a, b);
from_iterator_impl!(Pnt6, iterator, iterator, iterator, iterator, iterator, iterator);
bounded_impl!(Pnt6, x, y, z, w, a, b);
axpy_impl!(Pnt6, x, y, z, w, a, b);
iterable_impl!(Pnt6, 6);
iterable_mut_impl!(Pnt6, 6);
num_float_pnt_impl!(Pnt6, Vec6);
arbitrary_pnt_impl!(Pnt6, x, y, z, w, a, b);
rand_impl!(Pnt6, x, y, z, w, a, b);
pnt_display_impl!(Pnt6);

309
src/structs/point.rs Normal file
View File

@ -0,0 +1,309 @@
//! Points with dimension known at compile-time.
use std::mem;
use std::fmt;
use std::slice::{Iter, IterMut};
use std::iter::{Iterator, FromIterator, IntoIterator};
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
use rand::{Rand, Rng};
use num::{Zero, One};
use traits::operations::{ApproxEq, PartialOrder, PartialOrdering, Axpy};
use traits::structure::{Cast, Dimension, Indexable, Iterable, IterableMut, PointAsVector, Shape,
NumPoint, FloatPoint, BaseFloat, BaseNum, Bounded, Repeat};
use traits::geometry::{Origin, FromHomogeneous, ToHomogeneous};
use structs::vector::{Vector1, Vector2, Vector3, Vector4, Vector5, Vector6};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
/// Point of dimension 1.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Point1<N> {
/// First component of the point.
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);
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.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Point2<N> {
/// First component of the point.
pub x: N,
/// Second component of the point.
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);
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.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Point3<N> {
/// First component of the point.
pub x: N,
/// Second component of the point.
pub y: N,
/// Third component of the point.
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);
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.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Point4<N> {
/// First component of the point.
pub x: N,
/// Second component of the point.
pub y: N,
/// Third component of the point.
pub z: N,
/// Fourth component of the point.
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);
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.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Point5<N> {
/// First component of the point.
pub x: N,
/// Second component of the point.
pub y: N,
/// Third component of the point.
pub z: N,
/// Fourth component of the point.
pub w: N,
/// Fifth of the point.
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);
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.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Point6<N> {
/// First component of the point.
pub x: N,
/// Second component of the point.
pub y: N,
/// Third component of the point.
pub z: N,
/// Fourth component of the point.
pub w: N,
/// Fifth of the point.
pub a: N,
/// Sixth component of the point.
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);
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,37 +1,37 @@
#![macro_use] #![macro_use]
macro_rules! orig_impl( macro_rules! origin_impl(
($t: ident, $($compN: ident),+) => ( ($t: ident, $($compN: ident),+) => (
impl<N: Zero> Orig for $t<N> { impl<N: Zero> Origin for $t<N> {
#[inline] #[inline]
fn orig() -> $t<N> { fn origin() -> $t<N> {
$t { $t {
$($compN: ::zero() ),+ $($compN: ::zero() ),+
} }
} }
#[inline] #[inline]
fn is_orig(&self) -> bool { fn is_origin(&self) -> bool {
$(self.$compN.is_zero() )&&+ $(self.$compN.is_zero() )&&+
} }
} }
) )
); );
macro_rules! pnt_sub_impl( macro_rules! point_sub_impl(
($t: ident, $tv: ident) => ( ($t: ident, $tv: ident) => (
impl<N: Copy + Sub<N, Output = N>> Sub<$t<N>> for $t<N> { impl<N: Copy + Sub<N, Output = N>> Sub<$t<N>> for $t<N> {
type Output = $tv<N>; type Output = $tv<N>;
#[inline] #[inline]
fn sub(self, right: $t<N>) -> $tv<N> { fn sub(self, right: $t<N>) -> $tv<N> {
*self.as_vec() - *right.as_vec() *self.as_vector() - *right.as_vector()
} }
} }
) )
); );
macro_rules! pnt_add_vec_impl( macro_rules! point_add_vec_impl(
($t: ident, $tv: ident, $($compN: ident),+) => ( ($t: ident, $tv: ident, $($compN: ident),+) => (
impl<N: Copy + Add<N, Output = N>> Add<$tv<N>> for $t<N> { impl<N: Copy + Add<N, Output = N>> Add<$tv<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
@ -51,7 +51,7 @@ macro_rules! pnt_add_vec_impl(
) )
); );
macro_rules! pnt_sub_vec_impl( macro_rules! point_sub_vec_impl(
($t: ident, $tv: ident, $($compN: ident),+) => ( ($t: ident, $tv: ident, $($compN: ident),+) => (
impl<N: Copy + Sub<N, Output = N>> Sub<$tv<N>> for $t<N> { impl<N: Copy + Sub<N, Output = N>> Sub<$tv<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
@ -71,12 +71,12 @@ macro_rules! pnt_sub_vec_impl(
) )
); );
macro_rules! pnt_as_vec_impl( macro_rules! point_as_vec_impl(
($t: ident, $tv: ident, $($compN: ident),+) => ( ($t: ident, $tv: ident, $($compN: ident),+) => (
impl<N> $t<N> { impl<N> $t<N> {
/// Converts this point to its associated vector. /// Converts this point to its associated vector.
#[inline] #[inline]
pub fn to_vec(self) -> $tv<N> { pub fn to_vector(self) -> $tv<N> {
$tv::new( $tv::new(
$(self.$compN),+ $(self.$compN),+
) )
@ -84,7 +84,7 @@ macro_rules! pnt_as_vec_impl(
/// Converts a reference to this point to a reference to its associated vector. /// Converts a reference to this point to a reference to its associated vector.
#[inline] #[inline]
pub fn as_vec<'a>(&'a self) -> &'a $tv<N> { pub fn as_vector<'a>(&'a self) -> &'a $tv<N> {
unsafe { unsafe {
mem::transmute(self) mem::transmute(self)
} }
@ -96,17 +96,17 @@ macro_rules! pnt_as_vec_impl(
} }
} }
impl<N> PntAsVec for $t<N> { impl<N> PointAsVector for $t<N> {
type Vec = $tv<N>; type Vector = $tv<N>;
#[inline] #[inline]
fn to_vec(self) -> $tv<N> { fn to_vector(self) -> $tv<N> {
self.to_vec() self.to_vector()
} }
#[inline] #[inline]
fn as_vec<'a>(&'a self) -> &'a $tv<N> { fn as_vector<'a>(&'a self) -> &'a $tv<N> {
self.as_vec() self.as_vector()
} }
#[inline] #[inline]
@ -117,11 +117,11 @@ macro_rules! pnt_as_vec_impl(
) )
); );
macro_rules! pnt_to_homogeneous_impl( macro_rules! point_to_homogeneous_impl(
($t: ident, $t2: ident, $extra: ident, $($compN: ident),+) => ( ($t: ident, $t2: ident, $extra: ident, $($compN: ident),+) => (
impl<N: Copy + One + Zero> ToHomogeneous<$t2<N>> for $t<N> { impl<N: Copy + One + Zero> ToHomogeneous<$t2<N>> for $t<N> {
fn to_homogeneous(&self) -> $t2<N> { fn to_homogeneous(&self) -> $t2<N> {
let mut res: $t2<N> = Orig::orig(); let mut res: $t2<N> = Origin::origin();
$( res.$compN = self.$compN; )+ $( res.$compN = self.$compN; )+
res.$extra = ::one(); res.$extra = ::one();
@ -132,11 +132,11 @@ macro_rules! pnt_to_homogeneous_impl(
) )
); );
macro_rules! pnt_from_homogeneous_impl( macro_rules! point_from_homogeneous_impl(
($t: ident, $t2: ident, $extra: ident, $($compN: ident),+) => ( ($t: ident, $t2: ident, $extra: ident, $($compN: ident),+) => (
impl<N: Copy + Div<N, Output = N> + One + Zero> FromHomogeneous<$t2<N>> for $t<N> { impl<N: Copy + Div<N, Output = N> + One + Zero> FromHomogeneous<$t2<N>> for $t<N> {
fn from(v: &$t2<N>) -> $t<N> { fn from(v: &$t2<N>) -> $t<N> {
let mut res: $t<N> = Orig::orig(); let mut res: $t<N> = Origin::origin();
$( res.$compN = v.$compN / v.$extra; )+ $( res.$compN = v.$compN / v.$extra; )+
@ -146,19 +146,19 @@ macro_rules! pnt_from_homogeneous_impl(
) )
); );
macro_rules! num_float_pnt_impl( macro_rules! num_float_point_impl(
($t: ident, $tv: ident) => ( ($t: ident, $tv: ident) => (
impl<N> NumPnt<N> for $t<N> impl<N> NumPoint<N> for $t<N>
where N: BaseNum { where N: BaseNum {
} }
impl<N> FloatPnt<N> for $t<N> impl<N> FloatPoint<N> for $t<N>
where N: BaseFloat + ApproxEq<N> { where N: BaseFloat + ApproxEq<N> {
} }
) )
); );
macro_rules! arbitrary_pnt_impl( macro_rules! arbitrary_point_impl(
($t: ident, $($compN: ident),*) => ( ($t: ident, $($compN: ident),*) => (
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
impl<N: Arbitrary> Arbitrary for $t<N> { impl<N: Arbitrary> Arbitrary for $t<N> {
@ -172,7 +172,7 @@ macro_rules! arbitrary_pnt_impl(
) )
); );
macro_rules! pnt_display_impl( macro_rules! point_display_impl(
($t: ident) => ( ($t: ident) => (
impl<N: fmt::Display> fmt::Display for $t<N> { impl<N: fmt::Display> fmt::Display for $t<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

View File

@ -1,598 +0,0 @@
//! Quaternion definition.
use std::fmt;
use std::mem;
use std::slice::{Iter, IterMut};
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
use std::iter::{FromIterator, IntoIterator};
use rand::{Rand, Rng};
use num::{Zero, One};
use structs::{Vec3, Pnt3, Rot3, Mat3};
use traits::operations::{ApproxEq, Inv, POrd, POrdering, Axpy};
use traits::structure::{Cast, Indexable, Iterable, IterableMut, Dim, Shape, BaseFloat, BaseNum,
Bounded, Repeat};
use traits::geometry::{Norm, Rotation, RotationMatrix, Rotate, RotationTo, Transform};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
/// A quaternion.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Quat<N> {
/// The scalar component of the quaternion.
pub w: N,
/// The first vector component of the quaternion.
pub i: N,
/// The second vector component of the quaternion.
pub j: N,
/// The third vector component of the quaternion.
pub k: N
}
impl<N> Quat<N> {
/// Creates a new quaternion from its components.
#[inline]
pub fn new(w: N, i: N, j: N, k: N) -> Quat<N> {
Quat {
w: w,
i: i,
j: j,
k: k
}
}
/// The vector part `(i, j, k)` of this quaternion.
#[inline]
pub fn vector<'a>(&'a self) -> &'a Vec3<N> {
// FIXME: do this require a `repr(C)` ?
unsafe {
mem::transmute(&self.i)
}
}
/// The scalar part `w` of this quaternion.
#[inline]
pub fn scalar<'a>(&'a self) -> &'a N {
&self.w
}
}
impl<N: Neg<Output = N> + Copy> Quat<N> {
/// Compute the conjugate of this quaternion.
#[inline]
pub fn conjugate(&self) -> Quat<N> {
Quat { w: self.w, i: -self.i, j: -self.j, k: -self.k }
}
/// Replaces this quaternion by its conjugate.
#[inline]
pub fn conjugate_mut(&mut self) {
self.i = -self.i;
self.j = -self.j;
self.k = -self.k;
}
}
impl<N: BaseFloat + ApproxEq<N>> Inv for Quat<N> {
#[inline]
fn inv(&self) -> Option<Quat<N>> {
let mut res = *self;
if res.inv_mut() {
Some(res)
}
else {
None
}
}
#[inline]
fn inv_mut(&mut self) -> bool {
let sqnorm = Norm::sqnorm(self);
if ApproxEq::approx_eq(&sqnorm, &::zero()) {
false
}
else {
self.conjugate_mut();
self.w = self.w / sqnorm;
self.i = self.i / sqnorm;
self.j = self.j / sqnorm;
self.k = self.k / sqnorm;
true
}
}
}
impl<N: BaseFloat> Norm<N> for Quat<N> {
#[inline]
fn sqnorm(&self) -> N {
self.w * self.w + self.i * self.i + self.j * self.j + self.k * self.k
}
#[inline]
fn normalize(&self) -> Quat<N> {
let n = self.norm();
Quat::new(self.w / n, self.i / n, self.j / n, self.k / n)
}
#[inline]
fn normalize_mut(&mut self) -> N {
let n = Norm::norm(self);
self.w = self.w / n;
self.i = self.i / n;
self.j = self.j / n;
self.k = self.k / n;
n
}
}
impl<N> Mul<Quat<N>> for Quat<N>
where N: Copy + Mul<N, Output = N> + Sub<N, Output = N> + Add<N, Output = N> {
type Output = Quat<N>;
#[inline]
fn mul(self, right: Quat<N>) -> Quat<N> {
Quat::new(
self.w * right.w - self.i * right.i - self.j * right.j - self.k * right.k,
self.w * right.i + self.i * right.w + self.j * right.k - self.k * right.j,
self.w * right.j - self.i * right.k + self.j * right.w + self.k * right.i,
self.w * right.k + self.i * right.j - self.j * right.i + self.k * right.w)
}
}
impl<N> MulAssign<Quat<N>> for Quat<N>
where N: Copy + Mul<N, Output = N> + Sub<N, Output = N> + Add<N, Output = N> {
#[inline]
fn mul_assign(&mut self, right: Quat<N>) {
*self = *self * right;
}
}
impl<N: ApproxEq<N> + BaseFloat> Div<Quat<N>> for Quat<N> {
type Output = Quat<N>;
#[inline]
fn div(self, right: Quat<N>) -> Quat<N> {
self * right.inv().expect("Unable to invert the denominator.")
}
}
impl<N: ApproxEq<N> + BaseFloat> DivAssign<Quat<N>> for Quat<N> {
#[inline]
fn div_assign(&mut self, right: Quat<N>) {
*self *= right.inv().expect("Unable to invert the denominator.")
}
}
impl<N: fmt::Display> fmt::Display for Quat<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Quaternion {} ({}, {}, {})", self.w, self.i, self.j, self.k)
}
}
rand_impl!(Quat, w, i, j, k);
/// A unit quaternion that can represent a 3D rotation.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct UnitQuat<N> {
q: Quat<N>
}
impl<N: BaseFloat> UnitQuat<N> {
/// Creates a new unit quaternion from the axis-angle representation of a rotation.
#[inline]
pub fn new(axisangle: Vec3<N>) -> UnitQuat<N> {
let sqang = Norm::sqnorm(&axisangle);
if ::is_zero(&sqang) {
::one()
}
else {
let ang = sqang.sqrt();
let (s, c) = (ang / Cast::from(2.0)).sin_cos();
let s_ang = s / ang;
unsafe {
UnitQuat::new_with_unit_quat(
Quat::new(
c,
axisangle.x * s_ang,
axisangle.y * s_ang,
axisangle.z * s_ang)
)
}
}
}
/// Creates a new unit quaternion from a quaternion.
///
/// The input quaternion will be normalized.
#[inline]
pub fn new_with_quat(q: Quat<N>) -> UnitQuat<N> {
UnitQuat { q: q.normalize() }
}
/// Creates a new unit quaternion from Euler angles.
///
/// The primitive rotations are applied in order: 1 roll 2 pitch 3 yaw.
#[inline]
pub fn new_with_euler_angles(roll: N, pitch: N, yaw: N) -> UnitQuat<N> {
let _0_5: N = Cast::from(0.5);
let (sr, cr) = (roll * _0_5).sin_cos();
let (sp, cp) = (pitch * _0_5).sin_cos();
let (sy, cy) = (yaw * _0_5).sin_cos();
unsafe {
UnitQuat::new_with_unit_quat(
Quat::new(
cr * cp * cy + sr * sp * sy,
sr * cp * cy - cr * sp * sy,
cr * sp * cy + sr * cp * sy,
cr * cp * sy - sr * sp * cy)
)
}
}
/// Builds a rotation matrix from this quaternion.
pub fn to_rot(&self) -> Rot3<N> {
let _2: N = Cast::from(2.0);
let ww = self.q.w * self.q.w;
let ii = self.q.i * self.q.i;
let jj = self.q.j * self.q.j;
let kk = self.q.k * self.q.k;
let ij = _2 * self.q.i * self.q.j;
let wk = _2 * self.q.w * self.q.k;
let wj = _2 * self.q.w * self.q.j;
let ik = _2 * self.q.i * self.q.k;
let jk = _2 * self.q.j * self.q.k;
let wi = _2 * self.q.w * self.q.i;
unsafe {
Rot3::new_with_mat(
Mat3::new(
ww + ii - jj - kk, ij - wk, wj + ik,
wk + ij, ww - ii + jj - kk, jk - wi,
ik - wj, wi + jk, ww - ii - jj + kk
)
)
}
}
}
impl<N> UnitQuat<N> {
/// Creates a new unit quaternion from a quaternion.
///
/// This is unsafe because the input quaternion will not be normalized.
#[inline]
pub unsafe fn new_with_unit_quat(q: Quat<N>) -> UnitQuat<N> {
UnitQuat {
q: q
}
}
/// The `Quat` representation of this unit quaternion.
#[inline]
pub fn quat<'a>(&'a self) -> &'a Quat<N> {
&self.q
}
}
impl<N: BaseNum> One for UnitQuat<N> {
#[inline]
fn one() -> UnitQuat<N> {
unsafe {
UnitQuat::new_with_unit_quat(Quat::new(::one(), ::zero(), ::zero(), ::zero()))
}
}
}
impl<N: Copy + Neg<Output = N>> Inv for UnitQuat<N> {
#[inline]
fn inv(&self) -> Option<UnitQuat<N>> {
let mut cpy = *self;
cpy.inv_mut();
Some(cpy)
}
#[inline]
fn inv_mut(&mut self) -> bool {
self.q.conjugate_mut();
true
}
}
impl<N: Rand + BaseFloat> Rand for UnitQuat<N> {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> UnitQuat<N> {
UnitQuat::new(rng.gen())
}
}
impl<N: ApproxEq<N>> ApproxEq<N> for UnitQuat<N> {
#[inline]
fn approx_epsilon(_: Option<UnitQuat<N>>) -> N {
ApproxEq::approx_epsilon(None::<N>)
}
#[inline]
fn approx_ulps(_: Option<UnitQuat<N>>) -> u32 {
ApproxEq::approx_ulps(None::<N>)
}
#[inline]
fn approx_eq_eps(&self, other: &UnitQuat<N>, eps: &N) -> bool {
ApproxEq::approx_eq_eps(&self.q, &other.q, eps)
}
#[inline]
fn approx_eq_ulps(&self, other: &UnitQuat<N>, ulps: u32) -> bool {
ApproxEq::approx_eq_ulps(&self.q, &other.q, ulps)
}
}
impl<N: BaseFloat + ApproxEq<N>> Div<UnitQuat<N>> for UnitQuat<N> {
type Output = UnitQuat<N>;
#[inline]
fn div(self, other: UnitQuat<N>) -> UnitQuat<N> {
UnitQuat { q: self.q / other.q }
}
}
impl<N: BaseFloat + ApproxEq<N>> DivAssign<UnitQuat<N>> for UnitQuat<N> {
#[inline]
fn div_assign(&mut self, other: UnitQuat<N>) {
self.q /= other.q
}
}
impl<N: BaseNum> Mul<UnitQuat<N>> for UnitQuat<N> {
type Output = UnitQuat<N>;
#[inline]
fn mul(self, right: UnitQuat<N>) -> UnitQuat<N> {
UnitQuat { q: self.q * right.q }
}
}
impl<N: BaseNum> MulAssign<UnitQuat<N>> for UnitQuat<N> {
#[inline]
fn mul_assign(&mut self, right: UnitQuat<N>) {
self.q *= right.q
}
}
impl<N: BaseNum> Mul<Vec3<N>> for UnitQuat<N> {
type Output = Vec3<N>;
#[inline]
fn mul(self, right: Vec3<N>) -> Vec3<N> {
let _2: N = ::one::<N>() + ::one();
let mut t = ::cross(self.q.vector(), &right);
t.x = t.x * _2;
t.y = t.y * _2;
t.z = t.z * _2;
Vec3::new(t.x * self.q.w, t.y * self.q.w, t.z * self.q.w) + ::cross(self.q.vector(), &t) + right
}
}
impl<N: BaseNum> Mul<Pnt3<N>> for UnitQuat<N> {
type Output = Pnt3<N>;
#[inline]
fn mul(self, right: Pnt3<N>) -> Pnt3<N> {
::orig::<Pnt3<N>>() + self * *right.as_vec()
}
}
impl<N: BaseNum + Neg<Output = N>> Mul<UnitQuat<N>> for Vec3<N> {
type Output = Vec3<N>;
#[inline]
fn mul(self, right: UnitQuat<N>) -> Vec3<N> {
let mut inv_quat = right;
inv_quat.inv_mut();
inv_quat * self
}
}
impl<N: BaseNum + Neg<Output = N>> Mul<UnitQuat<N>> for Pnt3<N> {
type Output = Pnt3<N>;
#[inline]
fn mul(self, right: UnitQuat<N>) -> Pnt3<N> {
::orig::<Pnt3<N>>() + *self.as_vec() * right
}
}
impl<N: BaseNum + Neg<Output = N>> MulAssign<UnitQuat<N>> for Vec3<N> {
#[inline]
fn mul_assign(&mut self, right: UnitQuat<N>) {
*self = *self * right
}
}
impl<N: BaseNum + Neg<Output = N>> MulAssign<UnitQuat<N>> for Pnt3<N> {
#[inline]
fn mul_assign(&mut self, right: UnitQuat<N>) {
*self = *self * right
}
}
impl<N: BaseFloat> Rotation<Vec3<N>> for UnitQuat<N> {
#[inline]
fn rotation(&self) -> Vec3<N> {
let _2 = ::one::<N>() + ::one();
let mut v = *self.q.vector();
let ang = _2 * v.normalize_mut().atan2(self.q.w);
if ::is_zero(&ang) {
::zero()
}
else {
Vec3::new(v.x * ang, v.y * ang, v.z * ang)
}
}
#[inline]
fn inv_rotation(&self) -> Vec3<N> {
-self.rotation()
}
#[inline]
fn append_rotation_mut(&mut self, amount: &Vec3<N>) {
*self = Rotation::append_rotation(self, amount)
}
#[inline]
fn append_rotation(&self, amount: &Vec3<N>) -> UnitQuat<N> {
*self * UnitQuat::new(*amount)
}
#[inline]
fn prepend_rotation_mut(&mut self, amount: &Vec3<N>) {
*self = Rotation::prepend_rotation(self, amount)
}
#[inline]
fn prepend_rotation(&self, amount: &Vec3<N>) -> UnitQuat<N> {
UnitQuat::new(*amount) * *self
}
#[inline]
fn set_rotation(&mut self, v: Vec3<N>) {
*self = UnitQuat::new(v)
}
}
impl<N: BaseFloat> RotationMatrix<N, Vec3<N>, Vec3<N>> for UnitQuat<N> {
type Output = Rot3<N>;
#[inline]
fn to_rot_mat(&self) -> Rot3<N> {
self.to_rot()
}
}
impl<N: BaseNum + Neg<Output = N>> Rotate<Vec3<N>> for UnitQuat<N> {
#[inline]
fn rotate(&self, v: &Vec3<N>) -> Vec3<N> {
*self * *v
}
#[inline]
fn inv_rotate(&self, v: &Vec3<N>) -> Vec3<N> {
*v * *self
}
}
impl<N: BaseNum + Neg<Output = N>> Rotate<Pnt3<N>> for UnitQuat<N> {
#[inline]
fn rotate(&self, p: &Pnt3<N>) -> Pnt3<N> {
*self * *p
}
#[inline]
fn inv_rotate(&self, p: &Pnt3<N>) -> Pnt3<N> {
*p * *self
}
}
impl<N: BaseFloat + ApproxEq<N>> RotationTo for UnitQuat<N> {
type AngleType = N;
type DeltaRotationType = UnitQuat<N>;
#[inline]
fn angle_to(&self, other: &Self) -> N {
let delta = self.rotation_to(other);
let _2 = ::one::<N>() + ::one();
_2 * delta.q.vector().norm().atan2(delta.q.w)
}
#[inline]
fn rotation_to(&self, other: &Self) -> UnitQuat<N> {
*other / *self
}
}
impl<N: BaseNum + Neg<Output = N>> Transform<Vec3<N>> for UnitQuat<N> {
#[inline]
fn transform(&self, v: &Vec3<N>) -> Vec3<N> {
*self * *v
}
#[inline]
fn inv_transform(&self, v: &Vec3<N>) -> Vec3<N> {
*v * *self
}
}
impl<N: BaseNum + Neg<Output = N>> Transform<Pnt3<N>> for UnitQuat<N> {
#[inline]
fn transform(&self, p: &Pnt3<N>) -> Pnt3<N> {
*self * *p
}
#[inline]
fn inv_transform(&self, p: &Pnt3<N>) -> Pnt3<N> {
*p * *self
}
}
impl<N: fmt::Display> fmt::Display for UnitQuat<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Unit quaternion {} ({}, {}, {})", self.q.w, self.q.i, self.q.j, self.q.k)
}
}
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for UnitQuat<N> {
fn arbitrary<G: Gen>(g: &mut G) -> UnitQuat<N> {
UnitQuat::new(Arbitrary::arbitrary(g))
}
}
pord_impl!(Quat, w, i, j, k);
vec_axis_impl!(Quat, w, i, j, k);
vec_cast_impl!(Quat, w, i, j, k);
conversion_impl!(Quat, 4);
index_impl!(Quat);
indexable_impl!(Quat, 4);
at_fast_impl!(Quat, 4);
repeat_impl!(Quat, val, w, i, j, k);
dim_impl!(Quat, 3);
container_impl!(Quat);
add_impl!(Quat, w, i, j, k);
sub_impl!(Quat, w, i, j, k);
scalar_add_impl!(Quat, w, i, j, k);
scalar_sub_impl!(Quat, w, i, j, k);
scalar_mul_impl!(Quat, w, i, j, k);
scalar_div_impl!(Quat, w, i, j, k);
neg_impl!(Quat, w, i, j, k);
zero_one_impl!(Quat, w, i, j, k);
approx_eq_impl!(Quat, w, i, j, k);
from_iterator_impl!(Quat, iterator, iterator, iterator, iterator);
bounded_impl!(Quat, w, i, j, k);
axpy_impl!(Quat, w, i, j, k);
iterable_impl!(Quat, 4);
iterable_mut_impl!(Quat, 4);
arbitrary_impl!(Quat, w, i, j, k);
dim_impl!(UnitQuat, 3);

598
src/structs/quaternion.rs Normal file
View File

@ -0,0 +1,598 @@
//! Quaternion definition.
use std::fmt;
use std::mem;
use std::slice::{Iter, IterMut};
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
use std::iter::{FromIterator, IntoIterator};
use rand::{Rand, Rng};
use num::{Zero, One};
use structs::{Vector3, Point3, Rotation3, Matrix3};
use traits::operations::{ApproxEq, Inverse, PartialOrder, PartialOrdering, Axpy};
use traits::structure::{Cast, Indexable, Iterable, IterableMut, Dimension, Shape, BaseFloat, BaseNum,
Bounded, Repeat};
use traits::geometry::{Norm, Rotation, RotationMatrix, Rotate, RotationTo, Transform};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
/// A quaternion. See `UnitQuaternion` for a quaternion that can be used as a rotation.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Quaternion<N> {
/// The scalar component of the quaternion.
pub w: N,
/// The first vector component of the quaternion.
pub i: N,
/// The second vector component of the quaternion.
pub j: N,
/// The third vector component of the quaternion.
pub k: 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<'a>(&'a self) -> &'a Vector3<N> {
// FIXME: do this require a `repr(C)` ?
unsafe {
mem::transmute(&self.i)
}
}
/// The scalar part `w` of this quaternion.
#[inline]
pub fn scalar<'a>(&'a self) -> &'a N {
&self.w
}
}
impl<N: Neg<Output = N> + Copy> Quaternion<N> {
/// Compute the conjugate of this quaternion.
#[inline]
pub fn conjugate(&self) -> Quaternion<N> {
Quaternion { w: self.w, i: -self.i, j: -self.j, k: -self.k }
}
/// Replaces this quaternion by its conjugate.
#[inline]
pub fn conjugate_mut(&mut self) {
self.i = -self.i;
self.j = -self.j;
self.k = -self.k;
}
}
impl<N: BaseFloat + ApproxEq<N>> Inverse for Quaternion<N> {
#[inline]
fn inverse(&self) -> Option<Quaternion<N>> {
let mut res = *self;
if res.inverse_mut() {
Some(res)
}
else {
None
}
}
#[inline]
fn inverse_mut(&mut self) -> bool {
let norm_squared = Norm::norm_squared(self);
if ApproxEq::approx_eq(&norm_squared, &::zero()) {
false
}
else {
self.conjugate_mut();
self.w = self.w / norm_squared;
self.i = self.i / norm_squared;
self.j = self.j / norm_squared;
self.k = self.k / norm_squared;
true
}
}
}
impl<N: BaseFloat> Norm<N> for Quaternion<N> {
#[inline]
fn norm_squared(&self) -> N {
self.w * self.w + self.i * self.i + self.j * self.j + self.k * self.k
}
#[inline]
fn normalize(&self) -> Quaternion<N> {
let n = self.norm();
Quaternion::new(self.w / n, self.i / n, self.j / n, self.k / n)
}
#[inline]
fn normalize_mut(&mut self) -> N {
let n = Norm::norm(self);
self.w = self.w / n;
self.i = self.i / n;
self.j = self.j / n;
self.k = self.k / n;
n
}
}
impl<N> Mul<Quaternion<N>> for Quaternion<N>
where N: Copy + Mul<N, Output = N> + Sub<N, Output = N> + Add<N, Output = N> {
type Output = Quaternion<N>;
#[inline]
fn mul(self, right: Quaternion<N>) -> Quaternion<N> {
Quaternion::new(
self.w * right.w - self.i * right.i - self.j * right.j - self.k * right.k,
self.w * right.i + self.i * right.w + self.j * right.k - self.k * right.j,
self.w * right.j - self.i * right.k + self.j * right.w + self.k * right.i,
self.w * right.k + self.i * right.j - self.j * right.i + self.k * right.w)
}
}
impl<N> MulAssign<Quaternion<N>> for Quaternion<N>
where N: Copy + Mul<N, Output = N> + Sub<N, Output = N> + Add<N, Output = N> {
#[inline]
fn mul_assign(&mut self, right: Quaternion<N>) {
*self = *self * right;
}
}
impl<N: ApproxEq<N> + BaseFloat> Div<Quaternion<N>> for Quaternion<N> {
type Output = Quaternion<N>;
#[inline]
fn div(self, right: Quaternion<N>) -> Quaternion<N> {
self * right.inverse().expect("Unable to invert the denominator.")
}
}
impl<N: ApproxEq<N> + BaseFloat> DivAssign<Quaternion<N>> for Quaternion<N> {
#[inline]
fn div_assign(&mut self, right: Quaternion<N>) {
*self *= right.inverse().expect("Unable to invert the denominator.")
}
}
impl<N: fmt::Display> fmt::Display for Quaternion<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Quaternion {} ({}, {}, {})", self.w, self.i, self.j, self.k)
}
}
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)]
pub struct UnitQuaternion<N> {
q: Quaternion<N>
}
impl<N: BaseFloat> UnitQuaternion<N> {
/// Creates a new unit quaternion from the axis-angle representation of a rotation.
#[inline]
pub fn new(axisangle: Vector3<N>) -> UnitQuaternion<N> {
let sqang = Norm::norm_squared(&axisangle);
if ::is_zero(&sqang) {
::one()
}
else {
let ang = sqang.sqrt();
let (s, c) = (ang / Cast::from(2.0)).sin_cos();
let s_ang = s / ang;
unsafe {
UnitQuaternion::new_with_unit_quaternion(
Quaternion::new(
c,
axisangle.x * s_ang,
axisangle.y * s_ang,
axisangle.z * s_ang)
)
}
}
}
/// Creates a new unit quaternion from a quaternion.
///
/// The input quaternion will be normalized.
#[inline]
pub fn new_with_quaternion(q: Quaternion<N>) -> UnitQuaternion<N> {
UnitQuaternion { q: q.normalize() }
}
/// Creates a new unit quaternion from Euler angles.
///
/// The primitive rotations are applied in order: 1 roll 2 pitch 3 yaw.
#[inline]
pub fn new_with_euler_angles(roll: N, pitch: N, yaw: N) -> UnitQuaternion<N> {
let _0_5: N = Cast::from(0.5);
let (sr, cr) = (roll * _0_5).sin_cos();
let (sp, cp) = (pitch * _0_5).sin_cos();
let (sy, cy) = (yaw * _0_5).sin_cos();
unsafe {
UnitQuaternion::new_with_unit_quaternion(
Quaternion::new(
cr * cp * cy + sr * sp * sy,
sr * cp * cy - cr * sp * sy,
cr * sp * cy + sr * cp * sy,
cr * cp * sy - sr * sp * cy)
)
}
}
/// Builds a rotation matrix from this quaternion.
pub fn to_rotation_matrix(&self) -> Rotation3<N> {
let _2: N = Cast::from(2.0);
let ww = self.q.w * self.q.w;
let ii = self.q.i * self.q.i;
let jj = self.q.j * self.q.j;
let kk = self.q.k * self.q.k;
let ij = _2 * self.q.i * self.q.j;
let wk = _2 * self.q.w * self.q.k;
let wj = _2 * self.q.w * self.q.j;
let ik = _2 * self.q.i * self.q.k;
let jk = _2 * self.q.j * self.q.k;
let wi = _2 * self.q.w * self.q.i;
unsafe {
Rotation3::new_with_matrix(
Matrix3::new(
ww + ii - jj - kk, ij - wk, wj + ik,
wk + ij, ww - ii + jj - kk, jk - wi,
ik - wj, wi + jk, ww - ii - jj + kk
)
)
}
}
}
impl<N> UnitQuaternion<N> {
/// Creates a new unit quaternion from a quaternion.
///
/// This is unsafe because the input quaternion will not be normalized.
#[inline]
pub unsafe fn new_with_unit_quaternion(q: Quaternion<N>) -> UnitQuaternion<N> {
UnitQuaternion {
q: q
}
}
/// The `Quaternion` representation of this unit quaternion.
#[inline]
pub fn quaternion<'a>(&'a self) -> &'a Quaternion<N> {
&self.q
}
}
impl<N: BaseNum> One for UnitQuaternion<N> {
#[inline]
fn one() -> UnitQuaternion<N> {
unsafe {
UnitQuaternion::new_with_unit_quaternion(Quaternion::new(::one(), ::zero(), ::zero(), ::zero()))
}
}
}
impl<N: Copy + Neg<Output = N>> Inverse for UnitQuaternion<N> {
#[inline]
fn inverse(&self) -> Option<UnitQuaternion<N>> {
let mut cpy = *self;
cpy.inverse_mut();
Some(cpy)
}
#[inline]
fn inverse_mut(&mut self) -> bool {
self.q.conjugate_mut();
true
}
}
impl<N: Rand + BaseFloat> Rand for UnitQuaternion<N> {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> UnitQuaternion<N> {
UnitQuaternion::new(rng.gen())
}
}
impl<N: ApproxEq<N>> ApproxEq<N> for UnitQuaternion<N> {
#[inline]
fn approx_epsilon(_: Option<UnitQuaternion<N>>) -> N {
ApproxEq::approx_epsilon(None::<N>)
}
#[inline]
fn approx_ulps(_: Option<UnitQuaternion<N>>) -> u32 {
ApproxEq::approx_ulps(None::<N>)
}
#[inline]
fn approx_eq_eps(&self, other: &UnitQuaternion<N>, eps: &N) -> bool {
ApproxEq::approx_eq_eps(&self.q, &other.q, eps)
}
#[inline]
fn approx_eq_ulps(&self, other: &UnitQuaternion<N>, ulps: u32) -> bool {
ApproxEq::approx_eq_ulps(&self.q, &other.q, ulps)
}
}
impl<N: BaseFloat + ApproxEq<N>> Div<UnitQuaternion<N>> for UnitQuaternion<N> {
type Output = UnitQuaternion<N>;
#[inline]
fn div(self, other: UnitQuaternion<N>) -> UnitQuaternion<N> {
UnitQuaternion { q: self.q / other.q }
}
}
impl<N: BaseFloat + ApproxEq<N>> DivAssign<UnitQuaternion<N>> for UnitQuaternion<N> {
#[inline]
fn div_assign(&mut self, other: UnitQuaternion<N>) {
self.q /= other.q
}
}
impl<N: BaseNum> Mul<UnitQuaternion<N>> for UnitQuaternion<N> {
type Output = UnitQuaternion<N>;
#[inline]
fn mul(self, right: UnitQuaternion<N>) -> UnitQuaternion<N> {
UnitQuaternion { q: self.q * right.q }
}
}
impl<N: BaseNum> MulAssign<UnitQuaternion<N>> for UnitQuaternion<N> {
#[inline]
fn mul_assign(&mut self, right: UnitQuaternion<N>) {
self.q *= right.q
}
}
impl<N: BaseNum> Mul<Vector3<N>> for UnitQuaternion<N> {
type Output = Vector3<N>;
#[inline]
fn mul(self, right: Vector3<N>) -> Vector3<N> {
let _2: N = ::one::<N>() + ::one();
let mut t = ::cross(self.q.vector(), &right);
t.x = t.x * _2;
t.y = t.y * _2;
t.z = t.z * _2;
Vector3::new(t.x * self.q.w, t.y * self.q.w, t.z * self.q.w) + ::cross(self.q.vector(), &t) + right
}
}
impl<N: BaseNum> Mul<Point3<N>> for UnitQuaternion<N> {
type Output = Point3<N>;
#[inline]
fn mul(self, right: Point3<N>) -> Point3<N> {
::origin::<Point3<N>>() + self * *right.as_vector()
}
}
impl<N: BaseNum + Neg<Output = N>> Mul<UnitQuaternion<N>> for Vector3<N> {
type Output = Vector3<N>;
#[inline]
fn mul(self, right: UnitQuaternion<N>) -> Vector3<N> {
let mut inverse_quaternion = right;
inverse_quaternion.inverse_mut();
inverse_quaternion * self
}
}
impl<N: BaseNum + Neg<Output = N>> Mul<UnitQuaternion<N>> for Point3<N> {
type Output = Point3<N>;
#[inline]
fn mul(self, right: UnitQuaternion<N>) -> Point3<N> {
::origin::<Point3<N>>() + *self.as_vector() * right
}
}
impl<N: BaseNum + Neg<Output = N>> MulAssign<UnitQuaternion<N>> for Vector3<N> {
#[inline]
fn mul_assign(&mut self, right: UnitQuaternion<N>) {
*self = *self * right
}
}
impl<N: BaseNum + Neg<Output = N>> MulAssign<UnitQuaternion<N>> for Point3<N> {
#[inline]
fn mul_assign(&mut self, right: UnitQuaternion<N>) {
*self = *self * right
}
}
impl<N: BaseFloat> Rotation<Vector3<N>> for UnitQuaternion<N> {
#[inline]
fn rotation(&self) -> Vector3<N> {
let _2 = ::one::<N>() + ::one();
let mut v = *self.q.vector();
let ang = _2 * v.normalize_mut().atan2(self.q.w);
if ::is_zero(&ang) {
::zero()
}
else {
Vector3::new(v.x * ang, v.y * ang, v.z * ang)
}
}
#[inline]
fn inverse_rotation(&self) -> Vector3<N> {
-self.rotation()
}
#[inline]
fn append_rotation_mut(&mut self, amount: &Vector3<N>) {
*self = Rotation::append_rotation(self, amount)
}
#[inline]
fn append_rotation(&self, amount: &Vector3<N>) -> UnitQuaternion<N> {
*self * UnitQuaternion::new(*amount)
}
#[inline]
fn prepend_rotation_mut(&mut self, amount: &Vector3<N>) {
*self = Rotation::prepend_rotation(self, amount)
}
#[inline]
fn prepend_rotation(&self, amount: &Vector3<N>) -> UnitQuaternion<N> {
UnitQuaternion::new(*amount) * *self
}
#[inline]
fn set_rotation(&mut self, v: Vector3<N>) {
*self = UnitQuaternion::new(v)
}
}
impl<N: BaseFloat> RotationMatrix<N, Vector3<N>, Vector3<N>> for UnitQuaternion<N> {
type Output = Rotation3<N>;
#[inline]
fn to_rotation_matrix(&self) -> Rotation3<N> {
self.to_rotation_matrix()
}
}
impl<N: BaseNum + Neg<Output = N>> Rotate<Vector3<N>> for UnitQuaternion<N> {
#[inline]
fn rotate(&self, v: &Vector3<N>) -> Vector3<N> {
*self * *v
}
#[inline]
fn inverse_rotate(&self, v: &Vector3<N>) -> Vector3<N> {
*v * *self
}
}
impl<N: BaseNum + Neg<Output = N>> Rotate<Point3<N>> for UnitQuaternion<N> {
#[inline]
fn rotate(&self, p: &Point3<N>) -> Point3<N> {
*self * *p
}
#[inline]
fn inverse_rotate(&self, p: &Point3<N>) -> Point3<N> {
*p * *self
}
}
impl<N: BaseFloat + ApproxEq<N>> RotationTo for UnitQuaternion<N> {
type AngleType = N;
type DeltaRotationType = UnitQuaternion<N>;
#[inline]
fn angle_to(&self, other: &Self) -> N {
let delta = self.rotation_to(other);
let _2 = ::one::<N>() + ::one();
_2 * delta.q.vector().norm().atan2(delta.q.w)
}
#[inline]
fn rotation_to(&self, other: &Self) -> UnitQuaternion<N> {
*other / *self
}
}
impl<N: BaseNum + Neg<Output = N>> Transform<Vector3<N>> for UnitQuaternion<N> {
#[inline]
fn transform(&self, v: &Vector3<N>) -> Vector3<N> {
*self * *v
}
#[inline]
fn inverse_transform(&self, v: &Vector3<N>) -> Vector3<N> {
*v * *self
}
}
impl<N: BaseNum + Neg<Output = N>> Transform<Point3<N>> for UnitQuaternion<N> {
#[inline]
fn transform(&self, p: &Point3<N>) -> Point3<N> {
*self * *p
}
#[inline]
fn inverse_transform(&self, p: &Point3<N>) -> Point3<N> {
*p * *self
}
}
impl<N: fmt::Display> fmt::Display for UnitQuaternion<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Unit quaternion {} ({}, {}, {})", self.q.w, self.q.i, self.q.j, self.q.k)
}
}
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for UnitQuaternion<N> {
fn arbitrary<G: Gen>(g: &mut G) -> UnitQuaternion<N> {
UnitQuaternion::new(Arbitrary::arbitrary(g))
}
}
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);
zero_one_impl!(Quaternion, w, i, j, k);
approx_eq_impl!(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);

View File

@ -1,407 +0,0 @@
//! Rotations matrices.
use std::fmt;
use std::ops::{Mul, Neg, MulAssign, Index};
use rand::{Rand, Rng};
use num::{Zero, One};
use traits::geometry::{Rotate, Rotation, AbsoluteRotate, RotationMatrix, RotationTo, Transform,
ToHomogeneous, Norm, Cross};
use traits::structure::{Cast, Dim, Row, Col, BaseFloat, BaseNum, Eye, Diag};
use traits::operations::{Absolute, Inv, Transpose, ApproxEq};
use structs::vec::{Vec1, Vec2, Vec3};
use structs::pnt::{Pnt2, Pnt3};
use structs::mat::{Mat2, Mat3, Mat4};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
/// Two dimensional rotation matrix.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Hash, Copy)]
pub struct Rot2<N> {
submat: Mat2<N>
}
impl<N: Clone + BaseFloat + Neg<Output = N>> Rot2<N> {
/// Builds a 2 dimensional rotation matrix from an angle in radian.
pub fn new(angle: Vec1<N>) -> Rot2<N> {
let (sia, coa) = angle.x.sin_cos();
Rot2 {
submat: Mat2::new(coa.clone(), -sia, sia, coa)
}
}
}
impl<N: BaseFloat + Clone> Rotation<Vec1<N>> for Rot2<N> {
#[inline]
fn rotation(&self) -> Vec1<N> {
Vec1::new((-self.submat.m12).atan2(self.submat.m11.clone()))
}
#[inline]
fn inv_rotation(&self) -> Vec1<N> {
-self.rotation()
}
#[inline]
fn append_rotation_mut(&mut self, rot: &Vec1<N>) {
*self = Rotation::append_rotation(self, rot)
}
#[inline]
fn append_rotation(&self, rot: &Vec1<N>) -> Rot2<N> {
Rot2::new(rot.clone()) * *self
}
#[inline]
fn prepend_rotation_mut(&mut self, rot: &Vec1<N>) {
*self = Rotation::prepend_rotation(self, rot)
}
#[inline]
fn prepend_rotation(&self, rot: &Vec1<N>) -> Rot2<N> {
*self * Rot2::new(rot.clone())
}
#[inline]
fn set_rotation(&mut self, rot: Vec1<N>) {
*self = Rot2::new(rot)
}
}
impl<N: BaseFloat> RotationTo for Rot2<N> {
type AngleType = N;
type DeltaRotationType = Rot2<N>;
#[inline]
fn angle_to(&self, other: &Self) -> N {
self.rotation_to(other).rotation().norm()
}
#[inline]
fn rotation_to(&self, other: &Self) -> Rot2<N> {
*other * ::inv(self).unwrap()
}
}
impl<N: Rand + BaseFloat> Rand for Rot2<N> {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> Rot2<N> {
Rot2::new(rng.gen())
}
}
impl<N: BaseFloat> AbsoluteRotate<Vec2<N>> for Rot2<N> {
#[inline]
fn absolute_rotate(&self, v: &Vec2<N>) -> Vec2<N> {
// the matrix is skew-symetric, so we dont need to compute the absolute value of every
// component.
let m11 = ::abs(&self.submat.m11);
let m12 = ::abs(&self.submat.m12);
let m22 = ::abs(&self.submat.m22);
Vec2::new(m11 * v.x + m12 * v.y, m12 * v.x + m22 * v.y)
}
}
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + Clone + BaseFloat + Neg<Output = N>> Arbitrary for Rot2<N> {
fn arbitrary<G: Gen>(g: &mut G) -> Rot2<N> {
Rot2::new(Arbitrary::arbitrary(g))
}
}
/*
* 3d rotation
*/
/// Three dimensional rotation matrix.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Hash, Copy)]
pub struct Rot3<N> {
submat: Mat3<N>
}
impl<N: Clone + BaseFloat> Rot3<N> {
/// Builds a 3 dimensional rotation matrix from an axis and an angle.
///
/// # Arguments
/// * `axisangle` - A vector representing the rotation. Its magnitude is the amount of rotation
/// in radian. Its direction is the axis of rotation.
pub fn new(axisangle: Vec3<N>) -> Rot3<N> {
if ::is_zero(&Norm::sqnorm(&axisangle)) {
::one()
}
else {
let mut axis = axisangle;
let angle = axis.normalize_mut();
let _1: N = ::one();
let ux = axis.x.clone();
let uy = axis.y.clone();
let uz = axis.z.clone();
let sqx = ux * ux;
let sqy = uy * uy;
let sqz = uz * uz;
let (sin, cos) = angle.sin_cos();
let one_m_cos = _1 - cos;
Rot3 {
submat: Mat3::new(
(sqx + (_1 - sqx) * cos),
(ux * uy * one_m_cos - uz * sin),
(ux * uz * one_m_cos + uy * sin),
(ux * uy * one_m_cos + uz * sin),
(sqy + (_1 - sqy) * cos),
(uy * uz * one_m_cos - ux * sin),
(ux * uz * one_m_cos - uy * sin),
(uy * uz * one_m_cos + ux * sin),
(sqz + (_1 - sqz) * cos))
}
}
}
/// Builds a rotation matrix from an orthogonal matrix.
///
/// This is unsafe because the orthogonality of `mat` is not checked.
pub unsafe fn new_with_mat(mat: Mat3<N>) -> Rot3<N> {
Rot3 {
submat: mat
}
}
/// Creates a new rotation from Euler angles.
///
/// The primitive rotations are applied in order: 1 roll 2 pitch 3 yaw.
pub fn new_with_euler_angles(roll: N, pitch: N, yaw: N) -> Rot3<N> {
let (sr, cr) = roll.sin_cos();
let (sp, cp) = pitch.sin_cos();
let (sy, cy) = yaw.sin_cos();
unsafe {
Rot3::new_with_mat(
Mat3::new(
cy * cp, cy * sp * sr - sy * cr, cy * sp * cr + sy * sr,
sy * cp, sy * sp * sr + cy * cr, sy * sp * cr - cy * sr,
-sp, cp * sr, cp * cr
)
)
}
}
}
impl<N: Clone + BaseFloat> Rot3<N> {
/// Creates a rotation that corresponds to the local frame of an observer standing at the
/// origin and looking toward `dir`.
///
/// It maps the view direction `dir` to the positive `z` axis.
///
/// # Arguments
/// * dir - The look direction, that is, direction the matrix `z` axis will be aligned with.
/// * up - The vertical direction. The only requirement of this parameter is to not be
/// collinear
/// to `dir`. Non-collinearity is not checked.
#[inline]
pub fn new_observer_frame(dir: &Vec3<N>, up: &Vec3<N>) -> Rot3<N> {
let zaxis = Norm::normalize(dir);
let xaxis = Norm::normalize(&Cross::cross(up, &zaxis));
let yaxis = Norm::normalize(&Cross::cross(&zaxis, &xaxis));
unsafe {
Rot3::new_with_mat(Mat3::new(
xaxis.x.clone(), yaxis.x.clone(), zaxis.x.clone(),
xaxis.y.clone(), yaxis.y.clone(), zaxis.y.clone(),
xaxis.z , yaxis.z , zaxis.z))
}
}
/// Builds a right-handed look-at view matrix without translation.
///
/// This conforms to the common notion of right handed look-at matrix from the computer
/// graphics community.
///
/// # Arguments
/// * eye - The eye position.
/// * target - The target position.
/// * up - A vector approximately aligned with required the vertical axis. The only
/// requirement of this parameter is to not be collinear to `target - eye`.
#[inline]
pub fn look_at_rh(dir: &Vec3<N>, up: &Vec3<N>) -> Rot3<N> {
Rot3::new_observer_frame(&(-*dir), up).inv().unwrap()
}
/// Builds a left-handed look-at view matrix without translation.
///
/// This conforms to the common notion of left handed look-at matrix from the computer
/// graphics community.
///
/// # Arguments
/// * eye - The eye position.
/// * target - The target position.
/// * up - A vector approximately aligned with required the vertical axis. The only
/// requirement of this parameter is to not be collinear to `target - eye`.
#[inline]
pub fn look_at_lh(dir: &Vec3<N>, up: &Vec3<N>) -> Rot3<N> {
Rot3::new_observer_frame(&(*dir), up).inv().unwrap()
}
}
impl<N: Clone + BaseFloat + Cast<f64>>
Rotation<Vec3<N>> for Rot3<N> {
#[inline]
fn rotation(&self) -> Vec3<N> {
let angle = ((self.submat.m11 + self.submat.m22 + self.submat.m33 - ::one()) / Cast::from(2.0)).acos();
if angle != angle {
// FIXME: handle that correctly
::zero()
}
else if ::is_zero(&angle) {
::zero()
}
else {
let m32_m23 = self.submat.m32 - self.submat.m23;
let m13_m31 = self.submat.m13 - self.submat.m31;
let m21_m12 = self.submat.m21 - self.submat.m12;
let denom = (m32_m23 * m32_m23 + m13_m31 * m13_m31 + m21_m12 * m21_m12).sqrt();
if ::is_zero(&denom) {
// XXX: handle that properly
// panic!("Internal error: singularity.")
::zero()
}
else {
let a_d = angle / denom;
Vec3::new(m32_m23 * a_d, m13_m31 * a_d, m21_m12 * a_d)
}
}
}
#[inline]
fn inv_rotation(&self) -> Vec3<N> {
-self.rotation()
}
#[inline]
fn append_rotation_mut(&mut self, rot: &Vec3<N>) {
*self = Rotation::append_rotation(self, rot)
}
#[inline]
fn append_rotation(&self, axisangle: &Vec3<N>) -> Rot3<N> {
Rot3::new(axisangle.clone()) * *self
}
#[inline]
fn prepend_rotation_mut(&mut self, rot: &Vec3<N>) {
*self = Rotation::prepend_rotation(self, rot)
}
#[inline]
fn prepend_rotation(&self, axisangle: &Vec3<N>) -> Rot3<N> {
*self * Rot3::new(axisangle.clone())
}
#[inline]
fn set_rotation(&mut self, axisangle: Vec3<N>) {
*self = Rot3::new(axisangle)
}
}
impl<N: BaseFloat> RotationTo for Rot3<N> {
type AngleType = N;
type DeltaRotationType = Rot3<N>;
#[inline]
fn angle_to(&self, other: &Self) -> N {
// FIXME: refactor to avoid the normalization of the rotation axisangle vector.
self.rotation_to(other).rotation().norm()
}
#[inline]
fn rotation_to(&self, other: &Self) -> Rot3<N> {
*other * ::inv(self).unwrap()
}
}
impl<N: Clone + Rand + BaseFloat> Rand for Rot3<N> {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> Rot3<N> {
Rot3::new(rng.gen())
}
}
impl<N: BaseFloat> AbsoluteRotate<Vec3<N>> for Rot3<N> {
#[inline]
fn absolute_rotate(&self, v: &Vec3<N>) -> Vec3<N> {
Vec3::new(
::abs(&self.submat.m11) * v.x + ::abs(&self.submat.m12) * v.y + ::abs(&self.submat.m13) * v.z,
::abs(&self.submat.m21) * v.x + ::abs(&self.submat.m22) * v.y + ::abs(&self.submat.m23) * v.z,
::abs(&self.submat.m31) * v.x + ::abs(&self.submat.m32) * v.y + ::abs(&self.submat.m33) * v.z)
}
}
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + Clone + BaseFloat> Arbitrary for Rot3<N> {
fn arbitrary<G: Gen>(g: &mut G) -> Rot3<N> {
Rot3::new(Arbitrary::arbitrary(g))
}
}
/*
* Common implementations.
*/
submat_impl!(Rot2, Mat2);
rotate_impl!(Rot2, Vec2, Pnt2);
transform_impl!(Rot2, Vec2, Pnt2);
dim_impl!(Rot2, 2);
rot_mul_rot_impl!(Rot2);
rot_mul_vec_impl!(Rot2, Vec2);
vec_mul_rot_impl!(Rot2, Vec2);
rot_mul_pnt_impl!(Rot2, Pnt2);
pnt_mul_rot_impl!(Rot2, Pnt2);
one_impl!(Rot2);
eye_impl!(Rot2);
rotation_matrix_impl!(Rot2, Vec2, Vec1);
col_impl!(Rot2, Vec2);
row_impl!(Rot2, Vec2);
index_impl!(Rot2);
absolute_impl!(Rot2, Mat2);
to_homogeneous_impl!(Rot2, Mat3);
inv_impl!(Rot2);
transpose_impl!(Rot2);
approx_eq_impl!(Rot2);
diag_impl!(Rot2, Vec2);
rot_display_impl!(Rot2);
submat_impl!(Rot3, Mat3);
rotate_impl!(Rot3, Vec3, Pnt3);
transform_impl!(Rot3, Vec3, Pnt3);
dim_impl!(Rot3, 3);
rot_mul_rot_impl!(Rot3);
rot_mul_vec_impl!(Rot3, Vec3);
vec_mul_rot_impl!(Rot3, Vec3);
rot_mul_pnt_impl!(Rot3, Pnt3);
pnt_mul_rot_impl!(Rot3, Pnt3);
one_impl!(Rot3);
eye_impl!(Rot3);
rotation_matrix_impl!(Rot3, Vec3, Vec3);
col_impl!(Rot3, Vec3);
row_impl!(Rot3, Vec3);
index_impl!(Rot3);
absolute_impl!(Rot3, Mat3);
to_homogeneous_impl!(Rot3, Mat4);
inv_impl!(Rot3);
transpose_impl!(Rot3);
approx_eq_impl!(Rot3);
diag_impl!(Rot3, Vec3);
rot_display_impl!(Rot3);

407
src/structs/rotation.rs Normal file
View File

@ -0,0 +1,407 @@
//! Rotations matrices.
use std::fmt;
use std::ops::{Mul, Neg, MulAssign, Index};
use rand::{Rand, Rng};
use num::{Zero, One};
use traits::geometry::{Rotate, Rotation, AbsoluteRotate, RotationMatrix, RotationTo, Transform,
ToHomogeneous, Norm, Cross};
use traits::structure::{Cast, Dimension, Row, Column, BaseFloat, BaseNum, Eye, Diagonal};
use traits::operations::{Absolute, Inverse, Transpose, ApproxEq};
use structs::vector::{Vector1, Vector2, Vector3};
use structs::point::{Point2, Point3};
use structs::matrix::{Matrix2, Matrix3, Matrix4};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
/// Two dimensional rotation matrix.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Hash, Copy)]
pub struct Rotation2<N> {
submatrix: Matrix2<N>
}
impl<N: Clone + BaseFloat + Neg<Output = N>> Rotation2<N> {
/// Builds a 2 dimensional rotation matrix from an angle in radian.
pub fn new(angle: Vector1<N>) -> Rotation2<N> {
let (sia, coa) = angle.x.sin_cos();
Rotation2 {
submatrix: Matrix2::new(coa.clone(), -sia, sia, coa)
}
}
}
impl<N: BaseFloat + Clone> Rotation<Vector1<N>> for Rotation2<N> {
#[inline]
fn rotation(&self) -> Vector1<N> {
Vector1::new((-self.submatrix.m12).atan2(self.submatrix.m11.clone()))
}
#[inline]
fn inverse_rotation(&self) -> Vector1<N> {
-self.rotation()
}
#[inline]
fn append_rotation_mut(&mut self, rotation: &Vector1<N>) {
*self = Rotation::append_rotation(self, rotation)
}
#[inline]
fn append_rotation(&self, rotation: &Vector1<N>) -> Rotation2<N> {
Rotation2::new(rotation.clone()) * *self
}
#[inline]
fn prepend_rotation_mut(&mut self, rotation: &Vector1<N>) {
*self = Rotation::prepend_rotation(self, rotation)
}
#[inline]
fn prepend_rotation(&self, rotation: &Vector1<N>) -> Rotation2<N> {
*self * Rotation2::new(rotation.clone())
}
#[inline]
fn set_rotation(&mut self, rotation: Vector1<N>) {
*self = Rotation2::new(rotation)
}
}
impl<N: BaseFloat> RotationTo for Rotation2<N> {
type AngleType = N;
type DeltaRotationType = Rotation2<N>;
#[inline]
fn angle_to(&self, other: &Self) -> N {
self.rotation_to(other).rotation().norm()
}
#[inline]
fn rotation_to(&self, other: &Self) -> Rotation2<N> {
*other * ::inverse(self).unwrap()
}
}
impl<N: Rand + BaseFloat> Rand for Rotation2<N> {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> Rotation2<N> {
Rotation2::new(rng.gen())
}
}
impl<N: BaseFloat> AbsoluteRotate<Vector2<N>> for Rotation2<N> {
#[inline]
fn absolute_rotate(&self, v: &Vector2<N>) -> Vector2<N> {
// the matrix is skew-symetric, so we dont need to compute the absolute value of every
// component.
let m11 = ::abs(&self.submatrix.m11);
let m12 = ::abs(&self.submatrix.m12);
let m22 = ::abs(&self.submatrix.m22);
Vector2::new(m11 * v.x + m12 * v.y, m12 * v.x + m22 * v.y)
}
}
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + Clone + BaseFloat + Neg<Output = N>> Arbitrary for Rotation2<N> {
fn arbitrary<G: Gen>(g: &mut G) -> Rotation2<N> {
Rotation2::new(Arbitrary::arbitrary(g))
}
}
/*
* 3d rotation
*/
/// Three dimensional rotation matrix.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Hash, Copy)]
pub struct Rotation3<N> {
submatrix: Matrix3<N>
}
impl<N: Clone + BaseFloat> Rotation3<N> {
/// Builds a 3 dimensional rotation matrix from an axis and an angle.
///
/// # Arguments
/// * `axisangle` - A vector representing the rotation. Its magnitude is the amount of rotation
/// in radian. Its direction is the axis of rotation.
pub fn new(axisangle: Vector3<N>) -> Rotation3<N> {
if ::is_zero(&Norm::norm_squared(&axisangle)) {
::one()
}
else {
let mut axis = axisangle;
let angle = axis.normalize_mut();
let _1: N = ::one();
let ux = axis.x.clone();
let uy = axis.y.clone();
let uz = axis.z.clone();
let sqx = ux * ux;
let sqy = uy * uy;
let sqz = uz * uz;
let (sin, cos) = angle.sin_cos();
let one_m_cos = _1 - cos;
Rotation3 {
submatrix: Matrix3::new(
(sqx + (_1 - sqx) * cos),
(ux * uy * one_m_cos - uz * sin),
(ux * uz * one_m_cos + uy * sin),
(ux * uy * one_m_cos + uz * sin),
(sqy + (_1 - sqy) * cos),
(uy * uz * one_m_cos - ux * sin),
(ux * uz * one_m_cos - uy * sin),
(uy * uz * one_m_cos + ux * sin),
(sqz + (_1 - sqz) * cos))
}
}
}
/// Builds a rotation matrix from an orthogonal matrix.
///
/// This is unsafe because the orthogonality of `matrix` is not checked.
pub unsafe fn new_with_matrix(matrix: Matrix3<N>) -> Rotation3<N> {
Rotation3 {
submatrix: matrix
}
}
/// Creates a new rotation from Euler angles.
///
/// The primitive rotations are applied in order: 1 roll 2 pitch 3 yaw.
pub fn new_with_euler_angles(roll: N, pitch: N, yaw: N) -> Rotation3<N> {
let (sr, cr) = roll.sin_cos();
let (sp, cp) = pitch.sin_cos();
let (sy, cy) = yaw.sin_cos();
unsafe {
Rotation3::new_with_matrix(
Matrix3::new(
cy * cp, cy * sp * sr - sy * cr, cy * sp * cr + sy * sr,
sy * cp, sy * sp * sr + cy * cr, sy * sp * cr - cy * sr,
-sp, cp * sr, cp * cr
)
)
}
}
}
impl<N: Clone + BaseFloat> Rotation3<N> {
/// Creates a rotation that corresponds to the local frame of an observer standing at the
/// origin and looking toward `dir`.
///
/// It maps the view direction `dir` to the positive `z` axis.
///
/// # Arguments
/// * dir - The look direction, that is, direction the matrix `z` axis will be aligned with.
/// * up - The vertical direction. The only requirement of this parameter is to not be
/// collinear
/// to `dir`. Non-collinearity is not checked.
#[inline]
pub fn new_observer_frame(dir: &Vector3<N>, up: &Vector3<N>) -> Rotation3<N> {
let zaxis = Norm::normalize(dir);
let xaxis = Norm::normalize(&Cross::cross(up, &zaxis));
let yaxis = Norm::normalize(&Cross::cross(&zaxis, &xaxis));
unsafe {
Rotation3::new_with_matrix(Matrix3::new(
xaxis.x.clone(), yaxis.x.clone(), zaxis.x.clone(),
xaxis.y.clone(), yaxis.y.clone(), zaxis.y.clone(),
xaxis.z , yaxis.z , zaxis.z))
}
}
/// Builds a right-handed look-at view matrix without translation.
///
/// This conforms to the common notion of right handed look-at matrix from the computer
/// graphics community.
///
/// # Arguments
/// * eye - The eye position.
/// * target - The target position.
/// * up - A vector approximately aligned with required the vertical axis. The only
/// requirement of this parameter is to not be collinear to `target - eye`.
#[inline]
pub fn look_at_rh(dir: &Vector3<N>, up: &Vector3<N>) -> Rotation3<N> {
Rotation3::new_observer_frame(&(-*dir), up).inverse().unwrap()
}
/// Builds a left-handed look-at view matrix without translation.
///
/// This conforms to the common notion of left handed look-at matrix from the computer
/// graphics community.
///
/// # Arguments
/// * eye - The eye position.
/// * target - The target position.
/// * up - A vector approximately aligned with required the vertical axis. The only
/// requirement of this parameter is to not be collinear to `target - eye`.
#[inline]
pub fn look_at_lh(dir: &Vector3<N>, up: &Vector3<N>) -> Rotation3<N> {
Rotation3::new_observer_frame(&(*dir), up).inverse().unwrap()
}
}
impl<N: Clone + BaseFloat + Cast<f64>>
Rotation<Vector3<N>> for Rotation3<N> {
#[inline]
fn rotation(&self) -> Vector3<N> {
let angle = ((self.submatrix.m11 + self.submatrix.m22 + self.submatrix.m33 - ::one()) / Cast::from(2.0)).acos();
if angle != angle {
// FIXME: handle that correctly
::zero()
}
else if ::is_zero(&angle) {
::zero()
}
else {
let m32_m23 = self.submatrix.m32 - self.submatrix.m23;
let m13_m31 = self.submatrix.m13 - self.submatrix.m31;
let m21_m12 = self.submatrix.m21 - self.submatrix.m12;
let denom = (m32_m23 * m32_m23 + m13_m31 * m13_m31 + m21_m12 * m21_m12).sqrt();
if ::is_zero(&denom) {
// XXX: handle that properly
// panic!("Internal error: singularity.")
::zero()
}
else {
let a_d = angle / denom;
Vector3::new(m32_m23 * a_d, m13_m31 * a_d, m21_m12 * a_d)
}
}
}
#[inline]
fn inverse_rotation(&self) -> Vector3<N> {
-self.rotation()
}
#[inline]
fn append_rotation_mut(&mut self, rotation: &Vector3<N>) {
*self = Rotation::append_rotation(self, rotation)
}
#[inline]
fn append_rotation(&self, axisangle: &Vector3<N>) -> Rotation3<N> {
Rotation3::new(axisangle.clone()) * *self
}
#[inline]
fn prepend_rotation_mut(&mut self, rotation: &Vector3<N>) {
*self = Rotation::prepend_rotation(self, rotation)
}
#[inline]
fn prepend_rotation(&self, axisangle: &Vector3<N>) -> Rotation3<N> {
*self * Rotation3::new(axisangle.clone())
}
#[inline]
fn set_rotation(&mut self, axisangle: Vector3<N>) {
*self = Rotation3::new(axisangle)
}
}
impl<N: BaseFloat> RotationTo for Rotation3<N> {
type AngleType = N;
type DeltaRotationType = Rotation3<N>;
#[inline]
fn angle_to(&self, other: &Self) -> N {
// FIXME: refactor to avoid the normalization of the rotation axisangle vector.
self.rotation_to(other).rotation().norm()
}
#[inline]
fn rotation_to(&self, other: &Self) -> Rotation3<N> {
*other * ::inverse(self).unwrap()
}
}
impl<N: Clone + Rand + BaseFloat> Rand for Rotation3<N> {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> Rotation3<N> {
Rotation3::new(rng.gen())
}
}
impl<N: BaseFloat> AbsoluteRotate<Vector3<N>> for Rotation3<N> {
#[inline]
fn absolute_rotate(&self, v: &Vector3<N>) -> Vector3<N> {
Vector3::new(
::abs(&self.submatrix.m11) * v.x + ::abs(&self.submatrix.m12) * v.y + ::abs(&self.submatrix.m13) * v.z,
::abs(&self.submatrix.m21) * v.x + ::abs(&self.submatrix.m22) * v.y + ::abs(&self.submatrix.m23) * v.z,
::abs(&self.submatrix.m31) * v.x + ::abs(&self.submatrix.m32) * v.y + ::abs(&self.submatrix.m33) * v.z)
}
}
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + Clone + 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);
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);
col_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);
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);
col_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,12 +1,12 @@
#![macro_use] #![macro_use]
macro_rules! submat_impl( macro_rules! submat_impl(
($t: ident, $submat: ident) => ( ($t: ident, $submatrix: ident) => (
impl<N> $t<N> { impl<N> $t<N> {
/// This rotation's underlying matrix. /// This rotation's underlying matrix.
#[inline] #[inline]
pub fn submat<'r>(&'r self) -> &'r $submat<N> { pub fn submatrix<'r>(&'r self) -> &'r $submatrix<N> {
&self.submat &self.submatrix
} }
} }
) )
@ -21,7 +21,7 @@ macro_rules! rotate_impl(
} }
#[inline] #[inline]
fn inv_rotate(&self, v: &$tv<N>) -> $tv<N> { fn inverse_rotate(&self, v: &$tv<N>) -> $tv<N> {
*v * *self *v * *self
} }
} }
@ -33,7 +33,7 @@ macro_rules! rotate_impl(
} }
#[inline] #[inline]
fn inv_rotate(&self, p: &$tp<N>) -> $tp<N> { fn inverse_rotate(&self, p: &$tp<N>) -> $tp<N> {
*p * *self *p * *self
} }
} }
@ -49,8 +49,8 @@ macro_rules! transform_impl(
} }
#[inline] #[inline]
fn inv_transform(&self, v: &$tv<N>) -> $tv<N> { fn inverse_transform(&self, v: &$tv<N>) -> $tv<N> {
self.inv_rotate(v) self.inverse_rotate(v)
} }
} }
@ -61,19 +61,19 @@ macro_rules! transform_impl(
} }
#[inline] #[inline]
fn inv_transform(&self, p: &$tp<N>) -> $tp<N> { fn inverse_transform(&self, p: &$tp<N>) -> $tp<N> {
self.inv_rotate(p) self.inverse_rotate(p)
} }
} }
) )
); );
macro_rules! dim_impl( macro_rules! dim_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N> Dim for $t<N> { impl<N> Dimension for $t<N> {
#[inline] #[inline]
fn dim(_: Option<$t<N>>) -> usize { fn dimension(_: Option<$t<N>>) -> usize {
$dim $dimension
} }
} }
) )
@ -85,7 +85,7 @@ macro_rules! rotation_matrix_impl(
type Output = $t<N>; type Output = $t<N>;
#[inline] #[inline]
fn to_rot_mat(&self) -> $t<N> { fn to_rotation_matrix(&self) -> $t<N> {
self.clone() self.clone()
} }
} }
@ -97,7 +97,7 @@ macro_rules! one_impl(
impl<N: BaseNum> One for $t<N> { impl<N: BaseNum> One for $t<N> {
#[inline] #[inline]
fn one() -> $t<N> { fn one() -> $t<N> {
$t { submat: ::one() } $t { submatrix: ::one() }
} }
} }
) )
@ -107,9 +107,9 @@ macro_rules! eye_impl(
($t: ident) => ( ($t: ident) => (
impl<N: BaseNum> Eye for $t<N> { impl<N: BaseNum> Eye for $t<N> {
#[inline] #[inline]
fn new_identity(dim: usize) -> $t<N> { fn new_identity(dimension: usize) -> $t<N> {
if dim != ::dim::<$t<N>>() { if dimension != ::dimension::<$t<N>>() {
panic!("Dimension mismatch: should be {}, got {}.", ::dim::<$t<N>>(), dim); panic!("Dimension mismatch: should be {}, got {}.", ::dimension::<$t<N>>(), dimension);
} }
else { else {
::one() ::one()
@ -121,90 +121,90 @@ macro_rules! eye_impl(
macro_rules! diag_impl( macro_rules! diag_impl(
($t: ident, $tv: ident) => ( ($t: ident, $tv: ident) => (
impl<N: Copy + Zero> Diag<$tv<N>> for $t<N> { impl<N: Copy + Zero> Diagonal<$tv<N>> for $t<N> {
#[inline] #[inline]
fn from_diag(diag: &$tv<N>) -> $t<N> { fn from_diag(diagonal: &$tv<N>) -> $t<N> {
$t { submat: Diag::from_diag(diag) } $t { submatrix: Diagonal::from_diag(diagonal) }
} }
#[inline] #[inline]
fn diag(&self) -> $tv<N> { fn diagonal(&self) -> $tv<N> {
self.submat.diag() self.submatrix.diagonal()
} }
} }
) )
); );
macro_rules! rot_mul_rot_impl( macro_rules! rotation_mul_rotation_impl(
($t: ident) => ( ($t: ident) => (
impl<N: BaseNum> Mul<$t<N>> for $t<N> { impl<N: BaseNum> Mul<$t<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
#[inline] #[inline]
fn mul(self, right: $t<N>) -> $t<N> { fn mul(self, right: $t<N>) -> $t<N> {
$t { submat: self.submat * right.submat } $t { submatrix: self.submatrix * right.submatrix }
} }
} }
impl<N: Copy + BaseNum> MulAssign<$t<N>> for $t<N> { impl<N: Copy + BaseNum> MulAssign<$t<N>> for $t<N> {
#[inline] #[inline]
fn mul_assign(&mut self, right: $t<N>) { fn mul_assign(&mut self, right: $t<N>) {
self.submat *= right.submat self.submatrix *= right.submatrix
} }
} }
) )
); );
macro_rules! rot_mul_vec_impl( macro_rules! rotation_mul_vec_impl(
($t: ident, $tv: ident) => ( ($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$tv<N>> for $t<N> { impl<N: BaseNum> Mul<$tv<N>> for $t<N> {
type Output = $tv<N>; type Output = $tv<N>;
#[inline] #[inline]
fn mul(self, right: $tv<N>) -> $tv<N> { fn mul(self, right: $tv<N>) -> $tv<N> {
self.submat * right self.submatrix * right
} }
} }
) )
); );
macro_rules! rot_mul_pnt_impl( macro_rules! rotation_mul_point_impl(
($t: ident, $tv: ident) => ( ($t: ident, $tv: ident) => (
rot_mul_vec_impl!($t, $tv); rotation_mul_vec_impl!($t, $tv);
) )
); );
macro_rules! vec_mul_rot_impl( macro_rules! vec_mul_rotation_impl(
($t: ident, $tv: ident) => ( ($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$t<N>> for $tv<N> { impl<N: BaseNum> Mul<$t<N>> for $tv<N> {
type Output = $tv<N>; type Output = $tv<N>;
#[inline] #[inline]
fn mul(self, right: $t<N>) -> $tv<N> { fn mul(self, right: $t<N>) -> $tv<N> {
self * right.submat self * right.submatrix
} }
} }
impl<N: Copy + BaseNum> MulAssign<$t<N>> for $tv<N> { impl<N: Copy + BaseNum> MulAssign<$t<N>> for $tv<N> {
#[inline] #[inline]
fn mul_assign(&mut self, right: $t<N>) { fn mul_assign(&mut self, right: $t<N>) {
*self *= right.submat *self *= right.submatrix
} }
} }
) )
); );
macro_rules! pnt_mul_rot_impl( macro_rules! point_mul_rotation_impl(
($t: ident, $tv: ident) => ( ($t: ident, $tv: ident) => (
vec_mul_rot_impl!($t, $tv); vec_mul_rotation_impl!($t, $tv);
) )
); );
macro_rules! inv_impl( macro_rules! inverse_impl(
($t: ident) => ( ($t: ident) => (
impl<N: Copy> Inv for $t<N> { impl<N: Copy> Inverse for $t<N> {
#[inline] #[inline]
fn inv_mut(&mut self) -> bool { fn inverse_mut(&mut self) -> bool {
self.transpose_mut(); self.transpose_mut();
// always succeed // always succeed
@ -212,7 +212,7 @@ macro_rules! inv_impl(
} }
#[inline] #[inline]
fn inv(&self) -> Option<$t<N>> { fn inverse(&self) -> Option<$t<N>> {
// always succeed // always succeed
Some(self.transpose()) Some(self.transpose())
} }
@ -225,12 +225,12 @@ macro_rules! transpose_impl(
impl<N: Copy> Transpose for $t<N> { impl<N: Copy> Transpose for $t<N> {
#[inline] #[inline]
fn transpose(&self) -> $t<N> { fn transpose(&self) -> $t<N> {
$t { submat: Transpose::transpose(&self.submat) } $t { submatrix: Transpose::transpose(&self.submatrix) }
} }
#[inline] #[inline]
fn transpose_mut(&mut self) { fn transpose_mut(&mut self) {
self.submat.transpose_mut() self.submatrix.transpose_mut()
} }
} }
) )
@ -241,16 +241,16 @@ macro_rules! row_impl(
impl<N: Copy + Zero> Row<$tv<N>> for $t<N> { impl<N: Copy + Zero> Row<$tv<N>> for $t<N> {
#[inline] #[inline]
fn nrows(&self) -> usize { fn nrows(&self) -> usize {
self.submat.nrows() self.submatrix.nrows()
} }
#[inline] #[inline]
fn row(&self, i: usize) -> $tv<N> { fn row(&self, i: usize) -> $tv<N> {
self.submat.row(i) self.submatrix.row(i)
} }
#[inline] #[inline]
fn set_row(&mut self, i: usize, row: $tv<N>) { fn set_row(&mut self, i: usize, row: $tv<N>) {
self.submat.set_row(i, row); self.submatrix.set_row(i, row);
} }
} }
) )
@ -258,19 +258,19 @@ macro_rules! row_impl(
macro_rules! col_impl( macro_rules! col_impl(
($t: ident, $tv: ident) => ( ($t: ident, $tv: ident) => (
impl<N: Copy + Zero> Col<$tv<N>> for $t<N> { impl<N: Copy + Zero> Column<$tv<N>> for $t<N> {
#[inline] #[inline]
fn ncols(&self) -> usize { fn ncols(&self) -> usize {
self.submat.ncols() self.submatrix.ncols()
} }
#[inline] #[inline]
fn col(&self, i: usize) -> $tv<N> { fn column(&self, i: usize) -> $tv<N> {
self.submat.col(i) self.submatrix.column(i)
} }
#[inline] #[inline]
fn set_col(&mut self, i: usize, col: $tv<N>) { fn set_col(&mut self, i: usize, column: $tv<N>) {
self.submat.set_col(i, col); self.submatrix.set_col(i, column);
} }
} }
) )
@ -282,7 +282,7 @@ macro_rules! index_impl(
type Output = N; type Output = N;
fn index(&self, i: (usize, usize)) -> &N { fn index(&self, i: (usize, usize)) -> &N {
&self.submat[i] &self.submatrix[i]
} }
} }
) )
@ -293,7 +293,7 @@ macro_rules! to_homogeneous_impl(
impl<N: BaseNum> ToHomogeneous<$tm<N>> for $t<N> { impl<N: BaseNum> ToHomogeneous<$tm<N>> for $t<N> {
#[inline] #[inline]
fn to_homogeneous(&self) -> $tm<N> { fn to_homogeneous(&self) -> $tm<N> {
self.submat.to_homogeneous() self.submatrix.to_homogeneous()
} }
} }
) )
@ -314,17 +314,17 @@ macro_rules! approx_eq_impl(
#[inline] #[inline]
fn approx_eq(&self, other: &$t<N>) -> bool { fn approx_eq(&self, other: &$t<N>) -> bool {
ApproxEq::approx_eq(&self.submat, &other.submat) ApproxEq::approx_eq(&self.submatrix, &other.submatrix)
} }
#[inline] #[inline]
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N) -> bool { fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N) -> bool {
ApproxEq::approx_eq_eps(&self.submat, &other.submat, epsilon) ApproxEq::approx_eq_eps(&self.submatrix, &other.submatrix, epsilon)
} }
#[inline] #[inline]
fn approx_eq_ulps(&self, other: &$t<N>, ulps: u32) -> bool { fn approx_eq_ulps(&self, other: &$t<N>, ulps: u32) -> bool {
ApproxEq::approx_eq_ulps(&self.submat, &other.submat, ulps) ApproxEq::approx_eq_ulps(&self.submatrix, &other.submatrix, ulps)
} }
} }
) )
@ -335,20 +335,20 @@ macro_rules! absolute_impl(
impl<N: Absolute<N>> Absolute<$tm<N>> for $t<N> { impl<N: Absolute<N>> Absolute<$tm<N>> for $t<N> {
#[inline] #[inline]
fn abs(m: &$t<N>) -> $tm<N> { fn abs(m: &$t<N>) -> $tm<N> {
Absolute::abs(&m.submat) Absolute::abs(&m.submatrix)
} }
} }
) )
); );
macro_rules! rot_display_impl( macro_rules! rotation_display_impl(
($t: ident) => ( ($t: ident) => (
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> { impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let precision = f.precision().unwrap_or(3); let precision = f.precision().unwrap_or(3);
try!(writeln!(f, "Rotation matrix {{")); try!(writeln!(f, "Rotation matrix {{"));
try!(write!(f, "{:.*}", precision, self.submat)); try!(write!(f, "{:.*}", precision, self.submatrix));
writeln!(f, "}}") writeln!(f, "}}")
} }
} }

View File

@ -1,86 +0,0 @@
use std::fmt;
use std::ops::{Mul, Neg, MulAssign};
use rand::{Rand, Rng};
use num::One;
use structs::mat::{Mat3, Mat4};
use traits::structure::{Dim, Col, BaseFloat, BaseNum};
use traits::operations::{Inv, ApproxEq};
use traits::geometry::{Rotation, Transform, Transformation, Translation, ToHomogeneous};
use structs::vec::{Vec1, Vec2, Vec3};
use structs::pnt::{Pnt2, Pnt3};
use structs::rot::{Rot2, Rot3};
use structs::iso::{Iso2, Iso3};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
// FIXME: the name is not explicit at all but coherent with the other tree-letters names…
/// A two-dimensional similarity transformation.
///
/// This is a composition of a uniform scale, followed by a rotation, followed by a translation.
/// Vectors `Vec2` are not affected by the translational component of this transformation while
/// points `Pnt2` are.
/// Similarity transformations conserve angles. Distances are multiplied by some constant (the
/// scale factor). The scale factor cannot be zero.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct Sim2<N> {
/// The uniform scale applicable by this similarity transformation.
scale: N,
/// The isometry applicable by this similarity transformation.
pub isometry: Iso2<N>
}
/// A three-dimensional similarity transformation.
///
/// This is a composition of a scale, followed by a rotation, followed by a translation.
/// Vectors `Vec3` are not affected by the translational component of this transformation while
/// points `Pnt3` are.
/// Similarity transformations conserve angles. Distances are multiplied by some constant (the
/// scale factor). The scale factor cannot be zero.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct Sim3<N> {
/// The uniform scale applicable by this similarity transformation.
scale: N,
/// The isometry applicable by this similarity transformation.
pub isometry: Iso3<N>
}
sim_impl!(Sim2, Iso2, Rot2, Vec2, Vec1);
dim_impl!(Sim2, 2);
sim_scale_impl!(Sim2);
sim_one_impl!(Sim2);
sim_mul_sim_impl!(Sim2);
sim_mul_iso_impl!(Sim2, Iso2);
sim_mul_rot_impl!(Sim2, Rot2);
sim_mul_pnt_vec_impl!(Sim2, Pnt2);
sim_mul_pnt_vec_impl!(Sim2, Vec2);
transformation_impl!(Sim2);
sim_transform_impl!(Sim2, Pnt2);
sim_inv_impl!(Sim2);
sim_to_homogeneous_impl!(Sim2, Mat3);
sim_approx_eq_impl!(Sim2);
sim_rand_impl!(Sim2);
sim_arbitrary_impl!(Sim2);
sim_display_impl!(Sim2);
sim_impl!(Sim3, Iso3, Rot3, Vec3, Vec3);
dim_impl!(Sim3, 3);
sim_scale_impl!(Sim3);
sim_one_impl!(Sim3);
sim_mul_sim_impl!(Sim3);
sim_mul_iso_impl!(Sim3, Iso3);
sim_mul_rot_impl!(Sim3, Rot3);
sim_mul_pnt_vec_impl!(Sim3, Pnt3);
sim_mul_pnt_vec_impl!(Sim3, Vec3);
transformation_impl!(Sim3);
sim_transform_impl!(Sim3, Pnt3);
sim_inv_impl!(Sim3);
sim_to_homogeneous_impl!(Sim3, Mat4);
sim_approx_eq_impl!(Sim3);
sim_rand_impl!(Sim3);
sim_arbitrary_impl!(Sim3);
sim_display_impl!(Sim3);

86
src/structs/similarity.rs Normal file
View File

@ -0,0 +1,86 @@
use std::fmt;
use std::ops::{Mul, Neg, MulAssign};
use rand::{Rand, Rng};
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 structs::vector::{Vector1, Vector2, Vector3};
use structs::point::{Point2, Point3};
use structs::rotation::{Rotation2, Rotation3};
use structs::isometry::{Isometry2, Isometry3};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
// FIXME: the name is not explicit at all but coherent with the other tree-letters names…
/// A two-dimensional similarity transformation.
///
/// This is a composition of a uniform scale, followed by a rotation, followed by a translation.
/// Vectors `Vector2` are not affected by the translational component of this transformation while
/// points `Point2` are.
/// Similarity transformations conserve angles. Distances are multiplied by some constant (the
/// scale factor). The scale factor cannot be zero.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct Similarity2<N> {
/// The uniform scale applicable by this similarity transformation.
scale: N,
/// The isometry applicable by this similarity transformation.
pub isometry: Isometry2<N>
}
/// A three-dimensional similarity transformation.
///
/// This is a composition of a scale, followed by a rotation, followed by a translation.
/// Vectors `Vector3` are not affected by the translational component of this transformation while
/// points `Point3` are.
/// Similarity transformations conserve angles. Distances are multiplied by some constant (the
/// scale factor). The scale factor cannot be zero.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct Similarity3<N> {
/// The uniform scale applicable by this similarity transformation.
scale: N,
/// The isometry applicable by this similarity transformation.
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);
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,18 +1,18 @@
#![macro_use] #![macro_use]
macro_rules! sim_impl( macro_rules! sim_impl(
($t: ident, $iso: ident, $rotmat: ident, $subvec: ident, $subrotvec: ident) => ( ($t: ident, $isometry: ident, $rotation_matrix: ident, $subvector: ident, $subrotvector: ident) => (
impl<N: BaseFloat> $t<N> { impl<N: BaseFloat> $t<N> {
/// Creates a new similarity transformation from a vector, an axis-angle rotation, and a scale factor. /// Creates a new similarity transformation from a vector, an axis-angle rotation, and a scale factor.
/// ///
/// The scale factor may be negative but not zero. /// The scale factor may be negative but not zero.
#[inline] #[inline]
pub fn new(translation: $subvec<N>, rotation: $subrotvec<N>, scale: N) -> $t<N> { pub fn new(translation: $subvector<N>, rotation: $subrotvector<N>, scale: N) -> $t<N> {
assert!(!scale.is_zero(), "A similarity transformation scale factor cannot be zero."); assert!(!scale.is_zero(), "A similarity transformation scale factor cannot be zero.");
$t { $t {
scale: scale, scale: scale,
isometry: $iso::new(translation, rotation) isometry: $isometry::new(translation, rotation)
} }
} }
@ -20,12 +20,12 @@ macro_rules! sim_impl(
/// ///
/// The scale factor may be negative but not zero. /// The scale factor may be negative but not zero.
#[inline] #[inline]
pub fn new_with_rotmat(translation: $subvec<N>, rotation: $rotmat<N>, scale: N) -> $t<N> { pub fn new_with_rotation_matrix(translation: $subvector<N>, rotation: $rotation_matrix<N>, scale: N) -> $t<N> {
assert!(!scale.is_zero(), "A similarity transformation scale factor cannot be zero."); assert!(!scale.is_zero(), "A similarity transformation scale factor cannot be zero.");
$t { $t {
scale: scale, scale: scale,
isometry: $iso::new_with_rotmat(translation, rotation) isometry: $isometry::new_with_rotation_matrix(translation, rotation)
} }
} }
@ -33,7 +33,7 @@ macro_rules! sim_impl(
/// ///
/// The scale factor may be negative but not zero. /// The scale factor may be negative but not zero.
#[inline] #[inline]
pub fn new_with_iso(isometry: $iso<N>, scale: N) -> $t<N> { pub fn new_with_isometry(isometry: $isometry<N>, scale: N) -> $t<N> {
assert!(!scale.is_zero(), "A similarity transformation scale factor cannot be zero."); assert!(!scale.is_zero(), "A similarity transformation scale factor cannot be zero.");
$t { $t {
@ -56,7 +56,7 @@ macro_rules! sim_scale_impl(
/// The inverse scale factor of this similarity transformation. /// The inverse scale factor of this similarity transformation.
#[inline] #[inline]
pub fn inv_scale(&self) -> N { pub fn inverse_scale(&self) -> N {
::one::<N>() / self.scale ::one::<N>() / self.scale
} }
@ -72,7 +72,7 @@ macro_rules! sim_scale_impl(
#[inline] #[inline]
pub fn append_scale(&self, s: &N) -> $t<N> { pub fn append_scale(&self, s: &N) -> $t<N> {
assert!(!s.is_zero(), "Cannot append a zero scale to a similarity transformation."); assert!(!s.is_zero(), "Cannot append a zero scale to a similarity transformation.");
$t::new_with_rotmat(self.isometry.translation * *s, self.isometry.rotation, self.scale * *s) $t::new_with_rotation_matrix(self.isometry.translation * *s, self.isometry.rotation, self.scale * *s)
} }
/// Prepends in-place a scale to this similarity transformation. /// Prepends in-place a scale to this similarity transformation.
@ -86,7 +86,7 @@ macro_rules! sim_scale_impl(
#[inline] #[inline]
pub fn prepend_scale(&self, s: &N) -> $t<N> { pub fn prepend_scale(&self, s: &N) -> $t<N> {
assert!(!s.is_zero(), "A similarity transformation scale must not be zero."); assert!(!s.is_zero(), "A similarity transformation scale must not be zero.");
$t::new_with_iso(self.isometry, self.scale * *s) $t::new_with_isometry(self.isometry, self.scale * *s)
} }
/// Sets the scale of this similarity transformation. /// Sets the scale of this similarity transformation.
@ -104,7 +104,7 @@ macro_rules! sim_one_impl(
impl<N: BaseFloat> One for $t<N> { impl<N: BaseFloat> One for $t<N> {
#[inline] #[inline]
fn one() -> $t<N> { fn one() -> $t<N> {
$t::new_with_iso(::one(), ::one()) $t::new_with_isometry(::one(), ::one())
} }
} }
) )
@ -117,7 +117,7 @@ macro_rules! sim_mul_sim_impl(
#[inline] #[inline]
fn mul(self, right: $t<N>) -> $t<N> { fn mul(self, right: $t<N>) -> $t<N> {
$t::new_with_rotmat( $t::new_with_rotation_matrix(
self.isometry.translation + self.isometry.rotation * (right.isometry.translation * self.scale), self.isometry.translation + self.isometry.rotation * (right.isometry.translation * self.scale),
self.isometry.rotation * right.isometry.rotation, self.isometry.rotation * right.isometry.rotation,
self.scale * right.scale) self.scale * right.scale)
@ -135,14 +135,14 @@ macro_rules! sim_mul_sim_impl(
) )
); );
macro_rules! sim_mul_iso_impl( macro_rules! sim_mul_isometry_impl(
($t: ident, $ti: ident) => ( ($t: ident, $ti: ident) => (
impl<N: BaseFloat> Mul<$ti<N>> for $t<N> { impl<N: BaseFloat> Mul<$ti<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
#[inline] #[inline]
fn mul(self, right: $ti<N>) -> $t<N> { fn mul(self, right: $ti<N>) -> $t<N> {
$t::new_with_rotmat( $t::new_with_rotation_matrix(
self.isometry.translation + self.isometry.rotation * (right.translation * self.scale), self.isometry.translation + self.isometry.rotation * (right.translation * self.scale),
self.isometry.rotation * right.rotation, self.isometry.rotation * right.rotation,
self.scale) self.scale)
@ -162,7 +162,7 @@ macro_rules! sim_mul_iso_impl(
#[inline] #[inline]
fn mul(self, right: $t<N>) -> $t<N> { fn mul(self, right: $t<N>) -> $t<N> {
$t::new_with_rotmat( $t::new_with_rotation_matrix(
self.translation + self.rotation * right.isometry.translation, self.translation + self.rotation * right.isometry.translation,
self.rotation * right.isometry.rotation, self.rotation * right.isometry.rotation,
right.scale) right.scale)
@ -171,14 +171,14 @@ macro_rules! sim_mul_iso_impl(
) )
); );
macro_rules! sim_mul_rot_impl( macro_rules! sim_mul_rotation_impl(
($t: ident, $tr: ident) => ( ($t: ident, $tr: ident) => (
impl<N: BaseFloat> Mul<$tr<N>> for $t<N> { impl<N: BaseFloat> Mul<$tr<N>> for $t<N> {
type Output = $t<N>; type Output = $t<N>;
#[inline] #[inline]
fn mul(self, right: $tr<N>) -> $t<N> { fn mul(self, right: $tr<N>) -> $t<N> {
$t::new_with_rotmat( $t::new_with_rotation_matrix(
self.isometry.translation, self.isometry.translation,
self.isometry.rotation * right, self.isometry.rotation * right,
self.scale) self.scale)
@ -197,7 +197,7 @@ macro_rules! sim_mul_rot_impl(
#[inline] #[inline]
fn mul(self, right: $t<N>) -> $t<N> { fn mul(self, right: $t<N>) -> $t<N> {
$t::new_with_rotmat( $t::new_with_rotation_matrix(
self * right.isometry.translation, self * right.isometry.translation,
self * right.isometry.rotation, self * right.isometry.rotation,
right.scale) right.scale)
@ -206,7 +206,7 @@ macro_rules! sim_mul_rot_impl(
) )
); );
macro_rules! sim_mul_pnt_vec_impl( macro_rules! sim_mul_point_vec_impl(
($t: ident, $tv: ident) => ( ($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$tv<N>> for $t<N> { impl<N: BaseNum> Mul<$tv<N>> for $t<N> {
type Output = $tv<N>; type Output = $tv<N>;
@ -232,20 +232,20 @@ macro_rules! sim_transform_impl(
} }
#[inline] #[inline]
fn inv_transform(&self, p: &$tp<N>) -> $tp<N> { fn inverse_transform(&self, p: &$tp<N>) -> $tp<N> {
self.isometry.inv_transform(p) / self.scale self.isometry.inverse_transform(p) / self.scale
} }
} }
) )
); );
macro_rules! sim_inv_impl( macro_rules! sim_inverse_impl(
($t: ident) => ( ($t: ident) => (
impl<N: BaseNum + Neg<Output = N>> Inv for $t<N> { impl<N: BaseNum + Neg<Output = N>> Inverse for $t<N> {
#[inline] #[inline]
fn inv_mut(&mut self) -> bool { fn inverse_mut(&mut self) -> bool {
self.scale = ::one::<N>() / self.scale; self.scale = ::one::<N>() / self.scale;
self.isometry.inv_mut(); self.isometry.inverse_mut();
// We multiply (instead of dividing) by self.scale because it has already been // We multiply (instead of dividing) by self.scale because it has already been
// inverted. // inverted.
self.isometry.translation = self.isometry.translation * self.scale; self.isometry.translation = self.isometry.translation * self.scale;
@ -255,9 +255,9 @@ macro_rules! sim_inv_impl(
} }
#[inline] #[inline]
fn inv(&self) -> Option<$t<N>> { fn inverse(&self) -> Option<$t<N>> {
let mut res = *self; let mut res = *self;
res.inv_mut(); res.inverse_mut();
// Always succeed. // Always succeed.
Some(res) Some(res)
@ -270,12 +270,12 @@ macro_rules! sim_to_homogeneous_impl(
($t: ident, $th: ident) => ( ($t: ident, $th: ident) => (
impl<N: BaseNum> ToHomogeneous<$th<N>> for $t<N> { impl<N: BaseNum> ToHomogeneous<$th<N>> for $t<N> {
fn to_homogeneous(&self) -> $th<N> { fn to_homogeneous(&self) -> $th<N> {
let mut res = (*self.isometry.rotation.submat() * self.scale).to_homogeneous(); let mut res = (*self.isometry.rotation.submatrix() * self.scale).to_homogeneous();
// copy the translation // copy the translation
let dim = Dim::dim(None::<$th<N>>); let dimension = Dimension::dimension(None::<$th<N>>);
res.set_col(dim - 1, self.isometry.translation.as_pnt().to_homogeneous().to_vec()); res.set_col(dimension - 1, self.isometry.translation.as_point().to_homogeneous().to_vector());
res res
} }
@ -321,7 +321,7 @@ macro_rules! sim_rand_impl(
scale = rng.gen(); scale = rng.gen();
} }
$t::new_with_iso(rng.gen(), scale) $t::new_with_isometry(rng.gen(), scale)
} }
} }
) )
@ -332,7 +332,7 @@ macro_rules! sim_arbitrary_impl(
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for $t<N> { impl<N: Arbitrary + BaseFloat> Arbitrary for $t<N> {
fn arbitrary<G: Gen>(g: &mut G) -> $t<N> { fn arbitrary<G: Gen>(g: &mut G) -> $t<N> {
$t::new_with_iso( $t::new_with_isometry(
Arbitrary::arbitrary(g), Arbitrary::arbitrary(g),
Arbitrary::arbitrary(g) Arbitrary::arbitrary(g)
) )
@ -351,13 +351,13 @@ macro_rules! sim_display_impl(
try!(writeln!(f, "... scale factor: {:.*}", precision, self.scale)); try!(writeln!(f, "... scale factor: {:.*}", precision, self.scale));
try!(writeln!(f, "... translation: {:.*}", precision, self.isometry.translation)); try!(writeln!(f, "... translation: {:.*}", precision, self.isometry.translation));
try!(writeln!(f, "... rotation matrix:")); try!(writeln!(f, "... rotation matrix:"));
try!(write!(f, "{:.*}", precision, *self.isometry.rotation.submat())); try!(write!(f, "{:.*}", precision, *self.isometry.rotation.submatrix()));
} }
else { else {
try!(writeln!(f, "... scale factor: {}", self.scale)); try!(writeln!(f, "... scale factor: {}", self.scale));
try!(writeln!(f, "... translation: {}", self.isometry.translation)); try!(writeln!(f, "... translation: {}", self.isometry.translation));
try!(writeln!(f, "... rotation matrix:")); try!(writeln!(f, "... rotation matrix:"));
try!(write!(f, "{}", *self.isometry.rotation.submat())); try!(write!(f, "{}", *self.isometry.rotation.submatrix()));
} }
writeln!(f, "}}") writeln!(f, "}}")

View File

@ -1,307 +0,0 @@
use std::ops::{Sub, Mul, Neg};
use num::{Zero, One};
use traits::structure::{Cast, Row, Basis, BaseFloat};
use traits::geometry::{Norm, Cross, CrossMatrix, RotationTo, UniformSphereSample};
use structs::vec::{Vec1, Vec2, Vec3, Vec4};
use structs::mat::Mat3;
use structs::rot::{Rot2, Rot3};
impl<N: BaseFloat> RotationTo for Vec2<N> {
type AngleType = N;
type DeltaRotationType = Rot2<N>;
#[inline]
fn angle_to(&self, other: &Self) -> N {
::cross(self, other).x.atan2(::dot(self, other))
}
#[inline]
fn rotation_to(&self, other: &Self) -> Rot2<N> {
Rot2::new(Vec1::new(self.angle_to(other)))
}
}
impl<N: BaseFloat> RotationTo for Vec3<N> {
type AngleType = N;
type DeltaRotationType = Rot3<N>;
#[inline]
fn angle_to(&self, other: &Self) -> N {
::cross(self, other).norm().atan2(::dot(self, other))
}
#[inline]
fn rotation_to(&self, other: &Self) -> Rot3<N> {
let mut axis = ::cross(self, other);
let norm = axis.normalize_mut();
if ::is_zero(&norm) {
::one()
}
else {
let axis_angle = axis * norm.atan2(::dot(self, other));
Rot3::new(axis_angle)
}
}
}
impl<N: Copy + Mul<N, Output = N> + Sub<N, Output = N>> Cross for Vec2<N> {
type CrossProductType = Vec1<N>;
#[inline]
fn cross(&self, other: &Vec2<N>) -> Vec1<N> {
Vec1::new(self.x * other.y - self.y * other.x)
}
}
// FIXME: instead of returning a Vec2, define a Mat2x1 matrix?
impl<N: Neg<Output = N> + Copy> CrossMatrix<Vec2<N>> for Vec2<N> {
#[inline]
fn cross_matrix(&self) -> Vec2<N> {
Vec2::new(-self.y, self.x)
}
}
impl<N: Copy + Mul<N, Output = N> + Sub<N, Output = N>> Cross for Vec3<N> {
type CrossProductType = Vec3<N>;
#[inline]
fn cross(&self, other: &Vec3<N>) -> Vec3<N> {
Vec3::new(
self.y * other.z - self.z * other.y,
self.z * other.x - self.x * other.z,
self.x * other.y - self.y * other.x
)
}
}
impl<N: Neg<Output = N> + Zero + Copy> CrossMatrix<Mat3<N>> for Vec3<N> {
#[inline]
fn cross_matrix(&self) -> Mat3<N> {
Mat3::new(
::zero(), -self.z, self.y,
self.z, ::zero(), -self.x,
-self.y, self.x, ::zero()
)
}
}
// FIXME: implement this for all other vectors
impl<N: Copy> Row<Vec1<N>> for Vec2<N> {
#[inline]
fn nrows(&self) -> usize {
2
}
#[inline]
fn row(&self, i: usize) -> Vec1<N> {
match i {
0 => Vec1::new(self.x),
1 => Vec1::new(self.y),
_ => panic!(format!("Index out of range: 2d vectors do not have {} rows. ", i))
}
}
#[inline]
fn set_row(&mut self, i: usize, r: Vec1<N>) {
match i {
0 => self.x = r.x,
1 => self.y = r.x,
_ => panic!(format!("Index out of range: 2d vectors do not have {} rows.", i))
}
}
}
impl<N: One> Basis for Vec1<N> {
#[inline(always)]
fn canonical_basis<F: FnMut(Vec1<N>) -> bool>(mut f: F) {
f(Vec1::new(::one()));
}
#[inline(always)]
fn orthonormal_subspace_basis<F: FnMut(Vec1<N>) -> bool>(_: &Vec1<N>, _: F) { }
#[inline]
fn canonical_basis_element(i: usize) -> Option<Vec1<N>> {
if i == 0 {
Some(Vec1::new(::one()))
}
else {
None
}
}
}
impl<N: Copy + One + Zero + Neg<Output = N>> Basis for Vec2<N> {
#[inline(always)]
fn canonical_basis<F: FnMut(Vec2<N>) -> bool>(mut f: F) {
if !f(Vec2::new(::one(), ::zero())) { return };
f(Vec2::new(::zero(), ::one()));
}
#[inline]
fn orthonormal_subspace_basis<F: FnMut(Vec2<N>) -> bool>(n: &Vec2<N>, mut f: F) {
f(Vec2::new(-n.y, n.x));
}
#[inline]
fn canonical_basis_element(i: usize) -> Option<Vec2<N>> {
if i == 0 {
Some(Vec2::new(::one(), ::zero()))
}
else if i == 1 {
Some(Vec2::new(::zero(), ::one()))
}
else {
None
}
}
}
impl<N: BaseFloat> Basis for Vec3<N> {
#[inline(always)]
fn canonical_basis<F: FnMut(Vec3<N>) -> bool>(mut f: F) {
if !f(Vec3::new(::one(), ::zero(), ::zero())) { return };
if !f(Vec3::new(::zero(), ::one(), ::zero())) { return };
f(Vec3::new(::zero(), ::zero(), ::one()));
}
#[inline(always)]
fn orthonormal_subspace_basis<F: FnMut(Vec3<N>) -> bool>(n: &Vec3<N>, mut f: F) {
let a =
if n.x.abs() > n.y.abs() {
Norm::normalize(&Vec3::new(n.z, ::zero(), -n.x))
}
else {
Norm::normalize(&Vec3::new(::zero(), -n.z, n.y))
};
if !f(Cross::cross(&a, n)) { return };
f(a);
}
#[inline]
fn canonical_basis_element(i: usize) -> Option<Vec3<N>> {
if i == 0 {
Some(Vec3::new(::one(), ::zero(), ::zero()))
}
else if i == 1 {
Some(Vec3::new(::zero(), ::one(), ::zero()))
}
else if i == 2 {
Some(Vec3::new(::zero(), ::zero(), ::one()))
}
else {
None
}
}
}
// FIXME: this bad: this fixes definitly the number of samples…
static SAMPLES_2_F64: [Vec2<f64>; 21] = [
Vec2 { x: 1.0, y: 0.0 },
Vec2 { x: 0.95557281, y: 0.29475517 },
Vec2 { x: 0.82623877, y: 0.56332006 },
Vec2 { x: 0.6234898, y: 0.78183148 },
Vec2 { x: 0.36534102, y: 0.93087375 },
Vec2 { x: 0.07473009, y: 0.9972038 },
Vec2 { x: -0.22252093, y: 0.97492791 },
Vec2 { x: -0.5, y: 0.8660254 },
Vec2 { x: -0.73305187, y: 0.68017274 },
Vec2 { x: -0.90096887, y: 0.43388374 },
Vec2 { x: -0.98883083, y: 0.14904227 },
Vec2 { x: -0.98883083, y: -0.14904227 },
Vec2 { x: -0.90096887, y: -0.43388374 },
Vec2 { x: -0.73305187, y: -0.68017274 },
Vec2 { x: -0.5, y: -0.8660254 },
Vec2 { x: -0.22252093, y: -0.97492791 },
Vec2 { x: 0.07473009, y: -0.9972038 },
Vec2 { x: 0.36534102, y: -0.93087375 },
Vec2 { x: 0.6234898, y: -0.78183148 },
Vec2 { x: 0.82623877, y: -0.56332006 },
Vec2 { x: 0.95557281, y: -0.29475517 },
];
// Those vectors come from bullet 3d
static SAMPLES_3_F64: [Vec3<f64>; 42] = [
Vec3 { x: 0.000000 , y: -0.000000, z: -1.000000 },
Vec3 { x: 0.723608 , y: -0.525725, z: -0.447219 },
Vec3 { x: -0.276388, y: -0.850649, z: -0.447219 },
Vec3 { x: -0.894426, y: -0.000000, z: -0.447216 },
Vec3 { x: -0.276388, y: 0.850649 , z: -0.447220 },
Vec3 { x: 0.723608 , y: 0.525725 , z: -0.447219 },
Vec3 { x: 0.276388 , y: -0.850649, z: 0.447220 },
Vec3 { x: -0.723608, y: -0.525725, z: 0.447219 },
Vec3 { x: -0.723608, y: 0.525725 , z: 0.447219 },
Vec3 { x: 0.276388 , y: 0.850649 , z: 0.447219 },
Vec3 { x: 0.894426 , y: 0.000000 , z: 0.447216 },
Vec3 { x: -0.000000, y: 0.000000 , z: 1.000000 },
Vec3 { x: 0.425323 , y: -0.309011, z: -0.850654 },
Vec3 { x: -0.162456, y: -0.499995, z: -0.850654 },
Vec3 { x: 0.262869 , y: -0.809012, z: -0.525738 },
Vec3 { x: 0.425323 , y: 0.309011 , z: -0.850654 },
Vec3 { x: 0.850648 , y: -0.000000, z: -0.525736 },
Vec3 { x: -0.525730, y: -0.000000, z: -0.850652 },
Vec3 { x: -0.688190, y: -0.499997, z: -0.525736 },
Vec3 { x: -0.162456, y: 0.499995 , z: -0.850654 },
Vec3 { x: -0.688190, y: 0.499997 , z: -0.525736 },
Vec3 { x: 0.262869 , y: 0.809012 , z: -0.525738 },
Vec3 { x: 0.951058 , y: 0.309013 , z: 0.000000 },
Vec3 { x: 0.951058 , y: -0.309013, z: 0.000000 },
Vec3 { x: 0.587786 , y: -0.809017, z: 0.000000 },
Vec3 { x: 0.000000 , y: -1.000000, z: 0.000000 },
Vec3 { x: -0.587786, y: -0.809017, z: 0.000000 },
Vec3 { x: -0.951058, y: -0.309013, z: -0.000000 },
Vec3 { x: -0.951058, y: 0.309013 , z: -0.000000 },
Vec3 { x: -0.587786, y: 0.809017 , z: -0.000000 },
Vec3 { x: -0.000000, y: 1.000000 , z: -0.000000 },
Vec3 { x: 0.587786 , y: 0.809017 , z: -0.000000 },
Vec3 { x: 0.688190 , y: -0.499997, z: 0.525736 },
Vec3 { x: -0.262869, y: -0.809012, z: 0.525738 },
Vec3 { x: -0.850648, y: 0.000000 , z: 0.525736 },
Vec3 { x: -0.262869, y: 0.809012 , z: 0.525738 },
Vec3 { x: 0.688190 , y: 0.499997 , z: 0.525736 },
Vec3 { x: 0.525730 , y: 0.000000 , z: 0.850652 },
Vec3 { x: 0.162456 , y: -0.499995, z: 0.850654 },
Vec3 { x: -0.425323, y: -0.309011, z: 0.850654 },
Vec3 { x: -0.425323, y: 0.309011 , z: 0.850654 },
Vec3 { x: 0.162456 , y: 0.499995 , z: 0.850654 }
];
impl<N> UniformSphereSample for Vec1<N>
where Vec1<N>: One {
#[inline(always)]
fn sample<F: FnMut(Vec1<N>)>(mut f: F) {
f(::one())
}
}
impl<N: Cast<f64> + Copy> UniformSphereSample for Vec2<N> {
#[inline(always)]
fn sample<F: FnMut(Vec2<N>)>(mut f: F) {
for sample in SAMPLES_2_F64.iter() {
f(Cast::from(*sample))
}
}
}
impl<N: Cast<f64> + Copy> UniformSphereSample for Vec3<N> {
#[inline(always)]
fn sample<F: FnMut(Vec3<N>)>(mut f: F) {
for sample in SAMPLES_3_F64.iter() {
f(Cast::from(*sample))
}
}
}
impl<N: Cast<f64> + Copy> UniformSphereSample for Vec4<N> {
#[inline(always)]
fn sample<F: FnMut(Vec4<N>)>(_: F) {
panic!("UniformSphereSample::<Vec4<N>>::sample : Not yet implemented.")
// for sample in SAMPLES_3_F32.iter() {
// f(Cast::from(*sample))
// }
}
}

View File

@ -2,8 +2,8 @@
use std::num::Zero; use std::num::Zero;
use extra::complex::Cmplx; use extra::complex::Cmplx;
use traits::operations::{Absolute, Inv}; use traits::operations::{Absolute, Inverse};
use traits::structure::{Dim}; use traits::structure::{Dimension};
impl<N: Clone + BaseNum> Absolute<Cmplx<N>> for Cmplx<N> { impl<N: Clone + BaseNum> Absolute<Cmplx<N>> for Cmplx<N> {
#[inline] #[inline]
@ -12,7 +12,7 @@ impl<N: Clone + BaseNum> Absolute<Cmplx<N>> for Cmplx<N> {
} }
} }
impl<N: Clone + BaseNum + BaseNumCast + Zero> Inv for Cmplx<N> { impl<N: Clone + BaseNum + BaseNumCast + Zero> Inverse for Cmplx<N> {
#[inline] #[inline]
fn inverse(&self) -> Option<Cmplx<N>> { fn inverse(&self) -> Option<Cmplx<N>> {
if self.is_zero() { if self.is_zero() {
@ -43,55 +43,55 @@ impl<N: Clone + BaseNum + BaseNumCast + Zero> Inv for Cmplx<N> {
} }
} }
impl<N> Dim for Cmplx<N> { impl<N> Dimension for Cmplx<N> {
#[inline] #[inline]
fn dim(unsused_mut: Option<Cmplx<N>>) -> usize { fn dimension(unsused_mut: Option<Cmplx<N>>) -> usize {
2 2
} }
} }
impl<N> Rotation<Vec2<N>> for Cmplx<N> { impl<N> Rotation<Vector2<N>> for Cmplx<N> {
#[inline] #[inline]
fn rotation(&self) -> Vec2<N> { fn rotation(&self) -> Vector2<N> {
} }
#[inline] #[inline]
fn inv_rotation(&self) -> Vec2<N> { fn inverse_rotation(&self) -> Vector2<N> {
-self.rotation(); -self.rotation();
} }
#[inline] #[inline]
fn rotate_by(&mut self, rotation: &Vec2<N>) { fn rotate_by(&mut self, rotation: &Vector2<N>) {
} }
#[inline] #[inline]
fn rotated(&self, rotation: &Vec2<N>) -> Cmplx<N> { fn rotated(&self, rotation: &Vector2<N>) -> Cmplx<N> {
} }
#[inline] #[inline]
fn set_rotation(&mut self, rotation: Vec2<N>) { fn set_rotation(&mut self, rotation: Vector2<N>) {
} }
} }
impl<N> Rotate<Vec2<N>> for Cmplx<N> { impl<N> Rotate<Vector2<N>> for Cmplx<N> {
#[inline] #[inline]
fn rotate(&self, rotation: &V) -> V { fn rotate(&self, rotation: &V) -> V {
} }
#[inline] #[inline]
fn inv_rotate(&self, rotation: &V) -> V { fn inverse_rotate(&self, rotation: &V) -> V {
} }
} }
impl<N> RotationMatrix<Vec2<N>, Vec2<N>, Rotmat<Mat2<N>>> for Cmplx<N> { impl<N> RotationMatrix<Vector2<N>, Vector2<N>, Rotationmatrix<Matrix2<N>>> for Cmplx<N> {
#[inline] #[inline]
fn to_rot_mat(&self) -> Rotmat<Mat2<N>> { fn to_rotation_matrix(&self) -> Rotationmatrix<Matrix2<N>> {
} }
} }
impl<N> Norm<N> for Cmplx<N> { impl<N> Norm<N> for Cmplx<N> {
#[inline] #[inline]
fn sqnorm(&self) -> N { fn norm_squared(&self) -> N {
} }
#[inline] #[inline]

View File

@ -1,27 +1,27 @@
use std::ops::Mul; use std::ops::Mul;
use num::One; use num::One;
use structs::mat; use structs::matrix::Identity;
use traits::operations::{Inv, Transpose}; use traits::operations::{Inverse, Transpose};
use traits::geometry::{Translate, Rotate, Transform, AbsoluteRotate}; use traits::geometry::{Translate, Rotate, Transform, AbsoluteRotate};
impl One for mat::Identity { impl One for Identity {
#[inline] #[inline]
fn one() -> mat::Identity { fn one() -> Identity {
mat::Identity::new() Identity::new()
} }
} }
impl Inv for mat::Identity { impl Inverse for Identity {
fn inv(&self) -> Option<mat::Identity> { fn inverse(&self) -> Option<Identity> {
Some(mat::Identity::new()) Some(Identity::new())
} }
fn inv_mut(&mut self) -> bool { fn inverse_mut(&mut self) -> bool {
true true
} }
} }
impl<T: Clone> Mul<T> for mat::Identity { impl<T: Clone> Mul<T> for Identity {
type Output = T; type Output = T;
#[inline] #[inline]
@ -30,10 +30,10 @@ impl<T: Clone> Mul<T> for mat::Identity {
} }
} }
impl Transpose for mat::Identity { impl Transpose for Identity {
#[inline] #[inline]
fn transpose(&self) -> mat::Identity { fn transpose(&self) -> Identity {
mat::Identity::new() Identity::new()
} }
#[inline] #[inline]
@ -41,45 +41,45 @@ impl Transpose for mat::Identity {
} }
} }
impl<V: Clone> Translate<V> for mat::Identity { impl<V: Clone> Translate<V> for Identity {
#[inline] #[inline]
fn translate(&self, v: &V) -> V { fn translate(&self, v: &V) -> V {
v.clone() v.clone()
} }
#[inline] #[inline]
fn inv_translate(&self, v: &V) -> V { fn inverse_translate(&self, v: &V) -> V {
v.clone() v.clone()
} }
} }
impl<V: Clone> Rotate<V> for mat::Identity { impl<V: Clone> Rotate<V> for Identity {
#[inline] #[inline]
fn rotate(&self, v: &V) -> V { fn rotate(&self, v: &V) -> V {
v.clone() v.clone()
} }
#[inline] #[inline]
fn inv_rotate(&self, v: &V) -> V { fn inverse_rotate(&self, v: &V) -> V {
v.clone() v.clone()
} }
} }
impl<V: Clone> AbsoluteRotate<V> for mat::Identity { impl<V: Clone> AbsoluteRotate<V> for Identity {
#[inline] #[inline]
fn absolute_rotate(&self, v: &V) -> V { fn absolute_rotate(&self, v: &V) -> V {
v.clone() v.clone()
} }
} }
impl<V: Clone> Transform<V> for mat::Identity { impl<V: Clone> Transform<V> for Identity {
#[inline] #[inline]
fn transform(&self, v: &V) -> V { fn transform(&self, v: &V) -> V {
v.clone() v.clone()
} }
#[inline] #[inline]
fn inv_transform(&self, v: &V) -> V { fn inverse_transform(&self, v: &V) -> V {
v.clone() v.clone()
} }
} }

View File

@ -1,16 +1,16 @@
use std::ops::{Add, Mul, Neg, MulAssign}; use std::ops::{Add, Mul, Neg, MulAssign};
use structs::vec::{Vec2, Vec3}; use structs::vector::{Vector2, Vector3};
use structs::pnt::{Pnt2, Pnt3}; use structs::point::{Point2, Point3};
use structs::mat::{Mat1, Mat2, Mat3}; use structs::matrix::{Matrix1, Matrix2, Matrix3};
use traits::operations::{Inv, Det, ApproxEq}; use traits::operations::{Inverse, Determinant, ApproxEq};
use traits::structure::{Row, Col, BaseNum}; use traits::structure::{Row, Column, BaseNum};
// some specializations: // some specializations:
impl<N: BaseNum + ApproxEq<N>> Inv for Mat1<N> { impl<N: BaseNum + ApproxEq<N>> Inverse for Matrix1<N> {
#[inline] #[inline]
fn inv(&self) -> Option<Mat1<N>> { fn inverse(&self) -> Option<Matrix1<N>> {
let mut res = *self; let mut res = *self;
if res.inv_mut() { if res.inverse_mut() {
Some(res) Some(res)
} }
else { else {
@ -19,24 +19,24 @@ impl<N: BaseNum + ApproxEq<N>> Inv for Mat1<N> {
} }
#[inline] #[inline]
fn inv_mut(&mut self) -> bool { fn inverse_mut(&mut self) -> bool {
if ApproxEq::approx_eq(&self.m11, &::zero()) { if ApproxEq::approx_eq(&self.m11, &::zero()) {
false false
} }
else { else {
let _1: N = ::one(); let _1: N = ::one();
self.m11 = _1 / Det::det(self); self.m11 = _1 / Determinant::determinant(self);
true true
} }
} }
} }
impl<N: BaseNum + Neg<Output = N> + ApproxEq<N>> Inv for Mat2<N> { impl<N: BaseNum + Neg<Output = N> + ApproxEq<N>> Inverse for Matrix2<N> {
#[inline] #[inline]
fn inv(&self) -> Option<Mat2<N>> { fn inverse(&self) -> Option<Matrix2<N>> {
let mut res = *self; let mut res = *self;
if res.inv_mut() { if res.inverse_mut() {
Some(res) Some(res)
} }
else { else {
@ -45,28 +45,28 @@ impl<N: BaseNum + Neg<Output = N> + ApproxEq<N>> Inv for Mat2<N> {
} }
#[inline] #[inline]
fn inv_mut(&mut self) -> bool { fn inverse_mut(&mut self) -> bool {
let det = Det::det(self); let determinant = Determinant::determinant(self);
if ApproxEq::approx_eq(&det, &::zero()) { if ApproxEq::approx_eq(&determinant, &::zero()) {
false false
} }
else { else {
*self = Mat2::new( *self = Matrix2::new(
self.m22 / det , -self.m12 / det, self.m22 / determinant , -self.m12 / determinant,
-self.m21 / det, self.m11 / det); -self.m21 / determinant, self.m11 / determinant);
true true
} }
} }
} }
impl<N: BaseNum + Neg<Output = N> + ApproxEq<N>> Inv for Mat3<N> { impl<N: BaseNum + Neg<Output = N> + ApproxEq<N>> Inverse for Matrix3<N> {
#[inline] #[inline]
fn inv(&self) -> Option<Mat3<N>> { fn inverse(&self) -> Option<Matrix3<N>> {
let mut res = *self; let mut res = *self;
if res.inv_mut() { if res.inverse_mut() {
Some(res) Some(res)
} }
else { else {
@ -75,29 +75,29 @@ impl<N: BaseNum + Neg<Output = N> + ApproxEq<N>> Inv for Mat3<N> {
} }
#[inline] #[inline]
fn inv_mut(&mut self) -> bool { fn inverse_mut(&mut self) -> bool {
let minor_m12_m23 = self.m22 * self.m33 - self.m32 * self.m23; let minor_m12_m23 = self.m22 * self.m33 - self.m32 * self.m23;
let minor_m11_m23 = self.m21 * self.m33 - self.m31 * self.m23; let minor_m11_m23 = self.m21 * self.m33 - self.m31 * self.m23;
let minor_m11_m22 = self.m21 * self.m32 - self.m31 * self.m22; let minor_m11_m22 = self.m21 * self.m32 - self.m31 * self.m22;
let det = self.m11 * minor_m12_m23 - self.m12 * minor_m11_m23 + self.m13 * minor_m11_m22; let determinant = self.m11 * minor_m12_m23 - self.m12 * minor_m11_m23 + self.m13 * minor_m11_m22;
if ApproxEq::approx_eq(&det, &::zero()) { if ApproxEq::approx_eq(&determinant, &::zero()) {
false false
} }
else { else {
*self = Mat3::new( *self = Matrix3::new(
(minor_m12_m23 / det), (minor_m12_m23 / determinant),
((self.m13 * self.m32 - self.m33 * self.m12) / det), ((self.m13 * self.m32 - self.m33 * self.m12) / determinant),
((self.m12 * self.m23 - self.m22 * self.m13) / det), ((self.m12 * self.m23 - self.m22 * self.m13) / determinant),
(-minor_m11_m23 / det), (-minor_m11_m23 / determinant),
((self.m11 * self.m33 - self.m31 * self.m13) / det), ((self.m11 * self.m33 - self.m31 * self.m13) / determinant),
((self.m13 * self.m21 - self.m23 * self.m11) / det), ((self.m13 * self.m21 - self.m23 * self.m11) / determinant),
(minor_m11_m22 / det), (minor_m11_m22 / determinant),
((self.m12 * self.m31 - self.m32 * self.m11) / det), ((self.m12 * self.m31 - self.m32 * self.m11) / determinant),
((self.m11 * self.m22 - self.m21 * self.m12) / det) ((self.m11 * self.m22 - self.m21 * self.m12) / determinant)
); );
true true
@ -105,23 +105,23 @@ impl<N: BaseNum + Neg<Output = N> + ApproxEq<N>> Inv for Mat3<N> {
} }
} }
impl<N: BaseNum> Det<N> for Mat1<N> { impl<N: BaseNum> Determinant<N> for Matrix1<N> {
#[inline] #[inline]
fn det(&self) -> N { fn determinant(&self) -> N {
self.m11 self.m11
} }
} }
impl<N: BaseNum> Det<N> for Mat2<N> { impl<N: BaseNum> Determinant<N> for Matrix2<N> {
#[inline] #[inline]
fn det(&self) -> N { fn determinant(&self) -> N {
self.m11 * self.m22 - self.m21 * self.m12 self.m11 * self.m22 - self.m21 * self.m12
} }
} }
impl<N: BaseNum> Det<N> for Mat3<N> { impl<N: BaseNum> Determinant<N> for Matrix3<N> {
#[inline] #[inline]
fn det(&self) -> N { fn determinant(&self) -> N {
let minor_m12_m23 = self.m22 * self.m33 - self.m32 * self.m23; let minor_m12_m23 = self.m22 * self.m33 - self.m32 * self.m23;
let minor_m11_m23 = self.m21 * self.m33 - self.m31 * self.m23; let minor_m11_m23 = self.m21 * self.m33 - self.m31 * self.m23;
let minor_m11_m22 = self.m21 * self.m32 - self.m31 * self.m22; let minor_m11_m22 = self.m21 * self.m32 - self.m31 * self.m22;
@ -130,24 +130,24 @@ impl<N: BaseNum> Det<N> for Mat3<N> {
} }
} }
impl<N: Copy> Row<Vec3<N>> for Mat3<N> { impl<N: Copy> Row<Vector3<N>> for Matrix3<N> {
#[inline] #[inline]
fn nrows(&self) -> usize { fn nrows(&self) -> usize {
3 3
} }
#[inline] #[inline]
fn row(&self, i: usize) -> Vec3<N> { fn row(&self, i: usize) -> Vector3<N> {
match i { match i {
0 => Vec3::new(self.m11, self.m12, self.m13), 0 => Vector3::new(self.m11, self.m12, self.m13),
1 => Vec3::new(self.m21, self.m22, self.m23), 1 => Vector3::new(self.m21, self.m22, self.m23),
2 => Vec3::new(self.m31, self.m32, self.m33), 2 => Vector3::new(self.m31, self.m32, self.m33),
_ => panic!(format!("Index out of range: 3d matrices do not have {} rows.", i)) _ => panic!(format!("Index out of range: 3d matrices do not have {} rows.", i))
} }
} }
#[inline] #[inline]
fn set_row(&mut self, i: usize, r: Vec3<N>) { fn set_row(&mut self, i: usize, r: Vector3<N>) {
match i { match i {
0 => { 0 => {
self.m11 = r.x; self.m11 = r.x;
@ -170,24 +170,24 @@ impl<N: Copy> Row<Vec3<N>> for Mat3<N> {
} }
} }
impl<N: Copy> Col<Vec3<N>> for Mat3<N> { impl<N: Copy> Column<Vector3<N>> for Matrix3<N> {
#[inline] #[inline]
fn ncols(&self) -> usize { fn ncols(&self) -> usize {
3 3
} }
#[inline] #[inline]
fn col(&self, i: usize) -> Vec3<N> { fn column(&self, i: usize) -> Vector3<N> {
match i { match i {
0 => Vec3::new(self.m11, self.m21, self.m31), 0 => Vector3::new(self.m11, self.m21, self.m31),
1 => Vec3::new(self.m12, self.m22, self.m32), 1 => Vector3::new(self.m12, self.m22, self.m32),
2 => Vec3::new(self.m13, self.m23, self.m33), 2 => Vector3::new(self.m13, self.m23, self.m33),
_ => panic!(format!("Index out of range: 3d matrices do not have {} cols.", i)) _ => panic!(format!("Index out of range: 3d matrices do not have {} cols.", i))
} }
} }
#[inline] #[inline]
fn set_col(&mut self, i: usize, r: Vec3<N>) { fn set_col(&mut self, i: usize, r: Vector3<N>) {
match i { match i {
0 => { 0 => {
self.m11 = r.x; self.m11 = r.x;
@ -210,12 +210,12 @@ impl<N: Copy> Col<Vec3<N>> for Mat3<N> {
} }
} }
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat3<N>> for Mat3<N> { impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Matrix3<N> {
type Output = Mat3<N>; type Output = Matrix3<N>;
#[inline] #[inline]
fn mul(self, right: Mat3<N>) -> Mat3<N> { fn mul(self, right: Matrix3<N>) -> Matrix3<N> {
Mat3::new( Matrix3::new(
self.m11 * right.m11 + self.m12 * right.m21 + self.m13 * right.m31, self.m11 * right.m11 + self.m12 * right.m21 + self.m13 * right.m31,
self.m11 * right.m12 + self.m12 * right.m22 + self.m13 * right.m32, self.m11 * right.m12 + self.m12 * right.m22 + self.m13 * right.m32,
self.m11 * right.m13 + self.m12 * right.m23 + self.m13 * right.m33, self.m11 * right.m13 + self.m12 * right.m23 + self.m13 * right.m33,
@ -231,12 +231,12 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat3<N>> for Mat3<N>
} }
} }
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat2<N>> for Mat2<N> { impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Matrix2<N> {
type Output = Mat2<N>; type Output = Matrix2<N>;
#[inline(always)] #[inline(always)]
fn mul(self, right: Mat2<N>) -> Mat2<N> { fn mul(self, right: Matrix2<N>) -> Matrix2<N> {
Mat2::new( Matrix2::new(
self.m11 * right.m11 + self.m12 * right.m21, self.m11 * right.m11 + self.m12 * right.m21,
self.m11 * right.m12 + self.m12 * right.m22, self.m11 * right.m12 + self.m12 * right.m22,
@ -246,12 +246,12 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat2<N>> for Mat2<N>
} }
} }
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vec3<N>> for Mat3<N> { impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vector3<N>> for Matrix3<N> {
type Output = Vec3<N>; type Output = Vector3<N>;
#[inline(always)] #[inline(always)]
fn mul(self, right: Vec3<N>) -> Vec3<N> { fn mul(self, right: Vector3<N>) -> Vector3<N> {
Vec3::new( Vector3::new(
self.m11 * right.x + self.m12 * right.y + self.m13 * right.z, self.m11 * right.x + self.m12 * right.y + self.m13 * right.z,
self.m21 * right.x + self.m22 * right.y + self.m23 * right.z, self.m21 * right.x + self.m22 * right.y + self.m23 * right.z,
self.m31 * right.x + self.m32 * right.y + self.m33 * right.z self.m31 * right.x + self.m32 * right.y + self.m33 * right.z
@ -259,12 +259,12 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vec3<N>> for Mat3<N>
} }
} }
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat3<N>> for Vec3<N> { impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Vector3<N> {
type Output = Vec3<N>; type Output = Vector3<N>;
#[inline(always)] #[inline(always)]
fn mul(self, right: Mat3<N>) -> Vec3<N> { fn mul(self, right: Matrix3<N>) -> Vector3<N> {
Vec3::new( Vector3::new(
self.x * right.m11 + self.y * right.m21 + self.z * right.m31, self.x * right.m11 + self.y * right.m21 + self.z * right.m31,
self.x * right.m12 + self.y * right.m22 + self.z * right.m32, self.x * right.m12 + self.y * right.m22 + self.z * right.m32,
self.x * right.m13 + self.y * right.m23 + self.z * right.m33 self.x * right.m13 + self.y * right.m23 + self.z * right.m33
@ -272,36 +272,36 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat3<N>> for Vec3<N>
} }
} }
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat2<N>> for Vec2<N> { impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Vector2<N> {
type Output = Vec2<N>; type Output = Vector2<N>;
#[inline(always)] #[inline(always)]
fn mul(self, right: Mat2<N>) -> Vec2<N> { fn mul(self, right: Matrix2<N>) -> Vector2<N> {
Vec2::new( Vector2::new(
self.x * right.m11 + self.y * right.m21, self.x * right.m11 + self.y * right.m21,
self.x * right.m12 + self.y * right.m22 self.x * right.m12 + self.y * right.m22
) )
} }
} }
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vec2<N>> for Mat2<N> { impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vector2<N>> for Matrix2<N> {
type Output = Vec2<N>; type Output = Vector2<N>;
#[inline(always)] #[inline(always)]
fn mul(self, right: Vec2<N>) -> Vec2<N> { fn mul(self, right: Vector2<N>) -> Vector2<N> {
Vec2::new( Vector2::new(
self.m11 * right.x + self.m12 * right.y, self.m11 * right.x + self.m12 * right.y,
self.m21 * right.x + self.m22 * right.y self.m21 * right.x + self.m22 * right.y
) )
} }
} }
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Pnt3<N>> for Mat3<N> { impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Point3<N>> for Matrix3<N> {
type Output = Pnt3<N>; type Output = Point3<N>;
#[inline(always)] #[inline(always)]
fn mul(self, right: Pnt3<N>) -> Pnt3<N> { fn mul(self, right: Point3<N>) -> Point3<N> {
Pnt3::new( Point3::new(
self.m11 * right.x + self.m12 * right.y + self.m13 * right.z, self.m11 * right.x + self.m12 * right.y + self.m13 * right.z,
self.m21 * right.x + self.m22 * right.y + self.m23 * right.z, self.m21 * right.x + self.m22 * right.y + self.m23 * right.z,
self.m31 * right.x + self.m32 * right.y + self.m33 * right.z self.m31 * right.x + self.m32 * right.y + self.m33 * right.z
@ -309,12 +309,12 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Pnt3<N>> for Mat3<N>
} }
} }
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat3<N>> for Pnt3<N> { impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Point3<N> {
type Output = Pnt3<N>; type Output = Point3<N>;
#[inline(always)] #[inline(always)]
fn mul(self, right: Mat3<N>) -> Pnt3<N> { fn mul(self, right: Matrix3<N>) -> Point3<N> {
Pnt3::new( Point3::new(
self.x * right.m11 + self.y * right.m21 + self.z * right.m31, self.x * right.m11 + self.y * right.m21 + self.z * right.m31,
self.x * right.m12 + self.y * right.m22 + self.z * right.m32, self.x * right.m12 + self.y * right.m22 + self.z * right.m32,
self.x * right.m13 + self.y * right.m23 + self.z * right.m33 self.x * right.m13 + self.y * right.m23 + self.z * right.m33
@ -322,24 +322,24 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat3<N>> for Pnt3<N>
} }
} }
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat2<N>> for Pnt2<N> { impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Point2<N> {
type Output = Pnt2<N>; type Output = Point2<N>;
#[inline(always)] #[inline(always)]
fn mul(self, right: Mat2<N>) -> Pnt2<N> { fn mul(self, right: Matrix2<N>) -> Point2<N> {
Pnt2::new( Point2::new(
self.x * right.m11 + self.y * right.m21, self.x * right.m11 + self.y * right.m21,
self.x * right.m12 + self.y * right.m22 self.x * right.m12 + self.y * right.m22
) )
} }
} }
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Pnt2<N>> for Mat2<N> { impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Point2<N>> for Matrix2<N> {
type Output = Pnt2<N>; type Output = Point2<N>;
#[inline(always)] #[inline(always)]
fn mul(self, right: Pnt2<N>) -> Pnt2<N> { fn mul(self, right: Point2<N>) -> Point2<N> {
Pnt2::new( Point2::new(
self.m11 * right.x + self.m12 * right.y, self.m11 * right.x + self.m12 * right.y,
self.m21 * right.x + self.m22 * right.y self.m21 * right.x + self.m22 * right.y
) )
@ -360,10 +360,10 @@ macro_rules! impl_mul_assign_from_mul(
) )
); );
impl_mul_assign_from_mul!(Mat3, Mat3); impl_mul_assign_from_mul!(Matrix3, Matrix3);
impl_mul_assign_from_mul!(Mat2, Mat2); impl_mul_assign_from_mul!(Matrix2, Matrix2);
impl_mul_assign_from_mul!(Vec3, Mat3); impl_mul_assign_from_mul!(Vector3, Matrix3);
impl_mul_assign_from_mul!(Vec2, Mat2); impl_mul_assign_from_mul!(Vector2, Matrix2);
impl_mul_assign_from_mul!(Pnt3, Mat3); impl_mul_assign_from_mul!(Point3, Matrix3);
impl_mul_assign_from_mul!(Pnt2, Mat2); impl_mul_assign_from_mul!(Point2, Matrix2);

View File

@ -0,0 +1,307 @@
use std::ops::{Sub, Mul, Neg};
use num::{Zero, One};
use traits::structure::{Cast, Row, Basis, BaseFloat};
use traits::geometry::{Norm, Cross, CrossMatrix, RotationTo, UniformSphereSample};
use structs::vector::{Vector1, Vector2, Vector3, Vector4};
use structs::matrix::Matrix3;
use structs::rotation::{Rotation2, Rotation3};
impl<N: BaseFloat> RotationTo for Vector2<N> {
type AngleType = N;
type DeltaRotationType = Rotation2<N>;
#[inline]
fn angle_to(&self, other: &Self) -> N {
::cross(self, other).x.atan2(::dot(self, other))
}
#[inline]
fn rotation_to(&self, other: &Self) -> Rotation2<N> {
Rotation2::new(Vector1::new(self.angle_to(other)))
}
}
impl<N: BaseFloat> RotationTo for Vector3<N> {
type AngleType = N;
type DeltaRotationType = Rotation3<N>;
#[inline]
fn angle_to(&self, other: &Self) -> N {
::cross(self, other).norm().atan2(::dot(self, other))
}
#[inline]
fn rotation_to(&self, other: &Self) -> Rotation3<N> {
let mut axis = ::cross(self, other);
let norm = axis.normalize_mut();
if ::is_zero(&norm) {
::one()
}
else {
let axis_angle = axis * norm.atan2(::dot(self, other));
Rotation3::new(axis_angle)
}
}
}
impl<N: Copy + Mul<N, Output = N> + Sub<N, Output = N>> Cross for Vector2<N> {
type CrossProductType = Vector1<N>;
#[inline]
fn cross(&self, other: &Vector2<N>) -> Vector1<N> {
Vector1::new(self.x * other.y - self.y * other.x)
}
}
// FIXME: instead of returning a Vector2, define a Matrix2x1 matrix?
impl<N: Neg<Output = N> + Copy> CrossMatrix<Vector2<N>> for Vector2<N> {
#[inline]
fn cross_matrix(&self) -> Vector2<N> {
Vector2::new(-self.y, self.x)
}
}
impl<N: Copy + Mul<N, Output = N> + Sub<N, Output = N>> Cross for Vector3<N> {
type CrossProductType = Vector3<N>;
#[inline]
fn cross(&self, other: &Vector3<N>) -> Vector3<N> {
Vector3::new(
self.y * other.z - self.z * other.y,
self.z * other.x - self.x * other.z,
self.x * other.y - self.y * other.x
)
}
}
impl<N: Neg<Output = N> + Zero + Copy> CrossMatrix<Matrix3<N>> for Vector3<N> {
#[inline]
fn cross_matrix(&self) -> Matrix3<N> {
Matrix3::new(
::zero(), -self.z, self.y,
self.z, ::zero(), -self.x,
-self.y, self.x, ::zero()
)
}
}
// FIXME: implement this for all other vectors
impl<N: Copy> Row<Vector1<N>> for Vector2<N> {
#[inline]
fn nrows(&self) -> usize {
2
}
#[inline]
fn row(&self, i: usize) -> Vector1<N> {
match i {
0 => Vector1::new(self.x),
1 => Vector1::new(self.y),
_ => panic!(format!("Index out of range: 2d vectors do not have {} rows. ", i))
}
}
#[inline]
fn set_row(&mut self, i: usize, r: Vector1<N>) {
match i {
0 => self.x = r.x,
1 => self.y = r.x,
_ => panic!(format!("Index out of range: 2d vectors do not have {} rows.", i))
}
}
}
impl<N: One> Basis for Vector1<N> {
#[inline(always)]
fn canonical_basis<F: FnMut(Vector1<N>) -> bool>(mut f: F) {
f(Vector1::new(::one()));
}
#[inline(always)]
fn orthonormal_subspace_basis<F: FnMut(Vector1<N>) -> bool>(_: &Vector1<N>, _: F) { }
#[inline]
fn canonical_basis_element(i: usize) -> Option<Vector1<N>> {
if i == 0 {
Some(Vector1::new(::one()))
}
else {
None
}
}
}
impl<N: Copy + One + Zero + Neg<Output = N>> Basis for Vector2<N> {
#[inline(always)]
fn canonical_basis<F: FnMut(Vector2<N>) -> bool>(mut f: F) {
if !f(Vector2::new(::one(), ::zero())) { return };
f(Vector2::new(::zero(), ::one()));
}
#[inline]
fn orthonormal_subspace_basis<F: FnMut(Vector2<N>) -> bool>(n: &Vector2<N>, mut f: F) {
f(Vector2::new(-n.y, n.x));
}
#[inline]
fn canonical_basis_element(i: usize) -> Option<Vector2<N>> {
if i == 0 {
Some(Vector2::new(::one(), ::zero()))
}
else if i == 1 {
Some(Vector2::new(::zero(), ::one()))
}
else {
None
}
}
}
impl<N: BaseFloat> Basis for Vector3<N> {
#[inline(always)]
fn canonical_basis<F: FnMut(Vector3<N>) -> bool>(mut f: F) {
if !f(Vector3::new(::one(), ::zero(), ::zero())) { return };
if !f(Vector3::new(::zero(), ::one(), ::zero())) { return };
f(Vector3::new(::zero(), ::zero(), ::one()));
}
#[inline(always)]
fn orthonormal_subspace_basis<F: FnMut(Vector3<N>) -> bool>(n: &Vector3<N>, mut f: F) {
let a =
if n.x.abs() > n.y.abs() {
Norm::normalize(&Vector3::new(n.z, ::zero(), -n.x))
}
else {
Norm::normalize(&Vector3::new(::zero(), -n.z, n.y))
};
if !f(Cross::cross(&a, n)) { return };
f(a);
}
#[inline]
fn canonical_basis_element(i: usize) -> Option<Vector3<N>> {
if i == 0 {
Some(Vector3::new(::one(), ::zero(), ::zero()))
}
else if i == 1 {
Some(Vector3::new(::zero(), ::one(), ::zero()))
}
else if i == 2 {
Some(Vector3::new(::zero(), ::zero(), ::one()))
}
else {
None
}
}
}
// FIXME: this bad: this fixes definitly the number of samples…
static SAMPLES_2_F64: [Vector2<f64>; 21] = [
Vector2 { x: 1.0, y: 0.0 },
Vector2 { x: 0.95557281, y: 0.29475517 },
Vector2 { x: 0.82623877, y: 0.56332006 },
Vector2 { x: 0.6234898, y: 0.78183148 },
Vector2 { x: 0.36534102, y: 0.93087375 },
Vector2 { x: 0.07473009, y: 0.9972038 },
Vector2 { x: -0.22252093, y: 0.97492791 },
Vector2 { x: -0.5, y: 0.8660254 },
Vector2 { x: -0.73305187, y: 0.68017274 },
Vector2 { x: -0.90096887, y: 0.43388374 },
Vector2 { x: -0.98883083, y: 0.14904227 },
Vector2 { x: -0.98883083, y: -0.14904227 },
Vector2 { x: -0.90096887, y: -0.43388374 },
Vector2 { x: -0.73305187, y: -0.68017274 },
Vector2 { x: -0.5, y: -0.8660254 },
Vector2 { x: -0.22252093, y: -0.97492791 },
Vector2 { x: 0.07473009, y: -0.9972038 },
Vector2 { x: 0.36534102, y: -0.93087375 },
Vector2 { x: 0.6234898, y: -0.78183148 },
Vector2 { x: 0.82623877, y: -0.56332006 },
Vector2 { x: 0.95557281, y: -0.29475517 },
];
// Those vectors come from bullet 3d
static SAMPLES_3_F64: [Vector3<f64>; 42] = [
Vector3 { x: 0.000000 , y: -0.000000, z: -1.000000 },
Vector3 { x: 0.723608 , y: -0.525725, z: -0.447219 },
Vector3 { x: -0.276388, y: -0.850649, z: -0.447219 },
Vector3 { x: -0.894426, y: -0.000000, z: -0.447216 },
Vector3 { x: -0.276388, y: 0.850649 , z: -0.447220 },
Vector3 { x: 0.723608 , y: 0.525725 , z: -0.447219 },
Vector3 { x: 0.276388 , y: -0.850649, z: 0.447220 },
Vector3 { x: -0.723608, y: -0.525725, z: 0.447219 },
Vector3 { x: -0.723608, y: 0.525725 , z: 0.447219 },
Vector3 { x: 0.276388 , y: 0.850649 , z: 0.447219 },
Vector3 { x: 0.894426 , y: 0.000000 , z: 0.447216 },
Vector3 { x: -0.000000, y: 0.000000 , z: 1.000000 },
Vector3 { x: 0.425323 , y: -0.309011, z: -0.850654 },
Vector3 { x: -0.162456, y: -0.499995, z: -0.850654 },
Vector3 { x: 0.262869 , y: -0.809012, z: -0.525738 },
Vector3 { x: 0.425323 , y: 0.309011 , z: -0.850654 },
Vector3 { x: 0.850648 , y: -0.000000, z: -0.525736 },
Vector3 { x: -0.525730, y: -0.000000, z: -0.850652 },
Vector3 { x: -0.688190, y: -0.499997, z: -0.525736 },
Vector3 { x: -0.162456, y: 0.499995 , z: -0.850654 },
Vector3 { x: -0.688190, y: 0.499997 , z: -0.525736 },
Vector3 { x: 0.262869 , y: 0.809012 , z: -0.525738 },
Vector3 { x: 0.951058 , y: 0.309013 , z: 0.000000 },
Vector3 { x: 0.951058 , y: -0.309013, z: 0.000000 },
Vector3 { x: 0.587786 , y: -0.809017, z: 0.000000 },
Vector3 { x: 0.000000 , y: -1.000000, z: 0.000000 },
Vector3 { x: -0.587786, y: -0.809017, z: 0.000000 },
Vector3 { x: -0.951058, y: -0.309013, z: -0.000000 },
Vector3 { x: -0.951058, y: 0.309013 , z: -0.000000 },
Vector3 { x: -0.587786, y: 0.809017 , z: -0.000000 },
Vector3 { x: -0.000000, y: 1.000000 , z: -0.000000 },
Vector3 { x: 0.587786 , y: 0.809017 , z: -0.000000 },
Vector3 { x: 0.688190 , y: -0.499997, z: 0.525736 },
Vector3 { x: -0.262869, y: -0.809012, z: 0.525738 },
Vector3 { x: -0.850648, y: 0.000000 , z: 0.525736 },
Vector3 { x: -0.262869, y: 0.809012 , z: 0.525738 },
Vector3 { x: 0.688190 , y: 0.499997 , z: 0.525736 },
Vector3 { x: 0.525730 , y: 0.000000 , z: 0.850652 },
Vector3 { x: 0.162456 , y: -0.499995, z: 0.850654 },
Vector3 { x: -0.425323, y: -0.309011, z: 0.850654 },
Vector3 { x: -0.425323, y: 0.309011 , z: 0.850654 },
Vector3 { x: 0.162456 , y: 0.499995 , z: 0.850654 }
];
impl<N> UniformSphereSample for Vector1<N>
where Vector1<N>: One {
#[inline(always)]
fn sample<F: FnMut(Vector1<N>)>(mut f: F) {
f(::one())
}
}
impl<N: Cast<f64> + Copy> UniformSphereSample for Vector2<N> {
#[inline(always)]
fn sample<F: FnMut(Vector2<N>)>(mut f: F) {
for sample in SAMPLES_2_F64.iter() {
f(Cast::from(*sample))
}
}
}
impl<N: Cast<f64> + Copy> UniformSphereSample for Vector3<N> {
#[inline(always)]
fn sample<F: FnMut(Vector3<N>)>(mut f: F) {
for sample in SAMPLES_3_F64.iter() {
f(Cast::from(*sample))
}
}
}
impl<N: Cast<f64> + Copy> UniformSphereSample for Vector4<N> {
#[inline(always)]
fn sample<F: FnMut(Vector4<N>)>(_: F) {
panic!("UniformSphereSample::<Vector4<N>>::sample : Not yet implemented.")
// for sample in SAMPLES_3_F32.iter() {
// f(Cast::from(*sample))
// }
}
}

View File

@ -1,384 +0,0 @@
//! Vectors with dimension known at compile-time.
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
use std::mem;
use std::slice::{Iter, IterMut};
use std::iter::{Iterator, FromIterator, IntoIterator};
use std::fmt;
use rand::{Rand, Rng};
use num::{Zero, One};
use traits::operations::{ApproxEq, POrd, POrdering, Axpy, Absolute, Mean};
use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm,
Translation, Translate};
use traits::structure::{Basis, Cast, Dim, Indexable, Iterable, IterableMut, Shape, NumVec,
FloatVec, BaseFloat, BaseNum, Bounded, Repeat};
use structs::pnt::{Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
/// Vector of dimension 1.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vec1<N> {
/// First component of the vector.
pub x: N
}
new_impl!(Vec1, x);
pord_impl!(Vec1, x,);
vec_axis_impl!(Vec1, x);
vec_cast_impl!(Vec1, x);
conversion_impl!(Vec1, 1);
index_impl!(Vec1);
indexable_impl!(Vec1, 1);
at_fast_impl!(Vec1, 1);
repeat_impl!(Vec1, val, x);
dim_impl!(Vec1, 1);
container_impl!(Vec1);
// (specialized); basis_impl!(Vec1, 1);
add_impl!(Vec1, x);
sub_impl!(Vec1, x);
mul_impl!(Vec1, x);
div_impl!(Vec1, x);
scalar_add_impl!(Vec1, x);
scalar_sub_impl!(Vec1, x);
scalar_mul_impl!(Vec1, x);
scalar_div_impl!(Vec1, x);
neg_impl!(Vec1, x);
dot_impl!(Vec1, x);
translation_impl!(Vec1);
norm_impl!(Vec1, x);
approx_eq_impl!(Vec1, x);
zero_one_impl!(Vec1, x);
from_iterator_impl!(Vec1, iterator);
bounded_impl!(Vec1, x);
axpy_impl!(Vec1, x);
iterable_impl!(Vec1, 1);
iterable_mut_impl!(Vec1, 1);
vec_to_homogeneous_impl!(Vec1, Vec2, y, x);
vec_from_homogeneous_impl!(Vec1, Vec2, y, x);
translate_impl!(Vec1, Pnt1);
rotate_impl!(Vec1);
rotate_impl!(Pnt1);
transform_impl!(Vec1, Pnt1);
vec_as_pnt_impl!(Vec1, Pnt1, x);
num_float_vec_impl!(Vec1);
absolute_vec_impl!(Vec1, x);
arbitrary_impl!(Vec1, x);
rand_impl!(Vec1, x);
mean_impl!(Vec1);
vec_display_impl!(Vec1);
/// Vector of dimension 2.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vec2<N> {
/// First component of the vector.
pub x: N,
/// Second component of the vector.
pub y: N
}
new_impl!(Vec2, x, y);
pord_impl!(Vec2, x, y);
vec_axis_impl!(Vec2, x, y);
vec_cast_impl!(Vec2, x, y);
conversion_impl!(Vec2, 2);
index_impl!(Vec2);
indexable_impl!(Vec2, 2);
at_fast_impl!(Vec2, 2);
repeat_impl!(Vec2, val, x, y);
dim_impl!(Vec2, 2);
container_impl!(Vec2);
// (specialized); basis_impl!(Vec2, 1);
add_impl!(Vec2, x, y);
sub_impl!(Vec2, x, y);
mul_impl!(Vec2, x, y);
div_impl!(Vec2, x, y);
scalar_add_impl!(Vec2, x, y);
scalar_sub_impl!(Vec2, x, y);
scalar_mul_impl!(Vec2, x, y);
scalar_div_impl!(Vec2, x, y);
neg_impl!(Vec2, x, y);
dot_impl!(Vec2, x, y);
translation_impl!(Vec2);
norm_impl!(Vec2, x, y);
approx_eq_impl!(Vec2, x, y);
zero_one_impl!(Vec2, x, y);
from_iterator_impl!(Vec2, iterator, iterator);
bounded_impl!(Vec2, x, y);
axpy_impl!(Vec2, x, y);
iterable_impl!(Vec2, 2);
iterable_mut_impl!(Vec2, 2);
vec_to_homogeneous_impl!(Vec2, Vec3, z, x, y);
vec_from_homogeneous_impl!(Vec2, Vec3, z, x, y);
translate_impl!(Vec2, Pnt2);
rotate_impl!(Vec2);
rotate_impl!(Pnt2);
transform_impl!(Vec2, Pnt2);
vec_as_pnt_impl!(Vec2, Pnt2, x, y);
num_float_vec_impl!(Vec2);
absolute_vec_impl!(Vec2, x, y);
arbitrary_impl!(Vec2, x, y);
rand_impl!(Vec2, x, y);
mean_impl!(Vec2);
vec_display_impl!(Vec2);
/// Vector of dimension 3.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vec3<N> {
/// First component of the vector.
pub x: N,
/// Second component of the vector.
pub y: N,
/// Third component of the vector.
pub z: N
}
new_impl!(Vec3, x, y, z);
pord_impl!(Vec3, x, y, z);
vec_axis_impl!(Vec3, x, y, z);
vec_cast_impl!(Vec3, x, y, z);
conversion_impl!(Vec3, 3);
index_impl!(Vec3);
indexable_impl!(Vec3, 3);
at_fast_impl!(Vec3, 3);
repeat_impl!(Vec3, val, x, y, z);
dim_impl!(Vec3, 3);
container_impl!(Vec3);
// (specialized); basis_impl!(Vec3, 1);
add_impl!(Vec3, x, y, z);
sub_impl!(Vec3, x, y, z);
mul_impl!(Vec3, x, y, z);
div_impl!(Vec3, x, y, z);
scalar_add_impl!(Vec3, x, y, z);
scalar_sub_impl!(Vec3, x, y, z);
scalar_mul_impl!(Vec3, x, y, z);
scalar_div_impl!(Vec3, x, y, z);
neg_impl!(Vec3, x, y, z);
dot_impl!(Vec3, x, y, z);
translation_impl!(Vec3);
norm_impl!(Vec3, x, y ,z);
approx_eq_impl!(Vec3, x, y, z);
zero_one_impl!(Vec3, x, y, z);
from_iterator_impl!(Vec3, iterator, iterator, iterator);
bounded_impl!(Vec3, x, y, z);
axpy_impl!(Vec3, x, y, z);
iterable_impl!(Vec3, 3);
iterable_mut_impl!(Vec3, 3);
vec_to_homogeneous_impl!(Vec3, Vec4, w, x, y, z);
vec_from_homogeneous_impl!(Vec3, Vec4, w, x, y, z);
translate_impl!(Vec3, Pnt3);
rotate_impl!(Vec3);
rotate_impl!(Pnt3);
transform_impl!(Vec3, Pnt3);
vec_as_pnt_impl!(Vec3, Pnt3, x, y, z);
num_float_vec_impl!(Vec3);
absolute_vec_impl!(Vec3, x, y, z);
arbitrary_impl!(Vec3, x, y, z);
rand_impl!(Vec3, x, y, z);
mean_impl!(Vec3);
vec_display_impl!(Vec3);
/// Vector of dimension 4.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vec4<N> {
/// First component of the vector.
pub x: N,
/// Second component of the vector.
pub y: N,
/// Third component of the vector.
pub z: N,
/// Fourth component of the vector.
pub w: N
}
new_impl!(Vec4, x, y, z, w);
pord_impl!(Vec4, x, y, z, w);
vec_axis_impl!(Vec4, x, y, z, w);
vec_cast_impl!(Vec4, x, y, z, w);
conversion_impl!(Vec4, 4);
index_impl!(Vec4);
indexable_impl!(Vec4, 4);
at_fast_impl!(Vec4, 4);
repeat_impl!(Vec4, val, x, y, z, w);
dim_impl!(Vec4, 4);
container_impl!(Vec4);
basis_impl!(Vec4, 4);
add_impl!(Vec4, x, y, z, w);
sub_impl!(Vec4, x, y, z, w);
mul_impl!(Vec4, x, y, z, w);
div_impl!(Vec4, x, y, z, w);
scalar_add_impl!(Vec4, x, y, z, w);
scalar_sub_impl!(Vec4, x, y, z, w);
scalar_mul_impl!(Vec4, x, y, z, w);
scalar_div_impl!(Vec4, x, y, z, w);
neg_impl!(Vec4, x, y, z, w);
dot_impl!(Vec4, x, y, z, w);
translation_impl!(Vec4);
norm_impl!(Vec4, x, y, z, w);
approx_eq_impl!(Vec4, x, y, z, w);
zero_one_impl!(Vec4, x, y, z, w);
from_iterator_impl!(Vec4, iterator, iterator, iterator, iterator);
bounded_impl!(Vec4, x, y, z, w);
axpy_impl!(Vec4, x, y, z, w);
iterable_impl!(Vec4, 4);
iterable_mut_impl!(Vec4, 4);
vec_to_homogeneous_impl!(Vec4, Vec5, a, x, y, z, w);
vec_from_homogeneous_impl!(Vec4, Vec5, a, x, y, z, w);
translate_impl!(Vec4, Pnt4);
rotate_impl!(Vec4);
rotate_impl!(Pnt4);
transform_impl!(Vec4, Pnt4);
vec_as_pnt_impl!(Vec4, Pnt4, x, y, z, w);
num_float_vec_impl!(Vec4);
absolute_vec_impl!(Vec4, x, y, z, w);
arbitrary_impl!(Vec4, x, y, z, w);
rand_impl!(Vec4, x, y, z, w);
mean_impl!(Vec4);
vec_display_impl!(Vec4);
/// Vector of dimension 5.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vec5<N> {
/// First component of the vector.
pub x: N,
/// Second component of the vector.
pub y: N,
/// Third component of the vector.
pub z: N,
/// Fourth component of the vector.
pub w: N,
/// Fifth of the vector.
pub a: N
}
new_impl!(Vec5, x, y, z, w, a);
pord_impl!(Vec5, x, y, z, w, a);
vec_axis_impl!(Vec5, x, y, z, w, a);
vec_cast_impl!(Vec5, x, y, z, w, a);
conversion_impl!(Vec5, 5);
index_impl!(Vec5);
indexable_impl!(Vec5, 5);
at_fast_impl!(Vec5, 5);
repeat_impl!(Vec5, val, x, y, z, w, a);
dim_impl!(Vec5, 5);
container_impl!(Vec5);
basis_impl!(Vec5, 5);
add_impl!(Vec5, x, y, z, w, a);
sub_impl!(Vec5, x, y, z, w, a);
mul_impl!(Vec5, x, y, z, w, a);
div_impl!(Vec5, x, y, z, w, a);
scalar_add_impl!(Vec5, x, y, z, w, a);
scalar_sub_impl!(Vec5, x, y, z, w, a);
scalar_mul_impl!(Vec5, x, y, z, w, a);
scalar_div_impl!(Vec5, x, y, z, w, a);
neg_impl!(Vec5, x, y, z, w, a);
dot_impl!(Vec5, x, y, z, w, a);
translation_impl!(Vec5);
norm_impl!(Vec5, x, y, z, w, a);
approx_eq_impl!(Vec5, x, y, z, w, a);
zero_one_impl!(Vec5, x, y, z, w, a);
from_iterator_impl!(Vec5, iterator, iterator, iterator, iterator, iterator);
bounded_impl!(Vec5, x, y, z, w, a);
axpy_impl!(Vec5, x, y, z, w, a);
iterable_impl!(Vec5, 5);
iterable_mut_impl!(Vec5, 5);
vec_to_homogeneous_impl!(Vec5, Vec6, b, x, y, z, w, a);
vec_from_homogeneous_impl!(Vec5, Vec6, b, x, y, z, w, a);
translate_impl!(Vec5, Pnt5);
rotate_impl!(Vec5);
rotate_impl!(Pnt5);
transform_impl!(Vec5, Pnt5);
vec_as_pnt_impl!(Vec5, Pnt5, x, y, z, w, a);
num_float_vec_impl!(Vec5);
absolute_vec_impl!(Vec5, x, y, z, w, a);
arbitrary_impl!(Vec5, x, y, z, w, a);
rand_impl!(Vec5, x, y, z, w, a);
mean_impl!(Vec5);
vec_display_impl!(Vec5);
/// Vector of dimension 6.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vec6<N> {
/// First component of the vector.
pub x: N,
/// Second component of the vector.
pub y: N,
/// Third component of the vector.
pub z: N,
/// Fourth component of the vector.
pub w: N,
/// Fifth of the vector.
pub a: N,
/// Sixth component of the vector.
pub b: N
}
new_impl!(Vec6, x, y, z, w, a, b);
pord_impl!(Vec6, x, y, z, w, a, b);
vec_axis_impl!(Vec6, x, y, z, w, a, b);
vec_cast_impl!(Vec6, x, y, z, w, a, b);
conversion_impl!(Vec6, 6);
index_impl!(Vec6);
indexable_impl!(Vec6, 6);
at_fast_impl!(Vec6, 6);
repeat_impl!(Vec6, val, x, y, z, w, a, b);
dim_impl!(Vec6, 6);
container_impl!(Vec6);
basis_impl!(Vec6, 6);
add_impl!(Vec6, x, y, z, w, a, b);
sub_impl!(Vec6, x, y, z, w, a, b);
mul_impl!(Vec6, x, y, z, w, a, b);
div_impl!(Vec6, x, y, z, w, a, b);
scalar_add_impl!(Vec6, x, y, z, w, a, b);
scalar_sub_impl!(Vec6, x, y, z, w, a, b);
scalar_mul_impl!(Vec6, x, y, z, w, a, b);
scalar_div_impl!(Vec6, x, y, z, w, a, b);
neg_impl!(Vec6, x, y, z, w, a, b);
dot_impl!(Vec6, x, y, z, w, a, b);
translation_impl!(Vec6);
norm_impl!(Vec6, x, y, z, w, a, b);
approx_eq_impl!(Vec6, x, y, z, w, a, b);
zero_one_impl!(Vec6, x, y, z, w, a, b);
from_iterator_impl!(Vec6, iterator, iterator, iterator, iterator, iterator, iterator);
bounded_impl!(Vec6, x, y, z, w, a, b);
axpy_impl!(Vec6, x, y, z, w, a, b);
iterable_impl!(Vec6, 6);
iterable_mut_impl!(Vec6, 6);
translate_impl!(Vec6, Pnt6);
rotate_impl!(Vec6);
rotate_impl!(Pnt6);
transform_impl!(Vec6, Pnt6);
vec_as_pnt_impl!(Vec6, Pnt6, x, y, z, w, a, b);
num_float_vec_impl!(Vec6);
absolute_vec_impl!(Vec6, x, y, z, w, a, b);
arbitrary_impl!(Vec6, x, y, z, w, a, b);
rand_impl!(Vec6, x, y, z, w, a, b);
mean_impl!(Vec6);
vec_display_impl!(Vec6);

384
src/structs/vector.rs Normal file
View File

@ -0,0 +1,384 @@
//! Vectors with dimension known at compile-time.
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
use std::mem;
use std::slice::{Iter, IterMut};
use std::iter::{Iterator, FromIterator, IntoIterator};
use std::fmt;
use rand::{Rand, Rng};
use num::{Zero, One};
use traits::operations::{ApproxEq, PartialOrder, PartialOrdering, Axpy, Absolute, Mean};
use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm,
Translation, Translate};
use traits::structure::{Basis, Cast, Dimension, Indexable, Iterable, IterableMut, Shape, NumVector,
FloatVector, BaseFloat, BaseNum, Bounded, Repeat};
use structs::point::{Point1, Point2, Point3, Point4, Point5, Point6};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
/// Vector of dimension 1.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vector1<N> {
/// First component of the vector.
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);
from_iterator_impl!(Vector1, iterator);
bounded_impl!(Vector1, x);
axpy_impl!(Vector1, x);
iterable_impl!(Vector1, 1);
iterable_mut_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.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vector2<N> {
/// First component of the vector.
pub x: N,
/// Second component of the vector.
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);
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);
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.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vector3<N> {
/// First component of the vector.
pub x: N,
/// Second component of the vector.
pub y: N,
/// Third component of the vector.
pub z: N
}
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);
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);
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.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vector4<N> {
/// First component of the vector.
pub x: N,
/// Second component of the vector.
pub y: N,
/// Third component of the vector.
pub z: N,
/// Fourth component of the vector.
pub w: N
}
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);
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);
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.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vector5<N> {
/// First component of the vector.
pub x: N,
/// Second component of the vector.
pub y: N,
/// Third component of the vector.
pub z: N,
/// Fourth component of the vector.
pub w: N,
/// Fifth of the vector.
pub a: N
}
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);
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);
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.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vector6<N> {
/// First component of the vector.
pub x: N,
/// Second component of the vector.
pub y: N,
/// Third component of the vector.
pub z: N,
/// Fourth component of the vector.
pub w: N,
/// Fifth of the vector.
pub a: N,
/// Sixth component of the vector.
pub b: N
}
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);
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);

View File

@ -15,37 +15,37 @@ macro_rules! new_impl(
); );
macro_rules! conversion_impl( macro_rules! conversion_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N> AsRef<[N; $dim]> for $t<N> { impl<N> AsRef<[N; $dimension]> for $t<N> {
#[inline] #[inline]
fn as_ref(&self) -> &[N; $dim] { fn as_ref(&self) -> &[N; $dimension] {
unsafe { unsafe {
mem::transmute(self) mem::transmute(self)
} }
} }
} }
impl<N> AsMut<[N; $dim]> for $t<N> { impl<N> AsMut<[N; $dimension]> for $t<N> {
#[inline] #[inline]
fn as_mut(&mut self) -> &mut [N; $dim] { fn as_mut(&mut self) -> &mut [N; $dimension] {
unsafe { unsafe {
mem::transmute(self) mem::transmute(self)
} }
} }
} }
impl<'a, N> From<&'a [N; $dim]> for &'a $t<N> { impl<'a, N> From<&'a [N; $dimension]> for &'a $t<N> {
#[inline] #[inline]
fn from(arr: &'a [N; $dim]) -> &'a $t<N> { fn from(arr: &'a [N; $dimension]) -> &'a $t<N> {
unsafe { unsafe {
mem::transmute(arr) mem::transmute(arr)
} }
} }
} }
impl<'a, N> From<&'a mut [N; $dim]> for &'a mut $t<N> { impl<'a, N> From<&'a mut [N; $dimension]> for &'a mut $t<N> {
#[inline] #[inline]
fn from(arr: &'a mut [N; $dim]) -> &'a mut $t<N> { fn from(arr: &'a mut [N; $dimension]) -> &'a mut $t<N> {
unsafe { unsafe {
mem::transmute(arr) mem::transmute(arr)
} }
@ -55,7 +55,7 @@ macro_rules! conversion_impl(
); );
macro_rules! at_fast_impl( macro_rules! at_fast_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N: Copy> $t<N> { impl<N: Copy> $t<N> {
/// Unsafe read access to a vector element by index. /// Unsafe read access to a vector element by index.
#[inline] #[inline]
@ -76,7 +76,7 @@ macro_rules! at_fast_impl(
// However, f32/f64 does not implement Ord… // However, f32/f64 does not implement Ord…
macro_rules! pord_impl( macro_rules! pord_impl(
($t: ident, $comp0: ident, $($compN: ident),*) => ( ($t: ident, $comp0: ident, $($compN: ident),*) => (
impl<N: BaseFloat> POrd for $t<N> { impl<N: BaseFloat> PartialOrder for $t<N> {
#[inline] #[inline]
fn inf(&self, other: &$t<N>) -> $t<N> { fn inf(&self, other: &$t<N>) -> $t<N> {
$t::new(self.$comp0.min(other.$comp0) $t::new(self.$comp0.min(other.$comp0)
@ -90,24 +90,24 @@ macro_rules! pord_impl(
} }
#[inline] #[inline]
#[allow(unused_mut)] // otherwise there will be a warning for is_eq or Vec1. #[allow(unused_mut)] // otherwise there will be a warning for is_eq or Vector1.
fn partial_cmp(&self, other: &$t<N>) -> POrdering { fn partial_cmp(&self, other: &$t<N>) -> PartialOrdering {
let is_lt = self.$comp0 < other.$comp0; let is_lt = self.$comp0 < other.$comp0;
let mut is_eq = self.$comp0 == other.$comp0; let mut is_eq = self.$comp0 == other.$comp0;
if is_lt { // < if is_lt { // <
$( $(
if self.$compN > other.$compN { if self.$compN > other.$compN {
return POrdering::NotComparable return PartialOrdering::NotComparable
} }
)* )*
POrdering::PartialLess PartialOrdering::PartialLess
} }
else { // >= else { // >=
$( $(
if self.$compN < other.$compN { if self.$compN < other.$compN {
return POrdering::NotComparable return PartialOrdering::NotComparable
} }
else if self.$compN > other.$compN { else if self.$compN > other.$compN {
is_eq = false; is_eq = false;
@ -116,10 +116,10 @@ macro_rules! pord_impl(
)* )*
if is_eq { if is_eq {
POrdering::PartialEqual PartialOrdering::PartialEqual
} }
else { else {
POrdering::PartialGreater PartialOrdering::PartialGreater
} }
} }
} }
@ -177,11 +177,11 @@ macro_rules! vec_cast_impl(
); );
macro_rules! indexable_impl( macro_rules! indexable_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N> Shape<usize> for $t<N> { impl<N> Shape<usize> for $t<N> {
#[inline] #[inline]
fn shape(&self) -> usize { fn shape(&self) -> usize {
$dim $dimension
} }
} }
@ -189,18 +189,18 @@ macro_rules! indexable_impl(
#[inline] #[inline]
fn swap(&mut self, i1: usize, i2: usize) { fn swap(&mut self, i1: usize, i2: usize) {
unsafe { unsafe {
mem::transmute::<&mut $t<N>, &mut [N; $dim]>(self).swap(i1, i2) mem::transmute::<&mut $t<N>, &mut [N; $dimension]>(self).swap(i1, i2)
} }
} }
#[inline] #[inline]
unsafe fn unsafe_at(&self, i: usize) -> N { unsafe fn unsafe_at(&self, i: usize) -> N {
(*mem::transmute::<&$t<N>, &[N; $dim]>(self).get_unchecked(i)) (*mem::transmute::<&$t<N>, &[N; $dimension]>(self).get_unchecked(i))
} }
#[inline] #[inline]
unsafe fn unsafe_set(&mut self, i: usize, val: N) { unsafe fn unsafe_set(&mut self, i: usize, val: N) {
(*mem::transmute::<&mut $t<N>, &mut [N; $dim]>(self).get_unchecked_mut(i)) = val (*mem::transmute::<&mut $t<N>, &mut [N; $dimension]>(self).get_unchecked_mut(i)) = val
} }
} }
) )
@ -239,12 +239,12 @@ macro_rules! repeat_impl(
); );
macro_rules! iterable_impl( macro_rules! iterable_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N> Iterable<N> for $t<N> { impl<N> Iterable<N> for $t<N> {
#[inline] #[inline]
fn iter<'l>(&'l self) -> Iter<'l, N> { fn iter<'l>(&'l self) -> Iter<'l, N> {
unsafe { unsafe {
mem::transmute::<&'l $t<N>, &'l [N; $dim]>(self).iter() mem::transmute::<&'l $t<N>, &'l [N; $dimension]>(self).iter()
} }
} }
} }
@ -252,12 +252,12 @@ macro_rules! iterable_impl(
); );
macro_rules! iterable_mut_impl( macro_rules! iterable_mut_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N> IterableMut<N> for $t<N> { impl<N> IterableMut<N> for $t<N> {
#[inline] #[inline]
fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> { fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> {
unsafe { unsafe {
mem::transmute::<&'l mut $t<N>, &'l mut [N; $dim]>(self).iter_mut() mem::transmute::<&'l mut $t<N>, &'l mut [N; $dimension]>(self).iter_mut()
} }
} }
} }
@ -265,11 +265,11 @@ macro_rules! iterable_mut_impl(
); );
macro_rules! dim_impl( macro_rules! dim_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N> Dim for $t<N> { impl<N> Dimension for $t<N> {
#[inline] #[inline]
fn dim(_: Option<$t<N>>) -> usize { fn dimension(_: Option<$t<N>>) -> usize {
$dim $dimension
} }
} }
) )
@ -281,18 +281,18 @@ macro_rules! container_impl(
/// The dimension of this entity. /// The dimension of this entity.
#[inline] #[inline]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
Dim::dim(None::<$t<N>>) Dimension::dimension(None::<$t<N>>)
} }
} }
) )
); );
macro_rules! basis_impl( macro_rules! basis_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dimension: expr) => (
impl<N: BaseFloat + ApproxEq<N>> Basis for $t<N> { impl<N: BaseFloat + ApproxEq<N>> Basis for $t<N> {
#[inline] #[inline]
fn canonical_basis<F: FnMut($t<N>) -> bool>(mut f: F) { fn canonical_basis<F: FnMut($t<N>) -> bool>(mut f: F) {
for i in 0 .. $dim { for i in 0 .. $dimension {
if !f(Basis::canonical_basis_element(i).unwrap()) { return } if !f(Basis::canonical_basis_element(i).unwrap()) { return }
} }
} }
@ -303,14 +303,14 @@ macro_rules! basis_impl(
// orthogonalization algorithm. // orthogonalization algorithm.
let mut basis: Vec<$t<N>> = Vec::new(); let mut basis: Vec<$t<N>> = Vec::new();
for i in 0 .. $dim { for i in 0 .. $dimension {
let mut basis_element : $t<N> = ::zero(); let mut basis_element : $t<N> = ::zero();
unsafe { unsafe {
basis_element.set_fast(i, ::one()); basis_element.set_fast(i, ::one());
} }
if basis.len() == $dim - 1 { if basis.len() == $dimension - 1 {
break; break;
} }
@ -322,7 +322,7 @@ macro_rules! basis_impl(
elt = elt - *v * Dot::dot(&elt, v) elt = elt - *v * Dot::dot(&elt, v)
}; };
if !ApproxEq::approx_eq(&Norm::sqnorm(&elt), &::zero()) { if !ApproxEq::approx_eq(&Norm::norm_squared(&elt), &::zero()) {
let new_element = Norm::normalize(&elt); let new_element = Norm::normalize(&elt);
if !f(new_element) { return }; if !f(new_element) { return };
@ -334,7 +334,7 @@ macro_rules! basis_impl(
#[inline] #[inline]
fn canonical_basis_element(i: usize) -> Option<$t<N>> { fn canonical_basis_element(i: usize) -> Option<$t<N>> {
if i < $dim { if i < $dimension {
let mut basis_element : $t<N> = ::zero(); let mut basis_element : $t<N> = ::zero();
unsafe { unsafe {
@ -621,7 +621,7 @@ macro_rules! translation_impl(
} }
#[inline] #[inline]
fn inv_translation(&self) -> $t<N> { fn inverse_translation(&self) -> $t<N> {
-*self -*self
} }
@ -657,7 +657,7 @@ macro_rules! norm_impl(
($t: ident, $($compN: ident),+) => ( ($t: ident, $($compN: ident),+) => (
impl<N: BaseFloat> Norm<N> for $t<N> { impl<N: BaseFloat> Norm<N> for $t<N> {
#[inline] #[inline]
fn sqnorm(&self) -> N { fn norm_squared(&self) -> N {
Dot::dot(self, self) Dot::dot(self, self)
} }
@ -816,7 +816,7 @@ macro_rules! translate_impl(
*other + *self *other + *self
} }
fn inv_translate(&self, other: &$t<N>) -> $t<N> { fn inverse_translate(&self, other: &$t<N>) -> $t<N> {
*other - *self *other - *self
} }
} }
@ -830,7 +830,7 @@ macro_rules! rotate_impl(
*other *other
} }
fn inv_rotate(&self, other: &O) -> O { fn inverse_rotate(&self, other: &O) -> O {
*other *other
} }
} }
@ -844,19 +844,19 @@ macro_rules! transform_impl(
self.translate(other) self.translate(other)
} }
fn inv_transform(&self, other: &$t<N>) -> $t<N> { fn inverse_transform(&self, other: &$t<N>) -> $t<N> {
self.inv_translate(other) self.inverse_translate(other)
} }
} }
) )
); );
macro_rules! vec_as_pnt_impl( macro_rules! vec_as_point_impl(
($tv: ident, $t: ident, $($compN: ident),+) => ( ($tv: ident, $t: ident, $($compN: ident),+) => (
impl<N> $tv<N> { impl<N> $tv<N> {
/// Converts this vector to a point. /// Converts this vector to a point.
#[inline] #[inline]
pub fn to_pnt(self) -> $t<N> { pub fn to_point(self) -> $t<N> {
$t::new( $t::new(
$(self.$compN),+ $(self.$compN),+
) )
@ -864,7 +864,7 @@ macro_rules! vec_as_pnt_impl(
/// Reinterprets this vector as a point. /// Reinterprets this vector as a point.
#[inline] #[inline]
pub fn as_pnt(&self) -> &$t<N> { pub fn as_point(&self) -> &$t<N> {
unsafe { unsafe {
mem::transmute(self) mem::transmute(self)
} }
@ -875,11 +875,11 @@ macro_rules! vec_as_pnt_impl(
macro_rules! num_float_vec_impl( macro_rules! num_float_vec_impl(
($t: ident) => ( ($t: ident) => (
impl<N> NumVec<N> for $t<N> impl<N> NumVector<N> for $t<N>
where N: BaseNum { where N: BaseNum {
} }
impl<N> FloatVec<N> for $t<N> impl<N> FloatVector<N> for $t<N>
where N: BaseFloat + ApproxEq<N> { where N: BaseFloat + ApproxEq<N> {
} }
) )

View File

@ -7,35 +7,35 @@ use num::{Zero, One};
use generic_array::{GenericArray, ArrayLength}; use generic_array::{GenericArray, ArrayLength};
use traits::operations::{ApproxEq, Axpy, Mean}; use traits::operations::{ApproxEq, Axpy, Mean};
use traits::geometry::{Dot, Norm}; use traits::geometry::{Dot, Norm};
use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat, BaseNum, Cast, Dim}; use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat, BaseNum, Cast, Dimension};
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};
/// A static array of arbitrary dimension. /// A static array of arbitrary dimension.
#[repr(C)] #[repr(C)]
#[derive(Eq, PartialEq, Debug)] // FIXME: Hash, RustcEncodable, RustcDecodable #[derive(Eq, PartialEq, Debug)] // FIXME: Hash, RustcEncodable, RustcDecodable
pub struct VecN<N, D: ArrayLength<N>> { pub struct VectorN<N, D: ArrayLength<N>> {
/// The underlying data of the vector. /// The underlying data of the vector.
pub at: GenericArray<N, D> pub at: GenericArray<N, D>
} }
unsafe impl<N: Send, D: ArrayLength<N>> Send for VecN<N, D> { unsafe impl<N: Send, D: ArrayLength<N>> Send for VectorN<N, D> {
} }
impl<N: Clone, D: ArrayLength<N>> Clone for VecN<N, D> { impl<N: Clone, D: ArrayLength<N>> Clone for VectorN<N, D> {
fn clone(&self) -> VecN<N, D> { fn clone(&self) -> VectorN<N, D> {
VecN::new(self.at.clone()) VectorN::new(self.at.clone())
} }
} }
impl<N: Copy, D: ArrayLength<N>> Copy for VecN<N, D> impl<N: Copy, D: ArrayLength<N>> Copy for VectorN<N, D>
where D::ArrayType: Copy { } where D::ArrayType: Copy { }
impl<N, D: ArrayLength<N>> VecN<N, D> { impl<N, D: ArrayLength<N>> VectorN<N, D> {
/// Creates a new vector from a given arbirtarily-sized array. /// Creates a new vector from a given arbirtarily-sized array.
#[inline] #[inline]
pub fn new(components: GenericArray<N, D>) -> VecN<N, D> { pub fn new(components: GenericArray<N, D>) -> VectorN<N, D> {
VecN { VectorN {
at: components at: components
} }
} }
@ -47,31 +47,31 @@ impl<N, D: ArrayLength<N>> VecN<N, D> {
} }
} }
impl<N, D: ArrayLength<N>> Dim for VecN<N, D> { impl<N, D: ArrayLength<N>> Dimension for VectorN<N, D> {
fn dim(_unused: Option<Self>) -> usize { fn dimension(_unused: Option<Self>) -> usize {
D::to_usize() D::to_usize()
} }
} }
impl<N: Copy, D: ArrayLength<N>> FromIterator<N> for VecN<N, D> { impl<N: Copy, D: ArrayLength<N>> FromIterator<N> for VectorN<N, D> {
#[inline] #[inline]
fn from_iter<I: IntoIterator<Item = N>>(param: I) -> VecN<N, D> { fn from_iter<I: IntoIterator<Item = N>>(param: I) -> VectorN<N, D> {
let mut res: VecN<N, D> = unsafe { mem::uninitialized() }; let mut res: VectorN<N, D> = unsafe { mem::uninitialized() };
let mut it = param.into_iter(); let mut it = param.into_iter();
for e in res.iter_mut() { for e in res.iter_mut() {
*e = it.next().expect("Not enough data into the provided iterator to initialize this `VecN`."); *e = it.next().expect("Not enough data into the provided iterator to initialize this `VectorN`.");
} }
res res
} }
} }
impl<N: Rand + Zero, D: ArrayLength<N>> Rand for VecN<N, D> { impl<N: Rand + Zero, D: ArrayLength<N>> Rand for VectorN<N, D> {
#[inline] #[inline]
fn rand<R: Rng>(rng: &mut R) -> VecN<N, D> { fn rand<R: Rng>(rng: &mut R) -> VectorN<N, D> {
let mut res: VecN<N, D> = unsafe { mem::uninitialized() }; let mut res: VectorN<N, D> = unsafe { mem::uninitialized() };
for e in res.iter_mut() { for e in res.iter_mut() {
*e = Rand::rand(rng) *e = Rand::rand(rng)
@ -81,10 +81,10 @@ impl<N: Rand + Zero, D: ArrayLength<N>> Rand for VecN<N, D> {
} }
} }
impl<N: Copy + One + Zero, D: ArrayLength<N>> One for VecN<N, D> { impl<N: Copy + One + Zero, D: ArrayLength<N>> One for VectorN<N, D> {
#[inline] #[inline]
fn one() -> VecN<N, D> { fn one() -> VectorN<N, D> {
let mut res: VecN<N, D> = unsafe { mem::uninitialized() }; let mut res: VectorN<N, D> = unsafe { mem::uninitialized() };
for e in res.iter_mut() { for e in res.iter_mut() {
*e = ::one() *e = ::one()
@ -94,10 +94,10 @@ impl<N: Copy + One + Zero, D: ArrayLength<N>> One for VecN<N, D> {
} }
} }
impl<N: Copy + Zero, D: ArrayLength<N>> Zero for VecN<N, D> { impl<N: Copy + Zero, D: ArrayLength<N>> Zero for VectorN<N, D> {
#[inline] #[inline]
fn zero() -> VecN<N, D> { fn zero() -> VectorN<N, D> {
let mut res: VecN<N, D> = unsafe { mem::uninitialized() }; let mut res: VectorN<N, D> = unsafe { mem::uninitialized() };
for e in res.iter_mut() { for e in res.iter_mut() {
*e = ::zero() *e = ::zero()
@ -113,11 +113,11 @@ impl<N: Copy + Zero, D: ArrayLength<N>> Zero for VecN<N, D> {
} }
#[cfg(feature="arbitrary")] #[cfg(feature="arbitrary")]
impl<N: Arbitrary + Zero + Copy, D: 'static + ArrayLength<N>> Arbitrary for VecN<N, D> { impl<N: Arbitrary + Zero + Copy, D: 'static + ArrayLength<N>> Arbitrary for VectorN<N, D> {
#[inline] #[inline]
fn arbitrary<G: Gen>(g: &mut G) -> VecN<N, D> { fn arbitrary<G: Gen>(g: &mut G) -> VectorN<N, D> {
(0 .. D::to_usize()).map(|_| Arbitrary::arbitrary(g)).collect() (0 .. D::to_usize()).map(|_| Arbitrary::arbitrary(g)).collect()
} }
} }
vecn_dvec_common_impl!(VecN, D); vecn_dvec_common_impl!(VectorN, D);

View File

@ -497,7 +497,7 @@ macro_rules! vecn_dvec_common_impl(
*/ */
impl<N: BaseFloat $(, $param : ArrayLength<N>)*> Norm<N> for $vecn<N $(, $param)*> { impl<N: BaseFloat $(, $param : ArrayLength<N>)*> Norm<N> for $vecn<N $(, $param)*> {
#[inline] #[inline]
fn sqnorm(&self) -> N { fn norm_squared(&self) -> N {
Dot::dot(self, self) Dot::dot(self, self)
} }

View File

@ -1,7 +1,7 @@
//! Traits of operations having a well-known or explicit geometric meaning. //! Traits of operations having a well-known or explicit geometric meaning.
use std::ops::{Neg, Mul}; use std::ops::{Neg, Mul};
use traits::structure::{BaseFloat, SquareMat}; use traits::structure::{BaseFloat, SquareMatrix};
/// Trait of object which represent a translation, and to wich new translation /// Trait of object which represent a translation, and to wich new translation
/// can be appended. /// can be appended.
@ -11,7 +11,7 @@ pub trait Translation<V> {
fn translation(&self) -> V; fn translation(&self) -> V;
/// Gets the inverse translation associated with this object. /// Gets the inverse translation associated with this object.
fn inv_translation(&self) -> V; fn inverse_translation(&self) -> V;
/// Appends a translation to this object. /// Appends a translation to this object.
fn append_translation_mut(&mut self, &V); fn append_translation_mut(&mut self, &V);
@ -36,7 +36,7 @@ pub trait Translate<V> {
fn translate(&self, &V) -> V; fn translate(&self, &V) -> V;
/// Apply an inverse translation to an object. /// Apply an inverse translation to an object.
fn inv_translate(&self, &V) -> V; fn inverse_translate(&self, &V) -> V;
} }
/// Trait of object which can represent a rotation, and to which new rotations can be appended. A /// Trait of object which can represent a rotation, and to which new rotations can be appended. A
@ -46,7 +46,7 @@ pub trait Rotation<V> {
fn rotation(&self) -> V; fn rotation(&self) -> V;
/// Gets the inverse rotation associated with `self`. /// Gets the inverse rotation associated with `self`.
fn inv_rotation(&self) -> V; fn inverse_rotation(&self) -> V;
/// Appends a rotation to this object. /// Appends a rotation to this object.
fn append_rotation_mut(&mut self, &V); fn append_rotation_mut(&mut self, &V);
@ -88,7 +88,7 @@ pub trait Rotate<V> {
fn rotate(&self, v: &V) -> V; fn rotate(&self, v: &V) -> V;
/// Applies an inverse rotation to `v`. /// Applies an inverse rotation to `v`.
fn inv_rotate(&self, v: &V) -> V; fn inverse_rotate(&self, v: &V) -> V;
} }
/// Various composition of rotation and translation. /// Various composition of rotation and translation.
@ -159,10 +159,10 @@ impl<LV: Neg<Output = LV> + Copy, AV, M: Rotation<AV> + Translation<LV>> Rotatio
/// be implemented by quaternions to convert them to a rotation matrix. /// be implemented by quaternions to convert them to a rotation matrix.
pub trait RotationMatrix<N, LV: Mul<Self::Output, Output = LV>, AV> : Rotation<AV> { pub trait RotationMatrix<N, LV: Mul<Self::Output, Output = LV>, AV> : Rotation<AV> {
/// The output rotation matrix type. /// The output rotation matrix type.
type Output: SquareMat<N, LV> + Rotation<AV>; type Output: SquareMatrix<N, LV> + Rotation<AV>;
/// Gets the rotation matrix represented by `self`. /// Gets the rotation matrix represented by `self`.
fn to_rot_mat(&self) -> Self::Output; fn to_rotation_matrix(&self) -> Self::Output;
} }
/// Composition of a rotation and an absolute value. /// Composition of a rotation and an absolute value.
@ -187,7 +187,7 @@ pub trait Transformation<M> {
fn transformation(&self) -> M; fn transformation(&self) -> M;
/// Gets the inverse transformation of `self`. /// Gets the inverse transformation of `self`.
fn inv_transformation(&self) -> M; fn inverse_transformation(&self) -> M;
/// Appends a transformation to this object. /// Appends a transformation to this object.
fn append_transformation_mut(&mut self, &M); fn append_transformation_mut(&mut self, &M);
@ -213,7 +213,7 @@ pub trait Transform<V> {
fn transform(&self, &V) -> V; fn transform(&self, &V) -> V;
/// Applies an inverse transformation to `v`. /// Applies an inverse transformation to `v`.
fn inv_transform(&self, &V) -> V; fn inverse_transform(&self, &V) -> V;
} }
/// Traits of objects having a dot product. /// Traits of objects having a dot product.
@ -228,13 +228,13 @@ pub trait Norm<N: BaseFloat> {
/// Computes the norm of `self`. /// Computes the norm of `self`.
#[inline] #[inline]
fn norm(&self) -> N { fn norm(&self) -> N {
self.sqnorm().sqrt() self.norm_squared().sqrt()
} }
/// Computes the squared norm of `self`. /// Computes the squared norm of `self`.
/// ///
/// This is usually faster than computing the norm itself. /// This is usually faster than computing the norm itself.
fn sqnorm(&self) -> N; fn norm_squared(&self) -> N;
/// Gets the normalized version of a copy of `v`. /// Gets the normalized version of a copy of `v`.
fn normalize(&self) -> Self; fn normalize(&self) -> Self;
@ -288,10 +288,10 @@ pub trait UniformSphereSample : Sized {
} }
/// The zero element of a vector space, seen as an element of its embeding affine space. /// The zero element of a vector space, seen as an element of its embeding affine space.
// XXX: once associated types are suported, move this to the `AnyPnt` trait. // XXX: once associated types are suported, move this to the `AnyPoint` trait.
pub trait Orig { pub trait Origin {
/// The trivial origin. /// The trivial origin.
fn orig() -> Self; fn origin() -> Self;
/// Returns true if this points is exactly the trivial origin. /// Returns true if this points is exactly the trivial origin.
fn is_orig(&self) -> bool; fn is_origin(&self) -> bool;
} }

View File

@ -1,18 +1,18 @@
//! Mathematical traits. //! Matrixhematical traits.
pub use traits::geometry::{AbsoluteRotate, Cross, CrossMatrix, Dot, FromHomogeneous, Norm, Orig, pub use traits::geometry::{AbsoluteRotate, Cross, CrossMatrix, Dot, FromHomogeneous, Norm, Origin,
Rotate, Rotation, RotationMatrix, RotationWithTranslation, RotationTo, Rotate, Rotation, RotationMatrix, RotationWithTranslation, RotationTo,
ToHomogeneous, Transform, Transformation, Translate, Translation, ToHomogeneous, Transform, Transformation, Translate, Translation,
UniformSphereSample}; UniformSphereSample};
pub use traits::structure::{FloatVec, FloatPnt, Basis, Cast, Col, Dim, Indexable, Iterable, pub use traits::structure::{FloatVector, FloatPoint, Basis, Cast, Column, Dimension, Indexable, Iterable,
IterableMut, Mat, SquareMat, Row, NumVec, NumPnt, PntAsVec, ColSlice, IterableMut, Matrix, SquareMatrix, Row, NumVector, NumPoint, PointAsVector, ColumnSlice,
RowSlice, Diag, DiagMut, Eye, Repeat, Shape, BaseFloat, BaseNum, RowSlice, Diagonal, DiagMut, Eye, Repeat, Shape, BaseFloat, BaseNum,
Bounded}; Bounded};
pub use traits::operations::{Absolute, ApproxEq, Axpy, Cov, Det, Inv, Mean, Outer, POrd, Transpose, pub use traits::operations::{Absolute, ApproxEq, Axpy, Covariance, Determinant, Inverse, Mean, Outer, PartialOrder, Transpose,
EigenQR}; EigenQR};
pub use traits::operations::POrdering; pub use traits::operations::PartialOrdering;
pub mod geometry; pub mod geometry;
pub mod structure; pub mod structure;

View File

@ -3,11 +3,11 @@
use num::{Float, Signed}; use num::{Float, Signed};
use std::ops::Mul; use std::ops::Mul;
use std::cmp::Ordering; use std::cmp::Ordering;
use traits::structure::SquareMat; use traits::structure::SquareMatrix;
/// Result of a partial ordering. /// Result of a partial ordering.
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)] #[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub enum POrdering { pub enum PartialOrdering {
/// Result of a strict comparison. /// Result of a strict comparison.
PartialLess, PartialLess,
/// Equality relationship. /// Equality relationship.
@ -18,61 +18,61 @@ pub enum POrdering {
NotComparable NotComparable
} }
impl POrdering { impl PartialOrdering {
/// Returns `true` if `self` is equal to `Equal`. /// Returns `true` if `self` is equal to `Equal`.
pub fn is_eq(&self) -> bool { pub fn is_eq(&self) -> bool {
*self == POrdering::PartialEqual *self == PartialOrdering::PartialEqual
} }
/// Returns `true` if `self` is equal to `Less`. /// Returns `true` if `self` is equal to `Less`.
pub fn is_lt(&self) -> bool { pub fn is_lt(&self) -> bool {
*self == POrdering::PartialLess *self == PartialOrdering::PartialLess
} }
/// Returns `true` if `self` is equal to `Less` or `Equal`. /// Returns `true` if `self` is equal to `Less` or `Equal`.
pub fn is_le(&self) -> bool { pub fn is_le(&self) -> bool {
*self == POrdering::PartialLess || *self == POrdering::PartialEqual *self == PartialOrdering::PartialLess || *self == PartialOrdering::PartialEqual
} }
/// Returns `true` if `self` is equal to `Greater`. /// Returns `true` if `self` is equal to `Greater`.
pub fn is_gt(&self) -> bool { pub fn is_gt(&self) -> bool {
*self == POrdering::PartialGreater *self == PartialOrdering::PartialGreater
} }
/// Returns `true` if `self` is equal to `Greater` or `Equal`. /// Returns `true` if `self` is equal to `Greater` or `Equal`.
pub fn is_ge(&self) -> bool { pub fn is_ge(&self) -> bool {
*self == POrdering::PartialGreater || *self == POrdering::PartialEqual *self == PartialOrdering::PartialGreater || *self == PartialOrdering::PartialEqual
} }
/// Returns `true` if `self` is equal to `NotComparable`. /// Returns `true` if `self` is equal to `NotComparable`.
pub fn is_not_comparable(&self) -> bool { pub fn is_not_comparable(&self) -> bool {
*self == POrdering::NotComparable *self == PartialOrdering::NotComparable
} }
/// Creates a `POrdering` from an `Ordering`. /// Creates a `PartialOrdering` from an `Ordering`.
pub fn from_ordering(ord: Ordering) -> POrdering { pub fn from_ordering(ord: Ordering) -> PartialOrdering {
match ord { match ord {
Ordering::Less => POrdering::PartialLess, Ordering::Less => PartialOrdering::PartialLess,
Ordering::Equal => POrdering::PartialEqual, Ordering::Equal => PartialOrdering::PartialEqual,
Ordering::Greater => POrdering::PartialGreater Ordering::Greater => PartialOrdering::PartialGreater
} }
} }
/// Converts this `POrdering` to an `Ordering`. /// Converts this `PartialOrdering` to an `Ordering`.
/// ///
/// Returns `None` if `self` is `NotComparable`. /// Returns `None` if `self` is `NotComparable`.
pub fn to_ordering(self) -> Option<Ordering> { pub fn to_ordering(self) -> Option<Ordering> {
match self { match self {
POrdering::PartialLess => Some(Ordering::Less), PartialOrdering::PartialLess => Some(Ordering::Less),
POrdering::PartialEqual => Some(Ordering::Equal), PartialOrdering::PartialEqual => Some(Ordering::Equal),
POrdering::PartialGreater => Some(Ordering::Greater), PartialOrdering::PartialGreater => Some(Ordering::Greater),
POrdering::NotComparable => None PartialOrdering::NotComparable => None
} }
} }
} }
/// Pointwise ordering operations. /// Pointwise ordering operations.
pub trait POrd { pub trait PartialOrder {
/// Returns the infimum of this value and another /// Returns the infimum of this value and another
fn inf(&self, other: &Self) -> Self; fn inf(&self, other: &Self) -> Self;
@ -80,49 +80,49 @@ pub trait POrd {
fn sup(&self, other: &Self) -> Self; fn sup(&self, other: &Self) -> Self;
/// Compare `self` and `other` using a partial ordering relation. /// Compare `self` and `other` using a partial ordering relation.
fn partial_cmp(&self, other: &Self) -> POrdering; fn partial_cmp(&self, other: &Self) -> PartialOrdering;
/// Returns `true` iff `self` and `other` are comparable and `self <= other`. /// Returns `true` iff `self` and `other` are comparable and `self <= other`.
#[inline] #[inline]
fn partial_le(&self, other: &Self) -> bool { fn partial_le(&self, other: &Self) -> bool {
POrd::partial_cmp(self, other).is_le() PartialOrder::partial_cmp(self, other).is_le()
} }
/// Returns `true` iff `self` and `other` are comparable and `self < other`. /// Returns `true` iff `self` and `other` are comparable and `self < other`.
#[inline] #[inline]
fn partial_lt(&self, other: &Self) -> bool { fn partial_lt(&self, other: &Self) -> bool {
POrd::partial_cmp(self, other).is_lt() PartialOrder::partial_cmp(self, other).is_lt()
} }
/// Returns `true` iff `self` and `other` are comparable and `self >= other`. /// Returns `true` iff `self` and `other` are comparable and `self >= other`.
#[inline] #[inline]
fn partial_ge(&self, other: &Self) -> bool { fn partial_ge(&self, other: &Self) -> bool {
POrd::partial_cmp(self, other).is_ge() PartialOrder::partial_cmp(self, other).is_ge()
} }
/// Returns `true` iff `self` and `other` are comparable and `self > other`. /// Returns `true` iff `self` and `other` are comparable and `self > other`.
#[inline] #[inline]
fn partial_gt(&self, other: &Self) -> bool { fn partial_gt(&self, other: &Self) -> bool {
POrd::partial_cmp(self, other).is_gt() PartialOrder::partial_cmp(self, other).is_gt()
} }
/// Return the minimum of `self` and `other` if they are comparable. /// Return the minimum of `self` and `other` if they are comparable.
#[inline] #[inline]
fn partial_min<'a>(&'a self, other: &'a Self) -> Option<&'a Self> { fn partial_min<'a>(&'a self, other: &'a Self) -> Option<&'a Self> {
match POrd::partial_cmp(self, other) { match PartialOrder::partial_cmp(self, other) {
POrdering::PartialLess | POrdering::PartialEqual => Some(self), PartialOrdering::PartialLess | PartialOrdering::PartialEqual => Some(self),
POrdering::PartialGreater => Some(other), PartialOrdering::PartialGreater => Some(other),
POrdering::NotComparable => None PartialOrdering::NotComparable => None
} }
} }
/// Return the maximum of `self` and `other` if they are comparable. /// Return the maximum of `self` and `other` if they are comparable.
#[inline] #[inline]
fn partial_max<'a>(&'a self, other: &'a Self) -> Option<&'a Self> { fn partial_max<'a>(&'a self, other: &'a Self) -> Option<&'a Self> {
match POrd::partial_cmp(self, other) { match PartialOrder::partial_cmp(self, other) {
POrdering::PartialGreater | POrdering::PartialEqual => Some(self), PartialOrdering::PartialGreater | PartialOrdering::PartialEqual => Some(self),
POrdering::PartialLess => Some(other), PartialOrdering::PartialLess => Some(other),
POrdering::NotComparable => None PartialOrdering::NotComparable => None
} }
} }
@ -276,18 +276,18 @@ pub trait Absolute<A> {
} }
/// Trait of objects having an inverse. Typically used to implement matrix inverse. /// Trait of objects having an inverse. Typically used to implement matrix inverse.
pub trait Inv: Sized { pub trait Inverse: Sized {
/// Returns the inverse of `m`. /// Returns the inverse of `m`.
fn inv(&self) -> Option<Self>; fn inverse(&self) -> Option<Self>;
/// In-place version of `inverse`. /// In-place version of `inverse`.
fn inv_mut(&mut self) -> bool; fn inverse_mut(&mut self) -> bool;
} }
/// Trait of objects having a determinant. Typically used by square matrices. /// Trait of objects having a determinant. Typically used by square matrices.
pub trait Det<N> { pub trait Determinant<N> {
/// Returns the determinant of `m`. /// Returns the determinant of `m`.
fn det(&self) -> N; fn determinant(&self) -> N;
} }
/// Trait of objects which can be transposed. /// Trait of objects which can be transposed.
@ -309,19 +309,19 @@ pub trait Outer {
} }
/// Trait for computing the covariance of a set of data. /// Trait for computing the covariance of a set of data.
pub trait Cov<M> { pub trait Covariance<M> {
/// Computes the covariance of the obsevations stored by `m`: /// Computes the covariance of the obsevations stored by `m`:
/// ///
/// * For matrices, observations are stored in its rows. /// * For matrices, observations are stored in its rows.
/// * For vectors, observations are stored in its components (thus are 1-dimensional). /// * For vectors, observations are stored in its components (thus are 1-dimensional).
fn cov(&self) -> M; fn covariance(&self) -> M;
/// Computes the covariance of the obsevations stored by `m`: /// Computes the covariance of the obsevations stored by `m`:
/// ///
/// * For matrices, observations are stored in its rows. /// * For matrices, observations are stored in its rows.
/// * For vectors, observations are stored in its components (thus are 1-dimensional). /// * For vectors, observations are stored in its components (thus are 1-dimensional).
fn cov_to(&self, out: &mut M) { fn covariance_to(&self, out: &mut M) {
*out = self.cov() *out = self.covariance()
} }
} }
@ -335,7 +335,7 @@ pub trait Mean<N> {
} }
/// Trait for computing the eigenvector and eigenvalues of a square matrix usin the QR algorithm. /// Trait for computing the eigenvector and eigenvalues of a square matrix usin the QR algorithm.
pub trait EigenQR<N, V: Mul<Self, Output = V>>: SquareMat<N, V> { pub trait EigenQR<N, V: Mul<Self, Output = V>>: SquareMatrix<N, V> {
/// Computes the eigenvectors and eigenvalues of this matrix. /// Computes the eigenvectors and eigenvalues of this matrix.
fn eigen_qr(&self, eps: &N, niter: usize) -> (Self, V); fn eigen_qr(&self, eps: &N, niter: usize) -> (Self, V);
} }

View File

@ -6,8 +6,8 @@ use std::ops::{Add, Sub, Mul, Div, Rem,
AddAssign, SubAssign, MulAssign, DivAssign, RemAssign, AddAssign, SubAssign, MulAssign, DivAssign, RemAssign,
Index, IndexMut, Neg}; Index, IndexMut, Neg};
use num::{Float, Zero, One}; use num::{Float, Zero, One};
use traits::operations::{Axpy, Transpose, Inv, Absolute}; use traits::operations::{Axpy, Transpose, Inverse, Absolute};
use traits::geometry::{Dot, Norm, Orig}; use traits::geometry::{Dot, Norm, Origin};
/// Basic integral numeric trait. /// Basic integral numeric trait.
pub trait BaseNum: Copy + Zero + One + pub trait BaseNum: Copy + Zero + One +
@ -64,31 +64,31 @@ pub trait Cast<T> {
/// Trait of matrices. /// Trait of matrices.
/// ///
/// A matrix has rows and columns and are able to multiply them. /// A matrix has rows and columns and are able to multiply them.
pub trait Mat<N, R, C: Mul<Self, Output = R>>: Sized + pub trait Matrix<N, R, C: Mul<Self, Output = R>>: Sized +
Row<R> + Col<C> + Mul<R, Output = C> + Row<R> + Column<C> + Mul<R, Output = C> +
Index<(usize, usize), Output = N> Index<(usize, usize), Output = N>
{ } { }
impl<N, M, R, C> Mat<N, R, C> for M impl<N, M, R, C> Matrix<N, R, C> for M
where M: Row<R> + Col<C> + Mul<R, Output = C> + Index<(usize, usize), Output = N>, where M: Row<R> + Column<C> + Mul<R, Output = C> + Index<(usize, usize), Output = N>,
C: Mul<M, Output = R>, C: Mul<M, Output = R>,
{ } { }
/// Trait implemented by square matrices. /// Trait implemented by square matrices.
pub trait SquareMat<N, V: Mul<Self, Output = V>>: Mat<N, V, V> + pub trait SquareMatrix<N, V: Mul<Self, Output = V>>: Matrix<N, V, V> +
Mul<Self, Output = Self> + Mul<Self, Output = Self> +
Eye + Transpose + Diag<V> + Inv + Dim + One { Eye + Transpose + Diagonal<V> + Inverse + Dimension + One {
} }
impl<N, V, M> SquareMat<N, V> for M impl<N, V, M> SquareMatrix<N, V> for M
where M: Mat<N, V, V> + Mul<M, Output = M> + Eye + Transpose + Diag<V> + Inv + Dim + One, where M: Matrix<N, V, V> + Mul<M, Output = M> + Eye + Transpose + Diagonal<V> + Inverse + Dimension + One,
V: Mul<M, Output = V> { V: Mul<M, Output = V> {
} }
/// Trait for constructing the identity matrix /// Trait for constructing the identity matrix
pub trait Eye { pub trait Eye {
/// Return the identity matrix of specified dimension /// Return the identity matrix of specified dimension
fn new_identity(dim: usize) -> Self; fn new_identity(dimension: usize) -> Self;
} }
/// Trait for constructiong an object repeating a value. /// Trait for constructiong an object repeating a value.
@ -134,12 +134,12 @@ pub trait Row<R> {
} }
/// Trait to access columns of a matrix or vector. /// Trait to access columns of a matrix or vector.
pub trait Col<C> { pub trait Column<C> {
/// The number of column of this matrix or vector. /// The number of column of this matrix or vector.
fn ncols(&self) -> usize; fn ncols(&self) -> usize;
/// Reads the `i`-th column of `self`. /// Reads the `i`-th column of `self`.
fn col(&self, i: usize) -> C; fn column(&self, i: usize) -> C;
/// Writes the `i`-th column of `self`. /// Writes the `i`-th column of `self`.
fn set_col(&mut self, i: usize, C); fn set_col(&mut self, i: usize, C);
@ -149,7 +149,7 @@ pub trait Col<C> {
} }
/// Trait to access part of a column of a matrix /// Trait to access part of a column of a matrix
pub trait ColSlice<C> { pub trait ColumnSlice<C> {
/// Returns a view to a slice of a column of a matrix. /// Returns a view to a slice of a column of a matrix.
fn col_slice(&self, col_id: usize, row_start: usize, row_end: usize) -> C; fn col_slice(&self, col_id: usize, row_start: usize, row_end: usize) -> C;
} }
@ -161,24 +161,24 @@ pub trait RowSlice<R> {
} }
/// Trait of objects having a spacial dimension known at compile time. /// Trait of objects having a spacial dimension known at compile time.
pub trait Dim: Sized { pub trait Dimension: Sized {
/// The dimension of the object. /// The dimension of the object.
fn dim(_unused: Option<Self>) -> usize; fn dimension(_unused: Option<Self>) -> usize;
} }
/// Trait to get the diagonal of square matrices. /// Trait to get the diagonal of square matrices.
pub trait Diag<V> { pub trait Diagonal<V> {
/// Creates a new matrix with the given diagonal. /// Creates a new matrix with the given diagonal.
fn from_diag(diag: &V) -> Self; fn from_diag(diagonal: &V) -> Self;
/// The diagonal of this matrix. /// The diagonal of this matrix.
fn diag(&self) -> V; fn diagonal(&self) -> V;
} }
/// Trait to set the diagonal of square matrices. /// Trait to set the diagonal of square matrices.
pub trait DiagMut<V>: Diag<V> { pub trait DiagMut<V>: Diagonal<V> {
/// Sets the diagonal of this matrix. /// Sets the diagonal of this matrix.
fn set_diag(&mut self, diag: &V); fn set_diag(&mut self, diagonal: &V);
} }
/// The shape of an indexable object. /// The shape of an indexable object.
@ -223,10 +223,10 @@ pub trait IterableMut<N> {
} }
/* /*
* Vec related traits. * Vector related traits.
*/ */
/// Trait grouping most common operations on vectors. /// Trait grouping most common operations on vectors.
pub trait NumVec<N>: Add<Self, Output = Self> + Sub<Self, Output = Self> + pub trait NumVector<N>: Add<Self, Output = Self> + Sub<Self, Output = Self> +
Mul<Self, Output = Self> + Div<Self, Output = Self> + Mul<Self, Output = Self> + Div<Self, Output = Self> +
Add<N, Output = Self> + Sub<N, Output = Self> + Add<N, Output = Self> + Sub<N, Output = Self> +
@ -238,67 +238,67 @@ pub trait NumVec<N>: Add<Self, Output = Self> + Sub<Self, Output = Self> +
AddAssign<N> + SubAssign<N> + AddAssign<N> + SubAssign<N> +
MulAssign<N> + DivAssign<N> + MulAssign<N> + DivAssign<N> +
Dim + Index<usize, Output = N> + Dimension + Index<usize, Output = N> +
Zero + PartialEq + Dot<N> + Axpy<N> { Zero + PartialEq + Dot<N> + Axpy<N> {
} }
/// Trait of vector with components implementing the `BaseFloat` trait. /// Trait of vector with components implementing the `BaseFloat` trait.
pub trait FloatVec<N: BaseFloat>: NumVec<N> + Norm<N> + Neg<Output = Self> + Basis { pub trait FloatVector<N: BaseFloat>: NumVector<N> + Norm<N> + Neg<Output = Self> + Basis {
} }
/* /*
* Pnt related traits. * Point related traits.
*/ */
/// Trait that relates a point of an affine space to a vector of the associated vector space. /// Trait that relates a point of an affine space to a vector of the associated vector space.
pub trait PntAsVec { pub trait PointAsVector {
/// The vector type of the vector space associated to this point's affine space. /// The vector type of the vector space associated to this point's affine space.
type Vec; type Vector;
/// Converts this point to its associated vector. /// Converts this point to its associated vector.
fn to_vec(self) -> Self::Vec; fn to_vector(self) -> Self::Vector;
/// Converts a reference to this point to a reference to its associated vector. /// Converts a reference to this point to a reference to its associated vector.
fn as_vec<'a>(&'a self) -> &'a Self::Vec; fn as_vector<'a>(&'a self) -> &'a Self::Vector;
// NOTE: this is used in some places to overcome some limitations untill the trait reform is // NOTE: this is used in some places to overcome some limitations untill the trait reform is
// done on rustc. // done on rustc.
/// Sets the coordinates of this point to match those of a given vector. /// Sets the coordinates of this point to match those of a given vector.
fn set_coords(&mut self, coords: Self::Vec); fn set_coords(&mut self, coords: Self::Vector);
} }
/// Trait grouping most common operations on points. /// Trait grouping most common operations on points.
// XXX: the vector space element `V` should be an associated type. Though this would prevent V from // XXX: the vector space element `V` should be an associated type. Though this would prevent V from
// having bounds (they are not supported yet). So, for now, we will just use a type parameter. // having bounds (they are not supported yet). So, for now, we will just use a type parameter.
pub trait NumPnt<N>: pub trait NumPoint<N>:
Copy + Copy +
PntAsVec + PointAsVector +
Dim + Dimension +
Orig + Origin +
PartialEq + PartialEq +
Axpy<N> + Axpy<N> +
Sub<Self, Output = <Self as PntAsVec>::Vec> + Sub<Self, Output = <Self as PointAsVector>::Vector> +
Mul<N, Output = Self> + Div<N, Output = Self> + Mul<N, Output = Self> + Div<N, Output = Self> +
Add<<Self as PntAsVec>::Vec, Output = Self> + Add<<Self as PointAsVector>::Vector, Output = Self> +
MulAssign<N> + DivAssign<N> + MulAssign<N> + DivAssign<N> +
AddAssign<<Self as PntAsVec>::Vec> + AddAssign<<Self as PointAsVector>::Vector> +
Index<usize, Output = N> { // FIXME: + Sub<V, Self> Index<usize, Output = N> { // FIXME: + Sub<V, Self>
} }
/// Trait of points with components implementing the `BaseFloat` trait. /// Trait of points with components implementing the `BaseFloat` trait.
pub trait FloatPnt<N: BaseFloat>: NumPnt<N> + Sized pub trait FloatPoint<N: BaseFloat>: NumPoint<N> + Sized
where <Self as PntAsVec>::Vec: Norm<N> { where <Self as PointAsVector>::Vector: Norm<N> {
/// Computes the square distance between two points. /// Computes the square distance between two points.
#[inline] #[inline]
fn sqdist(&self, other: &Self) -> N { fn distance_squared(&self, other: &Self) -> N {
(*self - *other).sqnorm() (*self - *other).norm_squared()
} }
/// Computes the distance between two points. /// Computes the distance between two points.
#[inline] #[inline]
fn dist(&self, other: &Self) -> N { fn distance(&self, other: &Self) -> N {
(*self - *other).norm() (*self - *other).norm()
} }
} }

View File

@ -18,47 +18,47 @@ macro_rules! trivial_arb_test(
) )
); );
trivial_arb_test!(Vec1<f64>, arb_vec1); trivial_arb_test!(Vector1<f64>, arb_vec1);
trivial_arb_test!(Vec2<f64>, arb_vec2); trivial_arb_test!(Vector2<f64>, arb_vec2);
trivial_arb_test!(Vec3<f64>, arb_vec3); trivial_arb_test!(Vector3<f64>, arb_vec3);
trivial_arb_test!(Vec4<f64>, arb_vec4); trivial_arb_test!(Vector4<f64>, arb_vec4);
trivial_arb_test!(Vec5<f64>, arb_vec5); trivial_arb_test!(Vector5<f64>, arb_vec5);
trivial_arb_test!(Vec6<f64>, arb_vec6); trivial_arb_test!(Vector6<f64>, arb_vec6);
trivial_arb_test!(Pnt1<f64>, arb_pnt1); trivial_arb_test!(Point1<f64>, arb_point1);
trivial_arb_test!(Pnt2<f64>, arb_pnt2); trivial_arb_test!(Point2<f64>, arb_point2);
trivial_arb_test!(Pnt3<f64>, arb_pnt3); trivial_arb_test!(Point3<f64>, arb_point3);
trivial_arb_test!(Pnt4<f64>, arb_pnt4); trivial_arb_test!(Point4<f64>, arb_point4);
trivial_arb_test!(Pnt5<f64>, arb_pnt5); trivial_arb_test!(Point5<f64>, arb_point5);
trivial_arb_test!(Pnt6<f64>, arb_pnt6); trivial_arb_test!(Point6<f64>, arb_point6);
trivial_arb_test!(Mat1<f64>, arb_mat1); trivial_arb_test!(Matrix1<f64>, arb_mat1);
trivial_arb_test!(Mat2<f64>, arb_mat2); trivial_arb_test!(Matrix2<f64>, arb_mat2);
trivial_arb_test!(Mat3<f64>, arb_mat3); trivial_arb_test!(Matrix3<f64>, arb_mat3);
trivial_arb_test!(Mat4<f64>, arb_mat4); trivial_arb_test!(Matrix4<f64>, arb_mat4);
trivial_arb_test!(Mat5<f64>, arb_mat5); trivial_arb_test!(Matrix5<f64>, arb_mat5);
trivial_arb_test!(Mat6<f64>, arb_mat6); trivial_arb_test!(Matrix6<f64>, arb_mat6);
trivial_arb_test!(DVec1<f64>, arb_dvec1); trivial_arb_test!(DVector1<f64>, arb_dvec1);
trivial_arb_test!(DVec2<f64>, arb_dvec2); trivial_arb_test!(DVector2<f64>, arb_dvec2);
trivial_arb_test!(DVec3<f64>, arb_dvec3); trivial_arb_test!(DVector3<f64>, arb_dvec3);
trivial_arb_test!(DVec4<f64>, arb_dvec4); trivial_arb_test!(DVector4<f64>, arb_dvec4);
trivial_arb_test!(DVec5<f64>, arb_dvec5); trivial_arb_test!(DVector5<f64>, arb_dvec5);
trivial_arb_test!(DVec6<f64>, arb_dvec6); trivial_arb_test!(DVector6<f64>, arb_dvec6);
trivial_arb_test!(DMat<f64>, arb_dmat); trivial_arb_test!(DMatrix<f64>, arb_dmatrix);
trivial_arb_test!(DVec<f64>, arb_dvec); trivial_arb_test!(DVector<f64>, arb_dvector);
trivial_arb_test!(Quat<f64>, arb_quat); trivial_arb_test!(Quaternion<f64>, arb_quaternion);
trivial_arb_test!(UnitQuat<f64>, arb_unit_quat); trivial_arb_test!(UnitQuaternion<f64>, arb_unit_quaternion);
trivial_arb_test!(Iso2<f64>, arb_iso2); trivial_arb_test!(Isometry2<f64>, arb_iso2);
trivial_arb_test!(Iso3<f64>, arb_iso3); trivial_arb_test!(Isometry3<f64>, arb_iso3);
trivial_arb_test!(Rot2<f64>, arb_rot2); trivial_arb_test!(Rotation2<f64>, arb_rot2);
trivial_arb_test!(Rot3<f64>, arb_rot3); trivial_arb_test!(Rotation3<f64>, arb_rot3);
trivial_arb_test!(Ortho3<f64>, arb_ortho3); trivial_arb_test!(Orthographic3<f64>, arb_ortho3);
trivial_arb_test!(OrthoMat3<f64>, arb_ortho_mat3); trivial_arb_test!(OrthographicMatrix3<f64>, arb_ortho_mat3);
trivial_arb_test!(Persp3<f64>, arb_persp3); trivial_arb_test!(Perspective3<f64>, arb_persp3);
trivial_arb_test!(PerspMat3<f64>, arb_persp_mat3); trivial_arb_test!(PerspectiveMatrix3<f64>, arb_perspective_mat3);

View File

@ -3,7 +3,7 @@
#[macro_use] #[macro_use]
extern crate nalgebra; extern crate nalgebra;
use nalgebra::{ApproxEq, Vec2}; use nalgebra::{ApproxEq, Vector2};
#[test] #[test]
fn assert_approx_eq_f64() { fn assert_approx_eq_f64() {
@ -16,8 +16,8 @@ fn assert_approx_eq_f64() {
#[test] #[test]
#[should_panic] #[should_panic]
fn assert_approx_eq_vec2_f32_fail() { fn assert_approx_eq_vec2_f32_fail() {
let a = Vec2::new(1.0f32, 0.0); let a = Vector2::new(1.0f32, 0.0);
let b = Vec2::new(1.1f32, 0.1); let b = Vector2::new(1.1f32, 0.1);
assert_approx_eq!(a, b); assert_approx_eq!(a, b);
} }

View File

@ -2,18 +2,18 @@ extern crate nalgebra as na;
extern crate rand; extern crate rand;
use rand::random; use rand::random;
use na::{Rot2, Rot3, Iso2, Iso3, Sim2, Sim3, Vec3, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6, DMat, DVec, use na::{Rotation2, Rotation3, Isometry2, Isometry3, Similarity2, Similarity3, Vector3, Matrix1, Matrix2, Matrix3, Matrix4, Matrix5, Matrix6, DMatrix, DVector,
Row, Col, Diag, Transpose, RowSlice, ColSlice, Shape}; Row, Column, Diagonal, Transpose, RowSlice, ColumnSlice, Shape};
macro_rules! test_inv_mat_impl( macro_rules! test_inverse_mat_impl(
($t: ty) => ( ($t: ty) => (
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let randmat : $t = random(); let randmatrix : $t = random();
match na::inv(&randmat) { match na::inverse(&randmatrix) {
None => { }, None => { },
Some(i) => { Some(i) => {
assert!(na::approx_eq(&(i * randmat), &na::one())) assert!(na::approx_eq(&(i * randmatrix), &na::one()))
} }
} }
} }
@ -23,9 +23,9 @@ macro_rules! test_inv_mat_impl(
macro_rules! test_transpose_mat_impl( macro_rules! test_transpose_mat_impl(
($t: ty) => ( ($t: ty) => (
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let randmat : $t = random(); let randmatrix : $t = random();
assert!(na::transpose(&na::transpose(&randmat)) == randmat); assert!(na::transpose(&na::transpose(&randmatrix)) == randmatrix);
} }
); );
); );
@ -33,12 +33,12 @@ macro_rules! test_transpose_mat_impl(
macro_rules! test_qr_impl( macro_rules! test_qr_impl(
($t: ty) => ( ($t: ty) => (
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let randmat : $t = random(); let randmatrix : $t = random();
let (q, r) = na::qr(&randmat); let (q, r) = na::qr(&randmatrix);
let recomp = q * r; let recomp = q * r;
assert!(na::approx_eq(&randmat, &recomp)); assert!(na::approx_eq(&randmatrix, &recomp));
} }
); );
); );
@ -48,19 +48,19 @@ macro_rules! test_cholesky_impl(
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
// construct symmetric positive definite matrix // construct symmetric positive definite matrix
let mut randmat : $t = random(); let mut randmatrix : $t = random();
let mut diagmat : $t = Diag::from_diag(&na::diag(&randmat)); let mut diagmatrix : $t = Diagonal::from_diag(&na::diagonal(&randmatrix));
diagmat = na::abs(&diagmat) + 1.0; diagmatrix = na::abs(&diagmatrix) + 1.0;
randmat = randmat * diagmat * na::transpose(&randmat); randmatrix = randmatrix * diagmatrix * na::transpose(&randmatrix);
let result = na::cholesky(&randmat); let result = na::cholesky(&randmatrix);
assert!(result.is_ok()); assert!(result.is_ok());
let v = result.unwrap(); let v = result.unwrap();
let recomp = v * na::transpose(&v); let recomp = v * na::transpose(&v);
assert!(na::approx_eq(&randmat, &recomp)); assert!(na::approx_eq(&randmatrix, &recomp));
} }
); );
); );
@ -69,9 +69,9 @@ macro_rules! test_hessenberg_impl(
($t: ty) => ( ($t: ty) => (
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let randmat : $t = random(); let randmatrix : $t = random();
let (q, h) = na::hessenberg(&randmat); let (q, h) = na::hessenberg(&randmatrix);
let recomp = q * h * na::transpose(&q); let recomp = q * h * na::transpose(&q);
let (rows, cols) = h.shape(); let (rows, cols) = h.shape();
@ -85,7 +85,7 @@ macro_rules! test_hessenberg_impl(
} }
} }
assert!(na::approx_eq(&randmat, &recomp)); assert!(na::approx_eq(&randmatrix, &recomp));
} }
); );
); );
@ -93,138 +93,138 @@ macro_rules! test_hessenberg_impl(
macro_rules! test_eigen_qr_impl( macro_rules! test_eigen_qr_impl(
($t: ty) => { ($t: ty) => {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let randmat : $t = random(); let randmatrix : $t = random();
// Make it symetric so that we can recompose the matrix to test at the end. // Make it symetric so that we can recompose the matrix to test at the end.
let randmat = na::transpose(&randmat) * randmat; let randmatrix = na::transpose(&randmatrix) * randmatrix;
let (eigenvectors, eigenvalues) = na::eigen_qr(&randmat, &1e-13, 100); let (eigenvectors, eigenvalues) = na::eigen_qr(&randmatrix, &1e-13, 100);
let diag: $t = Diag::from_diag(&eigenvalues); let diagonal: $t = Diagonal::from_diag(&eigenvalues);
let recomp = eigenvectors * diag * na::transpose(&eigenvectors); let recomp = eigenvectors * diagonal * na::transpose(&eigenvectors);
println!("eigenvalues: {:?}", eigenvalues); println!("eigenvalues: {:?}", eigenvalues);
println!(" mat: {:?}", randmat); println!(" matrix: {:?}", randmatrix);
println!("recomp: {:?}", recomp); println!("recomp: {:?}", recomp);
assert!(na::approx_eq_eps(&randmat, &recomp, &1.0e-2)); assert!(na::approx_eq_eps(&randmatrix, &recomp, &1.0e-2));
} }
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let randmat : $t = random(); let randmatrix : $t = random();
// Take only diagonal part // Take only diagonal part
let randmat: $t = Diag::from_diag(&randmat.diag()); let randmatrix: $t = Diagonal::from_diag(&randmatrix.diagonal());
let (eigenvectors, eigenvalues) = na::eigen_qr(&randmat, &1e-13, 100); let (eigenvectors, eigenvalues) = na::eigen_qr(&randmatrix, &1e-13, 100);
let diag: $t = Diag::from_diag(&eigenvalues); let diagonal: $t = Diagonal::from_diag(&eigenvalues);
let recomp = eigenvectors * diag * na::transpose(&eigenvectors); let recomp = eigenvectors * diagonal * na::transpose(&eigenvectors);
println!("eigenvalues: {:?}", eigenvalues); println!("eigenvalues: {:?}", eigenvalues);
println!(" mat: {:?}", randmat); println!(" matrix: {:?}", randmatrix);
println!("recomp: {:?}", recomp); println!("recomp: {:?}", recomp);
assert!(na::approx_eq_eps(&randmat, &recomp, &1.0e-2)); assert!(na::approx_eq_eps(&randmatrix, &recomp, &1.0e-2));
} }
} }
); );
#[test] #[test]
fn test_transpose_mat1() { fn test_transpose_mat1() {
test_transpose_mat_impl!(Mat1<f64>); test_transpose_mat_impl!(Matrix1<f64>);
} }
#[test] #[test]
fn test_transpose_mat2() { fn test_transpose_mat2() {
test_transpose_mat_impl!(Mat2<f64>); test_transpose_mat_impl!(Matrix2<f64>);
} }
#[test] #[test]
fn test_transpose_mat3() { fn test_transpose_mat3() {
test_transpose_mat_impl!(Mat3<f64>); test_transpose_mat_impl!(Matrix3<f64>);
} }
#[test] #[test]
fn test_transpose_mat4() { fn test_transpose_mat4() {
test_transpose_mat_impl!(Mat4<f64>); test_transpose_mat_impl!(Matrix4<f64>);
} }
#[test] #[test]
fn test_transpose_mat5() { fn test_transpose_mat5() {
test_transpose_mat_impl!(Mat5<f64>); test_transpose_mat_impl!(Matrix5<f64>);
} }
#[test] #[test]
fn test_transpose_mat6() { fn test_transpose_mat6() {
test_transpose_mat_impl!(Mat6<f64>); test_transpose_mat_impl!(Matrix6<f64>);
} }
#[test] #[test]
fn test_inv_mat1() { fn test_inverse_mat1() {
test_inv_mat_impl!(Mat1<f64>); test_inverse_mat_impl!(Matrix1<f64>);
} }
#[test] #[test]
fn test_inv_mat2() { fn test_inverse_mat2() {
test_inv_mat_impl!(Mat2<f64>); test_inverse_mat_impl!(Matrix2<f64>);
} }
#[test] #[test]
fn test_inv_mat3() { fn test_inverse_mat3() {
test_inv_mat_impl!(Mat3<f64>); test_inverse_mat_impl!(Matrix3<f64>);
} }
#[test] #[test]
fn test_inv_mat4() { fn test_inverse_mat4() {
test_inv_mat_impl!(Mat4<f64>); test_inverse_mat_impl!(Matrix4<f64>);
} }
#[test] #[test]
fn test_inv_mat5() { fn test_inverse_mat5() {
test_inv_mat_impl!(Mat5<f64>); test_inverse_mat_impl!(Matrix5<f64>);
} }
#[test] #[test]
fn test_inv_mat6() { fn test_inverse_mat6() {
test_inv_mat_impl!(Mat6<f64>); test_inverse_mat_impl!(Matrix6<f64>);
} }
#[test] #[test]
fn test_inv_rot2() { fn test_inverse_rot2() {
test_inv_mat_impl!(Rot2<f64>); test_inverse_mat_impl!(Rotation2<f64>);
} }
#[test] #[test]
fn test_inv_rot3() { fn test_inverse_rot3() {
test_inv_mat_impl!(Rot3<f64>); test_inverse_mat_impl!(Rotation3<f64>);
} }
#[test] #[test]
fn test_inv_iso2() { fn test_inverse_iso2() {
test_inv_mat_impl!(Iso2<f64>); test_inverse_mat_impl!(Isometry2<f64>);
} }
#[test] #[test]
fn test_inv_iso3() { fn test_inverse_iso3() {
test_inv_mat_impl!(Iso3<f64>); test_inverse_mat_impl!(Isometry3<f64>);
} }
#[test] #[test]
fn test_inv_sim2() { fn test_inverse_sim2() {
test_inv_mat_impl!(Sim2<f64>); test_inverse_mat_impl!(Similarity2<f64>);
} }
#[test] #[test]
fn test_inv_sim3() { fn test_inverse_sim3() {
test_inv_mat_impl!(Sim3<f64>); test_inverse_mat_impl!(Similarity3<f64>);
} }
#[test] #[test]
fn test_index_mat2() { fn test_index_mat2() {
let mat: Mat2<f64> = random(); let matrix: Matrix2<f64> = random();
assert!(mat[(0, 1)] == na::transpose(&mat)[(1, 0)]); assert!(matrix[(0, 1)] == na::transpose(&matrix)[(1, 0)]);
} }
#[test] #[test]
fn test_mean_dmat() { fn test_mean_dmatrix() {
let mat = DMat::from_row_vec( let matrix = DMatrix::from_row_vector(
3, 3,
3, 3,
&[ &[
@ -234,12 +234,12 @@ fn test_mean_dmat() {
] ]
); );
assert!(na::approx_eq(&na::mean(&mat), &DVec::from_slice(3, &[4.0f64, 5.0, 6.0]))); assert!(na::approx_eq(&na::mean(&matrix), &DVector::from_slice(3, &[4.0f64, 5.0, 6.0])));
} }
#[test] #[test]
fn test_cov_dmat() { fn test_covariance_dmatrix() {
let mat = DMat::from_row_vec( let matrix = DMatrix::from_row_vector(
5, 5,
3, 3,
&[ &[
@ -251,7 +251,7 @@ fn test_cov_dmat() {
] ]
); );
let expected = DMat::from_row_vec( let expected = DMatrix::from_row_vector(
3, 3,
3, 3,
&[ &[
@ -261,12 +261,12 @@ fn test_cov_dmat() {
] ]
); );
assert!(na::approx_eq(&na::cov(&mat), &expected)); assert!(na::approx_eq(&na::covariance(&matrix), &expected));
} }
#[test] #[test]
fn test_transpose_dmat() { fn test_transpose_dmatrix() {
let mat = DMat::from_row_vec( let matrix = DMatrix::from_row_vector(
8, 8,
4, 4,
&[ &[
@ -281,12 +281,12 @@ fn test_transpose_dmat() {
] ]
); );
assert!(na::transpose(&na::transpose(&mat)) == mat); assert!(na::transpose(&na::transpose(&matrix)) == matrix);
} }
#[test] #[test]
fn test_row_dmat() { fn test_row_dmatrix() {
let mat = DMat::from_row_vec( let matrix = DMatrix::from_row_vector(
8, 8,
4, 4,
&[ &[
@ -301,19 +301,19 @@ fn test_row_dmat() {
] ]
); );
assert_eq!(&DVec::from_slice(4, &[1u32, 2, 3, 4]), &mat.row(0)); assert_eq!(&DVector::from_slice(4, &[1u32, 2, 3, 4]), &matrix.row(0));
assert_eq!(&DVec::from_slice(4, &[5u32, 6, 7, 8]), &mat.row(1)); assert_eq!(&DVector::from_slice(4, &[5u32, 6, 7, 8]), &matrix.row(1));
assert_eq!(&DVec::from_slice(4, &[9u32, 10, 11, 12]), &mat.row(2)); assert_eq!(&DVector::from_slice(4, &[9u32, 10, 11, 12]), &matrix.row(2));
assert_eq!(&DVec::from_slice(4, &[13u32, 14, 15, 16]), &mat.row(3)); assert_eq!(&DVector::from_slice(4, &[13u32, 14, 15, 16]), &matrix.row(3));
assert_eq!(&DVec::from_slice(4, &[17u32, 18, 19, 20]), &mat.row(4)); assert_eq!(&DVector::from_slice(4, &[17u32, 18, 19, 20]), &matrix.row(4));
assert_eq!(&DVec::from_slice(4, &[21u32, 22, 23, 24]), &mat.row(5)); assert_eq!(&DVector::from_slice(4, &[21u32, 22, 23, 24]), &matrix.row(5));
assert_eq!(&DVec::from_slice(4, &[25u32, 26, 27, 28]), &mat.row(6)); assert_eq!(&DVector::from_slice(4, &[25u32, 26, 27, 28]), &matrix.row(6));
assert_eq!(&DVec::from_slice(4, &[29u32, 30, 31, 32]), &mat.row(7)); assert_eq!(&DVector::from_slice(4, &[29u32, 30, 31, 32]), &matrix.row(7));
} }
#[test] #[test]
fn test_row_slice_dmat() { fn test_row_slice_dmatrix() {
let mat = DMat::from_row_vec( let matrix = DMatrix::from_row_vector(
5, 5,
4, 4,
&[ &[
@ -325,15 +325,15 @@ fn test_row_slice_dmat() {
] ]
); );
assert_eq!(&DVec::from_slice(4, &[1u32, 2, 3, 4]), &mat.row_slice(0, 0, 4)); assert_eq!(&DVector::from_slice(4, &[1u32, 2, 3, 4]), &matrix.row_slice(0, 0, 4));
assert_eq!(&DVec::from_slice(2, &[1u32, 2]), &mat.row_slice(0, 0, 2)); assert_eq!(&DVector::from_slice(2, &[1u32, 2]), &matrix.row_slice(0, 0, 2));
assert_eq!(&DVec::from_slice(2, &[10u32, 11]), &mat.row_slice(2, 1, 3)); assert_eq!(&DVector::from_slice(2, &[10u32, 11]), &matrix.row_slice(2, 1, 3));
assert_eq!(&DVec::from_slice(2, &[19u32, 20]), &mat.row_slice(4, 2, 4)); assert_eq!(&DVector::from_slice(2, &[19u32, 20]), &matrix.row_slice(4, 2, 4));
} }
#[test] #[test]
fn test_col_dmat() { fn test_col_dmatrix() {
let mat = DMat::from_row_vec( let matrix = DMatrix::from_row_vector(
8, 8,
4, 4,
&[ &[
@ -348,15 +348,15 @@ fn test_col_dmat() {
] ]
); );
assert_eq!(&DVec::from_slice(8, &[1u32, 5, 9, 13, 17, 21, 25, 29]), &mat.col(0)); assert_eq!(&DVector::from_slice(8, &[1u32, 5, 9, 13, 17, 21, 25, 29]), &matrix.column(0));
assert_eq!(&DVec::from_slice(8, &[2u32, 6, 10, 14, 18, 22, 26, 30]), &mat.col(1)); assert_eq!(&DVector::from_slice(8, &[2u32, 6, 10, 14, 18, 22, 26, 30]), &matrix.column(1));
assert_eq!(&DVec::from_slice(8, &[3u32, 7, 11, 15, 19, 23, 27, 31]), &mat.col(2)); assert_eq!(&DVector::from_slice(8, &[3u32, 7, 11, 15, 19, 23, 27, 31]), &matrix.column(2));
assert_eq!(&DVec::from_slice(8, &[4u32, 8, 12, 16, 20, 24, 28, 32]), &mat.col(3)); assert_eq!(&DVector::from_slice(8, &[4u32, 8, 12, 16, 20, 24, 28, 32]), &matrix.column(3));
} }
#[test] #[test]
fn test_col_slice_dmat() { fn test_col_slice_dmatrix() {
let mat = DMat::from_row_vec( let matrix = DMatrix::from_row_vector(
8, 8,
4, 4,
&[ &[
@ -371,15 +371,15 @@ fn test_col_slice_dmat() {
] ]
); );
assert_eq!(&DVec::from_slice(8, &[1u32, 5, 9, 13, 17, 21, 25, 29]), &mat.col_slice(0, 0, 8)); assert_eq!(&DVector::from_slice(8, &[1u32, 5, 9, 13, 17, 21, 25, 29]), &matrix.col_slice(0, 0, 8));
assert_eq!(&DVec::from_slice(3, &[1u32, 5, 9]), &mat.col_slice(0, 0, 3)); assert_eq!(&DVector::from_slice(3, &[1u32, 5, 9]), &matrix.col_slice(0, 0, 3));
assert_eq!(&DVec::from_slice(5, &[11u32, 15, 19, 23, 27]), &mat.col_slice(2, 2, 7)); assert_eq!(&DVector::from_slice(5, &[11u32, 15, 19, 23, 27]), &matrix.col_slice(2, 2, 7));
assert_eq!(&DVec::from_slice(2, &[28u32, 32]), &mat.col_slice(3, 6, 8)); assert_eq!(&DVector::from_slice(2, &[28u32, 32]), &matrix.col_slice(3, 6, 8));
} }
#[test] #[test]
fn test_dmat_from_vec() { fn test_dmat_from_vector() {
let mat1 = DMat::from_row_vec( let mat1 = DMatrix::from_row_vector(
8, 8,
4, 4,
&[ &[
@ -394,7 +394,7 @@ fn test_dmat_from_vec() {
] ]
); );
let mat2 = DMat::from_col_vec( let mat2 = DMatrix::from_col_vector(
8, 8,
4, 4,
&[ &[
@ -412,7 +412,7 @@ fn test_dmat_from_vec() {
#[test] #[test]
fn test_dmat_addition() { fn test_dmat_addition() {
let mat1 = DMat::from_row_vec( let mat1 = DMatrix::from_row_vector(
2, 2,
2, 2,
&[ &[
@ -421,7 +421,7 @@ fn test_dmat_addition() {
] ]
); );
let mat2 = DMat::from_row_vec( let mat2 = DMatrix::from_row_vector(
2, 2,
2, 2,
&[ &[
@ -430,7 +430,7 @@ fn test_dmat_addition() {
] ]
); );
let res = DMat::from_row_vec( let res = DMatrix::from_row_vector(
2, 2,
2, 2,
&[ &[
@ -444,7 +444,7 @@ fn test_dmat_addition() {
#[test] #[test]
fn test_dmat_multiplication() { fn test_dmat_multiplication() {
let mat1 = DMat::from_row_vec( let mat1 = DMatrix::from_row_vector(
2, 2,
2, 2,
&[ &[
@ -453,7 +453,7 @@ fn test_dmat_multiplication() {
] ]
); );
let mat2 = DMat::from_row_vec( let mat2 = DMatrix::from_row_vector(
2, 2,
2, 2,
&[ &[
@ -462,7 +462,7 @@ fn test_dmat_multiplication() {
] ]
); );
let res = DMat::from_row_vec( let res = DMatrix::from_row_vector(
2, 2,
2, 2,
&[ &[
@ -477,7 +477,7 @@ fn test_dmat_multiplication() {
// Tests multiplication of rectangular (non-square) matrices. // Tests multiplication of rectangular (non-square) matrices.
#[test] #[test]
fn test_dmat_multiplication_rect() { fn test_dmat_multiplication_rect() {
let mat1 = DMat::from_row_vec( let mat1 = DMatrix::from_row_vector(
1, 1,
2, 2,
&[ &[
@ -485,7 +485,7 @@ fn test_dmat_multiplication_rect() {
] ]
); );
let mat2 = DMat::from_row_vec( let mat2 = DMatrix::from_row_vector(
2, 2,
3, 3,
&[ &[
@ -494,7 +494,7 @@ fn test_dmat_multiplication_rect() {
] ]
); );
let res = DMat::from_row_vec( let res = DMatrix::from_row_vector(
1, 1,
3, 3,
&[ &[
@ -510,7 +510,7 @@ fn test_dmat_multiplication_rect() {
#[test] #[test]
fn test_dmat_subtraction() { fn test_dmat_subtraction() {
let mat1 = DMat::from_row_vec( let mat1 = DMatrix::from_row_vector(
2, 2,
2, 2,
&[ &[
@ -519,7 +519,7 @@ fn test_dmat_subtraction() {
] ]
); );
let mat2 = DMat::from_row_vec( let mat2 = DMatrix::from_row_vector(
2, 2,
2, 2,
&[ &[
@ -528,7 +528,7 @@ fn test_dmat_subtraction() {
] ]
); );
let res = DMat::from_row_vec( let res = DMatrix::from_row_vector(
2, 2,
2, 2,
&[ &[
@ -542,7 +542,7 @@ fn test_dmat_subtraction() {
#[test] #[test]
fn test_dmat_col() { fn test_dmat_col() {
let mat = DMat::from_row_vec( let matrix = DMatrix::from_row_vector(
3, 3,
3, 3,
&[ &[
@ -552,12 +552,12 @@ fn test_dmat_col() {
] ]
); );
assert!(mat.col(1) == DVec::from_slice(3, &[2.0, 5.0, 8.0])); assert!(matrix.column(1) == DVector::from_slice(3, &[2.0, 5.0, 8.0]));
} }
#[test] #[test]
fn test_dmat_set_col() { fn test_dmat_set_col() {
let mut mat = DMat::from_row_vec( let mut matrix = DMatrix::from_row_vector(
3, 3,
3, 3,
&[ &[
@ -567,9 +567,9 @@ fn test_dmat_set_col() {
] ]
); );
mat.set_col(1, DVec::from_slice(3, &[12.0, 15.0, 18.0])); matrix.set_col(1, DVector::from_slice(3, &[12.0, 15.0, 18.0]));
let expected = DMat::from_row_vec( let expected = DMatrix::from_row_vector(
3, 3,
3, 3,
&[ &[
@ -579,12 +579,12 @@ fn test_dmat_set_col() {
] ]
); );
assert!(mat == expected); assert!(matrix == expected);
} }
#[test] #[test]
fn test_dmat_row() { fn test_dmat_row() {
let mat = DMat::from_row_vec( let matrix = DMatrix::from_row_vector(
3, 3,
3, 3,
&[ &[
@ -594,12 +594,12 @@ fn test_dmat_row() {
] ]
); );
assert!(mat.row(1) == DVec::from_slice(3, &[4.0, 5.0, 6.0])); assert!(matrix.row(1) == DVector::from_slice(3, &[4.0, 5.0, 6.0]));
} }
#[test] #[test]
fn test_dmat_set_row() { fn test_dmat_set_row() {
let mut mat = DMat::from_row_vec( let mut matrix = DMatrix::from_row_vector(
3, 3,
3, 3,
&[ &[
@ -609,9 +609,9 @@ fn test_dmat_set_row() {
] ]
); );
mat.set_row(1, DVec::from_slice(3, &[14.0, 15.0, 16.0])); matrix.set_row(1, DVector::from_slice(3, &[14.0, 15.0, 16.0]));
let expected = DMat::from_row_vec( let expected = DMatrix::from_row_vector(
3, 3,
3, 3,
&[ &[
@ -621,10 +621,10 @@ fn test_dmat_set_row() {
] ]
); );
assert!(mat == expected); assert!(matrix == expected);
} }
/* FIXME: review qr decomposition to make it work with DMat. /* FIXME: review qr decomposition to make it work with DMatrix.
#[test] #[test]
fn test_qr() { fn test_qr() {
for _ in 0usize .. 10 { for _ in 0usize .. 10 {
@ -632,79 +632,79 @@ fn test_qr() {
let dim2: usize = random(); let dim2: usize = random();
let rows = min(40, max(dim1, dim2)); let rows = min(40, max(dim1, dim2));
let cols = min(40, min(dim1, dim2)); let cols = min(40, min(dim1, dim2));
let randmat: DMat<f64> = DMat::new_random(rows, cols); let randmatrix: DMatrix<f64> = DMatrix::new_random(rows, cols);
let (q, r) = na::qr(&randmat); let (q, r) = na::qr(&randmatrix);
let recomp = q * r; let recomp = q * r;
assert!(na::approx_eq(&randmat, &recomp)); assert!(na::approx_eq(&randmatrix, &recomp));
} }
} }
*/ */
#[test] #[test]
fn test_qr_mat1() { fn test_qr_mat1() {
test_qr_impl!(Mat1<f64>); test_qr_impl!(Matrix1<f64>);
} }
#[test] #[test]
fn test_qr_mat2() { fn test_qr_mat2() {
test_qr_impl!(Mat2<f64>); test_qr_impl!(Matrix2<f64>);
} }
#[test] #[test]
fn test_qr_mat3() { fn test_qr_mat3() {
test_qr_impl!(Mat3<f64>); test_qr_impl!(Matrix3<f64>);
} }
#[test] #[test]
fn test_qr_mat4() { fn test_qr_mat4() {
test_qr_impl!(Mat4<f64>); test_qr_impl!(Matrix4<f64>);
} }
#[test] #[test]
fn test_qr_mat5() { fn test_qr_mat5() {
test_qr_impl!(Mat5<f64>); test_qr_impl!(Matrix5<f64>);
} }
#[test] #[test]
fn test_qr_mat6() { fn test_qr_mat6() {
test_qr_impl!(Mat6<f64>); test_qr_impl!(Matrix6<f64>);
} }
#[test] #[test]
fn test_eigen_qr_mat1() { fn test_eigen_qr_mat1() {
test_eigen_qr_impl!(Mat1<f64>); test_eigen_qr_impl!(Matrix1<f64>);
} }
#[test] #[test]
fn test_eigen_qr_mat2() { fn test_eigen_qr_mat2() {
test_eigen_qr_impl!(Mat2<f64>); test_eigen_qr_impl!(Matrix2<f64>);
} }
#[test] #[test]
fn test_eigen_qr_mat3() { fn test_eigen_qr_mat3() {
test_eigen_qr_impl!(Mat3<f64>); test_eigen_qr_impl!(Matrix3<f64>);
} }
#[test] #[test]
fn test_eigen_qr_mat4() { fn test_eigen_qr_mat4() {
test_eigen_qr_impl!(Mat4<f64>); test_eigen_qr_impl!(Matrix4<f64>);
} }
#[test] #[test]
fn test_eigen_qr_mat5() { fn test_eigen_qr_mat5() {
test_eigen_qr_impl!(Mat5<f64>); test_eigen_qr_impl!(Matrix5<f64>);
} }
#[test] #[test]
fn test_eigen_qr_mat6() { fn test_eigen_qr_mat6() {
test_eigen_qr_impl!(Mat6<f64>); test_eigen_qr_impl!(Matrix6<f64>);
} }
#[test] #[test]
fn test_from_fn() { fn test_from_fn() {
let actual: DMat<usize> = DMat::from_fn(3, 4, |i, j| 10 * i + j); let actual: DMatrix<usize> = DMatrix::from_fn(3, 4, |i, j| 10 * i + j);
let expected: DMat<usize> = DMat::from_row_vec(3, 4, let expected: DMatrix<usize> = DMatrix::from_row_vector(3, 4,
&[ 0_0, 0_1, 0_2, 0_3, &[ 0_0, 0_1, 0_2, 0_3,
1_0, 1_1, 1_2, 1_3, 1_0, 1_1, 1_2, 1_3,
2_0, 2_1, 2_2, 2_3 ]); 2_0, 2_1, 2_2, 2_3 ]);
@ -714,21 +714,21 @@ fn test_from_fn() {
#[test] #[test]
fn test_row_3() { fn test_row_3() {
let mat = Mat3::new(0.0f32, 1.0, 2.0, let matrix = Matrix3::new(0.0f32, 1.0, 2.0,
3.0, 4.0, 5.0, 3.0, 4.0, 5.0,
6.0, 7.0, 8.0); 6.0, 7.0, 8.0);
let second_row = mat.row(1); let second_row = matrix.row(1);
let second_col = mat.col(1); let second_col = matrix.column(1);
assert!(second_row == Vec3::new(3.0, 4.0, 5.0)); assert!(second_row == Vector3::new(3.0, 4.0, 5.0));
assert!(second_col == Vec3::new(1.0, 4.0, 7.0)); assert!(second_col == Vector3::new(1.0, 4.0, 7.0));
} }
#[test] #[test]
fn test_cholesky_const() { fn test_cholesky_const() {
let a : Mat3<f64> = Mat3::<f64>::new(1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 1.0, 2.0, 3.0); let a : Matrix3<f64> = Matrix3::<f64>::new(1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 1.0, 2.0, 3.0);
let g : Mat3<f64> = Mat3::<f64>::new(1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0); let g : Matrix3<f64> = Matrix3::<f64>::new(1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0);
let result = na::cholesky(&a); let result = na::cholesky(&a);
@ -744,7 +744,7 @@ fn test_cholesky_const() {
#[test] #[test]
fn test_cholesky_not_spd() { fn test_cholesky_not_spd() {
let a : Mat3<f64> = Mat3::<f64>::new(1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 1.0, 1.0, 1.0); let a : Matrix3<f64> = Matrix3::<f64>::new(1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 1.0, 1.0, 1.0);
let result = na::cholesky(&a); let result = na::cholesky(&a);
@ -754,7 +754,7 @@ fn test_cholesky_not_spd() {
#[test] #[test]
fn test_cholesky_not_symmetric() { fn test_cholesky_not_symmetric() {
let a : Mat2<f64> = Mat2::<f64>::new(1.0, 1.0, -1.0, 1.0); let a : Matrix2<f64> = Matrix2::<f64>::new(1.0, 1.0, -1.0, 1.0);
let result = na::cholesky(&a); let result = na::cholesky(&a);
@ -763,83 +763,83 @@ fn test_cholesky_not_symmetric() {
#[test] #[test]
fn test_cholesky_mat1() { fn test_cholesky_mat1() {
test_cholesky_impl!(Mat1<f64>); test_cholesky_impl!(Matrix1<f64>);
} }
#[test] #[test]
fn test_cholesky_mat2() { fn test_cholesky_mat2() {
test_cholesky_impl!(Mat2<f64>); test_cholesky_impl!(Matrix2<f64>);
} }
#[test] #[test]
fn test_cholesky_mat3() { fn test_cholesky_mat3() {
test_cholesky_impl!(Mat3<f64>); test_cholesky_impl!(Matrix3<f64>);
} }
#[test] #[test]
fn test_cholesky_mat4() { fn test_cholesky_mat4() {
test_cholesky_impl!(Mat4<f64>); test_cholesky_impl!(Matrix4<f64>);
} }
#[test] #[test]
fn test_cholesky_mat5() { fn test_cholesky_mat5() {
test_cholesky_impl!(Mat5<f64>); test_cholesky_impl!(Matrix5<f64>);
} }
#[test] #[test]
fn test_cholesky_mat6() { fn test_cholesky_mat6() {
test_cholesky_impl!(Mat6<f64>); test_cholesky_impl!(Matrix6<f64>);
} }
#[test] #[test]
fn test_hessenberg_mat1() { fn test_hessenberg_mat1() {
test_hessenberg_impl!(Mat1<f64>); test_hessenberg_impl!(Matrix1<f64>);
} }
#[test] #[test]
fn test_hessenberg_mat2() { fn test_hessenberg_mat2() {
test_hessenberg_impl!(Mat2<f64>); test_hessenberg_impl!(Matrix2<f64>);
} }
#[test] #[test]
fn test_hessenberg_mat3() { fn test_hessenberg_mat3() {
test_hessenberg_impl!(Mat3<f64>); test_hessenberg_impl!(Matrix3<f64>);
} }
#[test] #[test]
fn test_hessenberg_mat4() { fn test_hessenberg_mat4() {
test_hessenberg_impl!(Mat4<f64>); test_hessenberg_impl!(Matrix4<f64>);
} }
#[test] #[test]
fn test_hessenberg_mat5() { fn test_hessenberg_mat5() {
test_hessenberg_impl!(Mat5<f64>); test_hessenberg_impl!(Matrix5<f64>);
} }
#[test] #[test]
fn test_hessenberg_mat6() { fn test_hessenberg_mat6() {
test_hessenberg_impl!(Mat6<f64>); test_hessenberg_impl!(Matrix6<f64>);
} }
#[test] #[test]
fn test_transpose_square_mat() { fn test_transpose_square_matrix() {
let col_major_mat = &[0, 1, 2, 3, let col_major_matrix = &[0, 1, 2, 3,
0, 1, 2, 3, 0, 1, 2, 3,
0, 1, 2, 3, 0, 1, 2, 3,
0, 1, 2, 3]; 0, 1, 2, 3];
let num_rows = 4; let num_rows = 4;
let num_cols = 4; let num_cols = 4;
let mut mat = DMat::from_col_vec(num_rows, num_cols, col_major_mat); let mut matrix = DMatrix::from_col_vector(num_rows, num_cols, col_major_matrix);
mat.transpose_mut(); matrix.transpose_mut();
for i in 0..num_rows { for i in 0..num_rows {
assert_eq!(&[0, 1, 2, 3], &mat.row_slice(i, 0, num_cols)[..]); assert_eq!(&[0, 1, 2, 3], &matrix.row_slice(i, 0, num_cols)[..]);
} }
} }
#[test] #[test]
fn test_outer_dvec() { fn test_outer_dvector() {
let vec = DVec::from_slice(5, &[ 1.0, 2.0, 3.0, 4.0, 5.0 ]); let vector = DVector::from_slice(5, &[ 1.0, 2.0, 3.0, 4.0, 5.0 ]);
let row = DMat::from_row_vec(1, 5, &vec[..]); let row = DMatrix::from_row_vector(1, 5, &vector[..]);
assert_eq!(row.transpose() * row, na::outer(&vec, &vec)) assert_eq!(row.transpose() * row, na::outer(&vector, &vector))
} }

View File

@ -3,7 +3,7 @@ extern crate rand;
use std::ops::{Mul, Div, Add, Sub, MulAssign, DivAssign, AddAssign, SubAssign}; use std::ops::{Mul, Div, Add, Sub, MulAssign, DivAssign, AddAssign, SubAssign};
use rand::random; use rand::random;
use na::{Pnt3, Vec3, Mat3, Rot3, Iso3, Sim3, Quat, UnitQuat}; use na::{Point3, Vector3, Matrix3, Rotation3, Isometry3, Similarity3, Quaternion, UnitQuaternion};
// NOTE: we test only the 3D version because the others share the same code anyway. // NOTE: we test only the 3D version because the others share the same code anyway.
@ -25,52 +25,52 @@ macro_rules! test_op_vs_op_assign(
); );
// Multiplication. // Multiplication.
test_op_vs_op_assign!(test_vec3_f32_mul_assign, Vec3<f32>, f32, mul, mul_assign); test_op_vs_op_assign!(test_vec3_f32_mul_assign, Vector3<f32>, f32, mul, mul_assign);
test_op_vs_op_assign!(test_mat3_f32_mul_assign, Mat3<f32>, f32, mul, mul_assign); test_op_vs_op_assign!(test_mat3_f32_mul_assign, Matrix3<f32>, f32, mul, mul_assign);
test_op_vs_op_assign!(test_quat_f32_mul_assign, Quat<f32>, f32, mul, mul_assign); test_op_vs_op_assign!(test_quaternion_f32_mul_assign, Quaternion<f32>, f32, mul, mul_assign);
test_op_vs_op_assign!(test_vec3_vec3_mul_assign, Vec3<f32>, Vec3<f32>, mul, mul_assign); test_op_vs_op_assign!(test_vec3_vec3_mul_assign, Vector3<f32>, Vector3<f32>, mul, mul_assign);
test_op_vs_op_assign!(test_quat_quat_mul_assign, Quat<f32>, Quat<f32>, mul, mul_assign); test_op_vs_op_assign!(test_quaternion_quaternion_mul_assign, Quaternion<f32>, Quaternion<f32>, mul, mul_assign);
test_op_vs_op_assign!(test_unit_quat_unit_quat_mul_assign, UnitQuat<f32>, UnitQuat<f32>, mul, mul_assign); test_op_vs_op_assign!(test_unit_quaternion_unit_quaternion_mul_assign, UnitQuaternion<f32>, UnitQuaternion<f32>, mul, mul_assign);
test_op_vs_op_assign!(test_vec3_unit_quat_mul_assign, Vec3<f32>, UnitQuat<f32>, mul, mul_assign); test_op_vs_op_assign!(test_vec3_unit_quaternion_mul_assign, Vector3<f32>, UnitQuaternion<f32>, mul, mul_assign);
test_op_vs_op_assign!(test_pnt3_unit_quat_mul_assign, Pnt3<f32>, UnitQuat<f32>, mul, mul_assign); test_op_vs_op_assign!(test_point3_unit_quaternion_mul_assign, Point3<f32>, UnitQuaternion<f32>, mul, mul_assign);
test_op_vs_op_assign!(test_mat3_mat3_mul_assign, Mat3<f32>, Mat3<f32>, mul, mul_assign); test_op_vs_op_assign!(test_mat3_mat3_mul_assign, Matrix3<f32>, Matrix3<f32>, mul, mul_assign);
test_op_vs_op_assign!(test_vec3_mat3_mul_assign, Vec3<f32>, Mat3<f32>, mul, mul_assign); test_op_vs_op_assign!(test_vec3_mat3_mul_assign, Vector3<f32>, Matrix3<f32>, mul, mul_assign);
test_op_vs_op_assign!(test_pnt3_mat3_mul_assign, Pnt3<f32>, Mat3<f32>, mul, mul_assign); test_op_vs_op_assign!(test_point3_mat3_mul_assign, Point3<f32>, Matrix3<f32>, mul, mul_assign);
test_op_vs_op_assign!(test_rot3_rot3_mul_assign, Rot3<f32>, Rot3<f32>, mul, mul_assign); test_op_vs_op_assign!(test_rot3_rot3_mul_assign, Rotation3<f32>, Rotation3<f32>, mul, mul_assign);
test_op_vs_op_assign!(test_vec3_rot3_mul_assign, Vec3<f32>, Rot3<f32>, mul, mul_assign); test_op_vs_op_assign!(test_vec3_rot3_mul_assign, Vector3<f32>, Rotation3<f32>, mul, mul_assign);
test_op_vs_op_assign!(test_pnt3_rot3_mul_assign, Pnt3<f32>, Rot3<f32>, mul, mul_assign); test_op_vs_op_assign!(test_point3_rot3_mul_assign, Point3<f32>, Rotation3<f32>, mul, mul_assign);
test_op_vs_op_assign!(test_iso3_iso3_mul_assign, Iso3<f32>, Iso3<f32>, mul, mul_assign); test_op_vs_op_assign!(test_iso3_iso3_mul_assign, Isometry3<f32>, Isometry3<f32>, mul, mul_assign);
test_op_vs_op_assign!(test_iso3_rot3_mul_assign, Iso3<f32>, Rot3<f32>, mul, mul_assign); test_op_vs_op_assign!(test_iso3_rot3_mul_assign, Isometry3<f32>, Rotation3<f32>, mul, mul_assign);
test_op_vs_op_assign!(test_sim3_sim3_mul_assign, Sim3<f32>, Sim3<f32>, mul, mul_assign); test_op_vs_op_assign!(test_sim3_sim3_mul_assign, Similarity3<f32>, Similarity3<f32>, mul, mul_assign);
test_op_vs_op_assign!(test_sim3_iso3_mul_assign, Sim3<f32>, Iso3<f32>, mul, mul_assign); test_op_vs_op_assign!(test_sim3_iso3_mul_assign, Similarity3<f32>, Isometry3<f32>, mul, mul_assign);
test_op_vs_op_assign!(test_sim3_rot3_mul_assign, Sim3<f32>, Rot3<f32>, mul, mul_assign); test_op_vs_op_assign!(test_sim3_rot3_mul_assign, Similarity3<f32>, Rotation3<f32>, mul, mul_assign);
// Division. // Division.
test_op_vs_op_assign!(test_vec3_vec3_div_assign, Vec3<f32>, Vec3<f32>, div, div_assign); test_op_vs_op_assign!(test_vec3_vec3_div_assign, Vector3<f32>, Vector3<f32>, div, div_assign);
test_op_vs_op_assign!(test_quat_quat_div_assign, Quat<f32>, Quat<f32>, div, div_assign); test_op_vs_op_assign!(test_quaternion_quaternion_div_assign, Quaternion<f32>, Quaternion<f32>, div, div_assign);
test_op_vs_op_assign!(test_unit_quat_unit_quat_div_assign, UnitQuat<f32>, UnitQuat<f32>, div, div_assign); test_op_vs_op_assign!(test_unit_quaternion_unit_quaternion_div_assign, UnitQuaternion<f32>, UnitQuaternion<f32>, div, div_assign);
test_op_vs_op_assign!(test_vec3_f32_div_assign, Vec3<f32>, f32, div, div_assign); test_op_vs_op_assign!(test_vec3_f32_div_assign, Vector3<f32>, f32, div, div_assign);
test_op_vs_op_assign!(test_mat3_f32_div_assign, Mat3<f32>, f32, div, div_assign); test_op_vs_op_assign!(test_mat3_f32_div_assign, Matrix3<f32>, f32, div, div_assign);
// Addition. // Addition.
test_op_vs_op_assign!(test_vec3_vec3_add_assign, Vec3<f32>, Vec3<f32>, add, add_assign); test_op_vs_op_assign!(test_vec3_vec3_add_assign, Vector3<f32>, Vector3<f32>, add, add_assign);
test_op_vs_op_assign!(test_mat3_mat3_add_assign, Mat3<f32>, Mat3<f32>, add, add_assign); test_op_vs_op_assign!(test_mat3_mat3_add_assign, Matrix3<f32>, Matrix3<f32>, add, add_assign);
test_op_vs_op_assign!(test_quat_quat_add_assign, Quat<f32>, Quat<f32>, add, add_assign); test_op_vs_op_assign!(test_quaternion_quaternion_add_assign, Quaternion<f32>, Quaternion<f32>, add, add_assign);
test_op_vs_op_assign!(test_vec3_f32_add_assign, Vec3<f32>, f32, add, add_assign); test_op_vs_op_assign!(test_vec3_f32_add_assign, Vector3<f32>, f32, add, add_assign);
test_op_vs_op_assign!(test_mat3_f32_add_assign, Mat3<f32>, f32, add, add_assign); test_op_vs_op_assign!(test_mat3_f32_add_assign, Matrix3<f32>, f32, add, add_assign);
// Subtraction. // Subtraction.
test_op_vs_op_assign!(test_vec3_vec3_sub_assign, Vec3<f32>, Vec3<f32>, sub, sub_assign); test_op_vs_op_assign!(test_vec3_vec3_sub_assign, Vector3<f32>, Vector3<f32>, sub, sub_assign);
test_op_vs_op_assign!(test_mat3_mat3_sub_assign, Mat3<f32>, Mat3<f32>, sub, sub_assign); test_op_vs_op_assign!(test_mat3_mat3_sub_assign, Matrix3<f32>, Matrix3<f32>, sub, sub_assign);
test_op_vs_op_assign!(test_quat_quat_sub_assign, Quat<f32>, Quat<f32>, sub, sub_assign); test_op_vs_op_assign!(test_quaternion_quaternion_sub_assign, Quaternion<f32>, Quaternion<f32>, sub, sub_assign);
test_op_vs_op_assign!(test_vec3_f32_sub_assign, Vec3<f32>, f32, sub, sub_assign); test_op_vs_op_assign!(test_vec3_f32_sub_assign, Vector3<f32>, f32, sub, sub_assign);
test_op_vs_op_assign!(test_mat3_f32_sub_assign, Mat3<f32>, f32, sub, sub_assign); test_op_vs_op_assign!(test_mat3_f32_sub_assign, Matrix3<f32>, f32, sub, sub_assign);

View File

@ -1,57 +1,57 @@
extern crate nalgebra as na; extern crate nalgebra as na;
extern crate rand; extern crate rand;
use na::{Pnt3, Vec3, Rot3, UnitQuat, Rotation}; use na::{Point3, Vector3, Rotation3, UnitQuaternion, Rotation};
use rand::random; use rand::random;
#[test] #[test]
fn test_quat_as_mat() { fn test_quaternion_as_matrix() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let axis_angle: Vec3<f64> = random(); let axis_angle: Vector3<f64> = random();
assert!(na::approx_eq(&UnitQuat::new(axis_angle).to_rot(), &Rot3::new(axis_angle))) assert!(na::approx_eq(&UnitQuaternion::new(axis_angle).to_rotation_matrix(), &Rotation3::new(axis_angle)))
} }
} }
#[test] #[test]
fn test_quat_mul_vec_or_pnt_as_mat() { fn test_quaternion_mul_vec_or_point_as_matrix() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let axis_angle: Vec3<f64> = random(); let axis_angle: Vector3<f64> = random();
let vec: Vec3<f64> = random(); let vector: Vector3<f64> = random();
let pnt: Pnt3<f64> = random(); let point: Point3<f64> = random();
let mat = Rot3::new(axis_angle); let matrix = Rotation3::new(axis_angle);
let quat = UnitQuat::new(axis_angle); let quaternion = UnitQuaternion::new(axis_angle);
assert!(na::approx_eq(&(mat * vec), &(quat * vec))); assert!(na::approx_eq(&(matrix * vector), &(quaternion * vector)));
assert!(na::approx_eq(&(mat * pnt), &(quat * pnt))); assert!(na::approx_eq(&(matrix * point), &(quaternion * point)));
assert!(na::approx_eq(&(vec * mat), &(vec * quat))); assert!(na::approx_eq(&(vector * matrix), &(vector * quaternion)));
assert!(na::approx_eq(&(pnt * mat), &(pnt * quat))); assert!(na::approx_eq(&(point * matrix), &(point * quaternion)));
} }
} }
#[test] #[test]
fn test_quat_div_quat() { fn test_quaternion_div_quaternion() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let axis_angle1: Vec3<f64> = random(); let axis_angle1: Vector3<f64> = random();
let axis_angle2: Vec3<f64> = random(); let axis_angle2: Vector3<f64> = random();
let r1 = Rot3::new(axis_angle1); let r1 = Rotation3::new(axis_angle1);
let r2 = na::inv(&Rot3::new(axis_angle2)).unwrap(); let r2 = na::inverse(&Rotation3::new(axis_angle2)).unwrap();
let q1 = UnitQuat::new(axis_angle1); let q1 = UnitQuaternion::new(axis_angle1);
let q2 = UnitQuat::new(axis_angle2); let q2 = UnitQuaternion::new(axis_angle2);
assert!(na::approx_eq(&(q1 / q2).to_rot(), &(r1 * r2))) assert!(na::approx_eq(&(q1 / q2).to_rotation_matrix(), &(r1 * r2)))
} }
} }
#[test] #[test]
fn test_quat_to_axis_angle() { fn test_quaternion_to_axis_angle() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let axis_angle: Vec3<f64> = random(); let axis_angle: Vector3<f64> = random();
let q = UnitQuat::new(axis_angle); let q = UnitQuaternion::new(axis_angle);
println!("{:?} {:?}", q.rotation(), axis_angle); println!("{:?} {:?}", q.rotation(), axis_angle);
assert!(na::approx_eq(&q.rotation(), &axis_angle)) assert!(na::approx_eq(&q.rotation(), &axis_angle))
@ -59,21 +59,21 @@ fn test_quat_to_axis_angle() {
} }
#[test] #[test]
fn test_quat_euler_angles() { fn test_quaternion_euler_angles() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let angles: Vec3<f64> = random(); let angles: Vector3<f64> = random();
let q = UnitQuat::new_with_euler_angles(angles.x, angles.y, angles.z); let q = UnitQuaternion::new_with_euler_angles(angles.x, angles.y, angles.z);
let m = Rot3::new_with_euler_angles(angles.x, angles.y, angles.z); let m = Rotation3::new_with_euler_angles(angles.x, angles.y, angles.z);
assert!(na::approx_eq(&q.to_rot(), &m)) assert!(na::approx_eq(&q.to_rotation_matrix(), &m))
} }
} }
#[test] #[test]
fn test_quat_rotation_between() { fn test_quaternion_rotation_between() {
let q1: UnitQuat<f64> = random(); let q1: UnitQuaternion<f64> = random();
let q2: UnitQuat<f64> = random(); let q2: UnitQuaternion<f64> = random();
let delta = na::rotation_between(&q1, &q2); let delta = na::rotation_between(&q1, &q2);
@ -81,9 +81,9 @@ fn test_quat_rotation_between() {
} }
#[test] #[test]
fn test_quat_angle_between() { fn test_quaternion_angle_between() {
let q1: UnitQuat<f64> = random(); let q1: UnitQuaternion<f64> = random();
let q2: UnitQuat<f64> = random(); let q2: UnitQuaternion<f64> = random();
let delta = na::rotation_between(&q1, &q2); let delta = na::rotation_between(&q1, &q2);
let delta_angle = na::angle_between(&q1, &q2); let delta_angle = na::angle_between(&q1, &q2);

View File

@ -2,35 +2,35 @@ extern crate nalgebra as na;
extern crate rand; extern crate rand;
use rand::random; use rand::random;
use na::{Pnt2, Pnt3, Vec2, Vec3, Vec1, Rot2, Rot3, Persp3, PerspMat3, Ortho3, OrthoMat3, use na::{Point2, Point3, Vector2, Vector3, Vector1, Rotation2, Rotation3, Perspective3, PerspectiveMatrix3, Orthographic3, OrthographicMatrix3,
Iso2, Iso3, Sim2, Sim3, BaseFloat, Transform}; Isometry2, Isometry3, Similarity2, Similarity3, BaseFloat, Transform};
#[test] #[test]
fn test_rotation2() { fn test_rotation2() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let randmat: na::Rot2<f64> = na::one(); let randmatrix: na::Rotation2<f64> = na::one();
let ang = Vec1::new(na::abs(&random::<f64>()) % <f64 as BaseFloat>::pi()); let ang = Vector1::new(na::abs(&random::<f64>()) % <f64 as BaseFloat>::pi());
assert!(na::approx_eq(&na::rotation(&na::append_rotation(&randmat, &ang)), &ang)); assert!(na::approx_eq(&na::rotation(&na::append_rotation(&randmatrix, &ang)), &ang));
} }
} }
#[test] #[test]
fn test_inv_rotation3() { fn test_inverse_rotation3() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let randmat: Rot3<f64> = na::one(); let randmatrix: Rotation3<f64> = na::one();
let dir: Vec3<f64> = random(); let dir: Vector3<f64> = random();
let ang = na::normalize(&dir) * (na::abs(&random::<f64>()) % <f64 as BaseFloat>::pi()); let ang = na::normalize(&dir) * (na::abs(&random::<f64>()) % <f64 as BaseFloat>::pi());
let rot = na::append_rotation(&randmat, &ang); let rotation = na::append_rotation(&randmatrix, &ang);
assert!(na::approx_eq(&(na::transpose(&rot) * rot), &na::one())); assert!(na::approx_eq(&(na::transpose(&rotation) * rotation), &na::one()));
} }
} }
#[test] #[test]
fn test_rot3_rotation_between() { fn test_rot3_rotation_between() {
let r1: Rot3<f64> = random(); let r1: Rotation3<f64> = random();
let r2: Rot3<f64> = random(); let r2: Rotation3<f64> = random();
let delta = na::rotation_between(&r1, &r2); let delta = na::rotation_between(&r1, &r2);
@ -39,8 +39,8 @@ fn test_rot3_rotation_between() {
#[test] #[test]
fn test_rot3_angle_between() { fn test_rot3_angle_between() {
let r1: Rot3<f64> = random(); let r1: Rotation3<f64> = random();
let r2: Rot3<f64> = random(); let r2: Rotation3<f64> = random();
let delta = na::rotation_between(&r1, &r2); let delta = na::rotation_between(&r1, &r2);
let delta_angle = na::angle_between(&r1, &r2); let delta_angle = na::angle_between(&r1, &r2);
@ -50,8 +50,8 @@ fn test_rot3_angle_between() {
#[test] #[test]
fn test_rot2_rotation_between() { fn test_rot2_rotation_between() {
let r1: Rot2<f64> = random(); let r1: Rotation2<f64> = random();
let r2: Rot2<f64> = random(); let r2: Rotation2<f64> = random();
let delta = na::rotation_between(&r1, &r2); let delta = na::rotation_between(&r1, &r2);
@ -60,8 +60,8 @@ fn test_rot2_rotation_between() {
#[test] #[test]
fn test_rot2_angle_between() { fn test_rot2_angle_between() {
let r1: Rot2<f64> = random(); let r1: Rotation2<f64> = random();
let r2: Rot2<f64> = random(); let r2: Rotation2<f64> = random();
let delta = na::rotation_between(&r1, &r2); let delta = na::rotation_between(&r1, &r2);
let delta_angle = na::angle_between(&r1, &r2); let delta_angle = na::angle_between(&r1, &r2);
@ -73,58 +73,58 @@ fn test_rot2_angle_between() {
#[test] #[test]
fn test_look_at_rh_iso3() { fn test_look_at_rh_iso3() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let eye = random::<Pnt3<f64>>(); let eye = random::<Point3<f64>>();
let target = random::<Pnt3<f64>>(); let target = random::<Point3<f64>>();
let up = random::<Vec3<f64>>(); let up = random::<Vector3<f64>>();
let viewmat = Iso3::look_at_rh(&eye, &target, &up); let viewmatrix = Isometry3::look_at_rh(&eye, &target, &up);
let origin: Pnt3<f64> = na::orig(); let origin: Point3<f64> = na::origin();
assert_eq!(&(viewmat * eye), &origin); assert_eq!(&(viewmatrix * eye), &origin);
assert!(na::approx_eq(&na::normalize(&(viewmat * (target - eye))), &-Vec3::z())); assert!(na::approx_eq(&na::normalize(&(viewmatrix * (target - eye))), &-Vector3::z()));
} }
} }
#[test] #[test]
fn test_look_at_rh_rot3() { fn test_look_at_rh_rot3() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let dir = random::<Vec3<f64>>(); let dir = random::<Vector3<f64>>();
let up = random::<Vec3<f64>>(); let up = random::<Vector3<f64>>();
let viewmat = Rot3::look_at_rh(&dir, &up); let viewmatrix = Rotation3::look_at_rh(&dir, &up);
println!("found: {}", viewmat * dir); println!("found: {}", viewmatrix * dir);
assert!(na::approx_eq(&na::normalize(&(viewmat * dir)), &-Vec3::z())); assert!(na::approx_eq(&na::normalize(&(viewmatrix * dir)), &-Vector3::z()));
} }
} }
#[test] #[test]
fn test_observer_frame_iso3() { fn test_observer_frame_iso3() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let eye = random::<Pnt3<f64>>(); let eye = random::<Point3<f64>>();
let target = random::<Pnt3<f64>>(); let target = random::<Point3<f64>>();
let up = random::<Vec3<f64>>(); let up = random::<Vector3<f64>>();
let observer = Iso3::new_observer_frame(&eye, &target, &up); let observer = Isometry3::new_observer_frame(&eye, &target, &up);
assert_eq!(&(observer * na::orig::<Pnt3<f64>>()), &eye); assert_eq!(&(observer * na::origin::<Point3<f64>>()), &eye);
assert!(na::approx_eq(&(observer * Vec3::z()), &na::normalize(&(target - eye)))); assert!(na::approx_eq(&(observer * Vector3::z()), &na::normalize(&(target - eye))));
} }
} }
#[test] #[test]
fn test_observer_frame_rot3() { fn test_observer_frame_rot3() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let dir = random::<Vec3<f64>>(); let dir = random::<Vector3<f64>>();
let up = random::<Vec3<f64>>(); let up = random::<Vector3<f64>>();
let observer = Rot3::new_observer_frame(&dir, &up); let observer = Rotation3::new_observer_frame(&dir, &up);
assert!(na::approx_eq(&(observer * Vec3::z()), &na::normalize(&dir))); assert!(na::approx_eq(&(observer * Vector3::z()), &na::normalize(&dir)));
} }
} }
#[test] #[test]
fn test_persp() { fn test_persp() {
let mut p = Persp3::new(42.0f64, 0.5, 1.5, 10.0); let mut p = Perspective3::new(42.0f64, 0.5, 1.5, 10.0);
let mut pm = PerspMat3::new(42.0f64, 0.5, 1.5, 10.0); let mut pm = PerspectiveMatrix3::new(42.0f64, 0.5, 1.5, 10.0);
assert!(p.to_mat() == pm.to_mat()); assert!(p.to_matrix() == pm.to_matrix());
assert!(p.aspect() == 42.0); assert!(p.aspect() == 42.0);
assert!(p.fovy() == 0.5); assert!(p.fovy() == 0.5);
assert!(p.znear() == 1.5); assert!(p.znear() == 1.5);
@ -136,19 +136,19 @@ fn test_persp() {
p.set_fovy(0.1); p.set_fovy(0.1);
pm.set_fovy(0.1); pm.set_fovy(0.1);
assert!(na::approx_eq(&p.to_mat(), pm.as_mat())); assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
p.set_znear(24.0); p.set_znear(24.0);
pm.set_znear(24.0); pm.set_znear(24.0);
assert!(na::approx_eq(&p.to_mat(), pm.as_mat())); assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
p.set_zfar(61.0); p.set_zfar(61.0);
pm.set_zfar(61.0); pm.set_zfar(61.0);
assert!(na::approx_eq(&p.to_mat(), pm.as_mat())); assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
p.set_aspect(23.0); p.set_aspect(23.0);
pm.set_aspect(23.0); pm.set_aspect(23.0);
assert!(na::approx_eq(&p.to_mat(), pm.as_mat())); assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
assert!(p.aspect() == 23.0); assert!(p.aspect() == 23.0);
assert!(p.fovy() == 0.1); assert!(p.fovy() == 0.1);
@ -162,9 +162,9 @@ fn test_persp() {
#[test] #[test]
fn test_ortho() { fn test_ortho() {
let mut p = Ortho3::new(-0.3, 5.2, -3.9, -1.0, 1.5, 10.0); let mut p = Orthographic3::new(-0.3, 5.2, -3.9, -1.0, 1.5, 10.0);
let mut pm = OrthoMat3::new(-0.3, 5.2, -3.9, -1.0, 1.5, 10.0); let mut pm = OrthographicMatrix3::new(-0.3, 5.2, -3.9, -1.0, 1.5, 10.0);
assert!(p.to_mat() == pm.to_mat()); assert!(p.to_matrix() == pm.to_matrix());
assert!(p.left() == -0.3); assert!(p.left() == -0.3);
assert!(p.right() == 5.2); assert!(p.right() == 5.2);
assert!(p.bottom() == -3.9); assert!(p.bottom() == -3.9);
@ -180,27 +180,27 @@ fn test_ortho() {
p.set_left(0.1); p.set_left(0.1);
pm.set_left(0.1); pm.set_left(0.1);
assert!(na::approx_eq(&p.to_mat(), pm.as_mat())); assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
p.set_right(10.1); p.set_right(10.1);
pm.set_right(10.1); pm.set_right(10.1);
assert!(na::approx_eq(&p.to_mat(), pm.as_mat())); assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
p.set_top(24.0); p.set_top(24.0);
pm.set_top(24.0); pm.set_top(24.0);
assert!(na::approx_eq(&p.to_mat(), pm.as_mat())); assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
p.set_bottom(-23.0); p.set_bottom(-23.0);
pm.set_bottom(-23.0); pm.set_bottom(-23.0);
assert!(na::approx_eq(&p.to_mat(), pm.as_mat())); assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
p.set_zfar(61.0); p.set_zfar(61.0);
pm.set_zfar(61.0); pm.set_zfar(61.0);
assert!(na::approx_eq(&p.to_mat(), pm.as_mat())); assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
p.set_znear(21.0); p.set_znear(21.0);
pm.set_znear(21.0); pm.set_znear(21.0);
assert!(na::approx_eq(&p.to_mat(), pm.as_mat())); assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
assert!(p.znear() == 21.0); assert!(p.znear() == 21.0);
assert!(p.zfar() == 61.0); assert!(p.zfar() == 61.0);
@ -208,15 +208,15 @@ fn test_ortho() {
assert!(na::approx_eq(&pm.zfar(), &61.0)); assert!(na::approx_eq(&pm.zfar(), &61.0));
} }
macro_rules! test_transform_inv_transform_impl( macro_rules! test_transform_inverse_transform_impl(
($fnname: ident, $t: ty, $p: ty) => ( ($fnname: ident, $t: ty, $p: ty) => (
#[test] #[test]
fn $fnname() { fn $fnname() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let randmat: $t = random(); let randmatrix: $t = random();
let expected: $p = random(); let expected: $p = random();
let computed = randmat.inv_transform(&randmat.transform(&expected)); let computed = randmatrix.inverse_transform(&randmatrix.transform(&expected));
println!("computed: {}, expected: {}", computed, expected); println!("computed: {}, expected: {}", computed, expected);
assert!(na::approx_eq(&computed, &expected)); assert!(na::approx_eq(&computed, &expected));
@ -225,12 +225,12 @@ macro_rules! test_transform_inv_transform_impl(
); );
); );
test_transform_inv_transform_impl!(test_transform_inv_transform_rot2, Rot2<f64>, Pnt2<f64>); test_transform_inverse_transform_impl!(test_transform_inverse_transform_rot2, Rotation2<f64>, Point2<f64>);
test_transform_inv_transform_impl!(test_transform_inv_transform_rot3, Rot3<f64>, Pnt3<f64>); test_transform_inverse_transform_impl!(test_transform_inverse_transform_rot3, Rotation3<f64>, Point3<f64>);
test_transform_inv_transform_impl!(test_transform_inv_transform_iso2, Iso2<f64>, Pnt2<f64>); test_transform_inverse_transform_impl!(test_transform_inverse_transform_iso2, Isometry2<f64>, Point2<f64>);
test_transform_inv_transform_impl!(test_transform_inv_transform_iso3, Iso3<f64>, Pnt3<f64>); test_transform_inverse_transform_impl!(test_transform_inverse_transform_iso3, Isometry3<f64>, Point3<f64>);
test_transform_inv_transform_impl!(test_transform_inv_transform_sim2, Sim2<f64>, Pnt2<f64>); test_transform_inverse_transform_impl!(test_transform_inverse_transform_sim2, Similarity2<f64>, Point2<f64>);
test_transform_inv_transform_impl!(test_transform_inv_transform_sim3, Sim3<f64>, Pnt3<f64>); test_transform_inverse_transform_impl!(test_transform_inverse_transform_sim3, Similarity3<f64>, Point3<f64>);
macro_rules! test_transform_mul_assoc( macro_rules! test_transform_mul_assoc(
($fnname: ident, $t1: ty, $t2: ty, $p: ty) => ( ($fnname: ident, $t1: ty, $t2: ty, $p: ty) => (
@ -253,28 +253,28 @@ macro_rules! test_transform_mul_assoc(
); );
); );
test_transform_mul_assoc!(test_transform_inv_transform_sim3_sim3_pnt3, Sim3<f64>, Sim3<f64>, Pnt3<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_sim3_sim3_point3, Similarity3<f64>, Similarity3<f64>, Point3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim3_iso3_pnt3, Sim3<f64>, Iso3<f64>, Pnt3<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_sim3_iso3_point3, Similarity3<f64>, Isometry3<f64>, Point3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim3_rot3_pnt3, Sim3<f64>, Rot3<f64>, Pnt3<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_sim3_rot3_point3, Similarity3<f64>, Rotation3<f64>, Point3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_iso3_iso3_pnt3, Iso3<f64>, Iso3<f64>, Pnt3<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_iso3_iso3_point3, Isometry3<f64>, Isometry3<f64>, Point3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_iso3_rot3_pnt3, Iso3<f64>, Rot3<f64>, Pnt3<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_iso3_rot3_point3, Isometry3<f64>, Rotation3<f64>, Point3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_rot3_rot3_pnt3, Rot3<f64>, Rot3<f64>, Pnt3<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_rot3_rot3_point3, Rotation3<f64>, Rotation3<f64>, Point3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim3_sim3_vec3, Sim3<f64>, Sim3<f64>, Vec3<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_sim3_sim3_vec3, Similarity3<f64>, Similarity3<f64>, Vector3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim3_iso3_vec3, Sim3<f64>, Iso3<f64>, Vec3<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_sim3_iso3_vec3, Similarity3<f64>, Isometry3<f64>, Vector3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim3_rot3_vec3, Sim3<f64>, Rot3<f64>, Vec3<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_sim3_rot3_vec3, Similarity3<f64>, Rotation3<f64>, Vector3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_iso3_iso3_vec3, Iso3<f64>, Iso3<f64>, Vec3<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_iso3_iso3_vec3, Isometry3<f64>, Isometry3<f64>, Vector3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_iso3_rot3_vec3, Iso3<f64>, Rot3<f64>, Vec3<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_iso3_rot3_vec3, Isometry3<f64>, Rotation3<f64>, Vector3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_rot3_rot3_vec3, Rot3<f64>, Rot3<f64>, Vec3<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_rot3_rot3_vec3, Rotation3<f64>, Rotation3<f64>, Vector3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim2_sim2_pnt2, Sim2<f64>, Sim2<f64>, Pnt2<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_sim2_sim2_point2, Similarity2<f64>, Similarity2<f64>, Point2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim2_iso2_pnt2, Sim2<f64>, Iso2<f64>, Pnt2<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_sim2_iso2_point2, Similarity2<f64>, Isometry2<f64>, Point2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim2_rot2_pnt2, Sim2<f64>, Rot2<f64>, Pnt2<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_sim2_rot2_point2, Similarity2<f64>, Rotation2<f64>, Point2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_iso2_iso2_pnt2, Iso2<f64>, Iso2<f64>, Pnt2<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_iso2_iso2_point2, Isometry2<f64>, Isometry2<f64>, Point2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_iso2_rot2_pnt2, Iso2<f64>, Rot2<f64>, Pnt2<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_iso2_rot2_point2, Isometry2<f64>, Rotation2<f64>, Point2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_rot2_rot2_pnt2, Rot2<f64>, Rot2<f64>, Pnt2<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_rot2_rot2_point2, Rotation2<f64>, Rotation2<f64>, Point2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim2_sim2_vec2, Sim2<f64>, Sim2<f64>, Vec2<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_sim2_sim2_vec2, Similarity2<f64>, Similarity2<f64>, Vector2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim2_iso2_vec2, Sim2<f64>, Iso2<f64>, Vec2<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_sim2_iso2_vec2, Similarity2<f64>, Isometry2<f64>, Vector2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim2_rot2_vec2, Sim2<f64>, Rot2<f64>, Vec2<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_sim2_rot2_vec2, Similarity2<f64>, Rotation2<f64>, Vector2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_iso2_iso2_vec2, Iso2<f64>, Iso2<f64>, Vec2<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_iso2_iso2_vec2, Isometry2<f64>, Isometry2<f64>, Vector2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_iso2_rot2_vec2, Iso2<f64>, Rot2<f64>, Vec2<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_iso2_rot2_vec2, Isometry2<f64>, Rotation2<f64>, Vector2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_rot2_rot2_vec2, Rot2<f64>, Rot2<f64>, Vec2<f64>); test_transform_mul_assoc!(test_transform_inverse_transform_rot2_rot2_vec2, Rotation2<f64>, Rotation2<f64>, Vector2<f64>);

View File

@ -4,12 +4,12 @@ extern crate typenum;
extern crate nalgebra as na; extern crate nalgebra as na;
use rand::random; use rand::random;
use na::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6, Mat3, Rot2, Rot3, Iterable, IterableMut}; use na::{Vector1, Vector2, Vector3, Vector4, Vector5, Vector6, Matrix3, Rotation2, Rotation3, Iterable, IterableMut};
#[cfg(feature="generic_sizes")] #[cfg(feature="generic_sizes")]
use typenum::U10; use typenum::U10;
#[cfg(feature="generic_sizes")] #[cfg(feature="generic_sizes")]
use na::VecN; use na::VectorN;
macro_rules! test_iterator_impl( macro_rules! test_iterator_impl(
@ -109,9 +109,9 @@ macro_rules! test_subspace_basis_impl(
#[test] #[test]
fn test_cross_vec3() { fn test_cross_vec3() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let v1 : Vec3<f64> = random(); let v1 : Vector3<f64> = random();
let v2 : Vec3<f64> = random(); let v2 : Vector3<f64> = random();
let v3 : Vec3<f64> = na::cross(&v1, &v2); let v3 : Vector3<f64> = na::cross(&v1, &v2);
assert!(na::approx_eq(&na::dot(&v3, &v2), &na::zero())); assert!(na::approx_eq(&na::dot(&v3, &v2), &na::zero()));
assert!(na::approx_eq(&na::dot(&v3, &v1), &na::zero())); assert!(na::approx_eq(&na::dot(&v3, &v1), &na::zero()));
@ -120,182 +120,182 @@ fn test_cross_vec3() {
#[test] #[test]
fn test_commut_dot_vec1() { fn test_commut_dot_vec1() {
test_commut_dot_impl!(Vec1<f64>); test_commut_dot_impl!(Vector1<f64>);
} }
#[test] #[test]
fn test_commut_dot_vec2() { fn test_commut_dot_vec2() {
test_commut_dot_impl!(Vec2<f64>); test_commut_dot_impl!(Vector2<f64>);
} }
#[test] #[test]
fn test_commut_dot_vec3() { fn test_commut_dot_vec3() {
test_commut_dot_impl!(Vec3<f64>); test_commut_dot_impl!(Vector3<f64>);
} }
#[test] #[test]
fn test_commut_dot_vec4() { fn test_commut_dot_vec4() {
test_commut_dot_impl!(Vec4<f64>); test_commut_dot_impl!(Vector4<f64>);
} }
#[test] #[test]
fn test_commut_dot_vec5() { fn test_commut_dot_vec5() {
test_commut_dot_impl!(Vec5<f64>); test_commut_dot_impl!(Vector5<f64>);
} }
#[test] #[test]
fn test_commut_dot_vec6() { fn test_commut_dot_vec6() {
test_commut_dot_impl!(Vec6<f64>); test_commut_dot_impl!(Vector6<f64>);
} }
#[test] #[test]
fn test_basis_vec1() { fn test_basis_vec1() {
test_basis_impl!(Vec1<f64>); test_basis_impl!(Vector1<f64>);
} }
#[test] #[test]
fn test_basis_vec2() { fn test_basis_vec2() {
test_basis_impl!(Vec2<f64>); test_basis_impl!(Vector2<f64>);
} }
#[test] #[test]
fn test_basis_vec3() { fn test_basis_vec3() {
test_basis_impl!(Vec3<f64>); test_basis_impl!(Vector3<f64>);
} }
#[test] #[test]
fn test_basis_vec4() { fn test_basis_vec4() {
test_basis_impl!(Vec4<f64>); test_basis_impl!(Vector4<f64>);
} }
#[test] #[test]
fn test_basis_vec5() { fn test_basis_vec5() {
test_basis_impl!(Vec5<f64>); test_basis_impl!(Vector5<f64>);
} }
#[test] #[test]
fn test_basis_vec6() { fn test_basis_vec6() {
test_basis_impl!(Vec6<f64>); test_basis_impl!(Vector6<f64>);
} }
#[test] #[test]
fn test_subspace_basis_vec1() { fn test_subspace_basis_vec1() {
test_subspace_basis_impl!(Vec1<f64>); test_subspace_basis_impl!(Vector1<f64>);
} }
#[test] #[test]
fn test_subspace_basis_vec2() { fn test_subspace_basis_vec2() {
test_subspace_basis_impl!(Vec2<f64>); test_subspace_basis_impl!(Vector2<f64>);
} }
#[test] #[test]
fn test_subspace_basis_vec3() { fn test_subspace_basis_vec3() {
test_subspace_basis_impl!(Vec3<f64>); test_subspace_basis_impl!(Vector3<f64>);
} }
#[test] #[test]
fn test_subspace_basis_vec4() { fn test_subspace_basis_vec4() {
test_subspace_basis_impl!(Vec4<f64>); test_subspace_basis_impl!(Vector4<f64>);
} }
#[test] #[test]
fn test_subspace_basis_vec5() { fn test_subspace_basis_vec5() {
test_subspace_basis_impl!(Vec5<f64>); test_subspace_basis_impl!(Vector5<f64>);
} }
#[test] #[test]
fn test_subspace_basis_vec6() { fn test_subspace_basis_vec6() {
test_subspace_basis_impl!(Vec6<f64>); test_subspace_basis_impl!(Vector6<f64>);
} }
#[test] #[test]
fn test_scalar_op_vec1() { fn test_scalar_op_vec1() {
test_scalar_op_impl!(Vec1<f64>, f64); test_scalar_op_impl!(Vector1<f64>, f64);
} }
#[test] #[test]
fn test_scalar_op_vec2() { fn test_scalar_op_vec2() {
test_scalar_op_impl!(Vec2<f64>, f64); test_scalar_op_impl!(Vector2<f64>, f64);
} }
#[test] #[test]
fn test_scalar_op_vec3() { fn test_scalar_op_vec3() {
test_scalar_op_impl!(Vec3<f64>, f64); test_scalar_op_impl!(Vector3<f64>, f64);
} }
#[test] #[test]
fn test_scalar_op_vec4() { fn test_scalar_op_vec4() {
test_scalar_op_impl!(Vec4<f64>, f64); test_scalar_op_impl!(Vector4<f64>, f64);
} }
#[test] #[test]
fn test_scalar_op_vec5() { fn test_scalar_op_vec5() {
test_scalar_op_impl!(Vec5<f64>, f64); test_scalar_op_impl!(Vector5<f64>, f64);
} }
#[test] #[test]
fn test_scalar_op_vec6() { fn test_scalar_op_vec6() {
test_scalar_op_impl!(Vec6<f64>, f64); test_scalar_op_impl!(Vector6<f64>, f64);
} }
#[test] #[test]
fn test_iterator_vec1() { fn test_iterator_vec1() {
test_iterator_impl!(Vec1<f64>, f64); test_iterator_impl!(Vector1<f64>, f64);
} }
#[test] #[test]
fn test_iterator_vec2() { fn test_iterator_vec2() {
test_iterator_impl!(Vec2<f64>, f64); test_iterator_impl!(Vector2<f64>, f64);
} }
#[test] #[test]
fn test_iterator_vec3() { fn test_iterator_vec3() {
test_iterator_impl!(Vec3<f64>, f64); test_iterator_impl!(Vector3<f64>, f64);
} }
#[test] #[test]
fn test_iterator_vec4() { fn test_iterator_vec4() {
test_iterator_impl!(Vec4<f64>, f64); test_iterator_impl!(Vector4<f64>, f64);
} }
#[test] #[test]
fn test_iterator_vec5() { fn test_iterator_vec5() {
test_iterator_impl!(Vec5<f64>, f64); test_iterator_impl!(Vector5<f64>, f64);
} }
#[test] #[test]
fn test_iterator_vec6() { fn test_iterator_vec6() {
test_iterator_impl!(Vec6<f64>, f64); test_iterator_impl!(Vector6<f64>, f64);
} }
#[test] #[test]
fn test_ord_vec3() { fn test_ord_vec3() {
// equality // equality
assert!(Vec3::new(0.5f64, 0.5, 0.5) == Vec3::new(0.5, 0.5, 0.5)); assert!(Vector3::new(0.5f64, 0.5, 0.5) == Vector3::new(0.5, 0.5, 0.5));
assert!(!(Vec3::new(1.5f64, 0.5, 0.5) == Vec3::new(0.5, 0.5, 0.5))); assert!(!(Vector3::new(1.5f64, 0.5, 0.5) == Vector3::new(0.5, 0.5, 0.5)));
assert!(Vec3::new(1.5f64, 0.5, 0.5) != Vec3::new(0.5, 0.5, 0.5)); assert!(Vector3::new(1.5f64, 0.5, 0.5) != Vector3::new(0.5, 0.5, 0.5));
// comparable // comparable
assert!(na::partial_cmp(&Vec3::new(0.5f64, 0.3, 0.3), &Vec3::new(1.0, 2.0, 1.0)).is_le()); assert!(na::partial_cmp(&Vector3::new(0.5f64, 0.3, 0.3), &Vector3::new(1.0, 2.0, 1.0)).is_le());
assert!(na::partial_cmp(&Vec3::new(0.5f64, 0.3, 0.3), &Vec3::new(1.0, 2.0, 1.0)).is_lt()); assert!(na::partial_cmp(&Vector3::new(0.5f64, 0.3, 0.3), &Vector3::new(1.0, 2.0, 1.0)).is_lt());
assert!(na::partial_cmp(&Vec3::new(2.0f64, 4.0, 2.0), &Vec3::new(1.0, 2.0, 1.0)).is_ge()); assert!(na::partial_cmp(&Vector3::new(2.0f64, 4.0, 2.0), &Vector3::new(1.0, 2.0, 1.0)).is_ge());
assert!(na::partial_cmp(&Vec3::new(2.0f64, 4.0, 2.0), &Vec3::new(1.0, 2.0, 1.0)).is_gt()); assert!(na::partial_cmp(&Vector3::new(2.0f64, 4.0, 2.0), &Vector3::new(1.0, 2.0, 1.0)).is_gt());
// not comparable // not comparable
assert!(na::partial_cmp(&Vec3::new(0.0f64, 3.0, 0.0), &Vec3::new(1.0, 2.0, 1.0)).is_not_comparable()); assert!(na::partial_cmp(&Vector3::new(0.0f64, 3.0, 0.0), &Vector3::new(1.0, 2.0, 1.0)).is_not_comparable());
} }
#[test] #[test]
fn test_min_max_vec3() { fn test_min_max_vec3() {
assert_eq!(na::sup(&Vec3::new(1.0f64, 2.0, 3.0), &Vec3::new(3.0, 2.0, 1.0)), Vec3::new(3.0, 2.0, 3.0)); assert_eq!(na::sup(&Vector3::new(1.0f64, 2.0, 3.0), &Vector3::new(3.0, 2.0, 1.0)), Vector3::new(3.0, 2.0, 3.0));
assert_eq!(na::inf(&Vec3::new(1.0f64, 2.0, 3.0), &Vec3::new(3.0, 2.0, 1.0)), Vec3::new(1.0, 2.0, 1.0)); assert_eq!(na::inf(&Vector3::new(1.0f64, 2.0, 3.0), &Vector3::new(3.0, 2.0, 1.0)), Vector3::new(1.0, 2.0, 1.0));
} }
#[test] #[test]
fn test_outer_vec3() { fn test_outer_vec3() {
assert_eq!( assert_eq!(
na::outer(&Vec3::new(1.0f64, 2.0, 3.0), &Vec3::new(4.0, 5.0, 6.0)), na::outer(&Vector3::new(1.0f64, 2.0, 3.0), &Vector3::new(4.0, 5.0, 6.0)),
Mat3::new( Matrix3::new(
4.0, 5.0, 6.0, 4.0, 5.0, 6.0,
8.0, 10.0, 12.0, 8.0, 10.0, 12.0,
12.0, 15.0, 18.0)); 12.0, 15.0, 18.0));
@ -305,7 +305,7 @@ fn test_outer_vec3() {
#[test] #[test]
fn test_vecn10_add_mul() { fn test_vecn10_add_mul() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let v1: VecN<f64, U10> = random(); let v1: VectorN<f64, U10> = random();
assert!(na::approx_eq(&(v1 + v1), &(v1 * 2.0))) assert!(na::approx_eq(&(v1 + v1), &(v1 * 2.0)))
} }
@ -315,29 +315,29 @@ fn test_vecn10_add_mul() {
#[test] #[test]
fn test_vec3_rotation_between() { fn test_vec3_rotation_between() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let v1: Vec3<f64> = random(); let v1: Vector3<f64> = random();
let mut v2: Vec3<f64> = random(); let mut v2: Vector3<f64> = random();
v2 = na::normalize(&v2) * na::norm(&v1); v2 = na::normalize(&v2) * na::norm(&v1);
let rot = na::rotation_between(&v1, &v2); let rotation = na::rotation_between(&v1, &v2);
assert!(na::approx_eq(&(rot * v1), &v2)) assert!(na::approx_eq(&(rotation * v1), &v2))
} }
} }
#[test] #[test]
fn test_vec3_angle_between() { fn test_vec3_angle_between() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let vec: Vec3<f64> = random(); let vector: Vector3<f64> = random();
let other: Vec3<f64> = random(); let other: Vector3<f64> = random();
// Ensure the axis we are using is orthogonal to `vec`. // Ensure the axis we are using is orthogonal to `vector`.
let axis_ang = na::cross(&vec, &other); let axis_ang = na::cross(&vector, &other);
let ang = na::norm(&axis_ang); let ang = na::norm(&axis_ang);
let rot = Rot3::new(axis_ang); let rotation = Rotation3::new(axis_ang);
let delta = na::angle_between(&vec, &(rot * vec)); let delta = na::angle_between(&vector, &(rotation * vector));
assert!(na::approx_eq(&ang, &delta)) assert!(na::approx_eq(&ang, &delta))
} }
@ -347,27 +347,27 @@ fn test_vec3_angle_between() {
#[test] #[test]
fn test_vec2_rotation_between() { fn test_vec2_rotation_between() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let v1: Vec2<f64> = random(); let v1: Vector2<f64> = random();
let mut v2: Vec2<f64> = random(); let mut v2: Vector2<f64> = random();
v2 = na::normalize(&v2) * na::norm(&v1); v2 = na::normalize(&v2) * na::norm(&v1);
let rot = na::rotation_between(&v1, &v2); let rotation = na::rotation_between(&v1, &v2);
assert!(na::approx_eq(&(rot * v1), &v2)) assert!(na::approx_eq(&(rotation * v1), &v2))
} }
} }
#[test] #[test]
fn test_vec2_angle_between() { fn test_vec2_angle_between() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let axis_ang: Vec1<f64> = random(); let axis_ang: Vector1<f64> = random();
let ang = na::norm(&axis_ang); let ang = na::norm(&axis_ang);
let rot: Rot2<f64> = Rot2::new(axis_ang); let rotation: Rotation2<f64> = Rotation2::new(axis_ang);
let vec: Vec2<f64> = random(); let vector: Vector2<f64> = random();
let delta = na::angle_between(&vec, &(rot * vec)); let delta = na::angle_between(&vector, &(rotation * vector));
assert!(na::approx_eq(&ang, &delta)) assert!(na::approx_eq(&ang, &delta))
} }