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.
### Modified
* Points and vectors are now linked to each other with associated types
(on the PntAsVec trait).
(on the PointAsVector trait).
## [0.6.0]
@ -20,22 +20,22 @@ you [there](http://users.nphysics.org)!
### Added
* Added a dependency to [generic-array](https://crates.io/crates/generic-array). Feature-gated:
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"`.
* Added similarity transformations (an uniform scale followed by a rotation followed by a
translation): `Sim2`, `Sim3`.
translation): `Similarity2`, `Similarity3`.
### Removed
* Removed zero-sized elements `Vec0`, `Pnt0`.
* Removed 4-dimensional transformations `Rot4` and `Iso4` (which had an implementation to incomplete to be useful).
* Removed zero-sized elements `Vector0`, `Point0`.
* Removed 4-dimensional transformations `Rotation4` and `Isometry4` (which had an implementation to incomplete to be useful).
### Modified
* 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).
* `{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`
variant to build a view matrix that
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`.
* 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
out-of-place operations.
* You can import the whole prelude using:
Thus, you can import the whole prelude using:
```.ignore
use nalgebra::*;
```
The preferred way to use **nalgebra** is to import types and traits explicitly, and call
free-functions using the `na::` prefix:
However, the recommended way to use **nalgebra** is to import types and traits
explicitly, and call free-functions using the `na::` prefix:
```.rust
extern crate nalgebra as na;
use na::{Vec3, Rot3, Rotation};
use na::{Vector3, Rotation3, Rotation};
fn main() {
let a = Vec3::new(1.0f64, 1.0, 1.0);
let mut b = Rot3::new(na::zero());
let a = Vector3::new(1.0f64, 1.0, 1.0);
let mut b = Rotation3::new(na::zero());
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
an optimized set of tools for computer graphics and physics. Those features include:
* Vectors with predefined static sizes: `Vec1`, `Vec2`, `Vec3`, `Vec4`, `Vec5`, `Vec6`.
* Vector with a user-defined static size: `VecN` (available only with the `generic_sizes` feature).
* Points with static sizes: `Pnt1`, `Pnt2`, `Pnt3`, `Pnt4`, `Pnt5`, `Pnt6`.
* Square matrices with static sizes: `Mat1`, `Mat2`, `Mat3`, `Mat4`, `Mat5`, `Mat6 `.
* Rotation matrices: `Rot2`, `Rot3`
* Quaternions: `Quat`, `UnitQuat`.
* Isometries (translation rotation): `Iso2`, `Iso3`
* Similarity transformations (translation rotation uniform scale): `Sim2`, `Sim3`.
* 3D projections for computer graphics: `Persp3`, `PerspMat3`, `Ortho3`, `OrthoMat3`.
* Dynamically sized heap-allocated vector: `DVec`.
* Dynamically sized stack-allocated vectors with a maximum size: `DVec1` to `DVec6`.
* Dynamically sized heap-allocated (square or rectangular) matrix: `DMat`.
* Linear algebra and data analysis operators: `Cov`, `Mean`, `qr`, `cholesky`.
* Vectors with predefined static sizes: `Vector1`, `Vector2`, `Vector3`, `Vector4`, `Vector5`, `Vector6`.
* Vector with a user-defined static size: `VectorN` (available only with the `generic_sizes` feature).
* Points with static sizes: `Point1`, `Point2`, `Point3`, `Point4`, `Point5`, `Point6`.
* Square matrices with static sizes: `Matrix1`, `Matrix2`, `Matrix3`, `Matrix4`, `Matrix5`, `Matrix6 `.
* Rotation matrices: `Rotation2`, `Rotation3`
* Quaternions: `Quaternion`, `UnitQuaternion`.
* Isometrymetries (translation rotation): `Isometry2`, `Isometry3`
* Similarity transformations (translation rotation uniform scale): `Similarity2`, `Similarity3`.
* 3D projections for computer graphics: `Persp3`, `PerspMatrix3`, `Ortho3`, `OrthoMatrix3`.
* Dynamically sized heap-allocated vector: `DVector`.
* Dynamically sized stack-allocated vectors with a maximum size: `DVector1` to `DVector6`.
* Dynamically sized heap-allocated (square or rectangular) matrix: `DMatrix`.
* Linear algebra and data analysis operators: `Covariance`, `Mean`, `qr`, `cholesky`.
* 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 test::Bencher;
use na::{UnitQuat, Rot2, Rot3, Vec1, Vec3};
use na::{UnitQuaternion, Rotation2, Rotation3, Vector1, Vector3};
#[path="common/macros.rs"]
mod macros;
bench_construction!(_bench_quat_from_axisangle, UnitQuat::new, axisangle: Vec3<f32>);
bench_construction!(_bench_rot2_from_axisangle, Rot2::new, axisangle: Vec1<f32>);
bench_construction!(_bench_rot3_from_axisangle, Rot3::new, axisangle: Vec3<f32>);
bench_construction!(_bench_quaternion_from_axisangle, UnitQuaternion::new, axisangle: Vector3<f32>);
bench_construction!(_bench_rot2_from_axisangle, Rotation2::new, axisangle: Vector1<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_rot3_from_euler_angles, Rot3::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, 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;
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.iter(|| {
let a: DMat<f64> = DMat::new_random($nrows, $ncols);
let mut b: DMat<f64> = DMat::new_random($nrows, $ncols);
let a: DMatrix<f64> = DMatrix::new_random($nrows, $ncols);
let mut b: DMatrix<f64> = DMatrix::new_random($nrows, $ncols);
for _ in 0usize .. 1000 {
// XXX: the clone here is highly undesirable!
@ -24,36 +24,36 @@ macro_rules! bench_mul_dmat(
#[bench]
fn bench_mul_dmat2(bh: &mut Bencher) {
bench_mul_dmat!(bh, 2, 2);
bench_mul_dmatrix!(bh, 2, 2);
}
#[bench]
fn bench_mul_dmat3(bh: &mut Bencher) {
bench_mul_dmat!(bh, 3, 3);
bench_mul_dmatrix!(bh, 3, 3);
}
#[bench]
fn bench_mul_dmat4(bh: &mut Bencher) {
bench_mul_dmat!(bh, 4, 4);
bench_mul_dmatrix!(bh, 4, 4);
}
#[bench]
fn bench_mul_dmat5(bh: &mut Bencher) {
bench_mul_dmat!(bh, 5, 5);
bench_mul_dmatrix!(bh, 5, 5);
}
#[bench]
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.iter(|| {
let m : DMat<f64> = DMat::new_random($nrows, $ncols);
let mut v : DVec<f64> = DVec::new_random($ncols);
let m : DMatrix<f64> = DMatrix::new_random($nrows, $ncols);
let mut v : DVector<f64> = DVector::new_random($ncols);
for _ in 0usize .. 1000 {
// XXX: the clone here is highly undesirable!
@ -66,25 +66,25 @@ macro_rules! bench_mul_dmat_dvec(
#[bench]
fn bench_mul_dmat_dvec2(bh: &mut Bencher) {
bench_mul_dmat_dvec!(bh, 2, 2);
bench_mul_dmat_dvector!(bh, 2, 2);
}
#[bench]
fn bench_mul_dmat_dvec3(bh: &mut Bencher) {
bench_mul_dmat_dvec!(bh, 3, 3);
bench_mul_dmat_dvector!(bh, 3, 3);
}
#[bench]
fn bench_mul_dmat_dvec4(bh: &mut Bencher) {
bench_mul_dmat_dvec!(bh, 4, 4);
bench_mul_dmat_dvector!(bh, 4, 4);
}
#[bench]
fn bench_mul_dmat_dvec5(bh: &mut Bencher) {
bench_mul_dmat_dvec!(bh, 5, 5);
bench_mul_dmat_dvector!(bh, 5, 5);
}
#[bench]
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 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};
#[path="common/macros.rs"]
mod macros;
bench_binop!(_bench_mat2_mul_m, Mat2<f32>, Mat2<f32>, mul);
bench_binop!(_bench_mat3_mul_m, Mat3<f32>, Mat3<f32>, mul);
bench_binop!(_bench_mat4_mul_m, Mat4<f32>, Mat4<f32>, mul);
bench_binop!(_bench_mat2_mul_m, Matrix2<f32>, Matrix2<f32>, mul);
bench_binop!(_bench_mat3_mul_m, Matrix3<f32>, Matrix3<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_mat3_add_m, Mat3<f32>, Mat3<f32>, add);
bench_binop!(_bench_mat4_add_m, Mat4<f32>, Mat4<f32>, add);
bench_binop!(_bench_mat2_add_m, Matrix2<f32>, Matrix2<f32>, add);
bench_binop!(_bench_mat3_add_m, Matrix3<f32>, Matrix3<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_mat3_sub_m, Mat3<f32>, Mat3<f32>, sub);
bench_binop!(_bench_mat4_sub_m, Mat4<f32>, Mat4<f32>, sub);
bench_binop!(_bench_mat2_sub_m, Matrix2<f32>, Matrix2<f32>, sub);
bench_binop!(_bench_mat3_sub_m, Matrix3<f32>, Matrix3<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_mat3_mul_v, Mat3<f32>, Vec3<f32>, mul);
bench_binop!(_bench_mat4_mul_v, Mat4<f32>, Vec4<f32>, mul);
bench_binop!(_bench_mat2_mul_v, Matrix2<f32>, Vector2<f32>, mul);
bench_binop!(_bench_mat3_mul_v, Matrix3<f32>, Vector3<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_mat3_mul_s, Mat3<f32>, f32, mul);
bench_binop!(_bench_mat4_mul_s, Mat4<f32>, f32, mul);
bench_binop!(_bench_mat2_mul_s, Matrix2<f32>, f32, mul);
bench_binop!(_bench_mat3_mul_s, Matrix3<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_mat3_div_s, Mat3<f32>, f32, div);
bench_binop!(_bench_mat4_div_s, Mat4<f32>, f32, div);
bench_binop!(_bench_mat2_div_s, Matrix2<f32>, f32, div);
bench_binop!(_bench_mat3_div_s, Matrix3<f32>, f32, div);
bench_binop!(_bench_mat4_div_s, Matrix4<f32>, f32, div);
bench_unop!(_bench_mat2_inv, Mat2<f32>, inv);
bench_unop!(_bench_mat3_inv, Mat3<f32>, inv);
bench_unop!(_bench_mat4_inv, Mat4<f32>, inv);
bench_unop!(_bench_mat2_inv, Matrix2<f32>, inverse);
bench_unop!(_bench_mat3_inv, Matrix3<f32>, inverse);
bench_unop!(_bench_mat4_inv, Matrix4<f32>, inverse);
bench_unop!(_bench_mat2_transpose, Mat2<f32>, transpose);
bench_unop!(_bench_mat3_transpose, Mat3<f32>, transpose);
bench_unop!(_bench_mat4_transpose, Mat4<f32>, transpose);
bench_unop!(_bench_mat2_transpose, Matrix2<f32>, transpose);
bench_unop!(_bench_mat3_transpose, Matrix3<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 test::Bencher;
use na::{Quat, UnitQuat, Vec3};
use na::{Quaternion, UnitQuaternion, Vector3};
use std::ops::{Add, Sub, Mul, Div};
#[path="common/macros.rs"]
mod macros;
bench_binop!(_bench_quat_add_q, Quat<f32>, Quat<f32>, add);
bench_binop!(_bench_quat_sub_q, Quat<f32>, Quat<f32>, sub);
bench_binop!(_bench_quat_mul_q, Quat<f32>, Quat<f32>, mul);
// bench_binop!(_bench_quat_div_q, Quat<f32>, Quat<f32>, div)
bench_binop!(_bench_quat_mul_v, UnitQuat<f32>, Vec3<f32>, mul);
bench_binop!(_bench_quat_mul_s, Quat<f32>, f32, mul);
bench_binop!(_bench_quat_div_s, Quat<f32>, f32, div);
bench_unop!(_bench_quat_inv, Quat<f32>, inv);
bench_unop_self!(_bench_quat_conjugate, Quat<f32>, conjugate);
bench_unop!(_bench_quat_normalize, Quat<f32>, normalize);
bench_binop!(_bench_quaternion_add_q, Quaternion<f32>, Quaternion<f32>, add);
bench_binop!(_bench_quaternion_sub_q, Quaternion<f32>, Quaternion<f32>, sub);
bench_binop!(_bench_quaternion_mul_q, Quaternion<f32>, Quaternion<f32>, mul);
// bench_binop!(_bench_quaternion_div_q, Quaternion<f32>, Quaternion<f32>, div)
bench_binop!(_bench_quaternion_mul_v, UnitQuaternion<f32>, Vector3<f32>, mul);
bench_binop!(_bench_quaternion_mul_s, Quaternion<f32>, f32, mul);
bench_binop!(_bench_quaternion_div_s, Quaternion<f32>, f32, div);
bench_unop!(_bench_quaternion_inv, Quaternion<f32>, inverse);
bench_unop_self!(_bench_quaternion_conjugate, Quaternion<f32>, conjugate);
bench_unop!(_bench_quaternion_normalize, Quaternion<f32>, normalize);

View File

@ -9,104 +9,104 @@ extern crate nalgebra as na;
use rand::{IsaacRng, Rng};
use test::Bencher;
use na::{Vec2, Vec3, Vec4};
use na::{Vector2, Vector3, Vector4};
use std::ops::{Add, Sub, Mul, Div};
#[path="common/macros.rs"]
mod macros;
bench_binop!(_bench_vec2_add_v, Vec2<f32>, Vec2<f32>, add);
bench_binop!(_bench_vec3_add_v, Vec3<f32>, Vec3<f32>, add);
bench_binop!(_bench_vec4_add_v, Vec4<f32>, Vec4<f32>, add);
bench_binop!(_bench_vec2_add_v, Vector2<f32>, Vector2<f32>, add);
bench_binop!(_bench_vec3_add_v, Vector3<f32>, Vector3<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_vec3_sub_v, Vec3<f32>, Vec3<f32>, sub);
bench_binop!(_bench_vec4_sub_v, Vec4<f32>, Vec4<f32>, sub);
bench_binop!(_bench_vec2_sub_v, Vector2<f32>, Vector2<f32>, sub);
bench_binop!(_bench_vec3_sub_v, Vector3<f32>, Vector3<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_vec3_mul_v, Vec3<f32>, Vec3<f32>, mul);
bench_binop!(_bench_vec4_mul_v, Vec4<f32>, Vec4<f32>, mul);
bench_binop!(_bench_vec2_mul_v, Vector2<f32>, Vector2<f32>, mul);
bench_binop!(_bench_vec3_mul_v, Vector3<f32>, Vector3<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_vec3_div_v, Vec3<f32>, Vec3<f32>, div);
bench_binop!(_bench_vec4_div_v, Vec4<f32>, Vec4<f32>, div);
bench_binop!(_bench_vec2_div_v, Vector2<f32>, Vector2<f32>, div);
bench_binop!(_bench_vec3_div_v, Vector3<f32>, Vector3<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_vec3_add_s, Vec3<f32>, f32, add);
bench_binop!(_bench_vec4_add_s, Vec4<f32>, f32, add);
bench_binop!(_bench_vec2_add_s, Vector2<f32>, f32, add);
bench_binop!(_bench_vec3_add_s, Vector3<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_vec3_sub_s, Vec3<f32>, f32, sub);
bench_binop!(_bench_vec4_sub_s, Vec4<f32>, f32, sub);
bench_binop!(_bench_vec2_sub_s, Vector2<f32>, f32, sub);
bench_binop!(_bench_vec3_sub_s, Vector3<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_vec3_mul_s, Vec3<f32>, f32, mul);
bench_binop!(_bench_vec4_mul_s, Vec4<f32>, f32, mul);
bench_binop!(_bench_vec2_mul_s, Vector2<f32>, f32, mul);
bench_binop!(_bench_vec3_mul_s, Vector3<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_vec3_div_s, Vec3<f32>, f32, div);
bench_binop!(_bench_vec4_div_s, Vec4<f32>, f32, div);
bench_binop!(_bench_vec2_div_s, Vector2<f32>, f32, div);
bench_binop!(_bench_vec3_div_s, Vector3<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_vec3_dot, Vec3<f32>, Vec3<f32>, dot);
bench_binop_na!(_bench_vec4_dot, Vec4<f32>, Vec4<f32>, dot);
bench_binop_na!(_bench_vec2_dot, Vector2<f32>, Vector2<f32>, dot);
bench_binop_na!(_bench_vec3_dot, Vector3<f32>, Vector3<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_vec3_norm, Vec3<f32>, norm);
bench_unop!(_bench_vec4_norm, Vec4<f32>, norm);
bench_unop!(_bench_vec2_norm, Vector2<f32>, norm);
bench_unop!(_bench_vec3_norm, Vector3<f32>, norm);
bench_unop!(_bench_vec4_norm, Vector4<f32>, norm);
bench_unop!(_bench_vec2_normalize, Vec2<f32>, normalize);
bench_unop!(_bench_vec3_normalize, Vec3<f32>, normalize);
bench_unop!(_bench_vec4_normalize, Vec4<f32>, normalize);
bench_unop!(_bench_vec2_normalize, Vector2<f32>, normalize);
bench_unop!(_bench_vec3_normalize, Vector3<f32>, normalize);
bench_unop!(_bench_vec4_normalize, Vector4<f32>, normalize);
#[cfg(feature = "generic_sizes")]
mod bench_vecn {
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_vecn3_add_v, VecN<f32, U3>, VecN<f32, U3>, add);
bench_binop!(_bench_vecn4_add_v, VecN<f32, U4>, VecN<f32, U4>, add);
bench_binop!(_bench_vecn2_add_v, VectorN<f32, U2>, VectorN<f32, U2>, add);
bench_binop!(_bench_vecn3_add_v, VectorN<f32, U3>, VectorN<f32, U3>, 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_vecn3_sub_v, VecN<f32, U3>, VecN<f32, U3>, sub);
bench_binop!(_bench_vecn4_sub_v, VecN<f32, U4>, VecN<f32, U4>, sub);
bench_binop!(_bench_vecn2_sub_v, VectorN<f32, U2>, VectorN<f32, U2>, sub);
bench_binop!(_bench_vecn3_sub_v, VectorN<f32, U3>, VectorN<f32, U3>, 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_vecn3_mul_v, VecN<f32, U3>, VecN<f32, U3>, mul);
bench_binop!(_bench_vecn4_mul_v, VecN<f32, U4>, VecN<f32, U4>, mul);
bench_binop!(_bench_vecn2_mul_v, VectorN<f32, U2>, VectorN<f32, U2>, mul);
bench_binop!(_bench_vecn3_mul_v, VectorN<f32, U3>, VectorN<f32, U3>, 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_vecn3_div_v, VecN<f32, U3>, VecN<f32, U3>, div);
bench_binop!(_bench_vecn4_div_v, VecN<f32, U4>, VecN<f32, U4>, div);
bench_binop!(_bench_vecn2_div_v, VectorN<f32, U2>, VectorN<f32, U2>, div);
bench_binop!(_bench_vecn3_div_v, VectorN<f32, U3>, VectorN<f32, U3>, 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_vecn3_add_s, VecN<f32, U3>, f32, add);
bench_binop!(_bench_vecn4_add_s, VecN<f32, U4>, f32, add);
bench_binop!(_bench_vecn2_add_s, VectorN<f32, U2>, f32, add);
bench_binop!(_bench_vecn3_add_s, VectorN<f32, U3>, 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_vecn3_sub_s, VecN<f32, U3>, f32, sub);
bench_binop!(_bench_vecn4_sub_s, VecN<f32, U4>, f32, sub);
bench_binop!(_bench_vecn2_sub_s, VectorN<f32, U2>, f32, sub);
bench_binop!(_bench_vecn3_sub_s, VectorN<f32, U3>, 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_vecn3_mul_s, VecN<f32, U3>, f32, mul);
bench_binop!(_bench_vecn4_mul_s, VecN<f32, U4>, f32, mul);
bench_binop!(_bench_vecn2_mul_s, VectorN<f32, U2>, f32, mul);
bench_binop!(_bench_vecn3_mul_s, VectorN<f32, U3>, 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_vecn3_div_s, VecN<f32, U3>, f32, div);
bench_binop!(_bench_vecn4_div_s, VecN<f32, U4>, f32, div);
bench_binop!(_bench_vecn2_div_s, VectorN<f32, U2>, f32, div);
bench_binop!(_bench_vecn3_div_s, VectorN<f32, U3>, 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_vecn3_dot, VecN<f32, U3>, VecN<f32, U3>, dot);
bench_binop_na!(_bench_vecn4_dot, VecN<f32, U4>, VecN<f32, U4>, dot);
bench_binop_na!(_bench_vecn2_dot, VectorN<f32, U2>, VectorN<f32, U2>, dot);
bench_binop_na!(_bench_vecn3_dot, VectorN<f32, U3>, VectorN<f32, U3>, 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_vecn3_norm, VecN<f32, U3>, norm);
bench_unop!(_bench_vecn4_norm, VecN<f32, U4>, norm);
bench_unop!(_bench_vecn2_norm, VectorN<f32, U2>, norm);
bench_unop!(_bench_vecn3_norm, VectorN<f32, U3>, norm);
bench_unop!(_bench_vecn4_norm, VectorN<f32, U4>, norm);
bench_unop!(_bench_vecn2_normalize, VecN<f32, U2>, normalize);
bench_unop!(_bench_vecn3_normalize, VecN<f32, U3>, normalize);
bench_unop!(_bench_vecn4_normalize, VecN<f32, U4>, normalize);
bench_unop!(_bench_vecn2_normalize, VectorN<f32, U2>, normalize);
bench_unop!(_bench_vecn3_normalize, VectorN<f32, U3>, 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
out-of-place operations.
* You can import the whole prelude using:
Thus, you can import the whole prelude using:
```.ignore
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:
```.rust
extern crate nalgebra as na;
use na::{Vec3, Rot3, Rotation};
use na::{Vector3, Rotation3, Rotation};
fn main() {
let a = Vec3::new(1.0f64, 1.0, 1.0);
let mut b = Rot3::new(na::zero());
let a = Vector3::new(1.0f64, 1.0, 1.0);
let mut b = Rotation3::new(na::zero());
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
an optimized set of tools for computer graphics and physics. Those features include:
* Vectors with predefined static sizes: `Vec1`, `Vec2`, `Vec3`, `Vec4`, `Vec5`, `Vec6`.
* Vector with a user-defined static size: `VecN` (available only with the `generic_sizes` feature).
* Points with static sizes: `Pnt1`, `Pnt2`, `Pnt3`, `Pnt4`, `Pnt5`, `Pnt6`.
* Square matrices with static sizes: `Mat1`, `Mat2`, `Mat3`, `Mat4`, `Mat5`, `Mat6 `.
* Rotation matrices: `Rot2`, `Rot3`
* Quaternions: `Quat`, `UnitQuat`.
* Isometries (translation rotation): `Iso2`, `Iso3`
* Similarity transformations (translation rotation uniform scale): `Sim2`, `Sim3`.
* 3D projections for computer graphics: `Persp3`, `PerspMat3`, `Ortho3`, `OrthoMat3`.
* Dynamically sized heap-allocated vector: `DVec`.
* Dynamically sized stack-allocated vectors with a maximum size: `DVec1` to `DVec6`.
* Dynamically sized heap-allocated (square or rectangular) matrix: `DMat`.
* Linear algebra and data analysis operators: `Cov`, `Mean`, `qr`, `cholesky`.
* Vectors with predefined static sizes: `Vector1`, `Vector2`, `Vector3`, `Vector4`, `Vector5`, `Vector6`.
* Vector with a user-defined static size: `VectorN` (available only with the `generic_sizes` feature).
* Points with static sizes: `Point1`, `Point2`, `Point3`, `Point4`, `Point5`, `Point6`.
* Square matrices with static sizes: `Matrix1`, `Matrix2`, `Matrix3`, `Matrix4`, `Matrix5`, `Matrix6 `.
* Rotation matrices: `Rotation2`, `Rotation3`
* Quaternions: `Quaternion`, `UnitQuaternion`.
* Isometrymetries (translation rotation): `Isometry2`, `Isometry3`
* Similarity transformations (translation rotation uniform scale): `Similarity2`, `Similarity3`.
* 3D projections for computer graphics: `Perspective3`, `PerspectiveMatrix3`, `Orthographic3`, `OrthographicMatrix3`.
* Dynamically sized heap-allocated vector: `DVector`.
* Dynamically sized stack-allocated vectors with a maximum size: `DVector1` to `DVector6`.
* Dynamically sized heap-allocated (square or rectangular) matrix: `DMatrix`.
* Linear algebra and data analysis operators: `Covariance`, `Mean`, `qr`, `cholesky`.
* Almost one trait per functionality: useful for generic programming.
@ -98,39 +98,39 @@ pub use traits::{
BaseNum,
Bounded,
Cast,
Col,
ColSlice, RowSlice,
Cov,
Column,
ColumnSlice, RowSlice,
Covariance,
Cross,
CrossMatrix,
Det,
Diag,
Dim,
Determinant,
Diagonal,
Dimension,
Dot,
EigenQR,
Eye,
FloatPnt,
FloatVec,
FloatPoint,
FloatVector,
FromHomogeneous,
Indexable,
Inv,
Inverse,
Iterable,
IterableMut,
Mat,
Matrix,
Mean,
Norm,
NumPnt,
NumVec,
Orig,
NumPoint,
NumVector,
Origin,
Outer,
POrd,
POrdering,
PntAsVec,
PartialOrder,
PartialOrdering,
PointAsVector,
Repeat,
Rotate, Rotation, RotationMatrix, RotationWithTranslation, RotationTo,
Row,
Shape,
SquareMat,
SquareMatrix,
ToHomogeneous,
Transform, Transformation,
Translate, Translation,
@ -139,22 +139,22 @@ pub use traits::{
};
#[cfg(feature="generic_sizes")]
pub use structs::VecN;
pub use structs::VectorN;
pub use structs::{
Identity,
DMat, DMat1, DMat2, DMat3, DMat4, DMat5, DMat6,
DVec, DVec1, DVec2, DVec3, DVec4, DVec5, DVec6,
Iso2, Iso3,
Sim2, Sim3,
Mat1, Mat2, Mat3, Mat4,
Mat5, Mat6,
Rot2, Rot3,
Vec1, Vec2, Vec3, Vec4, Vec5, Vec6,
Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6,
Persp3, PerspMat3,
Ortho3, OrthoMat3,
Quat, UnitQuat
DMatrix, DMatrix1, DMatrix2, DMatrix3, DMatrix4, DMatrix5, DMatrix6,
DVector, DVector1, DVector2, DVector3, DVector4, DVector5, DVector6,
Isometry2, Isometry3,
Similarity2, Similarity3,
Matrix1, Matrix2, Matrix3, Matrix4,
Matrix5, Matrix6,
Rotation2, Rotation3,
Vector1, Vector2, Vector3, Vector4, Vector5, Vector6,
Point1, Point2, Point3, Point4, Point5, Point6,
Perspective3, PerspectiveMatrix3,
Orthographic3, OrthographicMatrix3,
Quaternion, UnitQuaternion
};
pub use linalg::{
@ -202,63 +202,63 @@ pub fn min<T: Ord>(a: T, b: T) -> T {
/// Returns the infimum of `a` and `b`.
#[inline(always)]
pub fn inf<T: POrd>(a: &T, b: &T) -> T {
POrd::inf(a, b)
pub fn inf<T: PartialOrder>(a: &T, b: &T) -> T {
PartialOrder::inf(a, b)
}
/// Returns the supremum of `a` and `b`.
#[inline(always)]
pub fn sup<T: POrd>(a: &T, b: &T) -> T {
POrd::sup(a, b)
pub fn sup<T: PartialOrder>(a: &T, b: &T) -> T {
PartialOrder::sup(a, b)
}
/// Compare `a` and `b` using a partial ordering relation.
#[inline(always)]
pub fn partial_cmp<T: POrd>(a: &T, b: &T) -> POrdering {
POrd::partial_cmp(a, b)
pub fn partial_cmp<T: PartialOrder>(a: &T, b: &T) -> PartialOrdering {
PartialOrder::partial_cmp(a, b)
}
/// Returns `true` iff `a` and `b` are comparable and `a < b`.
#[inline(always)]
pub fn partial_lt<T: POrd>(a: &T, b: &T) -> bool {
POrd::partial_lt(a, b)
pub fn partial_lt<T: PartialOrder>(a: &T, b: &T) -> bool {
PartialOrder::partial_lt(a, b)
}
/// Returns `true` iff `a` and `b` are comparable and `a <= b`.
#[inline(always)]
pub fn partial_le<T: POrd>(a: &T, b: &T) -> bool {
POrd::partial_le(a, b)
pub fn partial_le<T: PartialOrder>(a: &T, b: &T) -> bool {
PartialOrder::partial_le(a, b)
}
/// Returns `true` iff `a` and `b` are comparable and `a > b`.
#[inline(always)]
pub fn partial_gt<T: POrd>(a: &T, b: &T) -> bool {
POrd::partial_gt(a, b)
pub fn partial_gt<T: PartialOrder>(a: &T, b: &T) -> bool {
PartialOrder::partial_gt(a, b)
}
/// Returns `true` iff `a` and `b` are comparable and `a >= b`.
#[inline(always)]
pub fn partial_ge<T: POrd>(a: &T, b: &T) -> bool {
POrd::partial_ge(a, b)
pub fn partial_ge<T: PartialOrder>(a: &T, b: &T) -> bool {
PartialOrder::partial_ge(a, b)
}
/// Return the minimum of `a` and `b` if they are comparable.
#[inline(always)]
pub fn partial_min<'a, T: POrd>(a: &'a T, b: &'a T) -> Option<&'a T> {
POrd::partial_min(a, b)
pub fn partial_min<'a, T: PartialOrder>(a: &'a T, b: &'a T) -> Option<&'a T> {
PartialOrder::partial_min(a, b)
}
/// Return the maximum of `a` and `b` if they are comparable.
#[inline(always)]
pub fn partial_max<'a, T: POrd>(a: &'a T, b: &'a T) -> Option<&'a T> {
POrd::partial_max(a, b)
pub fn partial_max<'a, T: PartialOrder>(a: &'a T, b: &'a T) -> Option<&'a T> {
PartialOrder::partial_max(a, b)
}
/// Clamp `value` between `min` and `max`. Returns `None` if `value` is not comparable to
/// `min` or `max`.
#[inline(always)]
pub fn partial_clamp<'a, T: POrd>(value: &'a T, min: &'a T, max: &'a T) -> Option<&'a T> {
POrd::partial_clamp(value, min, max)
pub fn partial_clamp<'a, T: PartialOrder>(value: &'a T, min: &'a T, max: &'a T) -> Option<&'a T> {
PartialOrder::partial_clamp(value, min, max)
}
//
@ -305,34 +305,34 @@ pub fn one<T: One>() -> T {
/// Returns the trivial origin of an affine space.
#[inline(always)]
pub fn orig<P: Orig>() -> P {
Orig::orig()
pub fn origin<P: Origin>() -> P {
Origin::origin()
}
/// Returns the center of two points.
#[inline]
pub fn center<N: BaseFloat, P: FloatPnt<N>>(a: &P, b: &P) -> P
where <P as PntAsVec>::Vec: Norm<N>
pub fn center<N: BaseFloat, P: FloatPoint<N>>(a: &P, b: &P) -> P
where <P as PointAsVector>::Vector: Norm<N>
{
let _2 = one::<N>() + one();
(*a + b.to_vec()) / _2
(*a + b.to_vector()) / _2
}
/*
* FloatPnt
* FloatPoint
*/
/// Returns the distance between two points.
#[inline(always)]
pub fn dist<N: BaseFloat, P: FloatPnt<N>>(a: &P, b: &P) -> N where <P as PntAsVec>::Vec: Norm<N> {
a.dist(b)
pub fn distance<N: BaseFloat, P: FloatPoint<N>>(a: &P, b: &P) -> N where <P as PointAsVector>::Vector: Norm<N> {
a.distance(b)
}
/// Returns the squared distance between two points.
#[inline(always)]
pub fn sqdist<N: BaseFloat, P: FloatPnt<N>>(a: &P, b: &P) -> N
where <P as PntAsVec>::Vec: Norm<N>
pub fn distance_squared<N: BaseFloat, P: FloatPoint<N>>(a: &P, b: &P) -> 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
/// extern crate nalgebra as na;
/// use na::{Vec3, Iso3};
/// use na::{Vector3, Isometry3};
///
/// 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);
///
/// assert!(trans == Vec3::new(1.0, 1.0, 1.0));
/// assert!(trans == Vector3::new(1.0, 1.0, 1.0));
/// }
/// ```
#[inline(always)]
@ -361,18 +361,18 @@ pub fn translation<V, M: Translation<V>>(m: &M) -> V {
///
/// ```rust
/// extern crate nalgebra as na;
/// use na::{Vec3, Iso3};
/// use na::{Vector3, Isometry3};
///
/// fn main() {
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
/// let itrans = na::inv_translation(&t);
/// let t = Isometry3::new(Vector3::new(1.0f64, 1.0, 1.0), na::zero());
/// 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)]
pub fn inv_translation<V, M: Translation<V>>(m: &M) -> V {
m.inv_translation()
pub fn inverse_translation<V, M: Translation<V>>(m: &M) -> V {
m.inverse_translation()
}
/// 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
/// extern crate nalgebra as na;
/// use na::{Pnt3, Vec3, Iso3};
/// use na::{Point3, Vector3, Isometry3};
///
/// fn main() {
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
/// let p = Pnt3::new(2.0, 2.0, 2.0);
/// let t = Isometry3::new(Vector3::new(1.0f64, 1.0, 1.0), na::zero());
/// let p = Point3::new(2.0, 2.0, 2.0);
///
/// 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)]
@ -409,19 +409,19 @@ pub fn translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
///
/// ```rust
/// extern crate nalgebra as na;
/// use na::{Pnt3, Vec3, Iso3};
/// use na::{Point3, Vector3, Isometry3};
///
/// fn main() {
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
/// let p = Pnt3::new(2.0, 2.0, 2.0);
/// let t = Isometry3::new(Vector3::new(1.0f64, 1.0, 1.0), na::zero());
/// 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)]
pub fn inv_translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
m.inv_translate(p)
pub fn inverse_translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
m.inverse_translate(p)
}
/*
@ -432,12 +432,12 @@ pub fn inv_translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
///
/// ```rust
/// extern crate nalgebra as na;
/// use na::{Vec3, Rot3};
/// use na::{Vector3, Rotation3};
///
/// 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)]
@ -450,17 +450,17 @@ pub fn rotation<V, M: Rotation<V>>(m: &M) -> V {
///
/// ```rust
/// extern crate nalgebra as na;
/// use na::{Vec3, Rot3};
/// use na::{Vector3, Rotation3};
///
/// 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)]
pub fn inv_rotation<V, M: Rotation<V>>(m: &M) -> V {
m.inv_rotation()
pub fn inverse_rotation<V, M: Rotation<V>>(m: &M) -> V {
m.inverse_rotation()
}
// FIXME: this example is a bit shity
@ -468,14 +468,14 @@ pub fn inv_rotation<V, M: Rotation<V>>(m: &M) -> V {
///
/// ```rust
/// extern crate nalgebra as na;
/// use na::{Vec3, Rot3};
/// use na::{Vector3, Rotation3};
///
/// fn main() {
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.0));
/// let v = Vec3::new(1.0, 1.0, 1.0);
/// let t = Rotation3::new(Vector3::new(0.0f64, 0.0, 0.0));
/// let v = Vector3::new(1.0, 1.0, 1.0);
/// 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)]
@ -488,14 +488,14 @@ pub fn append_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
///
/// ```rust
/// extern crate nalgebra as na;
/// use na::{Vec3, Rot3};
/// use na::{Vector3, Rotation3};
///
/// fn main() {
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.0));
/// let v = Vec3::new(1.0, 1.0, 1.0);
/// let t = Rotation3::new(Vector3::new(0.0f64, 0.0, 0.0));
/// let v = Vector3::new(1.0, 1.0, 1.0);
/// 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)]
@ -511,15 +511,15 @@ pub fn prepend_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
///
/// ```rust
/// extern crate nalgebra as na;
/// use na::{BaseFloat, Rot3, Vec3};
/// use na::{BaseFloat, Rotation3, Vector3};
///
/// fn main() {
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.5 * <f64 as BaseFloat>::pi()));
/// let v = Vec3::new(1.0, 0.0, 0.0);
/// let t = Rotation3::new(Vector3::new(0.0f64, 0.0, 0.5 * <f64 as BaseFloat>::pi()));
/// let v = Vector3::new(1.0, 0.0, 0.0);
///
/// 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)]
@ -532,20 +532,20 @@ pub fn rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
///
/// ```rust
/// extern crate nalgebra as na;
/// use na::{BaseFloat, Rot3, Vec3};
/// use na::{BaseFloat, Rotation3, Vector3};
///
/// fn main() {
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.5 * <f64 as BaseFloat>::pi()));
/// let v = Vec3::new(1.0, 0.0, 0.0);
/// let t = Rotation3::new(Vector3::new(0.0f64, 0.0, 0.5 * <f64 as BaseFloat>::pi()));
/// 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)]
pub fn inv_rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
m.inv_rotate(v)
pub fn inverse_rotate<V, M: Rotate<V>>(m: &M, v: &V) -> 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`.
#[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>,
M: SquareMat<N, LV> + Rotation<AV> + Copy,
M: SquareMatrix<N, LV> + Rotation<AV> + Copy,
LV: Mul<M, Output = LV>
{
// 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`.
#[inline(always)]
pub fn inv_transformation<T, M: Transformation<T>>(m: &M) -> T {
m.inv_transformation()
pub fn inverse_transformation<T, M: Transformation<T>>(m: &M) -> T {
m.inverse_transformation()
}
/// 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.
#[inline(always)]
pub fn inv_transform<V, M: Transform<V>>(m: &M, v: &V) -> V {
m.inv_transform(v)
pub fn inverse_transform<V, M: Transform<V>>(m: &M, v: &V) -> 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.
#[inline(always)]
pub fn sqnorm<V: Norm<N>, N: BaseFloat>(v: &V) -> N {
Norm::sqnorm(v)
pub fn norm_squared<V: Norm<N>, N: BaseFloat>(v: &V) -> N {
Norm::norm_squared(v)
}
/// 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.
#[inline(always)]
pub fn det<M: Det<N>, N>(m: &M) -> N {
Det::det(m)
pub fn determinant<M: Determinant<N>, N>(m: &M) -> N {
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.
#[inline(always)]
pub fn inv<M: Inv>(m: &M) -> Option<M> {
Inv::inv(m)
pub fn inverse<M: Inverse>(m: &M) -> Option<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.
#[inline(always)]
pub fn cov<M: Cov<Res>, Res>(observations: &M) -> Res {
Cov::cov(observations)
pub fn covariance<M: Covariance<Res>, Res>(observations: &M) -> Res {
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
#[inline(always)]
pub fn new_identity<M: Eye>(dim: usize) -> M {
Eye::new_identity(dim)
pub fn new_identity<M: Eye>(dimension: usize) -> M {
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.
#[inline(always)]
pub fn diag<M: Diag<V>, V>(m: &M) -> V {
m.diag()
pub fn diagonal<M: Diagonal<V>, V>(m: &M) -> V {
m.diagonal()
}
/*
* Dim
* Dimension
*/
/// Gets the dimension an object lives in.
///
/// Same as `Dim::dim::(None::<V>)`.
/// Same as `Dimension::dimension::(None::<V>)`.
#[inline(always)]
pub fn dim<V: Dim>() -> usize {
Dim::dim(None::<V>)
pub fn dimension<V: Dimension>() -> usize {
Dimension::dimension(None::<V>)
}
/// 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.
/// 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)
/// * A cast to a type with more type-level invariants cannot be done (eg. a cast from Mat<f64> to
/// Rot3<f64> is not possible)
/// * A cast to a type with more type-level invariants cannot be done (eg. a cast from Matrix<f64> to
/// Rotation3<f64> is not possible)
/// * 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
/// 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::structure::{ColSlice, Eye, Indexable, Diag, SquareMat, BaseFloat, Cast};
use traits::structure::{ColumnSlice, Eye, Indexable, Diagonal, SquareMatrix, BaseFloat, Cast};
use traits::geometry::Norm;
use std::cmp;
use std::ops::{Mul, Add, Sub};
/// 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
/// * `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
/// * `vec` - the vector defining the reflection.
pub fn householder_matrix<N, V, M>(dim: usize, start: usize, vec: V) -> M
/// * `vector` - the vector defining the reflection.
pub fn householder_matrix<N, V, M>(dimension: usize, start: usize, vector: V) -> M
where N: BaseFloat,
M: Eye + Indexable<(usize, usize), N>,
V: Indexable<usize, N> {
let mut qk : M = Eye::new_identity(dim);
let subdim = vec.shape();
let mut qk : M = Eye::new_identity(dimension);
let subdim = vector.shape();
let stop = subdim + start;
assert!(dim >= stop);
assert!(dimension >= stop);
for j in start .. stop {
for i in start .. stop {
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));
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)
where N: BaseFloat,
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> {
let (rows, cols) = m.shape();
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,
V: Mul<M, Output = V>,
VS: Indexable<usize, N> + Norm<N>,
M: Indexable<(usize, usize), N> + SquareMat<N, V> + Add<M, Output = M> +
Sub<M, Output = M> + ColSlice<VS> +
M: Indexable<(usize, usize), N> + SquareMatrix<N, V> + Add<M, Output = M> +
Sub<M, Output = M> + ColumnSlice<VS> +
ApproxEq<N> + Copy {
let (mut eigenvectors, mut eigenvalues) = hessenberg(m);
// Allocate arrays for Givens rotation components
let mut c = Vec::<N>::with_capacity(::dim::<M>() - 1);
let mut s = Vec::<N>::with_capacity(::dim::<M>() - 1);
let mut c = Vec::<N>::with_capacity(::dimension::<M>() - 1);
let mut s = Vec::<N>::with_capacity(::dimension::<M>() - 1);
if ::dim::<M>() == 1 {
return (eigenvectors, eigenvalues.diag());
if ::dimension::<M>() == 1 {
return (eigenvectors, eigenvalues.diagonal());
}
unsafe {
c.set_len(::dim::<M>() - 1);
s.set_len(::dim::<M>() - 1);
c.set_len(::dimension::<M>() - 1);
s.set_len(::dimension::<M>() - 1);
}
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;
@ -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 trace = a + d;
let det = a * d - b * c;
let determinant = a * d - b * c;
let constquarter: N = Cast::from(0.25f64);
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 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
for k in 0 .. curdim {
for i in 0 .. ::dim::<M>() {
for i in 0 .. ::dimension::<M>() {
unsafe {
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
@ -265,8 +265,8 @@ pub fn cholesky<N, V, VS, M>(m: &M) -> Result<M, &'static str>
where N: BaseFloat,
V: Mul<M, Output = V>,
VS: Indexable<usize, N> + Norm<N>,
M: Indexable<(usize, usize), N> + SquareMat<N, V> + Add<M, Output = M> +
Sub<M, Output = M> + ColSlice<VS> +
M: Indexable<(usize, usize), N> + SquareMatrix<N, V> + Add<M, Output = M> +
Sub<M, Output = M> + ColumnSlice<VS> +
ApproxEq<N> + Copy {
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)
where N: BaseFloat,
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> {
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 rand::{self, Rand};
use num::{Zero, One};
use structs::dvec::{DVec, DVec1, DVec2, DVec3, DVec4, DVec5, DVec6};
use traits::operations::{ApproxEq, Inv, Transpose, Mean, Cov};
use traits::structure::{Cast, Col, ColSlice, Row, RowSlice, Diag, DiagMut, Eye, Indexable, Shape, BaseNum};
use structs::dvector::{DVector, DVector1, DVector2, DVector3, DVector4, DVector5, DVector6};
use traits::operations::{ApproxEq, Inverse, Transpose, Mean, Covariance};
use traits::structure::{Cast, Column, ColumnSlice, Row, RowSlice, Diagonal, DiagMut, Eye, Indexable, Shape, BaseNum};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
/// Matrix with dimensions unknown at compile-time.
#[derive(Eq, PartialEq, Clone)]
pub struct DMat<N> {
pub struct DMatrix<N> {
nrows: usize,
ncols: usize,
mij: Vec<N>
}
impl<N> DMat<N> {
impl<N> DMatrix<N> {
/// Creates an uninitialized matrix.
#[inline]
pub unsafe fn new_uninitialized(nrows: usize, ncols: usize) -> DMat<N> {
let mut vec = Vec::with_capacity(nrows * ncols);
vec.set_len(nrows * ncols);
pub unsafe fn new_uninitialized(nrows: usize, ncols: usize) -> DMatrix<N> {
let mut vector = Vec::with_capacity(nrows * ncols);
vector.set_len(nrows * ncols);
DMat {
DMatrix {
nrows: nrows,
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.
#[inline]
pub fn from_elem(nrows: usize, ncols: usize, val: N) -> DMat<N> {
DMat {
pub fn from_elem(nrows: usize, ncols: usize, val: N) -> DMatrix<N> {
DMatrix {
nrows: nrows,
ncols: ncols,
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.
/// 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.
///
/// The vector must have exactly `nrows * ncols` elements.
#[inline]
pub fn from_row_vec(nrows: usize, ncols: usize, vec: &[N]) -> DMat<N> {
DMat::from_row_iter(nrows, ncols, vec.to_vec())
pub fn from_row_vector(nrows: usize, ncols: usize, vector: &[N]) -> DMatrix<N> {
DMatrix::from_row_iter(nrows, ncols, vector.to_vec())
}
/// Builds a matrix filled with the components provided by a vector.
/// 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.
///
/// The vector must have exactly `nrows * ncols` elements.
#[inline]
pub fn from_col_vec(nrows: usize, ncols: usize, vec: &[N]) -> DMat<N> {
DMat::from_col_iter(nrows, ncols, vec.to_vec())
pub fn from_col_vector(nrows: usize, ncols: usize, vector: &[N]) -> DMatrix<N> {
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.
/// 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.
///
/// The source must have exactly `nrows * ncols` elements.
#[inline]
pub fn from_row_iter<I: IntoIterator<Item = N>>(nrows: usize, ncols: usize, param: I) -> DMat<N> {
let mut res = DMat::from_col_iter(ncols, nrows, param);
pub fn from_row_iter<I: IntoIterator<Item = N>>(nrows: usize, ncols: usize, param: I) -> DMatrix<N> {
let mut res = DMatrix::from_col_iter(ncols, nrows, param);
// we transpose because the buffer is row_major
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.
/// 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.
///
/// The source must have exactly `nrows * ncols` elements.
#[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();
assert!(nrows * ncols == mij.len(), "The ammount of data provided does not matches the matrix size.");
DMat {
DMatrix {
nrows: nrows,
ncols: ncols,
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.
#[inline(always)]
pub fn from_fn<F: FnMut(usize, usize) -> N>(nrows: usize, ncols: usize, mut f: F) -> DMat<N> {
DMat {
pub fn from_fn<F: FnMut(usize, usize) -> N>(nrows: usize, ncols: usize, mut f: F) -> DMatrix<N> {
DMatrix {
nrows: nrows,
ncols: ncols,
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).
/// The returned vector contains the matrix data in column-major order.
#[inline]
pub fn into_vec(self) -> Vec<N> {
pub fn into_vector(self) -> Vec<N> {
self.mij
}
}
dmat_impl!(DMat, DVec);
dmat_impl!(DMatrix, DVector);
/// A stack-allocated dynamically sized matrix with at most one row and column.
pub struct DMat1<N> {
pub struct DMatrix1<N> {
nrows: usize,
ncols: usize,
mij: [N; 1 * 1],
}
small_dmat_impl!(DMat1, DVec1, 1, 0);
small_dmat_from_impl!(DMat1, 1, ::zero());
small_dmat_impl!(DMatrix1, DVector1, 1, 0);
small_dmat_from_impl!(DMatrix1, 1, ::zero());
/// 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,
ncols: usize,
mij: [N; 2 * 2],
}
small_dmat_impl!(DMat2, DVec2, 2, 0, 1,
small_dmat_impl!(DMatrix2, DVector2, 2, 0, 1,
2, 3);
small_dmat_from_impl!(DMat2, 2, ::zero(), ::zero(),
small_dmat_from_impl!(DMatrix2, 2, ::zero(), ::zero(),
::zero(), ::zero());
/// 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,
ncols: usize,
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,
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());
/// 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,
ncols: usize,
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,
8, 9, 10, 11,
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());
/// 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,
ncols: usize,
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,
10, 11, 12, 13, 14,
15, 16, 17, 18, 19,
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(),
@ -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.
pub struct DMat6<N> {
pub struct DMatrix6<N> {
nrows: usize,
ncols: usize,
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,
12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29,
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(),

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_rules! iso_impl(
($t: ident, $submat: ident, $subvec: ident, $subrotvec: ident) => (
macro_rules! isometry_impl(
($t: ident, $submatrix: ident, $subvector: ident, $subrotvector: ident) => (
impl<N: BaseFloat> $t<N> {
/// Creates a new isometry from an axis-angle rotation, and a vector.
#[inline]
pub fn new(translation: $subvec<N>, rotation: $subrotvec<N>) -> $t<N> {
pub fn new(translation: $subvector<N>, rotation: $subrotvector<N>) -> $t<N> {
$t {
rotation: $submat::new(rotation),
rotation: $submatrix::new(rotation),
translation: translation
}
}
/// Creates a new isometry from a rotation matrix and a vector.
#[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 {
rotation: rotation,
translation: translation
@ -25,13 +25,13 @@ macro_rules! iso_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>
RotationMatrix<N, $tlv<N>, $tav<N>> for $t<N> {
type Output = $trot<N>;
type Output = $trotation<N>;
#[inline]
fn to_rot_mat(&self) -> $trot<N> {
fn to_rotation_matrix(&self) -> $trotation<N> {
self.rotation
}
}
@ -40,11 +40,11 @@ macro_rules! rotation_matrix_impl(
macro_rules! dim_impl(
($t: ident, $dim: expr) => (
impl<N> Dim for $t<N> {
($t: ident, $dimension: expr) => (
impl<N> Dimension for $t<N> {
#[inline]
fn dim(_: Option<$t<N>>) -> usize {
$dim
fn dimension(_: Option<$t<N>>) -> usize {
$dimension
}
}
)
@ -55,20 +55,20 @@ macro_rules! one_impl(
impl<N: BaseFloat> One for $t<N> {
#[inline]
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) => (
impl<N: BaseFloat> Mul<$t<N>> for $t<N> {
type Output = $t<N>;
#[inline]
fn mul(self, right: $t<N>) -> $t<N> {
$t::new_with_rotmat(
$t::new_with_rotation_matrix(
self.translation + self.rotation * right.translation,
self.rotation * right.rotation)
}
@ -84,38 +84,38 @@ macro_rules! iso_mul_iso_impl(
)
);
macro_rules! iso_mul_rot_impl(
($t: ident, $rot: ident) => (
impl<N: BaseFloat> Mul<$rot<N>> for $t<N> {
macro_rules! isometry_mul_rotation_impl(
($t: ident, $rotation: ident) => (
impl<N: BaseFloat> Mul<$rotation<N>> for $t<N> {
type Output = $t<N>;
#[inline]
fn mul(self, right: $rot<N>) -> $t<N> {
$t::new_with_rotmat(self.translation, self.rotation * right)
fn mul(self, right: $rotation<N>) -> $t<N> {
$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>;
#[inline]
fn mul(self, right: $t<N>) -> $t<N> {
$t::new_with_rotmat(
$t::new_with_rotation_matrix(
self * right.translation,
self * right.rotation)
}
}
impl<N: BaseFloat> MulAssign<$rot<N>> for $t<N> {
impl<N: BaseFloat> MulAssign<$rotation<N>> for $t<N> {
#[inline]
fn mul_assign(&mut self, right: $rot<N>) {
fn mul_assign(&mut self, right: $rotation<N>) {
self.rotation *= right
}
}
)
);
macro_rules! iso_mul_pnt_impl(
macro_rules! isometry_mul_point_impl(
($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$tv<N>> for $t<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) => (
impl<N: BaseNum> Mul<$tv<N>> for $t<N> {
type Output = $tv<N>;
@ -150,7 +150,7 @@ macro_rules! translation_impl(
}
#[inline]
fn inv_translation(&self) -> $tv<N> {
fn inverse_translation(&self) -> $tv<N> {
-self.translation
}
@ -161,7 +161,7 @@ macro_rules! translation_impl(
#[inline]
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]
@ -171,7 +171,7 @@ macro_rules! translation_impl(
#[inline]
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]
@ -191,7 +191,7 @@ macro_rules! translate_impl(
}
#[inline]
fn inv_translate(&self, v: &$tv<N>) -> $tv<N> {
fn inverse_translate(&self, v: &$tv<N>) -> $tv<N> {
*v - self.translation
}
}
@ -199,7 +199,7 @@ macro_rules! translate_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> {
#[inline]
fn rotation(&self) -> $tav<N> {
@ -207,43 +207,43 @@ macro_rules! rotation_impl(
}
#[inline]
fn inv_rotation(&self) -> $tav<N> {
self.rotation.inv_rotation()
fn inverse_rotation(&self) -> $tav<N> {
self.rotation.inverse_rotation()
}
#[inline]
fn append_rotation_mut(&mut self, rot: &$tav<N>) {
let delta = $trot::new(*rot);
fn append_rotation_mut(&mut self, rotation: &$tav<N>) {
let delta = $trotation::new(*rotation);
self.rotation = delta * self.rotation;
self.translation = delta * self.translation;
}
#[inline]
fn append_rotation(&self, rot: &$tav<N>) -> $t<N> {
let delta = $trot::new(*rot);
fn append_rotation(&self, rotation: &$tav<N>) -> $t<N> {
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]
fn prepend_rotation_mut(&mut self, rot: &$tav<N>) {
let delta = $trot::new(*rot);
fn prepend_rotation_mut(&mut self, rotation: &$tav<N>) {
let delta = $trotation::new(*rotation);
self.rotation = self.rotation * delta;
}
#[inline]
fn prepend_rotation(&self, rot: &$tav<N>) -> $t<N> {
let delta = $trot::new(*rot);
fn prepend_rotation(&self, rotation: &$tav<N>) -> $t<N> {
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]
fn set_rotation(&mut self, rot: $tav<N>) {
fn set_rotation(&mut self, rotation: $tav<N>) {
// 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]
fn inv_rotate(&self, v: &$tv<N>) -> $tv<N> {
self.rotation.inv_rotate(v)
fn inverse_rotate(&self, v: &$tv<N>) -> $tv<N> {
self.rotation.inverse_rotate(v)
}
}
)
@ -272,9 +272,9 @@ macro_rules! transformation_impl(
*self
}
fn inv_transformation(&self) -> $t<N> {
fn inverse_transformation(&self) -> $t<N> {
// inversion will never fails
Inv::inv(self).unwrap()
Inverse::inverse(self).unwrap()
}
fn append_transformation_mut(&mut self, t: &$t<N>) {
@ -309,28 +309,28 @@ macro_rules! transform_impl(
}
#[inline]
fn inv_transform(&self, p: &$tp<N>) -> $tp<N> {
self.rotation.inv_transform(&(*p - self.translation))
fn inverse_transform(&self, p: &$tp<N>) -> $tp<N> {
self.rotation.inverse_transform(&(*p - self.translation))
}
}
)
);
macro_rules! inv_impl(
macro_rules! inverse_impl(
($t: ident) => (
impl<N: BaseNum + Neg<Output = N>> Inv for $t<N> {
impl<N: BaseNum + Neg<Output = N>> Inverse for $t<N> {
#[inline]
fn inv_mut(&mut self) -> bool {
self.rotation.inv_mut();
fn inverse_mut(&mut self) -> bool {
self.rotation.inverse_mut();
self.translation = self.rotation * -self.translation;
// always succeed
true
}
#[inline]
fn inv(&self) -> Option<$t<N>> {
fn inverse(&self) -> Option<$t<N>> {
let mut res = *self;
res.inv_mut();
res.inverse_mut();
// always succeed
Some(res)
}
@ -345,9 +345,9 @@ macro_rules! to_homogeneous_impl(
let mut res = self.rotation.to_homogeneous();
// 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
}
@ -405,12 +405,12 @@ macro_rules! absolute_rotate_impl(
)
);
macro_rules! arbitrary_iso_impl(
macro_rules! arbitrary_isometry_impl(
($t: ident) => (
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for $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)
)
@ -419,7 +419,7 @@ macro_rules! arbitrary_iso_impl(
)
);
macro_rules! iso_display_impl(
macro_rules! isometry_display_impl(
($t: ident) => (
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@ -428,12 +428,12 @@ macro_rules! iso_display_impl(
if let Some(precision) = f.precision() {
try!(writeln!(f, "... translation: {:.*}", precision, self.translation));
try!(writeln!(f, "... rotation matrix:"));
try!(write!(f, "{:.*}", precision, *self.rotation.submat()));
try!(write!(f, "{:.*}", precision, *self.rotation.submatrix()));
}
else {
try!(writeln!(f, "... translation: {}", self.translation));
try!(writeln!(f, "... rotation matrix:"));
try!(write!(f, "{}", *self.rotation.submat()));
try!(write!(f, "{}", *self.rotation.submatrix()));
}
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.
@ -9,14 +9,14 @@ use std::slice::{Iter, IterMut};
use rand::{Rand, Rng};
use num::{Zero, One};
use traits::operations::ApproxEq;
use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6};
use structs::pnt::{Pnt1, Pnt4, Pnt5, Pnt6};
use structs::dvec::{DVec1, DVec2, DVec3, DVec4, DVec5, DVec6};
use structs::vector::{Vector1, Vector2, Vector3, Vector4, Vector5, Vector6};
use structs::point::{Point1, Point4, Point5, Point6};
use structs::dvector::{DVector1, DVector2, DVector3, DVector4, DVector5, DVector6};
use traits::structure::{Cast, Row, Col, Iterable, IterableMut, Dim, Indexable, Eye, ColSlice,
RowSlice, Diag, DiagMut, Shape, BaseFloat, BaseNum, Repeat};
use traits::operations::{Absolute, Transpose, Inv, Outer, EigenQR, Mean};
use traits::geometry::{ToHomogeneous, FromHomogeneous, Orig};
use traits::structure::{Cast, Row, Column, Iterable, IterableMut, Dimension, Indexable, Eye, ColumnSlice,
RowSlice, Diagonal, DiagMut, Shape, BaseFloat, BaseNum, Repeat};
use traits::operations::{Absolute, Transpose, Inverse, Outer, EigenQR, Mean};
use traits::geometry::{ToHomogeneous, FromHomogeneous, Origin};
use linalg;
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
@ -38,331 +38,331 @@ impl Identity {
/// Square matrix of dimension 1.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Mat1<N> {
pub struct Matrix1<N> {
pub m11: N
}
eye_impl!(Mat1, 1, m11);
eye_impl!(Matrix1, 1, m11);
mat_impl!(Mat1, m11);
repeat_impl!(Mat1, m11);
conversion_impl!(Mat1, 1);
mat_cast_impl!(Mat1, m11);
add_impl!(Mat1, m11);
sub_impl!(Mat1, m11);
scalar_add_impl!(Mat1, m11);
scalar_sub_impl!(Mat1, m11);
scalar_mul_impl!(Mat1, m11);
scalar_div_impl!(Mat1, m11);
absolute_impl!(Mat1, m11);
zero_impl!(Mat1, m11);
one_impl!(Mat1, ::one);
iterable_impl!(Mat1, 1);
iterable_mut_impl!(Mat1, 1);
at_fast_impl!(Mat1, 1);
dim_impl!(Mat1, 1);
indexable_impl!(Mat1, 1);
index_impl!(Mat1, 1);
mat_mul_mat_impl!(Mat1, 1);
mat_mul_vec_impl!(Mat1, Vec1, 1, ::zero);
vec_mul_mat_impl!(Mat1, Vec1, 1, ::zero);
mat_mul_pnt_impl!(Mat1, Pnt1, 1, Orig::orig);
pnt_mul_mat_impl!(Mat1, Pnt1, 1, Orig::orig);
// (specialized); inv_impl!(Mat1, 1);
transpose_impl!(Mat1, 1);
approx_eq_impl!(Mat1);
row_impl!(Mat1, Vec1, 1);
col_impl!(Mat1, Vec1, 1);
col_slice_impl!(Mat1, Vec1, DVec1, 1);
row_slice_impl!(Mat1, Vec1, DVec1, 1);
diag_impl!(Mat1, Vec1, 1);
to_homogeneous_impl!(Mat1, Mat2, 1, 2);
from_homogeneous_impl!(Mat1, Mat2, 1, 2);
outer_impl!(Vec1, Mat1);
eigen_qr_impl!(Mat1, Vec1);
arbitrary_impl!(Mat1, m11);
rand_impl!(Mat1, m11);
mean_impl!(Mat1, Vec1, 1);
mat_display_impl!(Mat1, 1);
mat_impl!(Matrix1, m11);
repeat_impl!(Matrix1, m11);
conversion_impl!(Matrix1, 1);
mat_cast_impl!(Matrix1, m11);
add_impl!(Matrix1, m11);
sub_impl!(Matrix1, m11);
scalar_add_impl!(Matrix1, m11);
scalar_sub_impl!(Matrix1, m11);
scalar_mul_impl!(Matrix1, m11);
scalar_div_impl!(Matrix1, m11);
absolute_impl!(Matrix1, m11);
zero_impl!(Matrix1, m11);
one_impl!(Matrix1, ::one);
iterable_impl!(Matrix1, 1);
iterable_mut_impl!(Matrix1, 1);
at_fast_impl!(Matrix1, 1);
dim_impl!(Matrix1, 1);
indexable_impl!(Matrix1, 1);
index_impl!(Matrix1, 1);
mat_mul_mat_impl!(Matrix1, 1);
mat_mul_vec_impl!(Matrix1, Vector1, 1, ::zero);
vec_mul_mat_impl!(Matrix1, Vector1, 1, ::zero);
mat_mul_point_impl!(Matrix1, Point1, 1, Origin::origin);
point_mul_mat_impl!(Matrix1, Point1, 1, Origin::origin);
// (specialized); inverse_impl!(Matrix1, 1);
transpose_impl!(Matrix1, 1);
approx_eq_impl!(Matrix1);
row_impl!(Matrix1, Vector1, 1);
col_impl!(Matrix1, Vector1, 1);
col_slice_impl!(Matrix1, Vector1, DVector1, 1);
row_slice_impl!(Matrix1, Vector1, DVector1, 1);
diag_impl!(Matrix1, Vector1, 1);
to_homogeneous_impl!(Matrix1, Matrix2, 1, 2);
from_homogeneous_impl!(Matrix1, Matrix2, 1, 2);
outer_impl!(Vector1, Matrix1);
eigen_qr_impl!(Matrix1, Vector1);
arbitrary_impl!(Matrix1, m11);
rand_impl!(Matrix1, m11);
mean_impl!(Matrix1, Vector1, 1);
mat_display_impl!(Matrix1, 1);
/// Square matrix of dimension 2.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Mat2<N> {
pub struct Matrix2<N> {
pub m11: N, pub m21: 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);
repeat_impl!(Mat2, m11, m12,
repeat_impl!(Matrix2, m11, m12,
m21, m22);
conversion_impl!(Mat2, 2);
mat_cast_impl!(Mat2, m11, m12,
conversion_impl!(Matrix2, 2);
mat_cast_impl!(Matrix2, m11, m12,
m21, m22);
add_impl!(Mat2, m11, m12, m21, m22);
sub_impl!(Mat2, m11, m12, m21, m22);
scalar_add_impl!(Mat2, m11, m12, m21, m22);
scalar_sub_impl!(Mat2, m11, m12, m21, m22);
scalar_mul_impl!(Mat2, m11, m12, m21, m22);
scalar_div_impl!(Mat2, m11, m12, m21, m22);
absolute_impl!(Mat2, m11, m12,
add_impl!(Matrix2, m11, m12, m21, m22);
sub_impl!(Matrix2, m11, m12, m21, m22);
scalar_add_impl!(Matrix2, m11, m12, m21, m22);
scalar_sub_impl!(Matrix2, m11, m12, m21, m22);
scalar_mul_impl!(Matrix2, m11, m12, m21, m22);
scalar_div_impl!(Matrix2, m11, m12, m21, m22);
absolute_impl!(Matrix2, m11, m12,
m21, m22);
zero_impl!(Mat2, m11, m12,
zero_impl!(Matrix2, m11, m12,
m21, m22);
one_impl!(Mat2, ::one, ::zero,
one_impl!(Matrix2, ::one, ::zero,
::zero, ::one);
iterable_impl!(Mat2, 2);
iterable_mut_impl!(Mat2, 2);
dim_impl!(Mat2, 2);
indexable_impl!(Mat2, 2);
index_impl!(Mat2, 2);
at_fast_impl!(Mat2, 2);
// (specialized); mul_impl!(Mat2, 2);
// (specialized); rmul_impl!(Mat2, Vec2, 2);
// (specialized); lmul_impl!(Mat2, Vec2, 2);
// (specialized); inv_impl!(Mat2, 2);
transpose_impl!(Mat2, 2);
approx_eq_impl!(Mat2);
row_impl!(Mat2, Vec2, 2);
col_impl!(Mat2, Vec2, 2);
col_slice_impl!(Mat2, Vec2, DVec2, 2);
row_slice_impl!(Mat2, Vec2, DVec2, 2);
diag_impl!(Mat2, Vec2, 2);
to_homogeneous_impl!(Mat2, Mat3, 2, 3);
from_homogeneous_impl!(Mat2, Mat3, 2, 3);
outer_impl!(Vec2, Mat2);
eigen_qr_impl!(Mat2, Vec2);
arbitrary_impl!(Mat2, m11, m12, m21, m22);
rand_impl!(Mat2, m11, m12, m21, m22);
mean_impl!(Mat2, Vec2, 2);
mat_display_impl!(Mat2, 2);
iterable_impl!(Matrix2, 2);
iterable_mut_impl!(Matrix2, 2);
dim_impl!(Matrix2, 2);
indexable_impl!(Matrix2, 2);
index_impl!(Matrix2, 2);
at_fast_impl!(Matrix2, 2);
// (specialized); mul_impl!(Matrix2, 2);
// (specialized); rmul_impl!(Matrix2, Vector2, 2);
// (specialized); lmul_impl!(Matrix2, Vector2, 2);
// (specialized); inverse_impl!(Matrix2, 2);
transpose_impl!(Matrix2, 2);
approx_eq_impl!(Matrix2);
row_impl!(Matrix2, Vector2, 2);
col_impl!(Matrix2, Vector2, 2);
col_slice_impl!(Matrix2, Vector2, DVector2, 2);
row_slice_impl!(Matrix2, Vector2, DVector2, 2);
diag_impl!(Matrix2, Vector2, 2);
to_homogeneous_impl!(Matrix2, Matrix3, 2, 3);
from_homogeneous_impl!(Matrix2, Matrix3, 2, 3);
outer_impl!(Vector2, Matrix2);
eigen_qr_impl!(Matrix2, Vector2);
arbitrary_impl!(Matrix2, m11, m12, m21, m22);
rand_impl!(Matrix2, m11, m12, m21, m22);
mean_impl!(Matrix2, Vector2, 2);
mat_display_impl!(Matrix2, 2);
/// Square matrix of dimension 3.
#[repr(C)]
#[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 m12: N, pub m22: N, pub m32: 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,
m31, m32, m33);
repeat_impl!(Mat3, m11, m12, m13,
repeat_impl!(Matrix3, m11, m12, m13,
m21, m22, m23,
m31, m32, m33);
conversion_impl!(Mat3, 3);
mat_cast_impl!(Mat3, m11, m12, m13,
conversion_impl!(Matrix3, 3);
mat_cast_impl!(Matrix3, m11, m12, m13,
m21, m22, m23,
m31, m32, m33);
add_impl!(Mat3,
add_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
sub_impl!(Mat3,
sub_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
scalar_add_impl!(Mat3,
scalar_add_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
scalar_sub_impl!(Mat3,
scalar_sub_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
scalar_mul_impl!(Mat3,
scalar_mul_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
scalar_div_impl!(Mat3,
scalar_div_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
absolute_impl!(Mat3,
absolute_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
zero_impl!(Mat3,
zero_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
one_impl!(Mat3, ::one , ::zero, ::zero,
one_impl!(Matrix3, ::one , ::zero, ::zero,
::zero, ::one , ::zero,
::zero, ::zero, ::one);
iterable_impl!(Mat3, 3);
iterable_mut_impl!(Mat3, 3);
dim_impl!(Mat3, 3);
indexable_impl!(Mat3, 3);
index_impl!(Mat3, 3);
at_fast_impl!(Mat3, 3);
// (specialized); mul_impl!(Mat3, 3);
// (specialized); rmul_impl!(Mat3, Vec3, 3);
// (specialized); lmul_impl!(Mat3, Vec3, 3);
// (specialized); inv_impl!(Mat3, 3);
transpose_impl!(Mat3, 3);
approx_eq_impl!(Mat3);
// (specialized); row_impl!(Mat3, Vec3, 3);
// (specialized); col_impl!(Mat3, Vec3, 3);
col_slice_impl!(Mat3, Vec3, DVec3, 3);
row_slice_impl!(Mat3, Vec3, DVec3, 3);
diag_impl!(Mat3, Vec3, 3);
to_homogeneous_impl!(Mat3, Mat4, 3, 4);
from_homogeneous_impl!(Mat3, Mat4, 3, 4);
outer_impl!(Vec3, Mat3);
eigen_qr_impl!(Mat3, Vec3);
arbitrary_impl!(Mat3,
iterable_impl!(Matrix3, 3);
iterable_mut_impl!(Matrix3, 3);
dim_impl!(Matrix3, 3);
indexable_impl!(Matrix3, 3);
index_impl!(Matrix3, 3);
at_fast_impl!(Matrix3, 3);
// (specialized); mul_impl!(Matrix3, 3);
// (specialized); rmul_impl!(Matrix3, Vector3, 3);
// (specialized); lmul_impl!(Matrix3, Vector3, 3);
// (specialized); inverse_impl!(Matrix3, 3);
transpose_impl!(Matrix3, 3);
approx_eq_impl!(Matrix3);
// (specialized); row_impl!(Matrix3, Vector3, 3);
// (specialized); col_impl!(Matrix3, Vector3, 3);
col_slice_impl!(Matrix3, Vector3, DVector3, 3);
row_slice_impl!(Matrix3, Vector3, DVector3, 3);
diag_impl!(Matrix3, Vector3, 3);
to_homogeneous_impl!(Matrix3, Matrix4, 3, 4);
from_homogeneous_impl!(Matrix3, Matrix4, 3, 4);
outer_impl!(Vector3, Matrix3);
eigen_qr_impl!(Matrix3, Vector3);
arbitrary_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
rand_impl!(Mat3,
rand_impl!(Matrix3,
m11, m12, m13,
m21, m22, m23,
m31, m32, m33
);
mean_impl!(Mat3, Vec3, 3);
mat_display_impl!(Mat3, 3);
mean_impl!(Matrix3, Vector3, 3);
mat_display_impl!(Matrix3, 3);
/// Square matrix of dimension 4.
#[repr(C)]
#[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 m12: N, pub m22: N, pub m32: N, pub m42: 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
}
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,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
repeat_impl!(Mat4,
repeat_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
conversion_impl!(Mat4, 4);
mat_cast_impl!(Mat4,
conversion_impl!(Matrix4, 4);
mat_cast_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
add_impl!(Mat4,
add_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
sub_impl!(Mat4,
sub_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
scalar_add_impl!(Mat4,
scalar_add_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
scalar_sub_impl!(Mat4,
scalar_sub_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
scalar_mul_impl!(Mat4,
scalar_mul_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
scalar_div_impl!(Mat4,
scalar_div_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
absolute_impl!(Mat4,
absolute_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
zero_impl!(Mat4,
zero_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
one_impl!(Mat4, ::one , ::zero, ::zero, ::zero,
one_impl!(Matrix4, ::one , ::zero, ::zero, ::zero,
::zero, ::one , ::zero, ::zero,
::zero, ::zero, ::one , ::zero,
::zero, ::zero, ::zero, ::one);
iterable_impl!(Mat4, 4);
iterable_mut_impl!(Mat4, 4);
dim_impl!(Mat4, 4);
indexable_impl!(Mat4, 4);
index_impl!(Mat4, 4);
at_fast_impl!(Mat4, 4);
mat_mul_mat_impl!(Mat4, 4);
mat_mul_vec_impl!(Mat4, Vec4, 4, ::zero);
vec_mul_mat_impl!(Mat4, Vec4, 4, ::zero);
mat_mul_pnt_impl!(Mat4, Pnt4, 4, Orig::orig);
pnt_mul_mat_impl!(Mat4, Pnt4, 4, Orig::orig);
inv_impl!(Mat4, 4);
transpose_impl!(Mat4, 4);
approx_eq_impl!(Mat4);
row_impl!(Mat4, Vec4, 4);
col_impl!(Mat4, Vec4, 4);
col_slice_impl!(Mat4, Vec4, DVec4, 4);
row_slice_impl!(Mat4, Vec4, DVec4, 4);
diag_impl!(Mat4, Vec4, 4);
to_homogeneous_impl!(Mat4, Mat5, 4, 5);
from_homogeneous_impl!(Mat4, Mat5, 4, 5);
outer_impl!(Vec4, Mat4);
eigen_qr_impl!(Mat4, Vec4);
arbitrary_impl!(Mat4,
iterable_impl!(Matrix4, 4);
iterable_mut_impl!(Matrix4, 4);
dim_impl!(Matrix4, 4);
indexable_impl!(Matrix4, 4);
index_impl!(Matrix4, 4);
at_fast_impl!(Matrix4, 4);
mat_mul_mat_impl!(Matrix4, 4);
mat_mul_vec_impl!(Matrix4, Vector4, 4, ::zero);
vec_mul_mat_impl!(Matrix4, Vector4, 4, ::zero);
mat_mul_point_impl!(Matrix4, Point4, 4, Origin::origin);
point_mul_mat_impl!(Matrix4, Point4, 4, Origin::origin);
inverse_impl!(Matrix4, 4);
transpose_impl!(Matrix4, 4);
approx_eq_impl!(Matrix4);
row_impl!(Matrix4, Vector4, 4);
col_impl!(Matrix4, Vector4, 4);
col_slice_impl!(Matrix4, Vector4, DVector4, 4);
row_slice_impl!(Matrix4, Vector4, DVector4, 4);
diag_impl!(Matrix4, Vector4, 4);
to_homogeneous_impl!(Matrix4, Matrix5, 4, 5);
from_homogeneous_impl!(Matrix4, Matrix5, 4, 5);
outer_impl!(Vector4, Matrix4);
eigen_qr_impl!(Matrix4, Vector4);
arbitrary_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
rand_impl!(Mat4,
rand_impl!(Matrix4,
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44
);
mean_impl!(Mat4, Vec4, 4);
mat_display_impl!(Mat4, 4);
mean_impl!(Matrix4, Vector4, 4);
mat_display_impl!(Matrix4, 4);
/// Square matrix of dimension 5.
#[repr(C)]
#[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 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,
@ -370,137 +370,137 @@ pub struct Mat5<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,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
repeat_impl!(Mat5,
repeat_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
conversion_impl!(Mat5, 5);
mat_cast_impl!(Mat5,
conversion_impl!(Matrix5, 5);
mat_cast_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
absolute_impl!(Mat5,
absolute_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
zero_impl!(Mat5,
zero_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
one_impl!(Mat5,
one_impl!(Matrix5,
::one , ::zero, ::zero, ::zero, ::zero,
::zero, ::one , ::zero, ::zero, ::zero,
::zero, ::zero, ::one , ::zero, ::zero,
::zero, ::zero, ::zero, ::one , ::zero,
::zero, ::zero, ::zero, ::zero, ::one
);
add_impl!(Mat5,
add_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
sub_impl!(Mat5,
sub_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
scalar_add_impl!(Mat5,
scalar_add_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
scalar_sub_impl!(Mat5,
scalar_sub_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
scalar_mul_impl!(Mat5,
scalar_mul_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
scalar_div_impl!(Mat5,
scalar_div_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
iterable_impl!(Mat5, 5);
iterable_mut_impl!(Mat5, 5);
dim_impl!(Mat5, 5);
indexable_impl!(Mat5, 5);
index_impl!(Mat5, 5);
at_fast_impl!(Mat5, 5);
mat_mul_mat_impl!(Mat5, 5);
mat_mul_vec_impl!(Mat5, Vec5, 5, ::zero);
vec_mul_mat_impl!(Mat5, Vec5, 5, ::zero);
mat_mul_pnt_impl!(Mat5, Pnt5, 5, Orig::orig);
pnt_mul_mat_impl!(Mat5, Pnt5, 5, Orig::orig);
inv_impl!(Mat5, 5);
transpose_impl!(Mat5, 5);
approx_eq_impl!(Mat5);
row_impl!(Mat5, Vec5, 5);
col_impl!(Mat5, Vec5, 5);
col_slice_impl!(Mat5, Vec5, DVec5, 5);
row_slice_impl!(Mat5, Vec5, DVec5, 5);
diag_impl!(Mat5, Vec5, 5);
to_homogeneous_impl!(Mat5, Mat6, 5, 6);
from_homogeneous_impl!(Mat5, Mat6, 5, 6);
outer_impl!(Vec5, Mat5);
eigen_qr_impl!(Mat5, Vec5);
arbitrary_impl!(Mat5,
iterable_impl!(Matrix5, 5);
iterable_mut_impl!(Matrix5, 5);
dim_impl!(Matrix5, 5);
indexable_impl!(Matrix5, 5);
index_impl!(Matrix5, 5);
at_fast_impl!(Matrix5, 5);
mat_mul_mat_impl!(Matrix5, 5);
mat_mul_vec_impl!(Matrix5, Vector5, 5, ::zero);
vec_mul_mat_impl!(Matrix5, Vector5, 5, ::zero);
mat_mul_point_impl!(Matrix5, Point5, 5, Origin::origin);
point_mul_mat_impl!(Matrix5, Point5, 5, Origin::origin);
inverse_impl!(Matrix5, 5);
transpose_impl!(Matrix5, 5);
approx_eq_impl!(Matrix5);
row_impl!(Matrix5, Vector5, 5);
col_impl!(Matrix5, Vector5, 5);
col_slice_impl!(Matrix5, Vector5, DVector5, 5);
row_slice_impl!(Matrix5, Vector5, DVector5, 5);
diag_impl!(Matrix5, Vector5, 5);
to_homogeneous_impl!(Matrix5, Matrix6, 5, 6);
from_homogeneous_impl!(Matrix5, Matrix6, 5, 6);
outer_impl!(Vector5, Matrix5);
eigen_qr_impl!(Matrix5, Vector5);
arbitrary_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
rand_impl!(Mat5,
rand_impl!(Matrix5,
m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25,
m31, m32, m33, m34, m35,
m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55
);
mean_impl!(Mat5, Vec5, 5);
mat_display_impl!(Mat5, 5);
mean_impl!(Matrix5, Vector5, 5);
mat_display_impl!(Matrix5, 5);
/// Square matrix of dimension 6.
#[repr(C)]
#[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 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,
@ -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
}
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,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
@ -519,7 +519,7 @@ mat_impl!(Mat6,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
repeat_impl!(Mat6,
repeat_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
@ -527,8 +527,8 @@ repeat_impl!(Mat6,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
conversion_impl!(Mat6, 6);
mat_cast_impl!(Mat6,
conversion_impl!(Matrix6, 6);
mat_cast_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
@ -536,7 +536,7 @@ mat_cast_impl!(Mat6,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
add_impl!(Mat6,
add_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
@ -544,7 +544,7 @@ add_impl!(Mat6,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
sub_impl!(Mat6,
sub_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
@ -552,7 +552,7 @@ sub_impl!(Mat6,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
scalar_add_impl!(Mat6,
scalar_add_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
@ -560,7 +560,7 @@ scalar_add_impl!(Mat6,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
scalar_sub_impl!(Mat6,
scalar_sub_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
@ -568,7 +568,7 @@ scalar_sub_impl!(Mat6,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
scalar_mul_impl!(Mat6,
scalar_mul_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
@ -576,7 +576,7 @@ scalar_mul_impl!(Mat6,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
scalar_div_impl!(Mat6,
scalar_div_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
@ -584,15 +584,15 @@ scalar_div_impl!(Mat6,
m51, m52, m53, m54, m55, m56,
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,
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,
m61, m62, m63, m64, m65, m66);
one_impl!(Mat6,
one_impl!(Matrix6,
::one , ::zero, ::zero, ::zero, ::zero, ::zero,
::zero, ::one , ::zero, ::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, ::zero, ::one
);
iterable_impl!(Mat6, 6);
iterable_mut_impl!(Mat6, 6);
dim_impl!(Mat6, 6);
indexable_impl!(Mat6, 6);
index_impl!(Mat6, 6);
at_fast_impl!(Mat6, 6);
mat_mul_mat_impl!(Mat6, 6);
mat_mul_vec_impl!(Mat6, Vec6, 6, ::zero);
vec_mul_mat_impl!(Mat6, Vec6, 6, ::zero);
mat_mul_pnt_impl!(Mat6, Pnt6, 6, Orig::orig);
pnt_mul_mat_impl!(Mat6, Pnt6, 6, Orig::orig);
inv_impl!(Mat6, 6);
transpose_impl!(Mat6, 6);
approx_eq_impl!(Mat6);
row_impl!(Mat6, Vec6, 6);
col_impl!(Mat6, Vec6, 6);
col_slice_impl!(Mat6, Vec6, DVec6, 6);
row_slice_impl!(Mat6, Vec6, DVec6, 6);
diag_impl!(Mat6, Vec6, 6);
outer_impl!(Vec6, Mat6);
eigen_qr_impl!(Mat6, Vec6);
arbitrary_impl!(Mat6,
iterable_impl!(Matrix6, 6);
iterable_mut_impl!(Matrix6, 6);
dim_impl!(Matrix6, 6);
indexable_impl!(Matrix6, 6);
index_impl!(Matrix6, 6);
at_fast_impl!(Matrix6, 6);
mat_mul_mat_impl!(Matrix6, 6);
mat_mul_vec_impl!(Matrix6, Vector6, 6, ::zero);
vec_mul_mat_impl!(Matrix6, Vector6, 6, ::zero);
mat_mul_point_impl!(Matrix6, Point6, 6, Origin::origin);
point_mul_mat_impl!(Matrix6, Point6, 6, Origin::origin);
inverse_impl!(Matrix6, 6);
transpose_impl!(Matrix6, 6);
approx_eq_impl!(Matrix6);
row_impl!(Matrix6, Vector6, 6);
col_impl!(Matrix6, Vector6, 6);
col_slice_impl!(Matrix6, Vector6, DVector6, 6);
row_slice_impl!(Matrix6, Vector6, DVector6, 6);
diag_impl!(Matrix6, Vector6, 6);
outer_impl!(Vector6, Matrix6);
eigen_qr_impl!(Matrix6, Vector6);
arbitrary_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
@ -629,7 +629,7 @@ arbitrary_impl!(Mat6,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
rand_impl!(Mat6,
rand_impl!(Matrix6,
m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26,
m31, m32, m33, m34, m35, m36,
@ -637,5 +637,5 @@ rand_impl!(Mat6,
m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66
);
mean_impl!(Mat6, Vec6, 6);
mat_display_impl!(Mat6, 6);
mean_impl!(Matrix6, Vector6, 6);
mat_display_impl!(Matrix6, 6);

View File

@ -14,37 +14,37 @@ macro_rules! mat_impl(
);
macro_rules! conversion_impl(
($t: ident, $dim: expr) => (
impl<N> AsRef<[[N; $dim]; $dim]> for $t<N> {
($t: ident, $dimension: expr) => (
impl<N> AsRef<[[N; $dimension]; $dimension]> for $t<N> {
#[inline]
fn as_ref(&self) -> &[[N; $dim]; $dim] {
fn as_ref(&self) -> &[[N; $dimension]; $dimension] {
unsafe {
mem::transmute(self)
}
}
}
impl<N> AsMut<[[N; $dim]; $dim]> for $t<N> {
impl<N> AsMut<[[N; $dimension]; $dimension]> for $t<N> {
#[inline]
fn as_mut(&mut self) -> &mut [[N; $dim]; $dim] {
fn as_mut(&mut self) -> &mut [[N; $dimension]; $dimension] {
unsafe {
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]
fn from(arr: &'a [[N; $dim]; $dim]) -> &'a $t<N> {
fn from(arr: &'a [[N; $dimension]; $dimension]) -> &'a $t<N> {
unsafe {
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]
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 {
mem::transmute(arr)
}
@ -54,18 +54,18 @@ macro_rules! conversion_impl(
);
macro_rules! at_fast_impl(
($t: ident, $dim: expr) => (
($t: ident, $dimension: expr) => (
impl<N: Copy> $t<N> {
#[inline]
pub unsafe fn at_fast(&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]
pub unsafe fn set_fast(&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
}
}
)
@ -259,10 +259,10 @@ macro_rules! mat_sub_scalar_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> {
fn new_identity(dim: usize) -> $t<N> {
assert!(dim == $dim);
fn new_identity(dimension: usize) -> $t<N> {
assert!(dimension == $dimension);
let mut eye: $t<N> = ::zero();
$(eye.$comp_diagN = ::one();)+
eye
@ -295,12 +295,12 @@ macro_rules! absolute_impl(
);
macro_rules! iterable_impl(
($t: ident, $dim: expr) => (
($t: ident, $dimension: expr) => (
impl<N> Iterable<N> for $t<N> {
#[inline]
fn iter<'l>(&'l self) -> Iter<'l, N> {
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(
($t: ident, $dim: expr) => (
($t: ident, $dimension: expr) => (
impl<N> IterableMut<N> for $t<N> {
#[inline]
fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> {
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(
($t: ident, $dim: expr) => (
impl<N> Dim for $t<N> {
($t: ident, $dimension: expr) => (
impl<N> Dimension for $t<N> {
#[inline]
fn dim(_: Option<$t<N>>) -> usize {
$dim
fn dimension(_: Option<$t<N>>) -> usize {
$dimension
}
}
)
);
macro_rules! indexable_impl(
($t: ident, $dim: expr) => (
($t: ident, $dimension: expr) => (
impl<N> Shape<(usize, usize)> for $t<N> {
#[inline]
fn shape(&self) -> (usize, usize) {
($dim, $dim)
($dimension, $dimension)
}
}
@ -373,32 +373,32 @@ macro_rules! indexable_impl(
#[inline]
fn swap(&mut self, (i1, j1): (usize, usize), (i2, j2): (usize, usize)) {
unsafe {
mem::transmute::<&mut $t<N>, &mut [N; $dim * $dim]>(self)
.swap(i1 + j1 * $dim, i2 + j2 * $dim)
mem::transmute::<&mut $t<N>, &mut [N; $dimension * $dimension]>(self)
.swap(i1 + j1 * $dimension, i2 + j2 * $dimension)
}
}
#[inline]
unsafe fn unsafe_at(&self, (i, j): (usize, usize)) -> N {
(*mem::transmute::<&$t<N>, &[N; $dim * $dim]>(self).get_unchecked(i + j * $dim))
(*mem::transmute::<&$t<N>, &[N; $dimension * $dimension]>(self).get_unchecked(i + j * $dimension))
}
#[inline]
unsafe fn unsafe_set(&mut self, (i, j): (usize, usize), val: N) {
(*mem::transmute::<&mut $t<N>, &mut [N; $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(
($t: ident, $dim: expr) => (
($t: ident, $dimension: expr) => (
impl<N> Index<(usize, usize)> for $t<N> {
type Output = N;
fn index(&self, (i, j): (usize, usize)) -> &N {
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> {
fn index_mut(&mut self, (i, j): (usize, usize)) -> &mut N {
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(
($t: ident, $tv: ident, $slice: ident, $dim: expr) => (
impl<N: Clone + Copy + Zero> ColSlice<$slice<N>> for $t<N> {
($t: ident, $tv: ident, $slice: ident, $dimension: expr) => (
impl<N: Clone + Copy + Zero> ColumnSlice<$slice<N>> for $t<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(
($t: ident, $tv: ident, $dim: expr) => (
($t: ident, $tv: ident, $dimension: expr) => (
impl<N: Copy + Zero> Row<$tv<N>> for $t<N> {
#[inline]
fn nrows(&self) -> usize {
Dim::dim(None::<$t<N>>)
Dimension::dimension(None::<$t<N>>)
}
#[inline]
@ -455,7 +455,7 @@ macro_rules! row_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> {
fn row_slice(&self, rid: usize, cstart: usize, cend: usize) -> $slice<N> {
let row = self.row(rid);
@ -467,26 +467,26 @@ macro_rules! row_slice_impl(
);
macro_rules! col_impl(
($t: ident, $tv: ident, $dim: expr) => (
impl<N: Copy + Zero> Col<$tv<N>> for $t<N> {
($t: ident, $tv: ident, $dimension: expr) => (
impl<N: Copy + Zero> Column<$tv<N>> for $t<N> {
#[inline]
fn ncols(&self) -> usize {
Dim::dim(None::<$t<N>>)
Dimension::dimension(None::<$t<N>>)
}
#[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() {
self[(i, col)] = *e;
self[(i, column)] = *e;
}
}
#[inline]
fn col(&self, col: usize) -> $tv<N> {
fn column(&self, column: usize) -> $tv<N> {
let mut res: $tv<N> = ::zero();
for (i, e) in res.iter_mut().enumerate() {
*e = self[(i, col)];
*e = self[(i, column)];
}
res
@ -496,34 +496,34 @@ macro_rules! col_impl(
);
macro_rules! diag_impl(
($t: ident, $tv: ident, $dim: expr) => (
impl<N: Copy + Zero> Diag<$tv<N>> for $t<N> {
($t: ident, $tv: ident, $dimension: expr) => (
impl<N: Copy + Zero> Diagonal<$tv<N>> for $t<N> {
#[inline]
fn from_diag(diag: &$tv<N>) -> $t<N> {
fn from_diag(diagonal: &$tv<N>) -> $t<N> {
let mut res: $t<N> = ::zero();
res.set_diag(diag);
res.set_diag(diagonal);
res
}
#[inline]
fn diag(&self) -> $tv<N> {
let mut diag: $tv<N> = ::zero();
fn diagonal(&self) -> $tv<N> {
let mut diagonal: $tv<N> = ::zero();
for i in 0 .. $dim {
unsafe { diag.unsafe_set(i, self.unsafe_at((i, i))) }
for i in 0 .. $dimension {
unsafe { diagonal.unsafe_set(i, self.unsafe_at((i, i))) }
}
diag
diagonal
}
}
impl<N: Copy + Zero> DiagMut<$tv<N>> for $t<N> {
#[inline]
fn set_diag(&mut self, diag: &$tv<N>) {
for i in 0 .. $dim {
unsafe { self.unsafe_set((i, i), diag.unsafe_at(i)) }
fn set_diag(&mut self, diagonal: &$tv<N>) {
for i in 0 .. $dimension {
unsafe { self.unsafe_set((i, i), diagonal.unsafe_at(i)) }
}
}
}
@ -531,19 +531,19 @@ macro_rules! diag_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> {
type Output = $t<N>;
#[inline]
fn mul(self, right: $t<N>) -> $t<N> {
let mut res: $t<N> = ::zero();
for i in 0 .. $dim {
for j in 0 .. $dim {
for i in 0 .. $dimension {
for j in 0 .. $dimension {
let mut acc: N = ::zero();
unsafe {
for k in 0 .. $dim {
for k in 0 .. $dimension {
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(
($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> {
type Output = $v<N>;
@ -576,8 +576,8 @@ macro_rules! vec_mul_mat_impl(
fn mul(self, right: $t<N>) -> $v<N> {
let mut res : $v<N> = $zero();
for i in 0..$dim {
for j in 0..$dim {
for i in 0..$dimension {
for j in 0..$dimension {
unsafe {
let val = res.at_fast(i) + self.at_fast(j) * right.at_fast((j, i));
res.set_fast(i, val)
@ -601,7 +601,7 @@ macro_rules! vec_mul_mat_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> {
type Output = $v<N>;
@ -609,8 +609,8 @@ macro_rules! mat_mul_vec_impl(
fn mul(self, right: $v<N>) -> $v<N> {
let mut res : $v<N> = $zero();
for i in 0 .. $dim {
for j in 0 .. $dim {
for i in 0 .. $dimension {
for j in 0 .. $dimension {
unsafe {
let val = res.at_fast(i) + self.at_fast((i, j)) * right.at_fast(j);
res.set_fast(i, val)
@ -624,26 +624,26 @@ macro_rules! mat_mul_vec_impl(
)
);
macro_rules! pnt_mul_mat_impl(
($t: ident, $v: ident, $dim: expr, $zero: expr) => (
vec_mul_mat_impl!($t, $v, $dim, $zero);
macro_rules! point_mul_mat_impl(
($t: ident, $v: ident, $dimension: expr, $zero: expr) => (
vec_mul_mat_impl!($t, $v, $dimension, $zero);
)
);
macro_rules! mat_mul_pnt_impl(
($t: ident, $v: ident, $dim: expr, $zero: expr) => (
mat_mul_vec_impl!($t, $v, $dim, $zero);
macro_rules! mat_mul_point_impl(
($t: ident, $v: ident, $dimension: expr, $zero: expr) => (
mat_mul_vec_impl!($t, $v, $dimension, $zero);
)
);
macro_rules! inv_impl(
($t: ident, $dim: expr) => (
macro_rules! inverse_impl(
($t: ident, $dimension: expr) => (
impl<N: Copy + BaseNum>
Inv for $t<N> {
Inverse for $t<N> {
#[inline]
fn inv(&self) -> Option<$t<N>> {
fn inverse(&self) -> Option<$t<N>> {
let mut res : $t<N> = *self;
if res.inv_mut() {
if res.inverse_mut() {
Some(res)
}
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();
// 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
// FIXME: would it be worth it to spend some more time searching for the
// max instead?
let mut n0 = k; // index of a non-zero entry
while n0 != $dim {
while n0 != $dimension {
if self[(n0, k)] != ::zero() {
break;
}
@ -670,13 +670,13 @@ macro_rules! inv_impl(
n0 = n0 + 1;
}
if n0 == $dim {
if n0 == $dimension {
return false
}
// swap pivot line
if n0 != k {
for j in 0..$dim {
for j in 0..$dimension {
self.swap((n0, j), (k, j));
res.swap((n0, j), (k, j));
}
@ -684,26 +684,26 @@ macro_rules! inv_impl(
let pivot = self[(k, k)];
for j in k..$dim {
for j in k..$dimension {
let selfval = self[(k, j)] / pivot;
self[(k, j)] = selfval;
}
for j in 0..$dim {
for j in 0..$dimension {
let resval = res[(k, j)] / pivot;
res[(k, j)] = resval;
}
for l in 0..$dim {
for l in 0..$dimension {
if 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;
self[(l, j)] = selfval;
}
for j in 0..$dim {
for j in 0..$dimension {
let resval = res[(l, j)] - res[(k, j)] * normalizer;
res[(l, j)] = resval;
}
@ -720,7 +720,7 @@ macro_rules! inv_impl(
);
macro_rules! transpose_impl(
($t: ident, $dim: expr) => (
($t: ident, $dimension: expr) => (
impl<N: Copy> Transpose for $t<N> {
#[inline]
fn transpose(&self) -> $t<N> {
@ -732,7 +732,7 @@ macro_rules! transpose_impl(
#[inline]
fn transpose_mut(&mut self) {
for i in 1..$dim {
for i in 1..$dimension {
for j in 0..i {
self.swap((i, j), (j, i))
}
@ -771,14 +771,14 @@ macro_rules! approx_eq_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> {
#[inline]
fn to_homogeneous(&self) -> $t2<N> {
let mut res: $t2<N> = ::one();
for i in 0..$dim {
for j in 0..$dim {
for i in 0..$dimension {
for j in 0..$dimension {
res[(i, j)] = self[(i, j)]
}
}
@ -790,14 +790,14 @@ macro_rules! to_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> {
#[inline]
fn from(m: &$t2<N>) -> $t<N> {
let mut res: $t<N> = ::one();
for i in 0..$dim {
for j in 0..$dim {
for i in 0..$dimension {
for j in 0..$dimension {
res[(i, j)] = m[(i, j)]
}
}
@ -819,8 +819,8 @@ macro_rules! outer_impl(
#[inline]
fn outer(&self, other: &$t<N>) -> $m<N> {
let mut res: $m<N> = ::zero();
for i in 0..Dim::dim(None::<$t<N>>) {
for j in 0..Dim::dim(None::<$t<N>>) {
for i in 0..Dimension::dimension(None::<$t<N>>) {
for j in 0..Dimension::dimension(None::<$t<N>>) {
res[(i, j)] = self[i] * other[j]
}
}
@ -843,14 +843,14 @@ macro_rules! eigen_qr_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> {
fn mean(&self) -> $v<N> {
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 j in 0 .. $dim {
for i in 0 .. $dimension {
for j in 0 .. $dimension {
unsafe {
let acc = res.unsafe_at(j) + self.unsafe_at((i, j)) * normalizer;
res.unsafe_set(j, acc);
@ -865,7 +865,7 @@ macro_rules! mean_impl(
);
macro_rules! mat_display_impl(
($t: ident, $dim: expr) => (
($t: ident, $dimension: expr) => (
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
// XXX: will will not always work correctly due to rounding errors.
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 decimal_lengths: $t<usize> = ::zero();
for i in 0 .. $dim {
for j in 0 .. $dim {
for i in 0 .. $dimension {
for j in 0 .. $dimension {
decimal_lengths[(i, j)] = integral_length(&self[(i, j)].clone());
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 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, ""));
for j in 0 .. $dim {
for j in 0 .. $dimension {
let number_length = decimal_lengths[(i, j)] + precision + 1;
let pad = max_number_length - number_length;
try!(write!(f, " {:>thepad$}", "", thepad = pad));
@ -911,7 +911,7 @@ macro_rules! mat_display_impl(
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.
pub use self::dmat::{DMat, DMat1, DMat2, DMat3, DMat4, DMat5, DMat6};
pub use self::dvec::{DVec, DVec1, DVec2, DVec3, DVec4, DVec5, DVec6};
pub use self::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6};
pub use self::pnt::{Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6};
pub use self::mat::{Identity, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6};
pub use self::rot::{Rot2, Rot3};
pub use self::iso::{Iso2, Iso3};
pub use self::sim::{Sim2, Sim3};
pub use self::persp::{Persp3, PerspMat3};
pub use self::ortho::{Ortho3, OrthoMat3};
pub use self::quat::{Quat, UnitQuat};
pub use self::dmatrix::{DMatrix, DMatrix1, DMatrix2, DMatrix3, DMatrix4, DMatrix5, DMatrix6};
pub use self::dvector::{DVector, DVector1, DVector2, DVector3, DVector4, DVector5, DVector6};
pub use self::vector::{Vector1, Vector2, Vector3, Vector4, Vector5, Vector6};
pub use self::point::{Point1, Point2, Point3, Point4, Point5, Point6};
pub use self::matrix::{Identity, Matrix1, Matrix2, Matrix3, Matrix4, Matrix5, Matrix6};
pub use self::rotation::{Rotation2, Rotation3};
pub use self::isometry::{Isometry2, Isometry3};
pub use self::similarity::{Similarity2, Similarity3};
pub use self::perspective::{Perspective3, PerspectiveMatrix3};
pub use self::orthographic::{Orthographic3, OrthographicMatrix3};
pub use self::quaternion::{Quaternion, UnitQuaternion};
#[cfg(feature="generic_sizes")]
pub use self::vecn::VecN;
pub use self::vectorn::VectorN;
mod dmat_macros;
mod dmat;
mod vecn_macros;
mod dmatrix_macros;
mod dmatrix;
mod vectorn_macros;
#[cfg(feature="generic_sizes")]
mod vecn;
mod dvec_macros;
mod dvec;
mod vec_macros;
mod vec;
mod pnt_macros;
mod pnt;
mod quat;
mod mat_macros;
mod mat;
mod rot_macros;
mod rot;
mod iso_macros;
mod iso;
mod sim_macros;
mod sim;
mod persp;
mod ortho;
mod vectorn;
mod dvector_macros;
mod dvector;
mod vector_macros;
mod vector;
mod point_macros;
mod point;
mod quaternion;
mod matrix_macros;
mod matrix;
mod rotation_macros;
mod rotation;
mod isometry_macros;
mod isometry;
mod similarity_macros;
mod similarity;
mod perspective;
mod orthographic;
// Specialization for some 1d, 2d and 3d operations.
#[doc(hidden)]
mod spec {
mod specializations {
mod identity;
mod mat;
mod vec;
mod matrix;
mod vector;
mod primitives;
// mod complex;
}

View File

@ -1,5 +1,5 @@
use traits::structure::{BaseFloat, Cast};
use structs::{Pnt3, Vec3, Mat4};
use structs::{Point3, Vector3, Matrix4};
#[cfg(feature="arbitrary")]
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
/// applying the transformation is costly.
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct Ortho3<N> {
pub struct Orthographic3<N> {
left: N,
right: 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
/// applying the transformation is cheap.
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct OrthoMat3<N> {
mat: Mat4<N>
pub struct OrthographicMatrix3<N> {
matrix: Matrix4<N>
}
impl<N: BaseFloat> Ortho3<N> {
impl<N: BaseFloat> Orthographic3<N> {
/// 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(&(left - right)));
assert!(!::is_zero(&(top - bottom)));
Ortho3 {
Orthographic3 {
left: left,
right: right,
bottom: bottom,
@ -48,30 +48,30 @@ impl<N: BaseFloat> Ortho3<N> {
}
/// Builds a 4D projection matrix (using homogeneous coordinates) for this projection.
pub fn to_mat(&self) -> Mat4<N> {
self.to_persp_mat().mat
pub fn to_matrix(&self) -> Matrix4<N> {
self.to_orthographic_matrix().matrix
}
/// Build a `OrthoMat3` representing this projection.
pub fn to_persp_mat(&self) -> OrthoMat3<N> {
OrthoMat3::new(self.left, self.right, self.bottom, self.top, self.znear, self.zfar)
/// Build a `OrthographicMatrix3` representing this projection.
pub fn to_orthographic_matrix(&self) -> OrthographicMatrix3<N> {
OrthographicMatrix3::new(self.left, self.right, self.bottom, self.top, self.znear, self.zfar)
}
}
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for Ortho3<N> {
fn arbitrary<G: Gen>(g: &mut G) -> Ortho3<N> {
impl<N: Arbitrary + BaseFloat> Arbitrary for Orthographic3<N> {
fn arbitrary<G: Gen>(g: &mut G) -> Orthographic3<N> {
let left = Arbitrary::arbitrary(g);
let right = reject(g, |x: &N| *x > left);
let bottom = Arbitrary::arbitrary(g);
let top = reject(g, |x: &N| *x > bottom);
let znear = Arbitrary::arbitrary(g);
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.
#[inline]
pub fn left(&self) -> N {
@ -152,29 +152,29 @@ impl<N: BaseFloat + Clone> Ortho3<N> {
/// Projects a point.
#[inline]
pub fn project_pnt(&self, p: &Pnt3<N>) -> Pnt3<N> {
pub fn project_point(&self, p: &Point3<N>) -> Point3<N> {
// FIXME: optimize that
self.to_persp_mat().project_pnt(p)
self.to_orthographic_matrix().project_point(p)
}
/// Projects a vector.
#[inline]
pub fn project_vec(&self, p: &Vec3<N>) -> Vec3<N> {
pub fn project_vector(&self, p: &Vector3<N>) -> Vector3<N> {
// 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.
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!(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.");
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_bottom_and_top(bottom, top);
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.
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!(!::is_zero(&aspect));
@ -192,59 +192,59 @@ impl<N: BaseFloat> OrthoMat3<N> {
let width = zfar * (vfov / _2).tan();
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.
///
/// This is unsafe because the input matrix is not checked to be a orthographic projection.
#[inline]
pub unsafe fn new_with_mat(mat: Mat4<N>) -> OrthoMat3<N> {
OrthoMat3 {
mat: mat
pub unsafe fn new_with_matrix(matrix: Matrix4<N>) -> OrthographicMatrix3<N> {
OrthographicMatrix3 {
matrix: matrix
}
}
/// Returns a reference to the 4D matrix (using homogeneous coordinates) of this projection.
#[inline]
pub fn as_mat<'a>(&'a self) -> &'a Mat4<N> {
&self.mat
pub fn as_matrix<'a>(&'a self) -> &'a Matrix4<N> {
&self.matrix
}
/// The smallest x-coordinate of the view cuboid.
#[inline]
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.
#[inline]
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.
#[inline]
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.
#[inline]
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.
#[inline]
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.
#[inline]
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.
@ -293,65 +293,65 @@ impl<N: BaseFloat> OrthoMat3<N> {
#[inline]
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.");
self.mat.m11 = <N as Cast<f64>>::from(2.0) / (right - left);
self.mat.m14 = -(right + left) / (right - left);
self.matrix.m11 = <N as Cast<f64>>::from(2.0) / (right - left);
self.matrix.m14 = -(right + left) / (right - left);
}
/// Sets the view cuboid coordinates along the `y` axis.
#[inline]
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.");
self.mat.m22 = <N as Cast<f64>>::from(2.0) / (top - bottom);
self.mat.m24 = -(top + bottom) / (top - bottom);
self.matrix.m22 = <N as Cast<f64>>::from(2.0) / (top - bottom);
self.matrix.m24 = -(top + bottom) / (top - bottom);
}
/// Sets the near and far plane offsets of the view cuboid.
#[inline]
pub fn set_znear_and_zfar(&mut self, znear: N, zfar: N) {
assert!(!::is_zero(&(zfar - znear)));
self.mat.m33 = -<N as Cast<f64>>::from(2.0) / (zfar - znear);
self.mat.m34 = -(zfar + znear) / (zfar - znear);
self.matrix.m33 = -<N as Cast<f64>>::from(2.0) / (zfar - znear);
self.matrix.m34 = -(zfar + znear) / (zfar - znear);
}
/// Projects a point.
#[inline]
pub fn project_pnt(&self, p: &Pnt3<N>) -> Pnt3<N> {
Pnt3::new(
self.mat.m11 * p.x + self.mat.m14,
self.mat.m22 * p.y + self.mat.m24,
self.mat.m33 * p.z + self.mat.m34
pub fn project_point(&self, p: &Point3<N>) -> Point3<N> {
Point3::new(
self.matrix.m11 * p.x + self.matrix.m14,
self.matrix.m22 * p.y + self.matrix.m24,
self.matrix.m33 * p.z + self.matrix.m34
)
}
/// Projects a vector.
#[inline]
pub fn project_vec(&self, p: &Vec3<N>) -> Vec3<N> {
Vec3::new(
self.mat.m11 * p.x,
self.mat.m22 * p.y,
self.mat.m33 * p.z
pub fn project_vector(&self, p: &Vector3<N>) -> Vector3<N> {
Vector3::new(
self.matrix.m11 * p.x,
self.matrix.m22 * p.y,
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.
#[inline]
pub fn to_mat<'a>(&'a self) -> Mat4<N> {
self.mat.clone()
pub fn to_matrix<'a>(&'a self) -> Matrix4<N> {
self.matrix.clone()
}
}
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for OrthoMat3<N> {
fn arbitrary<G: Gen>(g: &mut G) -> OrthoMat3<N> {
let x: Ortho3<N> = Arbitrary::arbitrary(g);
x.to_persp_mat()
impl<N: Arbitrary + BaseFloat> Arbitrary for OrthographicMatrix3<N> {
fn arbitrary<G: Gen>(g: &mut G) -> OrthographicMatrix3<N> {
let x: Orthographic3<N> = Arbitrary::arbitrary(g);
x.to_orthographic_matrix()
}
}
/// Simple helper function for rejection sampling
/// Similarityple helper function for rejection sampling
#[cfg(feature="arbitrary")]
#[inline]
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 structs::{Pnt3, Vec3, Mat4};
use structs::{Point3, Vector3, Matrix4};
#[cfg(feature="arbitrary")]
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
/// transformation is costly.
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct Persp3<N> {
pub struct Perspective3<N> {
aspect: N,
fovy: N,
fovy: N,
znear: 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
/// transformation is cheap.
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct PerspMat3<N> {
mat: Mat4<N>
pub struct PerspectiveMatrix3<N> {
matrix: Matrix4<N>
}
impl<N: BaseFloat> Persp3<N> {
impl<N: BaseFloat> Perspective3<N> {
/// 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(&aspect));
Persp3 {
Perspective3 {
aspect: aspect,
fovy: fovy,
fovy: fovy,
znear: znear,
zfar: zfar
}
}
/// Builds a 4D projection matrix (using homogeneous coordinates) for this projection.
pub fn to_mat(&self) -> Mat4<N> {
self.to_persp_mat().mat
pub fn to_matrix(&self) -> Matrix4<N> {
self.to_perspective_matrix().matrix
}
/// Build a `PerspMat3` representing this projection.
pub fn to_persp_mat(&self) -> PerspMat3<N> {
PerspMat3::new(self.aspect, self.fovy, self.znear, self.zfar)
/// Build a `PerspectiveMatrix3` representing this projection.
pub fn to_perspective_matrix(&self) -> PerspectiveMatrix3<N> {
PerspectiveMatrix3::new(self.aspect, self.fovy, self.znear, self.zfar)
}
}
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for Persp3<N> {
fn arbitrary<G: Gen>(g: &mut G) -> Persp3<N> {
use structs::ortho::reject;
impl<N: Arbitrary + BaseFloat> Arbitrary for Perspective3<N> {
fn arbitrary<G: Gen>(g: &mut G) -> Perspective3<N> {
use structs::orthographic::reject;
let znear = Arbitrary::arbitrary(g);
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.
#[inline]
pub fn aspect(&self) -> N {
@ -122,33 +122,33 @@ impl<N: BaseFloat + Clone> Persp3<N> {
/// Projects a point.
#[inline]
pub fn project_pnt(&self, p: &Pnt3<N>) -> Pnt3<N> {
pub fn project_point(&self, p: &Point3<N>) -> Point3<N> {
// FIXME: optimize that
self.to_persp_mat().project_pnt(p)
self.to_perspective_matrix().project_point(p)
}
/// Projects a vector.
#[inline]
pub fn project_vec(&self, p: &Vec3<N>) -> Vec3<N> {
pub fn project_vector(&self, p: &Vector3<N>) -> Vector3<N> {
// 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.
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(&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_aspect(aspect);
res.set_znear_and_zfar(znear, zfar);
res.mat.m44 = ::zero();
res.mat.m43 = -::one::<N>();
res.matrix.m44 = ::zero();
res.matrix.m43 = -::one::<N>();
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.
#[inline]
pub unsafe fn new_with_mat(mat: Mat4<N>) -> PerspMat3<N> {
PerspMat3 {
mat: mat
pub unsafe fn new_with_matrix(matrix: Matrix4<N>) -> PerspectiveMatrix3<N> {
PerspectiveMatrix3 {
matrix: matrix
}
}
/// Returns a reference to the 4D matrix (using homogeneous coordinates) of this projection.
#[inline]
pub fn as_mat<'a>(&'a self) -> &'a Mat4<N> {
&self.mat
pub fn as_matrix<'a>(&'a self) -> &'a Matrix4<N> {
&self.matrix
}
/// Gets the `width / height` aspect ratio of the view frustrum.
#[inline]
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.
@ -181,7 +181,7 @@ impl<N: BaseFloat> PerspMat3<N> {
let _1: N = ::one();
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.
@ -189,9 +189,9 @@ impl<N: BaseFloat> PerspMat3<N> {
pub fn znear(&self) -> N {
let _1: N = ::one();
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.
@ -199,9 +199,9 @@ impl<N: BaseFloat> PerspMat3<N> {
pub fn zfar(&self) -> N {
let _1: N = ::one();
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?
@ -211,7 +211,7 @@ impl<N: BaseFloat> PerspMat3<N> {
#[inline]
pub fn set_aspect(&mut self, aspect: N) {
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.
@ -220,9 +220,9 @@ impl<N: BaseFloat> PerspMat3<N> {
let _1: N = ::one();
let _2 = _1 + _1;
let old_m22 = self.mat.m22.clone();
self.mat.m22 = _1 / (fovy / _2).tan();
self.mat.m11 = self.mat.m11 * (self.mat.m22 / old_m22);
let old_m22 = self.matrix.m22.clone();
self.matrix.m22 = _1 / (fovy / _2).tan();
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.
@ -245,47 +245,47 @@ impl<N: BaseFloat> PerspMat3<N> {
let _1: N = ::one();
let _2 = _1 + _1;
self.mat.m33 = (zfar + znear) / (znear - zfar);
self.mat.m34 = zfar * znear * _2 / (znear - zfar);
self.matrix.m33 = (zfar + znear) / (znear - zfar);
self.matrix.m34 = zfar * znear * _2 / (znear - zfar);
}
/// Projects a point.
#[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 inv_denom = -_1 / p.z;
Pnt3::new(
self.mat.m11 * p.x * inv_denom,
self.mat.m22 * p.y * inv_denom,
(self.mat.m33 * p.z + self.mat.m34) * inv_denom
let inverse_denom = -_1 / p.z;
Point3::new(
self.matrix.m11 * p.x * inverse_denom,
self.matrix.m22 * p.y * inverse_denom,
(self.matrix.m33 * p.z + self.matrix.m34) * inverse_denom
)
}
/// Projects a vector.
#[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 inv_denom = -_1 / p.z;
Vec3::new(
self.mat.m11 * p.x * inv_denom,
self.mat.m22 * p.y * inv_denom,
self.mat.m33
let inverse_denom = -_1 / p.z;
Vector3::new(
self.matrix.m11 * p.x * inverse_denom,
self.matrix.m22 * p.y * inverse_denom,
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.
#[inline]
pub fn to_mat<'a>(&'a self) -> Mat4<N> {
self.mat.clone()
pub fn to_matrix<'a>(&'a self) -> Matrix4<N> {
self.matrix.clone()
}
}
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for PerspMat3<N> {
fn arbitrary<G: Gen>(g: &mut G) -> PerspMat3<N> {
let x: Persp3<N> = Arbitrary::arbitrary(g);
x.to_persp_mat()
impl<N: Arbitrary + BaseFloat> Arbitrary for PerspectiveMatrix3<N> {
fn arbitrary<G: Gen>(g: &mut G) -> PerspectiveMatrix3<N> {
let x: Perspective3<N> = Arbitrary::arbitrary(g);
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_rules! orig_impl(
macro_rules! origin_impl(
($t: ident, $($compN: ident),+) => (
impl<N: Zero> Orig for $t<N> {
impl<N: Zero> Origin for $t<N> {
#[inline]
fn orig() -> $t<N> {
fn origin() -> $t<N> {
$t {
$($compN: ::zero() ),+
}
}
#[inline]
fn is_orig(&self) -> bool {
fn is_origin(&self) -> bool {
$(self.$compN.is_zero() )&&+
}
}
)
);
macro_rules! pnt_sub_impl(
macro_rules! point_sub_impl(
($t: ident, $tv: ident) => (
impl<N: Copy + Sub<N, Output = N>> Sub<$t<N>> for $t<N> {
type Output = $tv<N>;
#[inline]
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),+) => (
impl<N: Copy + Add<N, Output = N>> Add<$tv<N>> for $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),+) => (
impl<N: Copy + Sub<N, Output = N>> Sub<$tv<N>> for $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),+) => (
impl<N> $t<N> {
/// Converts this point to its associated vector.
#[inline]
pub fn to_vec(self) -> $tv<N> {
pub fn to_vector(self) -> $tv<N> {
$tv::new(
$(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.
#[inline]
pub fn as_vec<'a>(&'a self) -> &'a $tv<N> {
pub fn as_vector<'a>(&'a self) -> &'a $tv<N> {
unsafe {
mem::transmute(self)
}
@ -96,17 +96,17 @@ macro_rules! pnt_as_vec_impl(
}
}
impl<N> PntAsVec for $t<N> {
type Vec = $tv<N>;
impl<N> PointAsVector for $t<N> {
type Vector = $tv<N>;
#[inline]
fn to_vec(self) -> $tv<N> {
self.to_vec()
fn to_vector(self) -> $tv<N> {
self.to_vector()
}
#[inline]
fn as_vec<'a>(&'a self) -> &'a $tv<N> {
self.as_vec()
fn as_vector<'a>(&'a self) -> &'a $tv<N> {
self.as_vector()
}
#[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),+) => (
impl<N: Copy + One + Zero> ToHomogeneous<$t2<N>> for $t<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.$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),+) => (
impl<N: Copy + Div<N, Output = N> + One + Zero> FromHomogeneous<$t2<N>> for $t<N> {
fn from(v: &$t2<N>) -> $t<N> {
let mut res: $t<N> = Orig::orig();
let mut res: $t<N> = Origin::origin();
$( 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) => (
impl<N> NumPnt<N> for $t<N>
impl<N> NumPoint<N> for $t<N>
where N: BaseNum {
}
impl<N> FloatPnt<N> for $t<N>
impl<N> FloatPoint<N> for $t<N>
where N: BaseFloat + ApproxEq<N> {
}
)
);
macro_rules! arbitrary_pnt_impl(
macro_rules! arbitrary_point_impl(
($t: ident, $($compN: ident),*) => (
#[cfg(feature="arbitrary")]
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) => (
impl<N: fmt::Display> fmt::Display for $t<N> {
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_rules! submat_impl(
($t: ident, $submat: ident) => (
($t: ident, $submatrix: ident) => (
impl<N> $t<N> {
/// This rotation's underlying matrix.
#[inline]
pub fn submat<'r>(&'r self) -> &'r $submat<N> {
&self.submat
pub fn submatrix<'r>(&'r self) -> &'r $submatrix<N> {
&self.submatrix
}
}
)
@ -21,7 +21,7 @@ macro_rules! rotate_impl(
}
#[inline]
fn inv_rotate(&self, v: &$tv<N>) -> $tv<N> {
fn inverse_rotate(&self, v: &$tv<N>) -> $tv<N> {
*v * *self
}
}
@ -33,7 +33,7 @@ macro_rules! rotate_impl(
}
#[inline]
fn inv_rotate(&self, p: &$tp<N>) -> $tp<N> {
fn inverse_rotate(&self, p: &$tp<N>) -> $tp<N> {
*p * *self
}
}
@ -49,8 +49,8 @@ macro_rules! transform_impl(
}
#[inline]
fn inv_transform(&self, v: &$tv<N>) -> $tv<N> {
self.inv_rotate(v)
fn inverse_transform(&self, v: &$tv<N>) -> $tv<N> {
self.inverse_rotate(v)
}
}
@ -61,19 +61,19 @@ macro_rules! transform_impl(
}
#[inline]
fn inv_transform(&self, p: &$tp<N>) -> $tp<N> {
self.inv_rotate(p)
fn inverse_transform(&self, p: &$tp<N>) -> $tp<N> {
self.inverse_rotate(p)
}
}
)
);
macro_rules! dim_impl(
($t: ident, $dim: expr) => (
impl<N> Dim for $t<N> {
($t: ident, $dimension: expr) => (
impl<N> Dimension for $t<N> {
#[inline]
fn dim(_: Option<$t<N>>) -> usize {
$dim
fn dimension(_: Option<$t<N>>) -> usize {
$dimension
}
}
)
@ -85,7 +85,7 @@ macro_rules! rotation_matrix_impl(
type Output = $t<N>;
#[inline]
fn to_rot_mat(&self) -> $t<N> {
fn to_rotation_matrix(&self) -> $t<N> {
self.clone()
}
}
@ -97,7 +97,7 @@ macro_rules! one_impl(
impl<N: BaseNum> One for $t<N> {
#[inline]
fn one() -> $t<N> {
$t { submat: ::one() }
$t { submatrix: ::one() }
}
}
)
@ -107,9 +107,9 @@ macro_rules! eye_impl(
($t: ident) => (
impl<N: BaseNum> Eye for $t<N> {
#[inline]
fn new_identity(dim: usize) -> $t<N> {
if dim != ::dim::<$t<N>>() {
panic!("Dimension mismatch: should be {}, got {}.", ::dim::<$t<N>>(), dim);
fn new_identity(dimension: usize) -> $t<N> {
if dimension != ::dimension::<$t<N>>() {
panic!("Dimension mismatch: should be {}, got {}.", ::dimension::<$t<N>>(), dimension);
}
else {
::one()
@ -121,90 +121,90 @@ macro_rules! eye_impl(
macro_rules! diag_impl(
($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]
fn from_diag(diag: &$tv<N>) -> $t<N> {
$t { submat: Diag::from_diag(diag) }
fn from_diag(diagonal: &$tv<N>) -> $t<N> {
$t { submatrix: Diagonal::from_diag(diagonal) }
}
#[inline]
fn diag(&self) -> $tv<N> {
self.submat.diag()
fn diagonal(&self) -> $tv<N> {
self.submatrix.diagonal()
}
}
)
);
macro_rules! rot_mul_rot_impl(
macro_rules! rotation_mul_rotation_impl(
($t: ident) => (
impl<N: BaseNum> Mul<$t<N>> for $t<N> {
type Output = $t<N>;
#[inline]
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> {
#[inline]
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) => (
impl<N: BaseNum> Mul<$tv<N>> for $t<N> {
type Output = $tv<N>;
#[inline]
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) => (
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) => (
impl<N: BaseNum> Mul<$t<N>> for $tv<N> {
type Output = $tv<N>;
#[inline]
fn mul(self, right: $t<N>) -> $tv<N> {
self * right.submat
self * right.submatrix
}
}
impl<N: Copy + BaseNum> MulAssign<$t<N>> for $tv<N> {
#[inline]
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) => (
vec_mul_rot_impl!($t, $tv);
vec_mul_rotation_impl!($t, $tv);
)
);
macro_rules! inv_impl(
macro_rules! inverse_impl(
($t: ident) => (
impl<N: Copy> Inv for $t<N> {
impl<N: Copy> Inverse for $t<N> {
#[inline]
fn inv_mut(&mut self) -> bool {
fn inverse_mut(&mut self) -> bool {
self.transpose_mut();
// always succeed
@ -212,7 +212,7 @@ macro_rules! inv_impl(
}
#[inline]
fn inv(&self) -> Option<$t<N>> {
fn inverse(&self) -> Option<$t<N>> {
// always succeed
Some(self.transpose())
}
@ -225,12 +225,12 @@ macro_rules! transpose_impl(
impl<N: Copy> Transpose for $t<N> {
#[inline]
fn transpose(&self) -> $t<N> {
$t { submat: Transpose::transpose(&self.submat) }
$t { submatrix: Transpose::transpose(&self.submatrix) }
}
#[inline]
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> {
#[inline]
fn nrows(&self) -> usize {
self.submat.nrows()
self.submatrix.nrows()
}
#[inline]
fn row(&self, i: usize) -> $tv<N> {
self.submat.row(i)
self.submatrix.row(i)
}
#[inline]
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(
($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]
fn ncols(&self) -> usize {
self.submat.ncols()
self.submatrix.ncols()
}
#[inline]
fn col(&self, i: usize) -> $tv<N> {
self.submat.col(i)
fn column(&self, i: usize) -> $tv<N> {
self.submatrix.column(i)
}
#[inline]
fn set_col(&mut self, i: usize, col: $tv<N>) {
self.submat.set_col(i, col);
fn set_col(&mut self, i: usize, column: $tv<N>) {
self.submatrix.set_col(i, column);
}
}
)
@ -282,7 +282,7 @@ macro_rules! index_impl(
type Output = 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> {
#[inline]
fn to_homogeneous(&self) -> $tm<N> {
self.submat.to_homogeneous()
self.submatrix.to_homogeneous()
}
}
)
@ -314,17 +314,17 @@ macro_rules! approx_eq_impl(
#[inline]
fn approx_eq(&self, other: &$t<N>) -> bool {
ApproxEq::approx_eq(&self.submat, &other.submat)
ApproxEq::approx_eq(&self.submatrix, &other.submatrix)
}
#[inline]
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]
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> {
#[inline]
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) => (
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let precision = f.precision().unwrap_or(3);
try!(writeln!(f, "Rotation matrix {{"));
try!(write!(f, "{:.*}", precision, self.submat));
try!(write!(f, "{:.*}", precision, self.submatrix));
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_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> {
/// Creates a new similarity transformation from a vector, an axis-angle rotation, and a scale factor.
///
/// The scale factor may be negative but not zero.
#[inline]
pub fn new(translation: $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.");
$t {
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.
#[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.");
$t {
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.
#[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.");
$t {
@ -56,7 +56,7 @@ macro_rules! sim_scale_impl(
/// The inverse scale factor of this similarity transformation.
#[inline]
pub fn inv_scale(&self) -> N {
pub fn inverse_scale(&self) -> N {
::one::<N>() / self.scale
}
@ -72,7 +72,7 @@ macro_rules! sim_scale_impl(
#[inline]
pub fn append_scale(&self, s: &N) -> $t<N> {
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.
@ -86,7 +86,7 @@ macro_rules! sim_scale_impl(
#[inline]
pub fn prepend_scale(&self, s: &N) -> $t<N> {
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.
@ -104,7 +104,7 @@ macro_rules! sim_one_impl(
impl<N: BaseFloat> One for $t<N> {
#[inline]
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]
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.rotation * right.isometry.rotation,
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) => (
impl<N: BaseFloat> Mul<$ti<N>> for $t<N> {
type Output = $t<N>;
#[inline]
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.rotation * right.rotation,
self.scale)
@ -162,7 +162,7 @@ macro_rules! sim_mul_iso_impl(
#[inline]
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.rotation * right.isometry.rotation,
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) => (
impl<N: BaseFloat> Mul<$tr<N>> for $t<N> {
type Output = $t<N>;
#[inline]
fn mul(self, right: $tr<N>) -> $t<N> {
$t::new_with_rotmat(
$t::new_with_rotation_matrix(
self.isometry.translation,
self.isometry.rotation * right,
self.scale)
@ -197,7 +197,7 @@ macro_rules! sim_mul_rot_impl(
#[inline]
fn mul(self, right: $t<N>) -> $t<N> {
$t::new_with_rotmat(
$t::new_with_rotation_matrix(
self * right.isometry.translation,
self * right.isometry.rotation,
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) => (
impl<N: BaseNum> Mul<$tv<N>> for $t<N> {
type Output = $tv<N>;
@ -232,20 +232,20 @@ macro_rules! sim_transform_impl(
}
#[inline]
fn inv_transform(&self, p: &$tp<N>) -> $tp<N> {
self.isometry.inv_transform(p) / self.scale
fn inverse_transform(&self, p: &$tp<N>) -> $tp<N> {
self.isometry.inverse_transform(p) / self.scale
}
}
)
);
macro_rules! sim_inv_impl(
macro_rules! sim_inverse_impl(
($t: ident) => (
impl<N: BaseNum + Neg<Output = N>> Inv for $t<N> {
impl<N: BaseNum + Neg<Output = N>> Inverse for $t<N> {
#[inline]
fn inv_mut(&mut self) -> bool {
fn inverse_mut(&mut self) -> bool {
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
// inverted.
self.isometry.translation = self.isometry.translation * self.scale;
@ -255,9 +255,9 @@ macro_rules! sim_inv_impl(
}
#[inline]
fn inv(&self) -> Option<$t<N>> {
fn inverse(&self) -> Option<$t<N>> {
let mut res = *self;
res.inv_mut();
res.inverse_mut();
// Always succeed.
Some(res)
@ -270,12 +270,12 @@ macro_rules! sim_to_homogeneous_impl(
($t: ident, $th: ident) => (
impl<N: BaseNum> ToHomogeneous<$th<N>> for $t<N> {
fn to_homogeneous(&self) -> $th<N> {
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
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
}
@ -321,7 +321,7 @@ macro_rules! sim_rand_impl(
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")]
impl<N: Arbitrary + BaseFloat> Arbitrary for $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)
)
@ -351,13 +351,13 @@ macro_rules! sim_display_impl(
try!(writeln!(f, "... scale factor: {:.*}", precision, self.scale));
try!(writeln!(f, "... translation: {:.*}", precision, self.isometry.translation));
try!(writeln!(f, "... rotation matrix:"));
try!(write!(f, "{:.*}", precision, *self.isometry.rotation.submat()));
try!(write!(f, "{:.*}", precision, *self.isometry.rotation.submatrix()));
}
else {
try!(writeln!(f, "... scale factor: {}", self.scale));
try!(writeln!(f, "... translation: {}", self.isometry.translation));
try!(writeln!(f, "... rotation matrix:"));
try!(write!(f, "{}", *self.isometry.rotation.submat()));
try!(write!(f, "{}", *self.isometry.rotation.submatrix()));
}
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 extra::complex::Cmplx;
use traits::operations::{Absolute, Inv};
use traits::structure::{Dim};
use traits::operations::{Absolute, Inverse};
use traits::structure::{Dimension};
impl<N: Clone + BaseNum> Absolute<Cmplx<N>> for Cmplx<N> {
#[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]
fn inverse(&self) -> Option<Cmplx<N>> {
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]
fn dim(unsused_mut: Option<Cmplx<N>>) -> usize {
fn dimension(unsused_mut: Option<Cmplx<N>>) -> usize {
2
}
}
impl<N> Rotation<Vec2<N>> for Cmplx<N> {
impl<N> Rotation<Vector2<N>> for Cmplx<N> {
#[inline]
fn rotation(&self) -> Vec2<N> {
fn rotation(&self) -> Vector2<N> {
}
#[inline]
fn inv_rotation(&self) -> Vec2<N> {
fn inverse_rotation(&self) -> Vector2<N> {
-self.rotation();
}
#[inline]
fn rotate_by(&mut self, rotation: &Vec2<N>) {
fn rotate_by(&mut self, rotation: &Vector2<N>) {
}
#[inline]
fn rotated(&self, rotation: &Vec2<N>) -> Cmplx<N> {
fn rotated(&self, rotation: &Vector2<N>) -> Cmplx<N> {
}
#[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]
fn rotate(&self, rotation: &V) -> V {
}
#[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]
fn to_rot_mat(&self) -> Rotmat<Mat2<N>> {
fn to_rotation_matrix(&self) -> Rotationmatrix<Matrix2<N>> {
}
}
impl<N> Norm<N> for Cmplx<N> {
#[inline]
fn sqnorm(&self) -> N {
fn norm_squared(&self) -> N {
}
#[inline]

View File

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

View File

@ -1,16 +1,16 @@
use std::ops::{Add, Mul, Neg, MulAssign};
use structs::vec::{Vec2, Vec3};
use structs::pnt::{Pnt2, Pnt3};
use structs::mat::{Mat1, Mat2, Mat3};
use traits::operations::{Inv, Det, ApproxEq};
use traits::structure::{Row, Col, BaseNum};
use structs::vector::{Vector2, Vector3};
use structs::point::{Point2, Point3};
use structs::matrix::{Matrix1, Matrix2, Matrix3};
use traits::operations::{Inverse, Determinant, ApproxEq};
use traits::structure::{Row, Column, BaseNum};
// some specializations:
impl<N: BaseNum + ApproxEq<N>> Inv for Mat1<N> {
impl<N: BaseNum + ApproxEq<N>> Inverse for Matrix1<N> {
#[inline]
fn inv(&self) -> Option<Mat1<N>> {
fn inverse(&self) -> Option<Matrix1<N>> {
let mut res = *self;
if res.inv_mut() {
if res.inverse_mut() {
Some(res)
}
else {
@ -19,24 +19,24 @@ impl<N: BaseNum + ApproxEq<N>> Inv for Mat1<N> {
}
#[inline]
fn inv_mut(&mut self) -> bool {
fn inverse_mut(&mut self) -> bool {
if ApproxEq::approx_eq(&self.m11, &::zero()) {
false
}
else {
let _1: N = ::one();
self.m11 = _1 / Det::det(self);
self.m11 = _1 / Determinant::determinant(self);
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]
fn inv(&self) -> Option<Mat2<N>> {
fn inverse(&self) -> Option<Matrix2<N>> {
let mut res = *self;
if res.inv_mut() {
if res.inverse_mut() {
Some(res)
}
else {
@ -45,28 +45,28 @@ impl<N: BaseNum + Neg<Output = N> + ApproxEq<N>> Inv for Mat2<N> {
}
#[inline]
fn inv_mut(&mut self) -> bool {
let det = Det::det(self);
fn inverse_mut(&mut self) -> bool {
let determinant = Determinant::determinant(self);
if ApproxEq::approx_eq(&det, &::zero()) {
if ApproxEq::approx_eq(&determinant, &::zero()) {
false
}
else {
*self = Mat2::new(
self.m22 / det , -self.m12 / det,
-self.m21 / det, self.m11 / det);
*self = Matrix2::new(
self.m22 / determinant , -self.m12 / determinant,
-self.m21 / determinant, self.m11 / determinant);
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]
fn inv(&self) -> Option<Mat3<N>> {
fn inverse(&self) -> Option<Matrix3<N>> {
let mut res = *self;
if res.inv_mut() {
if res.inverse_mut() {
Some(res)
}
else {
@ -75,29 +75,29 @@ impl<N: BaseNum + Neg<Output = N> + ApproxEq<N>> Inv for Mat3<N> {
}
#[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_m11_m23 = self.m21 * self.m33 - self.m31 * self.m23;
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
}
else {
*self = Mat3::new(
(minor_m12_m23 / det),
((self.m13 * self.m32 - self.m33 * self.m12) / det),
((self.m12 * self.m23 - self.m22 * self.m13) / det),
*self = Matrix3::new(
(minor_m12_m23 / determinant),
((self.m13 * self.m32 - self.m33 * self.m12) / determinant),
((self.m12 * self.m23 - self.m22 * self.m13) / determinant),
(-minor_m11_m23 / det),
((self.m11 * self.m33 - self.m31 * self.m13) / det),
((self.m13 * self.m21 - self.m23 * self.m11) / det),
(-minor_m11_m23 / determinant),
((self.m11 * self.m33 - self.m31 * self.m13) / determinant),
((self.m13 * self.m21 - self.m23 * self.m11) / determinant),
(minor_m11_m22 / det),
((self.m12 * self.m31 - self.m32 * self.m11) / det),
((self.m11 * self.m22 - self.m21 * self.m12) / det)
(minor_m11_m22 / determinant),
((self.m12 * self.m31 - self.m32 * self.m11) / determinant),
((self.m11 * self.m22 - self.m21 * self.m12) / determinant)
);
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]
fn det(&self) -> N {
fn determinant(&self) -> N {
self.m11
}
}
impl<N: BaseNum> Det<N> for Mat2<N> {
impl<N: BaseNum> Determinant<N> for Matrix2<N> {
#[inline]
fn det(&self) -> N {
fn determinant(&self) -> N {
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]
fn det(&self) -> N {
fn determinant(&self) -> N {
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_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]
fn nrows(&self) -> usize {
3
}
#[inline]
fn row(&self, i: usize) -> Vec3<N> {
fn row(&self, i: usize) -> Vector3<N> {
match i {
0 => Vec3::new(self.m11, self.m12, self.m13),
1 => Vec3::new(self.m21, self.m22, self.m23),
2 => Vec3::new(self.m31, self.m32, self.m33),
0 => Vector3::new(self.m11, self.m12, self.m13),
1 => Vector3::new(self.m21, self.m22, self.m23),
2 => Vector3::new(self.m31, self.m32, self.m33),
_ => panic!(format!("Index out of range: 3d matrices do not have {} rows.", i))
}
}
#[inline]
fn set_row(&mut self, i: usize, r: Vec3<N>) {
fn set_row(&mut self, i: usize, r: Vector3<N>) {
match i {
0 => {
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]
fn ncols(&self) -> usize {
3
}
#[inline]
fn col(&self, i: usize) -> Vec3<N> {
fn column(&self, i: usize) -> Vector3<N> {
match i {
0 => Vec3::new(self.m11, self.m21, self.m31),
1 => Vec3::new(self.m12, self.m22, self.m32),
2 => Vec3::new(self.m13, self.m23, self.m33),
0 => Vector3::new(self.m11, self.m21, self.m31),
1 => Vector3::new(self.m12, self.m22, self.m32),
2 => Vector3::new(self.m13, self.m23, self.m33),
_ => panic!(format!("Index out of range: 3d matrices do not have {} cols.", i))
}
}
#[inline]
fn set_col(&mut self, i: usize, r: Vec3<N>) {
fn set_col(&mut self, i: usize, r: Vector3<N>) {
match i {
0 => {
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> {
type Output = Mat3<N>;
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Matrix3<N> {
type Output = Matrix3<N>;
#[inline]
fn mul(self, right: Mat3<N>) -> Mat3<N> {
Mat3::new(
fn mul(self, right: Matrix3<N>) -> Matrix3<N> {
Matrix3::new(
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.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> {
type Output = Mat2<N>;
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Matrix2<N> {
type Output = Matrix2<N>;
#[inline(always)]
fn mul(self, right: Mat2<N>) -> Mat2<N> {
Mat2::new(
fn mul(self, right: Matrix2<N>) -> Matrix2<N> {
Matrix2::new(
self.m11 * right.m11 + self.m12 * right.m21,
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> {
type Output = Vec3<N>;
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vector3<N>> for Matrix3<N> {
type Output = Vector3<N>;
#[inline(always)]
fn mul(self, right: Vec3<N>) -> Vec3<N> {
Vec3::new(
fn mul(self, right: Vector3<N>) -> Vector3<N> {
Vector3::new(
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.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> {
type Output = Vec3<N>;
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Vector3<N> {
type Output = Vector3<N>;
#[inline(always)]
fn mul(self, right: Mat3<N>) -> Vec3<N> {
Vec3::new(
fn mul(self, right: Matrix3<N>) -> Vector3<N> {
Vector3::new(
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.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> {
type Output = Vec2<N>;
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Vector2<N> {
type Output = Vector2<N>;
#[inline(always)]
fn mul(self, right: Mat2<N>) -> Vec2<N> {
Vec2::new(
fn mul(self, right: Matrix2<N>) -> Vector2<N> {
Vector2::new(
self.x * right.m11 + self.y * right.m21,
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> {
type Output = Vec2<N>;
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vector2<N>> for Matrix2<N> {
type Output = Vector2<N>;
#[inline(always)]
fn mul(self, right: Vec2<N>) -> Vec2<N> {
Vec2::new(
fn mul(self, right: Vector2<N>) -> Vector2<N> {
Vector2::new(
self.m11 * right.x + self.m12 * 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> {
type Output = Pnt3<N>;
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Point3<N>> for Matrix3<N> {
type Output = Point3<N>;
#[inline(always)]
fn mul(self, right: Pnt3<N>) -> Pnt3<N> {
Pnt3::new(
fn mul(self, right: Point3<N>) -> Point3<N> {
Point3::new(
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.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> {
type Output = Pnt3<N>;
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Point3<N> {
type Output = Point3<N>;
#[inline(always)]
fn mul(self, right: Mat3<N>) -> Pnt3<N> {
Pnt3::new(
fn mul(self, right: Matrix3<N>) -> Point3<N> {
Point3::new(
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.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> {
type Output = Pnt2<N>;
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Point2<N> {
type Output = Point2<N>;
#[inline(always)]
fn mul(self, right: Mat2<N>) -> Pnt2<N> {
Pnt2::new(
fn mul(self, right: Matrix2<N>) -> Point2<N> {
Point2::new(
self.x * right.m11 + self.y * right.m21,
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> {
type Output = Pnt2<N>;
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Point2<N>> for Matrix2<N> {
type Output = Point2<N>;
#[inline(always)]
fn mul(self, right: Pnt2<N>) -> Pnt2<N> {
Pnt2::new(
fn mul(self, right: Point2<N>) -> Point2<N> {
Point2::new(
self.m11 * right.x + self.m12 * 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!(Mat2, Mat2);
impl_mul_assign_from_mul!(Matrix3, Matrix3);
impl_mul_assign_from_mul!(Matrix2, Matrix2);
impl_mul_assign_from_mul!(Vec3, Mat3);
impl_mul_assign_from_mul!(Vec2, Mat2);
impl_mul_assign_from_mul!(Pnt3, Mat3);
impl_mul_assign_from_mul!(Pnt2, Mat2);
impl_mul_assign_from_mul!(Vector3, Matrix3);
impl_mul_assign_from_mul!(Vector2, Matrix2);
impl_mul_assign_from_mul!(Point3, Matrix3);
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(
($t: ident, $dim: expr) => (
impl<N> AsRef<[N; $dim]> for $t<N> {
($t: ident, $dimension: expr) => (
impl<N> AsRef<[N; $dimension]> for $t<N> {
#[inline]
fn as_ref(&self) -> &[N; $dim] {
fn as_ref(&self) -> &[N; $dimension] {
unsafe {
mem::transmute(self)
}
}
}
impl<N> AsMut<[N; $dim]> for $t<N> {
impl<N> AsMut<[N; $dimension]> for $t<N> {
#[inline]
fn as_mut(&mut self) -> &mut [N; $dim] {
fn as_mut(&mut self) -> &mut [N; $dimension] {
unsafe {
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]
fn from(arr: &'a [N; $dim]) -> &'a $t<N> {
fn from(arr: &'a [N; $dimension]) -> &'a $t<N> {
unsafe {
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]
fn from(arr: &'a mut [N; $dim]) -> &'a mut $t<N> {
fn from(arr: &'a mut [N; $dimension]) -> &'a mut $t<N> {
unsafe {
mem::transmute(arr)
}
@ -55,7 +55,7 @@ macro_rules! conversion_impl(
);
macro_rules! at_fast_impl(
($t: ident, $dim: expr) => (
($t: ident, $dimension: expr) => (
impl<N: Copy> $t<N> {
/// Unsafe read access to a vector element by index.
#[inline]
@ -76,7 +76,7 @@ macro_rules! at_fast_impl(
// However, f32/f64 does not implement Ord…
macro_rules! pord_impl(
($t: ident, $comp0: ident, $($compN: ident),*) => (
impl<N: BaseFloat> POrd for $t<N> {
impl<N: BaseFloat> PartialOrder for $t<N> {
#[inline]
fn inf(&self, other: &$t<N>) -> $t<N> {
$t::new(self.$comp0.min(other.$comp0)
@ -90,24 +90,24 @@ macro_rules! pord_impl(
}
#[inline]
#[allow(unused_mut)] // otherwise there will be a warning for is_eq or Vec1.
fn partial_cmp(&self, other: &$t<N>) -> POrdering {
#[allow(unused_mut)] // otherwise there will be a warning for is_eq or Vector1.
fn partial_cmp(&self, other: &$t<N>) -> PartialOrdering {
let is_lt = self.$comp0 < other.$comp0;
let mut is_eq = self.$comp0 == other.$comp0;
if is_lt { // <
$(
if self.$compN > other.$compN {
return POrdering::NotComparable
return PartialOrdering::NotComparable
}
)*
POrdering::PartialLess
PartialOrdering::PartialLess
}
else { // >=
$(
if self.$compN < other.$compN {
return POrdering::NotComparable
return PartialOrdering::NotComparable
}
else if self.$compN > other.$compN {
is_eq = false;
@ -116,10 +116,10 @@ macro_rules! pord_impl(
)*
if is_eq {
POrdering::PartialEqual
PartialOrdering::PartialEqual
}
else {
POrdering::PartialGreater
PartialOrdering::PartialGreater
}
}
}
@ -177,11 +177,11 @@ macro_rules! vec_cast_impl(
);
macro_rules! indexable_impl(
($t: ident, $dim: expr) => (
($t: ident, $dimension: expr) => (
impl<N> Shape<usize> for $t<N> {
#[inline]
fn shape(&self) -> usize {
$dim
$dimension
}
}
@ -189,18 +189,18 @@ macro_rules! indexable_impl(
#[inline]
fn swap(&mut self, i1: usize, i2: usize) {
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]
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]
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(
($t: ident, $dim: expr) => (
($t: ident, $dimension: expr) => (
impl<N> Iterable<N> for $t<N> {
#[inline]
fn iter<'l>(&'l self) -> Iter<'l, N> {
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(
($t: ident, $dim: expr) => (
($t: ident, $dimension: expr) => (
impl<N> IterableMut<N> for $t<N> {
#[inline]
fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> {
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(
($t: ident, $dim: expr) => (
impl<N> Dim for $t<N> {
($t: ident, $dimension: expr) => (
impl<N> Dimension for $t<N> {
#[inline]
fn dim(_: Option<$t<N>>) -> usize {
$dim
fn dimension(_: Option<$t<N>>) -> usize {
$dimension
}
}
)
@ -281,18 +281,18 @@ macro_rules! container_impl(
/// The dimension of this entity.
#[inline]
pub fn len(&self) -> usize {
Dim::dim(None::<$t<N>>)
Dimension::dimension(None::<$t<N>>)
}
}
)
);
macro_rules! basis_impl(
($t: ident, $dim: expr) => (
($t: ident, $dimension: expr) => (
impl<N: BaseFloat + ApproxEq<N>> Basis for $t<N> {
#[inline]
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 }
}
}
@ -303,14 +303,14 @@ macro_rules! basis_impl(
// orthogonalization algorithm.
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();
unsafe {
basis_element.set_fast(i, ::one());
}
if basis.len() == $dim - 1 {
if basis.len() == $dimension - 1 {
break;
}
@ -322,7 +322,7 @@ macro_rules! basis_impl(
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);
if !f(new_element) { return };
@ -334,7 +334,7 @@ macro_rules! basis_impl(
#[inline]
fn canonical_basis_element(i: usize) -> Option<$t<N>> {
if i < $dim {
if i < $dimension {
let mut basis_element : $t<N> = ::zero();
unsafe {
@ -621,7 +621,7 @@ macro_rules! translation_impl(
}
#[inline]
fn inv_translation(&self) -> $t<N> {
fn inverse_translation(&self) -> $t<N> {
-*self
}
@ -657,7 +657,7 @@ macro_rules! norm_impl(
($t: ident, $($compN: ident),+) => (
impl<N: BaseFloat> Norm<N> for $t<N> {
#[inline]
fn sqnorm(&self) -> N {
fn norm_squared(&self) -> N {
Dot::dot(self, self)
}
@ -816,7 +816,7 @@ macro_rules! translate_impl(
*other + *self
}
fn inv_translate(&self, other: &$t<N>) -> $t<N> {
fn inverse_translate(&self, other: &$t<N>) -> $t<N> {
*other - *self
}
}
@ -830,7 +830,7 @@ macro_rules! rotate_impl(
*other
}
fn inv_rotate(&self, other: &O) -> O {
fn inverse_rotate(&self, other: &O) -> O {
*other
}
}
@ -844,19 +844,19 @@ macro_rules! transform_impl(
self.translate(other)
}
fn inv_transform(&self, other: &$t<N>) -> $t<N> {
self.inv_translate(other)
fn inverse_transform(&self, other: &$t<N>) -> $t<N> {
self.inverse_translate(other)
}
}
)
);
macro_rules! vec_as_pnt_impl(
macro_rules! vec_as_point_impl(
($tv: ident, $t: ident, $($compN: ident),+) => (
impl<N> $tv<N> {
/// Converts this vector to a point.
#[inline]
pub fn to_pnt(self) -> $t<N> {
pub fn to_point(self) -> $t<N> {
$t::new(
$(self.$compN),+
)
@ -864,7 +864,7 @@ macro_rules! vec_as_pnt_impl(
/// Reinterprets this vector as a point.
#[inline]
pub fn as_pnt(&self) -> &$t<N> {
pub fn as_point(&self) -> &$t<N> {
unsafe {
mem::transmute(self)
}
@ -875,11 +875,11 @@ macro_rules! vec_as_pnt_impl(
macro_rules! num_float_vec_impl(
($t: ident) => (
impl<N> NumVec<N> for $t<N>
impl<N> NumVector<N> for $t<N>
where N: BaseNum {
}
impl<N> FloatVec<N> for $t<N>
impl<N> FloatVector<N> for $t<N>
where N: BaseFloat + ApproxEq<N> {
}
)

View File

@ -7,35 +7,35 @@ use num::{Zero, One};
use generic_array::{GenericArray, ArrayLength};
use traits::operations::{ApproxEq, Axpy, Mean};
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")]
use quickcheck::{Arbitrary, Gen};
/// A static array of arbitrary dimension.
#[repr(C)]
#[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.
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> {
fn clone(&self) -> VecN<N, D> {
VecN::new(self.at.clone())
impl<N: Clone, D: ArrayLength<N>> Clone for VectorN<N, D> {
fn clone(&self) -> VectorN<N, D> {
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 { }
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.
#[inline]
pub fn new(components: GenericArray<N, D>) -> VecN<N, D> {
VecN {
pub fn new(components: GenericArray<N, D>) -> VectorN<N, D> {
VectorN {
at: components
}
}
@ -47,31 +47,31 @@ impl<N, D: ArrayLength<N>> VecN<N, D> {
}
}
impl<N, D: ArrayLength<N>> Dim for VecN<N, D> {
fn dim(_unused: Option<Self>) -> usize {
impl<N, D: ArrayLength<N>> Dimension for VectorN<N, D> {
fn dimension(_unused: Option<Self>) -> 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]
fn from_iter<I: IntoIterator<Item = N>>(param: I) -> VecN<N, D> {
let mut res: VecN<N, D> = unsafe { mem::uninitialized() };
fn from_iter<I: IntoIterator<Item = N>>(param: I) -> VectorN<N, D> {
let mut res: VectorN<N, D> = unsafe { mem::uninitialized() };
let mut it = param.into_iter();
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
}
}
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]
fn rand<R: Rng>(rng: &mut R) -> VecN<N, D> {
let mut res: VecN<N, D> = unsafe { mem::uninitialized() };
fn rand<R: Rng>(rng: &mut R) -> VectorN<N, D> {
let mut res: VectorN<N, D> = unsafe { mem::uninitialized() };
for e in res.iter_mut() {
*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]
fn one() -> VecN<N, D> {
let mut res: VecN<N, D> = unsafe { mem::uninitialized() };
fn one() -> VectorN<N, D> {
let mut res: VectorN<N, D> = unsafe { mem::uninitialized() };
for e in res.iter_mut() {
*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]
fn zero() -> VecN<N, D> {
let mut res: VecN<N, D> = unsafe { mem::uninitialized() };
fn zero() -> VectorN<N, D> {
let mut res: VectorN<N, D> = unsafe { mem::uninitialized() };
for e in res.iter_mut() {
*e = ::zero()
@ -113,11 +113,11 @@ impl<N: Copy + Zero, D: ArrayLength<N>> Zero for VecN<N, D> {
}
#[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]
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()
}
}
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)*> {
#[inline]
fn sqnorm(&self) -> N {
fn norm_squared(&self) -> N {
Dot::dot(self, self)
}

View File

@ -1,7 +1,7 @@
//! Traits of operations having a well-known or explicit geometric meaning.
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
/// can be appended.
@ -11,7 +11,7 @@ pub trait Translation<V> {
fn translation(&self) -> V;
/// Gets the inverse translation associated with this object.
fn inv_translation(&self) -> V;
fn inverse_translation(&self) -> V;
/// Appends a translation to this object.
fn append_translation_mut(&mut self, &V);
@ -36,7 +36,7 @@ pub trait Translate<V> {
fn translate(&self, &V) -> V;
/// 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
@ -46,7 +46,7 @@ pub trait Rotation<V> {
fn rotation(&self) -> V;
/// Gets the inverse rotation associated with `self`.
fn inv_rotation(&self) -> V;
fn inverse_rotation(&self) -> V;
/// Appends a rotation to this object.
fn append_rotation_mut(&mut self, &V);
@ -88,7 +88,7 @@ pub trait Rotate<V> {
fn rotate(&self, v: &V) -> 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.
@ -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.
pub trait RotationMatrix<N, LV: Mul<Self::Output, Output = LV>, AV> : Rotation<AV> {
/// 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`.
fn to_rot_mat(&self) -> Self::Output;
fn to_rotation_matrix(&self) -> Self::Output;
}
/// Composition of a rotation and an absolute value.
@ -187,7 +187,7 @@ pub trait Transformation<M> {
fn transformation(&self) -> M;
/// Gets the inverse transformation of `self`.
fn inv_transformation(&self) -> M;
fn inverse_transformation(&self) -> M;
/// Appends a transformation to this object.
fn append_transformation_mut(&mut self, &M);
@ -213,7 +213,7 @@ pub trait Transform<V> {
fn transform(&self, &V) -> 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.
@ -228,13 +228,13 @@ pub trait Norm<N: BaseFloat> {
/// Computes the norm of `self`.
#[inline]
fn norm(&self) -> N {
self.sqnorm().sqrt()
self.norm_squared().sqrt()
}
/// Computes the squared norm of `self`.
///
/// 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`.
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.
// XXX: once associated types are suported, move this to the `AnyPnt` trait.
pub trait Orig {
// XXX: once associated types are suported, move this to the `AnyPoint` trait.
pub trait Origin {
/// The trivial origin.
fn orig() -> Self;
fn origin() -> Self;
/// 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,
ToHomogeneous, Transform, Transformation, Translate, Translation,
UniformSphereSample};
pub use traits::structure::{FloatVec, FloatPnt, Basis, Cast, Col, Dim, Indexable, Iterable,
IterableMut, Mat, SquareMat, Row, NumVec, NumPnt, PntAsVec, ColSlice,
RowSlice, Diag, DiagMut, Eye, Repeat, Shape, BaseFloat, BaseNum,
pub use traits::structure::{FloatVector, FloatPoint, Basis, Cast, Column, Dimension, Indexable, Iterable,
IterableMut, Matrix, SquareMatrix, Row, NumVector, NumPoint, PointAsVector, ColumnSlice,
RowSlice, Diagonal, DiagMut, Eye, Repeat, Shape, BaseFloat, BaseNum,
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};
pub use traits::operations::POrdering;
pub use traits::operations::PartialOrdering;
pub mod geometry;
pub mod structure;

View File

@ -3,11 +3,11 @@
use num::{Float, Signed};
use std::ops::Mul;
use std::cmp::Ordering;
use traits::structure::SquareMat;
use traits::structure::SquareMatrix;
/// Result of a partial ordering.
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub enum POrdering {
pub enum PartialOrdering {
/// Result of a strict comparison.
PartialLess,
/// Equality relationship.
@ -18,61 +18,61 @@ pub enum POrdering {
NotComparable
}
impl POrdering {
impl PartialOrdering {
/// Returns `true` if `self` is equal to `Equal`.
pub fn is_eq(&self) -> bool {
*self == POrdering::PartialEqual
*self == PartialOrdering::PartialEqual
}
/// Returns `true` if `self` is equal to `Less`.
pub fn is_lt(&self) -> bool {
*self == POrdering::PartialLess
*self == PartialOrdering::PartialLess
}
/// Returns `true` if `self` is equal to `Less` or `Equal`.
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`.
pub fn is_gt(&self) -> bool {
*self == POrdering::PartialGreater
*self == PartialOrdering::PartialGreater
}
/// Returns `true` if `self` is equal to `Greater` or `Equal`.
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`.
pub fn is_not_comparable(&self) -> bool {
*self == POrdering::NotComparable
*self == PartialOrdering::NotComparable
}
/// Creates a `POrdering` from an `Ordering`.
pub fn from_ordering(ord: Ordering) -> POrdering {
/// Creates a `PartialOrdering` from an `Ordering`.
pub fn from_ordering(ord: Ordering) -> PartialOrdering {
match ord {
Ordering::Less => POrdering::PartialLess,
Ordering::Equal => POrdering::PartialEqual,
Ordering::Greater => POrdering::PartialGreater
Ordering::Less => PartialOrdering::PartialLess,
Ordering::Equal => PartialOrdering::PartialEqual,
Ordering::Greater => PartialOrdering::PartialGreater
}
}
/// Converts this `POrdering` to an `Ordering`.
/// Converts this `PartialOrdering` to an `Ordering`.
///
/// Returns `None` if `self` is `NotComparable`.
pub fn to_ordering(self) -> Option<Ordering> {
match self {
POrdering::PartialLess => Some(Ordering::Less),
POrdering::PartialEqual => Some(Ordering::Equal),
POrdering::PartialGreater => Some(Ordering::Greater),
POrdering::NotComparable => None
PartialOrdering::PartialLess => Some(Ordering::Less),
PartialOrdering::PartialEqual => Some(Ordering::Equal),
PartialOrdering::PartialGreater => Some(Ordering::Greater),
PartialOrdering::NotComparable => None
}
}
}
/// Pointwise ordering operations.
pub trait POrd {
pub trait PartialOrder {
/// Returns the infimum of this value and another
fn inf(&self, other: &Self) -> Self;
@ -80,49 +80,49 @@ pub trait POrd {
fn sup(&self, other: &Self) -> Self;
/// 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`.
#[inline]
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`.
#[inline]
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`.
#[inline]
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`.
#[inline]
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.
#[inline]
fn partial_min<'a>(&'a self, other: &'a Self) -> Option<&'a Self> {
match POrd::partial_cmp(self, other) {
POrdering::PartialLess | POrdering::PartialEqual => Some(self),
POrdering::PartialGreater => Some(other),
POrdering::NotComparable => None
match PartialOrder::partial_cmp(self, other) {
PartialOrdering::PartialLess | PartialOrdering::PartialEqual => Some(self),
PartialOrdering::PartialGreater => Some(other),
PartialOrdering::NotComparable => None
}
}
/// Return the maximum of `self` and `other` if they are comparable.
#[inline]
fn partial_max<'a>(&'a self, other: &'a Self) -> Option<&'a Self> {
match POrd::partial_cmp(self, other) {
POrdering::PartialGreater | POrdering::PartialEqual => Some(self),
POrdering::PartialLess => Some(other),
POrdering::NotComparable => None
match PartialOrder::partial_cmp(self, other) {
PartialOrdering::PartialGreater | PartialOrdering::PartialEqual => Some(self),
PartialOrdering::PartialLess => Some(other),
PartialOrdering::NotComparable => None
}
}
@ -276,18 +276,18 @@ pub trait Absolute<A> {
}
/// 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`.
fn inv(&self) -> Option<Self>;
fn inverse(&self) -> Option<Self>;
/// 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.
pub trait Det<N> {
pub trait Determinant<N> {
/// Returns the determinant of `m`.
fn det(&self) -> N;
fn determinant(&self) -> N;
}
/// Trait of objects which can be transposed.
@ -309,19 +309,19 @@ pub trait Outer {
}
/// 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`:
///
/// * For matrices, observations are stored in its rows.
/// * 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`:
///
/// * For matrices, observations are stored in its rows.
/// * For vectors, observations are stored in its components (thus are 1-dimensional).
fn cov_to(&self, out: &mut M) {
*out = self.cov()
fn covariance_to(&self, out: &mut M) {
*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.
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.
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,
Index, IndexMut, Neg};
use num::{Float, Zero, One};
use traits::operations::{Axpy, Transpose, Inv, Absolute};
use traits::geometry::{Dot, Norm, Orig};
use traits::operations::{Axpy, Transpose, Inverse, Absolute};
use traits::geometry::{Dot, Norm, Origin};
/// Basic integral numeric trait.
pub trait BaseNum: Copy + Zero + One +
@ -64,31 +64,31 @@ pub trait Cast<T> {
/// Trait of matrices.
///
/// A matrix has rows and columns and are able to multiply them.
pub trait Mat<N, R, C: Mul<Self, Output = R>>: Sized +
Row<R> + Col<C> + Mul<R, Output = C> +
pub trait Matrix<N, R, C: Mul<Self, Output = R>>: Sized +
Row<R> + Column<C> + Mul<R, Output = C> +
Index<(usize, usize), Output = N>
{ }
impl<N, M, R, C> Mat<N, R, C> for M
where M: Row<R> + Col<C> + Mul<R, Output = C> + Index<(usize, usize), Output = N>,
impl<N, M, R, C> Matrix<N, R, C> for M
where M: Row<R> + Column<C> + Mul<R, Output = C> + Index<(usize, usize), Output = N>,
C: Mul<M, Output = R>,
{ }
/// 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> +
Eye + Transpose + Diag<V> + Inv + Dim + One {
Eye + Transpose + Diagonal<V> + Inverse + Dimension + One {
}
impl<N, V, M> SquareMat<N, V> for M
where M: Mat<N, V, V> + Mul<M, Output = M> + Eye + Transpose + Diag<V> + Inv + Dim + One,
impl<N, V, M> SquareMatrix<N, V> for M
where M: Matrix<N, V, V> + Mul<M, Output = M> + Eye + Transpose + Diagonal<V> + Inverse + Dimension + One,
V: Mul<M, Output = V> {
}
/// Trait for constructing the identity matrix
pub trait Eye {
/// 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.
@ -134,12 +134,12 @@ pub trait Row<R> {
}
/// 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.
fn ncols(&self) -> usize;
/// 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`.
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
pub trait ColSlice<C> {
pub trait ColumnSlice<C> {
/// 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;
}
@ -161,24 +161,24 @@ pub trait RowSlice<R> {
}
/// Trait of objects having a spacial dimension known at compile time.
pub trait Dim: Sized {
pub trait Dimension: Sized {
/// 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.
pub trait Diag<V> {
pub trait Diagonal<V> {
/// 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.
fn diag(&self) -> V;
fn diagonal(&self) -> V;
}
/// 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.
fn set_diag(&mut self, diag: &V);
fn set_diag(&mut self, diagonal: &V);
}
/// 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.
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> +
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> +
MulAssign<N> + DivAssign<N> +
Dim + Index<usize, Output = N> +
Dimension + Index<usize, Output = N> +
Zero + PartialEq + Dot<N> + Axpy<N> {
}
/// 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.
pub trait PntAsVec {
pub trait PointAsVector {
/// 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.
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.
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
// done on rustc.
/// 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.
// XXX: the vector space element `V` should be an associated type. Though this would prevent V from
// having bounds (they are not supported yet). So, for now, we will just use a type parameter.
pub trait NumPnt<N>:
pub trait NumPoint<N>:
Copy +
PntAsVec +
Dim +
Orig +
PointAsVector +
Dimension +
Origin +
PartialEq +
Axpy<N> +
Sub<Self, Output = <Self as PntAsVec>::Vec> +
Sub<Self, Output = <Self as PointAsVector>::Vector> +
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> +
AddAssign<<Self as PntAsVec>::Vec> +
AddAssign<<Self as PointAsVector>::Vector> +
Index<usize, Output = N> { // FIXME: + Sub<V, Self>
}
/// Trait of points with components implementing the `BaseFloat` trait.
pub trait FloatPnt<N: BaseFloat>: NumPnt<N> + Sized
where <Self as PntAsVec>::Vec: Norm<N> {
pub trait FloatPoint<N: BaseFloat>: NumPoint<N> + Sized
where <Self as PointAsVector>::Vector: Norm<N> {
/// Computes the square distance between two points.
#[inline]
fn sqdist(&self, other: &Self) -> N {
(*self - *other).sqnorm()
fn distance_squared(&self, other: &Self) -> N {
(*self - *other).norm_squared()
}
/// Computes the distance between two points.
#[inline]
fn dist(&self, other: &Self) -> N {
fn distance(&self, other: &Self) -> N {
(*self - *other).norm()
}
}

View File

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

View File

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

View File

@ -2,18 +2,18 @@ extern crate nalgebra as na;
extern crate rand;
use rand::random;
use na::{Rot2, Rot3, Iso2, Iso3, Sim2, Sim3, Vec3, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6, DMat, DVec,
Row, Col, Diag, Transpose, RowSlice, ColSlice, Shape};
use na::{Rotation2, Rotation3, Isometry2, Isometry3, Similarity2, Similarity3, Vector3, Matrix1, Matrix2, Matrix3, Matrix4, Matrix5, Matrix6, DMatrix, DVector,
Row, Column, Diagonal, Transpose, RowSlice, ColumnSlice, Shape};
macro_rules! test_inv_mat_impl(
macro_rules! test_inverse_mat_impl(
($t: ty) => (
for _ in 0usize .. 10000 {
let randmat : $t = random();
let randmatrix : $t = random();
match na::inv(&randmat) {
match na::inverse(&randmatrix) {
None => { },
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(
($t: ty) => (
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(
($t: ty) => (
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;
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 {
// construct symmetric positive definite matrix
let mut randmat : $t = random();
let mut diagmat : $t = Diag::from_diag(&na::diag(&randmat));
let mut randmatrix : $t = random();
let mut diagmatrix : $t = Diagonal::from_diag(&na::diagonal(&randmatrix));
diagmat = na::abs(&diagmat) + 1.0;
randmat = randmat * diagmat * na::transpose(&randmat);
diagmatrix = na::abs(&diagmatrix) + 1.0;
randmatrix = randmatrix * diagmatrix * na::transpose(&randmatrix);
let result = na::cholesky(&randmat);
let result = na::cholesky(&randmatrix);
assert!(result.is_ok());
let v = result.unwrap();
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) => (
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 (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(
($t: ty) => {
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.
let randmat = na::transpose(&randmat) * randmat;
let (eigenvectors, eigenvalues) = na::eigen_qr(&randmat, &1e-13, 100);
let randmatrix = na::transpose(&randmatrix) * randmatrix;
let (eigenvectors, eigenvalues) = na::eigen_qr(&randmatrix, &1e-13, 100);
let diag: $t = Diag::from_diag(&eigenvalues);
let recomp = eigenvectors * diag * na::transpose(&eigenvectors);
let diagonal: $t = Diagonal::from_diag(&eigenvalues);
let recomp = eigenvectors * diagonal * na::transpose(&eigenvectors);
println!("eigenvalues: {:?}", eigenvalues);
println!(" mat: {:?}", randmat);
println!(" matrix: {:?}", randmatrix);
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 {
let randmat : $t = random();
let randmatrix : $t = random();
// Take only diagonal part
let randmat: $t = Diag::from_diag(&randmat.diag());
let (eigenvectors, eigenvalues) = na::eigen_qr(&randmat, &1e-13, 100);
let randmatrix: $t = Diagonal::from_diag(&randmatrix.diagonal());
let (eigenvectors, eigenvalues) = na::eigen_qr(&randmatrix, &1e-13, 100);
let diag: $t = Diag::from_diag(&eigenvalues);
let recomp = eigenvectors * diag * na::transpose(&eigenvectors);
let diagonal: $t = Diagonal::from_diag(&eigenvalues);
let recomp = eigenvectors * diagonal * na::transpose(&eigenvectors);
println!("eigenvalues: {:?}", eigenvalues);
println!(" mat: {:?}", randmat);
println!(" matrix: {:?}", randmatrix);
println!("recomp: {:?}", recomp);
assert!(na::approx_eq_eps(&randmat, &recomp, &1.0e-2));
assert!(na::approx_eq_eps(&randmatrix, &recomp, &1.0e-2));
}
}
);
#[test]
fn test_transpose_mat1() {
test_transpose_mat_impl!(Mat1<f64>);
test_transpose_mat_impl!(Matrix1<f64>);
}
#[test]
fn test_transpose_mat2() {
test_transpose_mat_impl!(Mat2<f64>);
test_transpose_mat_impl!(Matrix2<f64>);
}
#[test]
fn test_transpose_mat3() {
test_transpose_mat_impl!(Mat3<f64>);
test_transpose_mat_impl!(Matrix3<f64>);
}
#[test]
fn test_transpose_mat4() {
test_transpose_mat_impl!(Mat4<f64>);
test_transpose_mat_impl!(Matrix4<f64>);
}
#[test]
fn test_transpose_mat5() {
test_transpose_mat_impl!(Mat5<f64>);
test_transpose_mat_impl!(Matrix5<f64>);
}
#[test]
fn test_transpose_mat6() {
test_transpose_mat_impl!(Mat6<f64>);
test_transpose_mat_impl!(Matrix6<f64>);
}
#[test]
fn test_inv_mat1() {
test_inv_mat_impl!(Mat1<f64>);
fn test_inverse_mat1() {
test_inverse_mat_impl!(Matrix1<f64>);
}
#[test]
fn test_inv_mat2() {
test_inv_mat_impl!(Mat2<f64>);
fn test_inverse_mat2() {
test_inverse_mat_impl!(Matrix2<f64>);
}
#[test]
fn test_inv_mat3() {
test_inv_mat_impl!(Mat3<f64>);
fn test_inverse_mat3() {
test_inverse_mat_impl!(Matrix3<f64>);
}
#[test]
fn test_inv_mat4() {
test_inv_mat_impl!(Mat4<f64>);
fn test_inverse_mat4() {
test_inverse_mat_impl!(Matrix4<f64>);
}
#[test]
fn test_inv_mat5() {
test_inv_mat_impl!(Mat5<f64>);
fn test_inverse_mat5() {
test_inverse_mat_impl!(Matrix5<f64>);
}
#[test]
fn test_inv_mat6() {
test_inv_mat_impl!(Mat6<f64>);
fn test_inverse_mat6() {
test_inverse_mat_impl!(Matrix6<f64>);
}
#[test]
fn test_inv_rot2() {
test_inv_mat_impl!(Rot2<f64>);
fn test_inverse_rot2() {
test_inverse_mat_impl!(Rotation2<f64>);
}
#[test]
fn test_inv_rot3() {
test_inv_mat_impl!(Rot3<f64>);
fn test_inverse_rot3() {
test_inverse_mat_impl!(Rotation3<f64>);
}
#[test]
fn test_inv_iso2() {
test_inv_mat_impl!(Iso2<f64>);
fn test_inverse_iso2() {
test_inverse_mat_impl!(Isometry2<f64>);
}
#[test]
fn test_inv_iso3() {
test_inv_mat_impl!(Iso3<f64>);
fn test_inverse_iso3() {
test_inverse_mat_impl!(Isometry3<f64>);
}
#[test]
fn test_inv_sim2() {
test_inv_mat_impl!(Sim2<f64>);
fn test_inverse_sim2() {
test_inverse_mat_impl!(Similarity2<f64>);
}
#[test]
fn test_inv_sim3() {
test_inv_mat_impl!(Sim3<f64>);
fn test_inverse_sim3() {
test_inverse_mat_impl!(Similarity3<f64>);
}
#[test]
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]
fn test_mean_dmat() {
let mat = DMat::from_row_vec(
fn test_mean_dmatrix() {
let matrix = DMatrix::from_row_vector(
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]
fn test_cov_dmat() {
let mat = DMat::from_row_vec(
fn test_covariance_dmatrix() {
let matrix = DMatrix::from_row_vector(
5,
3,
&[
@ -251,7 +251,7 @@ fn test_cov_dmat() {
]
);
let expected = DMat::from_row_vec(
let expected = DMatrix::from_row_vector(
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]
fn test_transpose_dmat() {
let mat = DMat::from_row_vec(
fn test_transpose_dmatrix() {
let matrix = DMatrix::from_row_vector(
8,
4,
&[
@ -281,12 +281,12 @@ fn test_transpose_dmat() {
]
);
assert!(na::transpose(&na::transpose(&mat)) == mat);
assert!(na::transpose(&na::transpose(&matrix)) == matrix);
}
#[test]
fn test_row_dmat() {
let mat = DMat::from_row_vec(
fn test_row_dmatrix() {
let matrix = DMatrix::from_row_vector(
8,
4,
&[
@ -301,19 +301,19 @@ fn test_row_dmat() {
]
);
assert_eq!(&DVec::from_slice(4, &[1u32, 2, 3, 4]), &mat.row(0));
assert_eq!(&DVec::from_slice(4, &[5u32, 6, 7, 8]), &mat.row(1));
assert_eq!(&DVec::from_slice(4, &[9u32, 10, 11, 12]), &mat.row(2));
assert_eq!(&DVec::from_slice(4, &[13u32, 14, 15, 16]), &mat.row(3));
assert_eq!(&DVec::from_slice(4, &[17u32, 18, 19, 20]), &mat.row(4));
assert_eq!(&DVec::from_slice(4, &[21u32, 22, 23, 24]), &mat.row(5));
assert_eq!(&DVec::from_slice(4, &[25u32, 26, 27, 28]), &mat.row(6));
assert_eq!(&DVec::from_slice(4, &[29u32, 30, 31, 32]), &mat.row(7));
assert_eq!(&DVector::from_slice(4, &[1u32, 2, 3, 4]), &matrix.row(0));
assert_eq!(&DVector::from_slice(4, &[5u32, 6, 7, 8]), &matrix.row(1));
assert_eq!(&DVector::from_slice(4, &[9u32, 10, 11, 12]), &matrix.row(2));
assert_eq!(&DVector::from_slice(4, &[13u32, 14, 15, 16]), &matrix.row(3));
assert_eq!(&DVector::from_slice(4, &[17u32, 18, 19, 20]), &matrix.row(4));
assert_eq!(&DVector::from_slice(4, &[21u32, 22, 23, 24]), &matrix.row(5));
assert_eq!(&DVector::from_slice(4, &[25u32, 26, 27, 28]), &matrix.row(6));
assert_eq!(&DVector::from_slice(4, &[29u32, 30, 31, 32]), &matrix.row(7));
}
#[test]
fn test_row_slice_dmat() {
let mat = DMat::from_row_vec(
fn test_row_slice_dmatrix() {
let matrix = DMatrix::from_row_vector(
5,
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!(&DVec::from_slice(2, &[1u32, 2]), &mat.row_slice(0, 0, 2));
assert_eq!(&DVec::from_slice(2, &[10u32, 11]), &mat.row_slice(2, 1, 3));
assert_eq!(&DVec::from_slice(2, &[19u32, 20]), &mat.row_slice(4, 2, 4));
assert_eq!(&DVector::from_slice(4, &[1u32, 2, 3, 4]), &matrix.row_slice(0, 0, 4));
assert_eq!(&DVector::from_slice(2, &[1u32, 2]), &matrix.row_slice(0, 0, 2));
assert_eq!(&DVector::from_slice(2, &[10u32, 11]), &matrix.row_slice(2, 1, 3));
assert_eq!(&DVector::from_slice(2, &[19u32, 20]), &matrix.row_slice(4, 2, 4));
}
#[test]
fn test_col_dmat() {
let mat = DMat::from_row_vec(
fn test_col_dmatrix() {
let matrix = DMatrix::from_row_vector(
8,
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!(&DVec::from_slice(8, &[2u32, 6, 10, 14, 18, 22, 26, 30]), &mat.col(1));
assert_eq!(&DVec::from_slice(8, &[3u32, 7, 11, 15, 19, 23, 27, 31]), &mat.col(2));
assert_eq!(&DVec::from_slice(8, &[4u32, 8, 12, 16, 20, 24, 28, 32]), &mat.col(3));
assert_eq!(&DVector::from_slice(8, &[1u32, 5, 9, 13, 17, 21, 25, 29]), &matrix.column(0));
assert_eq!(&DVector::from_slice(8, &[2u32, 6, 10, 14, 18, 22, 26, 30]), &matrix.column(1));
assert_eq!(&DVector::from_slice(8, &[3u32, 7, 11, 15, 19, 23, 27, 31]), &matrix.column(2));
assert_eq!(&DVector::from_slice(8, &[4u32, 8, 12, 16, 20, 24, 28, 32]), &matrix.column(3));
}
#[test]
fn test_col_slice_dmat() {
let mat = DMat::from_row_vec(
fn test_col_slice_dmatrix() {
let matrix = DMatrix::from_row_vector(
8,
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!(&DVec::from_slice(3, &[1u32, 5, 9]), &mat.col_slice(0, 0, 3));
assert_eq!(&DVec::from_slice(5, &[11u32, 15, 19, 23, 27]), &mat.col_slice(2, 2, 7));
assert_eq!(&DVec::from_slice(2, &[28u32, 32]), &mat.col_slice(3, 6, 8));
assert_eq!(&DVector::from_slice(8, &[1u32, 5, 9, 13, 17, 21, 25, 29]), &matrix.col_slice(0, 0, 8));
assert_eq!(&DVector::from_slice(3, &[1u32, 5, 9]), &matrix.col_slice(0, 0, 3));
assert_eq!(&DVector::from_slice(5, &[11u32, 15, 19, 23, 27]), &matrix.col_slice(2, 2, 7));
assert_eq!(&DVector::from_slice(2, &[28u32, 32]), &matrix.col_slice(3, 6, 8));
}
#[test]
fn test_dmat_from_vec() {
let mat1 = DMat::from_row_vec(
fn test_dmat_from_vector() {
let mat1 = DMatrix::from_row_vector(
8,
4,
&[
@ -394,7 +394,7 @@ fn test_dmat_from_vec() {
]
);
let mat2 = DMat::from_col_vec(
let mat2 = DMatrix::from_col_vector(
8,
4,
&[
@ -412,7 +412,7 @@ fn test_dmat_from_vec() {
#[test]
fn test_dmat_addition() {
let mat1 = DMat::from_row_vec(
let mat1 = DMatrix::from_row_vector(
2,
2,
&[
@ -421,7 +421,7 @@ fn test_dmat_addition() {
]
);
let mat2 = DMat::from_row_vec(
let mat2 = DMatrix::from_row_vector(
2,
2,
&[
@ -430,7 +430,7 @@ fn test_dmat_addition() {
]
);
let res = DMat::from_row_vec(
let res = DMatrix::from_row_vector(
2,
2,
&[
@ -444,7 +444,7 @@ fn test_dmat_addition() {
#[test]
fn test_dmat_multiplication() {
let mat1 = DMat::from_row_vec(
let mat1 = DMatrix::from_row_vector(
2,
2,
&[
@ -453,7 +453,7 @@ fn test_dmat_multiplication() {
]
);
let mat2 = DMat::from_row_vec(
let mat2 = DMatrix::from_row_vector(
2,
2,
&[
@ -462,7 +462,7 @@ fn test_dmat_multiplication() {
]
);
let res = DMat::from_row_vec(
let res = DMatrix::from_row_vector(
2,
2,
&[
@ -477,7 +477,7 @@ fn test_dmat_multiplication() {
// Tests multiplication of rectangular (non-square) matrices.
#[test]
fn test_dmat_multiplication_rect() {
let mat1 = DMat::from_row_vec(
let mat1 = DMatrix::from_row_vector(
1,
2,
&[
@ -485,7 +485,7 @@ fn test_dmat_multiplication_rect() {
]
);
let mat2 = DMat::from_row_vec(
let mat2 = DMatrix::from_row_vector(
2,
3,
&[
@ -494,7 +494,7 @@ fn test_dmat_multiplication_rect() {
]
);
let res = DMat::from_row_vec(
let res = DMatrix::from_row_vector(
1,
3,
&[
@ -510,7 +510,7 @@ fn test_dmat_multiplication_rect() {
#[test]
fn test_dmat_subtraction() {
let mat1 = DMat::from_row_vec(
let mat1 = DMatrix::from_row_vector(
2,
2,
&[
@ -519,7 +519,7 @@ fn test_dmat_subtraction() {
]
);
let mat2 = DMat::from_row_vec(
let mat2 = DMatrix::from_row_vector(
2,
2,
&[
@ -528,7 +528,7 @@ fn test_dmat_subtraction() {
]
);
let res = DMat::from_row_vec(
let res = DMatrix::from_row_vector(
2,
2,
&[
@ -542,7 +542,7 @@ fn test_dmat_subtraction() {
#[test]
fn test_dmat_col() {
let mat = DMat::from_row_vec(
let matrix = DMatrix::from_row_vector(
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]
fn test_dmat_set_col() {
let mut mat = DMat::from_row_vec(
let mut matrix = DMatrix::from_row_vector(
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,
&[
@ -579,12 +579,12 @@ fn test_dmat_set_col() {
]
);
assert!(mat == expected);
assert!(matrix == expected);
}
#[test]
fn test_dmat_row() {
let mat = DMat::from_row_vec(
let matrix = DMatrix::from_row_vector(
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]
fn test_dmat_set_row() {
let mut mat = DMat::from_row_vec(
let mut matrix = DMatrix::from_row_vector(
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,
&[
@ -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]
fn test_qr() {
for _ in 0usize .. 10 {
@ -632,79 +632,79 @@ fn test_qr() {
let dim2: usize = random();
let rows = min(40, max(dim1, dim2));
let cols = min(40, min(dim1, dim2));
let randmat: DMat<f64> = DMat::new_random(rows, cols);
let (q, r) = na::qr(&randmat);
let randmatrix: DMatrix<f64> = DMatrix::new_random(rows, cols);
let (q, r) = na::qr(&randmatrix);
let recomp = q * r;
assert!(na::approx_eq(&randmat, &recomp));
assert!(na::approx_eq(&randmatrix, &recomp));
}
}
*/
#[test]
fn test_qr_mat1() {
test_qr_impl!(Mat1<f64>);
test_qr_impl!(Matrix1<f64>);
}
#[test]
fn test_qr_mat2() {
test_qr_impl!(Mat2<f64>);
test_qr_impl!(Matrix2<f64>);
}
#[test]
fn test_qr_mat3() {
test_qr_impl!(Mat3<f64>);
test_qr_impl!(Matrix3<f64>);
}
#[test]
fn test_qr_mat4() {
test_qr_impl!(Mat4<f64>);
test_qr_impl!(Matrix4<f64>);
}
#[test]
fn test_qr_mat5() {
test_qr_impl!(Mat5<f64>);
test_qr_impl!(Matrix5<f64>);
}
#[test]
fn test_qr_mat6() {
test_qr_impl!(Mat6<f64>);
test_qr_impl!(Matrix6<f64>);
}
#[test]
fn test_eigen_qr_mat1() {
test_eigen_qr_impl!(Mat1<f64>);
test_eigen_qr_impl!(Matrix1<f64>);
}
#[test]
fn test_eigen_qr_mat2() {
test_eigen_qr_impl!(Mat2<f64>);
test_eigen_qr_impl!(Matrix2<f64>);
}
#[test]
fn test_eigen_qr_mat3() {
test_eigen_qr_impl!(Mat3<f64>);
test_eigen_qr_impl!(Matrix3<f64>);
}
#[test]
fn test_eigen_qr_mat4() {
test_eigen_qr_impl!(Mat4<f64>);
test_eigen_qr_impl!(Matrix4<f64>);
}
#[test]
fn test_eigen_qr_mat5() {
test_eigen_qr_impl!(Mat5<f64>);
test_eigen_qr_impl!(Matrix5<f64>);
}
#[test]
fn test_eigen_qr_mat6() {
test_eigen_qr_impl!(Mat6<f64>);
test_eigen_qr_impl!(Matrix6<f64>);
}
#[test]
fn test_from_fn() {
let actual: DMat<usize> = DMat::from_fn(3, 4, |i, j| 10 * i + j);
let expected: DMat<usize> = DMat::from_row_vec(3, 4,
let actual: DMatrix<usize> = DMatrix::from_fn(3, 4, |i, j| 10 * i + j);
let expected: DMatrix<usize> = DMatrix::from_row_vector(3, 4,
&[ 0_0, 0_1, 0_2, 0_3,
1_0, 1_1, 1_2, 1_3,
2_0, 2_1, 2_2, 2_3 ]);
@ -714,21 +714,21 @@ fn test_from_fn() {
#[test]
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,
6.0, 7.0, 8.0);
let second_row = mat.row(1);
let second_col = mat.col(1);
let second_row = matrix.row(1);
let second_col = matrix.column(1);
assert!(second_row == Vec3::new(3.0, 4.0, 5.0));
assert!(second_col == Vec3::new(1.0, 4.0, 7.0));
assert!(second_row == Vector3::new(3.0, 4.0, 5.0));
assert!(second_col == Vector3::new(1.0, 4.0, 7.0));
}
#[test]
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 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 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 : 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);
@ -744,7 +744,7 @@ fn test_cholesky_const() {
#[test]
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);
@ -754,7 +754,7 @@ fn test_cholesky_not_spd() {
#[test]
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);
@ -763,83 +763,83 @@ fn test_cholesky_not_symmetric() {
#[test]
fn test_cholesky_mat1() {
test_cholesky_impl!(Mat1<f64>);
test_cholesky_impl!(Matrix1<f64>);
}
#[test]
fn test_cholesky_mat2() {
test_cholesky_impl!(Mat2<f64>);
test_cholesky_impl!(Matrix2<f64>);
}
#[test]
fn test_cholesky_mat3() {
test_cholesky_impl!(Mat3<f64>);
test_cholesky_impl!(Matrix3<f64>);
}
#[test]
fn test_cholesky_mat4() {
test_cholesky_impl!(Mat4<f64>);
test_cholesky_impl!(Matrix4<f64>);
}
#[test]
fn test_cholesky_mat5() {
test_cholesky_impl!(Mat5<f64>);
test_cholesky_impl!(Matrix5<f64>);
}
#[test]
fn test_cholesky_mat6() {
test_cholesky_impl!(Mat6<f64>);
test_cholesky_impl!(Matrix6<f64>);
}
#[test]
fn test_hessenberg_mat1() {
test_hessenberg_impl!(Mat1<f64>);
test_hessenberg_impl!(Matrix1<f64>);
}
#[test]
fn test_hessenberg_mat2() {
test_hessenberg_impl!(Mat2<f64>);
test_hessenberg_impl!(Matrix2<f64>);
}
#[test]
fn test_hessenberg_mat3() {
test_hessenberg_impl!(Mat3<f64>);
test_hessenberg_impl!(Matrix3<f64>);
}
#[test]
fn test_hessenberg_mat4() {
test_hessenberg_impl!(Mat4<f64>);
test_hessenberg_impl!(Matrix4<f64>);
}
#[test]
fn test_hessenberg_mat5() {
test_hessenberg_impl!(Mat5<f64>);
test_hessenberg_impl!(Matrix5<f64>);
}
#[test]
fn test_hessenberg_mat6() {
test_hessenberg_impl!(Mat6<f64>);
test_hessenberg_impl!(Matrix6<f64>);
}
#[test]
fn test_transpose_square_mat() {
let col_major_mat = &[0, 1, 2, 3,
fn test_transpose_square_matrix() {
let col_major_matrix = &[0, 1, 2, 3,
0, 1, 2, 3,
0, 1, 2, 3,
0, 1, 2, 3];
let num_rows = 4;
let num_cols = 4;
let mut mat = DMat::from_col_vec(num_rows, num_cols, col_major_mat);
mat.transpose_mut();
let mut matrix = DMatrix::from_col_vector(num_rows, num_cols, col_major_matrix);
matrix.transpose_mut();
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]
fn test_outer_dvec() {
let vec = DVec::from_slice(5, &[ 1.0, 2.0, 3.0, 4.0, 5.0 ]);
let row = DMat::from_row_vec(1, 5, &vec[..]);
fn test_outer_dvector() {
let vector = DVector::from_slice(5, &[ 1.0, 2.0, 3.0, 4.0, 5.0 ]);
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 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.
@ -25,52 +25,52 @@ macro_rules! test_op_vs_op_assign(
);
// Multiplication.
test_op_vs_op_assign!(test_vec3_f32_mul_assign, Vec3<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_quat_f32_mul_assign, Quat<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, Matrix3<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_quat_quat_mul_assign, Quat<f32>, Quat<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_vec3_vec3_mul_assign, Vector3<f32>, Vector3<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_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_pnt3_unit_quat_mul_assign, Pnt3<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_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_vec3_mat3_mul_assign, Vec3<f32>, Mat3<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_mat3_mat3_mul_assign, Matrix3<f32>, Matrix3<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_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_vec3_rot3_mul_assign, Vec3<f32>, Rot3<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_rot3_rot3_mul_assign, Rotation3<f32>, Rotation3<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_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_rot3_mul_assign, Iso3<f32>, Rot3<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, 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_iso3_mul_assign, Sim3<f32>, Iso3<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_sim3_mul_assign, Similarity3<f32>, Similarity3<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, Similarity3<f32>, Rotation3<f32>, mul, mul_assign);
// Division.
test_op_vs_op_assign!(test_vec3_vec3_div_assign, Vec3<f32>, Vec3<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_unit_quat_unit_quat_div_assign, UnitQuat<f32>, UnitQuat<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_quaternion_quaternion_div_assign, Quaternion<f32>, Quaternion<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_mat3_f32_div_assign, Mat3<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, Matrix3<f32>, f32, div, div_assign);
// Addition.
test_op_vs_op_assign!(test_vec3_vec3_add_assign, Vec3<f32>, Vec3<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_quat_quat_add_assign, Quat<f32>, Quat<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, Matrix3<f32>, Matrix3<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_mat3_f32_add_assign, Mat3<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, Matrix3<f32>, f32, add, add_assign);
// Subtraction.
test_op_vs_op_assign!(test_vec3_vec3_sub_assign, Vec3<f32>, Vec3<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_quat_quat_sub_assign, Quat<f32>, Quat<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, Matrix3<f32>, Matrix3<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_mat3_f32_sub_assign, Mat3<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, Matrix3<f32>, f32, sub, sub_assign);

View File

@ -1,57 +1,57 @@
extern crate nalgebra as na;
extern crate rand;
use na::{Pnt3, Vec3, Rot3, UnitQuat, Rotation};
use na::{Point3, Vector3, Rotation3, UnitQuaternion, Rotation};
use rand::random;
#[test]
fn test_quat_as_mat() {
fn test_quaternion_as_matrix() {
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]
fn test_quat_mul_vec_or_pnt_as_mat() {
fn test_quaternion_mul_vec_or_point_as_matrix() {
for _ in 0usize .. 10000 {
let axis_angle: Vec3<f64> = random();
let vec: Vec3<f64> = random();
let pnt: Pnt3<f64> = random();
let axis_angle: Vector3<f64> = random();
let vector: Vector3<f64> = random();
let point: Point3<f64> = random();
let mat = Rot3::new(axis_angle);
let quat = UnitQuat::new(axis_angle);
let matrix = Rotation3::new(axis_angle);
let quaternion = UnitQuaternion::new(axis_angle);
assert!(na::approx_eq(&(mat * vec), &(quat * vec)));
assert!(na::approx_eq(&(mat * pnt), &(quat * pnt)));
assert!(na::approx_eq(&(vec * mat), &(vec * quat)));
assert!(na::approx_eq(&(pnt * mat), &(pnt * quat)));
assert!(na::approx_eq(&(matrix * vector), &(quaternion * vector)));
assert!(na::approx_eq(&(matrix * point), &(quaternion * point)));
assert!(na::approx_eq(&(vector * matrix), &(vector * quaternion)));
assert!(na::approx_eq(&(point * matrix), &(point * quaternion)));
}
}
#[test]
fn test_quat_div_quat() {
fn test_quaternion_div_quaternion() {
for _ in 0usize .. 10000 {
let axis_angle1: Vec3<f64> = random();
let axis_angle2: Vec3<f64> = random();
let axis_angle1: Vector3<f64> = random();
let axis_angle2: Vector3<f64> = random();
let r1 = Rot3::new(axis_angle1);
let r2 = na::inv(&Rot3::new(axis_angle2)).unwrap();
let r1 = Rotation3::new(axis_angle1);
let r2 = na::inverse(&Rotation3::new(axis_angle2)).unwrap();
let q1 = UnitQuat::new(axis_angle1);
let q2 = UnitQuat::new(axis_angle2);
let q1 = UnitQuaternion::new(axis_angle1);
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]
fn test_quat_to_axis_angle() {
fn test_quaternion_to_axis_angle() {
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);
assert!(na::approx_eq(&q.rotation(), &axis_angle))
@ -59,21 +59,21 @@ fn test_quat_to_axis_angle() {
}
#[test]
fn test_quat_euler_angles() {
fn test_quaternion_euler_angles() {
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 m = Rot3::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 = 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]
fn test_quat_rotation_between() {
let q1: UnitQuat<f64> = random();
let q2: UnitQuat<f64> = random();
fn test_quaternion_rotation_between() {
let q1: UnitQuaternion<f64> = random();
let q2: UnitQuaternion<f64> = random();
let delta = na::rotation_between(&q1, &q2);
@ -81,9 +81,9 @@ fn test_quat_rotation_between() {
}
#[test]
fn test_quat_angle_between() {
let q1: UnitQuat<f64> = random();
let q2: UnitQuat<f64> = random();
fn test_quaternion_angle_between() {
let q1: UnitQuaternion<f64> = random();
let q2: UnitQuaternion<f64> = random();
let delta = na::rotation_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;
use rand::random;
use na::{Pnt2, Pnt3, Vec2, Vec3, Vec1, Rot2, Rot3, Persp3, PerspMat3, Ortho3, OrthoMat3,
Iso2, Iso3, Sim2, Sim3, BaseFloat, Transform};
use na::{Point2, Point3, Vector2, Vector3, Vector1, Rotation2, Rotation3, Perspective3, PerspectiveMatrix3, Orthographic3, OrthographicMatrix3,
Isometry2, Isometry3, Similarity2, Similarity3, BaseFloat, Transform};
#[test]
fn test_rotation2() {
for _ in 0usize .. 10000 {
let randmat: na::Rot2<f64> = na::one();
let ang = Vec1::new(na::abs(&random::<f64>()) % <f64 as BaseFloat>::pi());
let randmatrix: na::Rotation2<f64> = na::one();
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]
fn test_inv_rotation3() {
fn test_inverse_rotation3() {
for _ in 0usize .. 10000 {
let randmat: Rot3<f64> = na::one();
let dir: Vec3<f64> = random();
let randmatrix: Rotation3<f64> = na::one();
let dir: Vector3<f64> = random();
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]
fn test_rot3_rotation_between() {
let r1: Rot3<f64> = random();
let r2: Rot3<f64> = random();
let r1: Rotation3<f64> = random();
let r2: Rotation3<f64> = random();
let delta = na::rotation_between(&r1, &r2);
@ -39,8 +39,8 @@ fn test_rot3_rotation_between() {
#[test]
fn test_rot3_angle_between() {
let r1: Rot3<f64> = random();
let r2: Rot3<f64> = random();
let r1: Rotation3<f64> = random();
let r2: Rotation3<f64> = random();
let delta = na::rotation_between(&r1, &r2);
let delta_angle = na::angle_between(&r1, &r2);
@ -50,8 +50,8 @@ fn test_rot3_angle_between() {
#[test]
fn test_rot2_rotation_between() {
let r1: Rot2<f64> = random();
let r2: Rot2<f64> = random();
let r1: Rotation2<f64> = random();
let r2: Rotation2<f64> = random();
let delta = na::rotation_between(&r1, &r2);
@ -60,8 +60,8 @@ fn test_rot2_rotation_between() {
#[test]
fn test_rot2_angle_between() {
let r1: Rot2<f64> = random();
let r2: Rot2<f64> = random();
let r1: Rotation2<f64> = random();
let r2: Rotation2<f64> = random();
let delta = na::rotation_between(&r1, &r2);
let delta_angle = na::angle_between(&r1, &r2);
@ -73,58 +73,58 @@ fn test_rot2_angle_between() {
#[test]
fn test_look_at_rh_iso3() {
for _ in 0usize .. 10000 {
let eye = random::<Pnt3<f64>>();
let target = random::<Pnt3<f64>>();
let up = random::<Vec3<f64>>();
let viewmat = Iso3::look_at_rh(&eye, &target, &up);
let eye = random::<Point3<f64>>();
let target = random::<Point3<f64>>();
let up = random::<Vector3<f64>>();
let viewmatrix = Isometry3::look_at_rh(&eye, &target, &up);
let origin: Pnt3<f64> = na::orig();
assert_eq!(&(viewmat * eye), &origin);
assert!(na::approx_eq(&na::normalize(&(viewmat * (target - eye))), &-Vec3::z()));
let origin: Point3<f64> = na::origin();
assert_eq!(&(viewmatrix * eye), &origin);
assert!(na::approx_eq(&na::normalize(&(viewmatrix * (target - eye))), &-Vector3::z()));
}
}
#[test]
fn test_look_at_rh_rot3() {
for _ in 0usize .. 10000 {
let dir = random::<Vec3<f64>>();
let up = random::<Vec3<f64>>();
let viewmat = Rot3::look_at_rh(&dir, &up);
let dir = random::<Vector3<f64>>();
let up = random::<Vector3<f64>>();
let viewmatrix = Rotation3::look_at_rh(&dir, &up);
println!("found: {}", viewmat * dir);
assert!(na::approx_eq(&na::normalize(&(viewmat * dir)), &-Vec3::z()));
println!("found: {}", viewmatrix * dir);
assert!(na::approx_eq(&na::normalize(&(viewmatrix * dir)), &-Vector3::z()));
}
}
#[test]
fn test_observer_frame_iso3() {
for _ in 0usize .. 10000 {
let eye = random::<Pnt3<f64>>();
let target = random::<Pnt3<f64>>();
let up = random::<Vec3<f64>>();
let observer = Iso3::new_observer_frame(&eye, &target, &up);
let eye = random::<Point3<f64>>();
let target = random::<Point3<f64>>();
let up = random::<Vector3<f64>>();
let observer = Isometry3::new_observer_frame(&eye, &target, &up);
assert_eq!(&(observer * na::orig::<Pnt3<f64>>()), &eye);
assert!(na::approx_eq(&(observer * Vec3::z()), &na::normalize(&(target - eye))));
assert_eq!(&(observer * na::origin::<Point3<f64>>()), &eye);
assert!(na::approx_eq(&(observer * Vector3::z()), &na::normalize(&(target - eye))));
}
}
#[test]
fn test_observer_frame_rot3() {
for _ in 0usize .. 10000 {
let dir = random::<Vec3<f64>>();
let up = random::<Vec3<f64>>();
let observer = Rot3::new_observer_frame(&dir, &up);
let dir = random::<Vector3<f64>>();
let up = random::<Vector3<f64>>();
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]
fn test_persp() {
let mut p = Persp3::new(42.0f64, 0.5, 1.5, 10.0);
let mut pm = PerspMat3::new(42.0f64, 0.5, 1.5, 10.0);
assert!(p.to_mat() == pm.to_mat());
let mut p = Perspective3::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_matrix() == pm.to_matrix());
assert!(p.aspect() == 42.0);
assert!(p.fovy() == 0.5);
assert!(p.znear() == 1.5);
@ -136,19 +136,19 @@ fn test_persp() {
p.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);
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);
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);
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.fovy() == 0.1);
@ -162,9 +162,9 @@ fn test_persp() {
#[test]
fn test_ortho() {
let mut p = Ortho3::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);
assert!(p.to_mat() == pm.to_mat());
let mut p = Orthographic3::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_matrix() == pm.to_matrix());
assert!(p.left() == -0.3);
assert!(p.right() == 5.2);
assert!(p.bottom() == -3.9);
@ -180,27 +180,27 @@ fn test_ortho() {
p.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);
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);
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);
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);
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);
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.zfar() == 61.0);
@ -208,15 +208,15 @@ fn test_ortho() {
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) => (
#[test]
fn $fnname() {
for _ in 0usize .. 10000 {
let randmat: $t = random();
let randmatrix: $t = 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);
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_inv_transform_impl!(test_transform_inv_transform_rot3, Rot3<f64>, Pnt3<f64>);
test_transform_inv_transform_impl!(test_transform_inv_transform_iso2, Iso2<f64>, Pnt2<f64>);
test_transform_inv_transform_impl!(test_transform_inv_transform_iso3, Iso3<f64>, Pnt3<f64>);
test_transform_inv_transform_impl!(test_transform_inv_transform_sim2, Sim2<f64>, Pnt2<f64>);
test_transform_inv_transform_impl!(test_transform_inv_transform_sim3, Sim3<f64>, Pnt3<f64>);
test_transform_inverse_transform_impl!(test_transform_inverse_transform_rot2, Rotation2<f64>, Point2<f64>);
test_transform_inverse_transform_impl!(test_transform_inverse_transform_rot3, Rotation3<f64>, Point3<f64>);
test_transform_inverse_transform_impl!(test_transform_inverse_transform_iso2, Isometry2<f64>, Point2<f64>);
test_transform_inverse_transform_impl!(test_transform_inverse_transform_iso3, Isometry3<f64>, Point3<f64>);
test_transform_inverse_transform_impl!(test_transform_inverse_transform_sim2, Similarity2<f64>, Point2<f64>);
test_transform_inverse_transform_impl!(test_transform_inverse_transform_sim3, Similarity3<f64>, Point3<f64>);
macro_rules! test_transform_mul_assoc(
($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_inv_transform_sim3_iso3_pnt3, Sim3<f64>, Iso3<f64>, Pnt3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim3_rot3_pnt3, Sim3<f64>, Rot3<f64>, Pnt3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_iso3_iso3_pnt3, Iso3<f64>, Iso3<f64>, Pnt3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_iso3_rot3_pnt3, Iso3<f64>, Rot3<f64>, Pnt3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_rot3_rot3_pnt3, Rot3<f64>, Rot3<f64>, Pnt3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim3_sim3_vec3, Sim3<f64>, Sim3<f64>, Vec3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim3_iso3_vec3, Sim3<f64>, Iso3<f64>, Vec3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim3_rot3_vec3, Sim3<f64>, Rot3<f64>, Vec3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_iso3_iso3_vec3, Iso3<f64>, Iso3<f64>, Vec3<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_iso3_rot3_vec3, Iso3<f64>, Rot3<f64>, Vec3<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_sim3_sim3_point3, Similarity3<f64>, Similarity3<f64>, Point3<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_sim3_iso3_point3, Similarity3<f64>, Isometry3<f64>, Point3<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_sim3_rot3_point3, Similarity3<f64>, Rotation3<f64>, Point3<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_iso3_iso3_point3, Isometry3<f64>, Isometry3<f64>, Point3<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_iso3_rot3_point3, Isometry3<f64>, Rotation3<f64>, Point3<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_rot3_rot3_point3, Rotation3<f64>, Rotation3<f64>, Point3<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_sim3_sim3_vec3, Similarity3<f64>, Similarity3<f64>, Vector3<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_sim3_iso3_vec3, Similarity3<f64>, Isometry3<f64>, Vector3<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_sim3_rot3_vec3, Similarity3<f64>, Rotation3<f64>, Vector3<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_iso3_iso3_vec3, Isometry3<f64>, Isometry3<f64>, Vector3<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_iso3_rot3_vec3, Isometry3<f64>, Rotation3<f64>, Vector3<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_inv_transform_sim2_iso2_pnt2, Sim2<f64>, Iso2<f64>, Pnt2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim2_rot2_pnt2, Sim2<f64>, Rot2<f64>, Pnt2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_iso2_iso2_pnt2, Iso2<f64>, Iso2<f64>, Pnt2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_iso2_rot2_pnt2, Iso2<f64>, Rot2<f64>, Pnt2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_rot2_rot2_pnt2, Rot2<f64>, Rot2<f64>, Pnt2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim2_sim2_vec2, Sim2<f64>, Sim2<f64>, Vec2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim2_iso2_vec2, Sim2<f64>, Iso2<f64>, Vec2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_sim2_rot2_vec2, Sim2<f64>, Rot2<f64>, Vec2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_iso2_iso2_vec2, Iso2<f64>, Iso2<f64>, Vec2<f64>);
test_transform_mul_assoc!(test_transform_inv_transform_iso2_rot2_vec2, Iso2<f64>, Rot2<f64>, Vec2<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_sim2_sim2_point2, Similarity2<f64>, Similarity2<f64>, Point2<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_sim2_iso2_point2, Similarity2<f64>, Isometry2<f64>, Point2<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_sim2_rot2_point2, Similarity2<f64>, Rotation2<f64>, Point2<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_iso2_iso2_point2, Isometry2<f64>, Isometry2<f64>, Point2<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_iso2_rot2_point2, Isometry2<f64>, Rotation2<f64>, Point2<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_rot2_rot2_point2, Rotation2<f64>, Rotation2<f64>, Point2<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_sim2_sim2_vec2, Similarity2<f64>, Similarity2<f64>, Vector2<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_sim2_iso2_vec2, Similarity2<f64>, Isometry2<f64>, Vector2<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_sim2_rot2_vec2, Similarity2<f64>, Rotation2<f64>, Vector2<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_iso2_iso2_vec2, Isometry2<f64>, Isometry2<f64>, Vector2<f64>);
test_transform_mul_assoc!(test_transform_inverse_transform_iso2_rot2_vec2, Isometry2<f64>, Rotation2<f64>, Vector2<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;
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")]
use typenum::U10;
#[cfg(feature="generic_sizes")]
use na::VecN;
use na::VectorN;
macro_rules! test_iterator_impl(
@ -109,9 +109,9 @@ macro_rules! test_subspace_basis_impl(
#[test]
fn test_cross_vec3() {
for _ in 0usize .. 10000 {
let v1 : Vec3<f64> = random();
let v2 : Vec3<f64> = random();
let v3 : Vec3<f64> = na::cross(&v1, &v2);
let v1 : Vector3<f64> = random();
let v2 : Vector3<f64> = random();
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, &v1), &na::zero()));
@ -120,182 +120,182 @@ fn test_cross_vec3() {
#[test]
fn test_commut_dot_vec1() {
test_commut_dot_impl!(Vec1<f64>);
test_commut_dot_impl!(Vector1<f64>);
}
#[test]
fn test_commut_dot_vec2() {
test_commut_dot_impl!(Vec2<f64>);
test_commut_dot_impl!(Vector2<f64>);
}
#[test]
fn test_commut_dot_vec3() {
test_commut_dot_impl!(Vec3<f64>);
test_commut_dot_impl!(Vector3<f64>);
}
#[test]
fn test_commut_dot_vec4() {
test_commut_dot_impl!(Vec4<f64>);
test_commut_dot_impl!(Vector4<f64>);
}
#[test]
fn test_commut_dot_vec5() {
test_commut_dot_impl!(Vec5<f64>);
test_commut_dot_impl!(Vector5<f64>);
}
#[test]
fn test_commut_dot_vec6() {
test_commut_dot_impl!(Vec6<f64>);
test_commut_dot_impl!(Vector6<f64>);
}
#[test]
fn test_basis_vec1() {
test_basis_impl!(Vec1<f64>);
test_basis_impl!(Vector1<f64>);
}
#[test]
fn test_basis_vec2() {
test_basis_impl!(Vec2<f64>);
test_basis_impl!(Vector2<f64>);
}
#[test]
fn test_basis_vec3() {
test_basis_impl!(Vec3<f64>);
test_basis_impl!(Vector3<f64>);
}
#[test]
fn test_basis_vec4() {
test_basis_impl!(Vec4<f64>);
test_basis_impl!(Vector4<f64>);
}
#[test]
fn test_basis_vec5() {
test_basis_impl!(Vec5<f64>);
test_basis_impl!(Vector5<f64>);
}
#[test]
fn test_basis_vec6() {
test_basis_impl!(Vec6<f64>);
test_basis_impl!(Vector6<f64>);
}
#[test]
fn test_subspace_basis_vec1() {
test_subspace_basis_impl!(Vec1<f64>);
test_subspace_basis_impl!(Vector1<f64>);
}
#[test]
fn test_subspace_basis_vec2() {
test_subspace_basis_impl!(Vec2<f64>);
test_subspace_basis_impl!(Vector2<f64>);
}
#[test]
fn test_subspace_basis_vec3() {
test_subspace_basis_impl!(Vec3<f64>);
test_subspace_basis_impl!(Vector3<f64>);
}
#[test]
fn test_subspace_basis_vec4() {
test_subspace_basis_impl!(Vec4<f64>);
test_subspace_basis_impl!(Vector4<f64>);
}
#[test]
fn test_subspace_basis_vec5() {
test_subspace_basis_impl!(Vec5<f64>);
test_subspace_basis_impl!(Vector5<f64>);
}
#[test]
fn test_subspace_basis_vec6() {
test_subspace_basis_impl!(Vec6<f64>);
test_subspace_basis_impl!(Vector6<f64>);
}
#[test]
fn test_scalar_op_vec1() {
test_scalar_op_impl!(Vec1<f64>, f64);
test_scalar_op_impl!(Vector1<f64>, f64);
}
#[test]
fn test_scalar_op_vec2() {
test_scalar_op_impl!(Vec2<f64>, f64);
test_scalar_op_impl!(Vector2<f64>, f64);
}
#[test]
fn test_scalar_op_vec3() {
test_scalar_op_impl!(Vec3<f64>, f64);
test_scalar_op_impl!(Vector3<f64>, f64);
}
#[test]
fn test_scalar_op_vec4() {
test_scalar_op_impl!(Vec4<f64>, f64);
test_scalar_op_impl!(Vector4<f64>, f64);
}
#[test]
fn test_scalar_op_vec5() {
test_scalar_op_impl!(Vec5<f64>, f64);
test_scalar_op_impl!(Vector5<f64>, f64);
}
#[test]
fn test_scalar_op_vec6() {
test_scalar_op_impl!(Vec6<f64>, f64);
test_scalar_op_impl!(Vector6<f64>, f64);
}
#[test]
fn test_iterator_vec1() {
test_iterator_impl!(Vec1<f64>, f64);
test_iterator_impl!(Vector1<f64>, f64);
}
#[test]
fn test_iterator_vec2() {
test_iterator_impl!(Vec2<f64>, f64);
test_iterator_impl!(Vector2<f64>, f64);
}
#[test]
fn test_iterator_vec3() {
test_iterator_impl!(Vec3<f64>, f64);
test_iterator_impl!(Vector3<f64>, f64);
}
#[test]
fn test_iterator_vec4() {
test_iterator_impl!(Vec4<f64>, f64);
test_iterator_impl!(Vector4<f64>, f64);
}
#[test]
fn test_iterator_vec5() {
test_iterator_impl!(Vec5<f64>, f64);
test_iterator_impl!(Vector5<f64>, f64);
}
#[test]
fn test_iterator_vec6() {
test_iterator_impl!(Vec6<f64>, f64);
test_iterator_impl!(Vector6<f64>, f64);
}
#[test]
fn test_ord_vec3() {
// equality
assert!(Vec3::new(0.5f64, 0.5, 0.5) == Vec3::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!(Vec3::new(1.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!(!(Vector3::new(1.5f64, 0.5, 0.5) == Vector3::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
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(&Vec3::new(0.5f64, 0.3, 0.3), &Vec3::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(&Vec3::new(2.0f64, 4.0, 2.0), &Vec3::new(1.0, 2.0, 1.0)).is_gt());
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(&Vector3::new(0.5f64, 0.3, 0.3), &Vector3::new(1.0, 2.0, 1.0)).is_lt());
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(&Vector3::new(2.0f64, 4.0, 2.0), &Vector3::new(1.0, 2.0, 1.0)).is_gt());
// 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]
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::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::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(&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]
fn test_outer_vec3() {
assert_eq!(
na::outer(&Vec3::new(1.0f64, 2.0, 3.0), &Vec3::new(4.0, 5.0, 6.0)),
Mat3::new(
na::outer(&Vector3::new(1.0f64, 2.0, 3.0), &Vector3::new(4.0, 5.0, 6.0)),
Matrix3::new(
4.0, 5.0, 6.0,
8.0, 10.0, 12.0,
12.0, 15.0, 18.0));
@ -305,7 +305,7 @@ fn test_outer_vec3() {
#[test]
fn test_vecn10_add_mul() {
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)))
}
@ -315,29 +315,29 @@ fn test_vecn10_add_mul() {
#[test]
fn test_vec3_rotation_between() {
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);
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]
fn test_vec3_angle_between() {
for _ in 0usize .. 10000 {
let vec: Vec3<f64> = random();
let other: Vec3<f64> = random();
let vector: Vector3<f64> = random();
let other: Vector3<f64> = random();
// Ensure the axis we are using is orthogonal to `vec`.
let axis_ang = na::cross(&vec, &other);
// Ensure the axis we are using is orthogonal to `vector`.
let axis_ang = na::cross(&vector, &other);
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))
}
@ -347,27 +347,27 @@ fn test_vec3_angle_between() {
#[test]
fn test_vec2_rotation_between() {
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);
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]
fn test_vec2_angle_between() {
for _ in 0usize .. 10000 {
let axis_ang: Vec1<f64> = random();
let axis_ang: Vector1<f64> = random();
let ang = na::norm(&axis_ang);
let rot: Rot2<f64> = Rot2::new(axis_ang);
let vec: Vec2<f64> = random();
let rotation: Rotation2<f64> = Rotation2::new(axis_ang);
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))
}