diff --git a/CHANGELOG.md b/CHANGELOG.md index ea2c7aa1..0795fca5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. diff --git a/README.md b/README.md index 528dc563..7ddc7084 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/benches/construction.rs b/benches/construction.rs index 7c512549..8afef416 100644 --- a/benches/construction.rs +++ b/benches/construction.rs @@ -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); -bench_construction!(_bench_rot2_from_axisangle, Rot2::new, axisangle: Vec1); -bench_construction!(_bench_rot3_from_axisangle, Rot3::new, axisangle: Vec3); +bench_construction!(_bench_quaternion_from_axisangle, UnitQuaternion::new, axisangle: Vector3); +bench_construction!(_bench_rot2_from_axisangle, Rotation2::new, axisangle: Vector1); +bench_construction!(_bench_rot3_from_axisangle, Rotation3::new, axisangle: Vector3); -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); diff --git a/benches/dmat.rs b/benches/dmat.rs index b41c8d4d..2d2ea784 100644 --- a/benches/dmat.rs +++ b/benches/dmat.rs @@ -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 = DMat::new_random($nrows, $ncols); - let mut b: DMat = DMat::new_random($nrows, $ncols); + let a: DMatrix = DMatrix::new_random($nrows, $ncols); + let mut b: DMatrix = 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 = DMat::new_random($nrows, $ncols); - let mut v : DVec = DVec::new_random($ncols); + let m : DMatrix = DMatrix::new_random($nrows, $ncols); + let mut v : DVector = 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); } diff --git a/benches/mat.rs b/benches/mat.rs index 76436052..7fed7c84 100644 --- a/benches/mat.rs +++ b/benches/mat.rs @@ -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, Mat2, mul); -bench_binop!(_bench_mat3_mul_m, Mat3, Mat3, mul); -bench_binop!(_bench_mat4_mul_m, Mat4, Mat4, mul); +bench_binop!(_bench_mat2_mul_m, Matrix2, Matrix2, mul); +bench_binop!(_bench_mat3_mul_m, Matrix3, Matrix3, mul); +bench_binop!(_bench_mat4_mul_m, Matrix4, Matrix4, mul); -bench_binop!(_bench_mat2_add_m, Mat2, Mat2, add); -bench_binop!(_bench_mat3_add_m, Mat3, Mat3, add); -bench_binop!(_bench_mat4_add_m, Mat4, Mat4, add); +bench_binop!(_bench_mat2_add_m, Matrix2, Matrix2, add); +bench_binop!(_bench_mat3_add_m, Matrix3, Matrix3, add); +bench_binop!(_bench_mat4_add_m, Matrix4, Matrix4, add); -bench_binop!(_bench_mat2_sub_m, Mat2, Mat2, sub); -bench_binop!(_bench_mat3_sub_m, Mat3, Mat3, sub); -bench_binop!(_bench_mat4_sub_m, Mat4, Mat4, sub); +bench_binop!(_bench_mat2_sub_m, Matrix2, Matrix2, sub); +bench_binop!(_bench_mat3_sub_m, Matrix3, Matrix3, sub); +bench_binop!(_bench_mat4_sub_m, Matrix4, Matrix4, sub); -bench_binop!(_bench_mat2_mul_v, Mat2, Vec2, mul); -bench_binop!(_bench_mat3_mul_v, Mat3, Vec3, mul); -bench_binop!(_bench_mat4_mul_v, Mat4, Vec4, mul); +bench_binop!(_bench_mat2_mul_v, Matrix2, Vector2, mul); +bench_binop!(_bench_mat3_mul_v, Matrix3, Vector3, mul); +bench_binop!(_bench_mat4_mul_v, Matrix4, Vector4, mul); -bench_binop!(_bench_mat2_mul_s, Mat2, f32, mul); -bench_binop!(_bench_mat3_mul_s, Mat3, f32, mul); -bench_binop!(_bench_mat4_mul_s, Mat4, f32, mul); +bench_binop!(_bench_mat2_mul_s, Matrix2, f32, mul); +bench_binop!(_bench_mat3_mul_s, Matrix3, f32, mul); +bench_binop!(_bench_mat4_mul_s, Matrix4, f32, mul); -bench_binop!(_bench_mat2_div_s, Mat2, f32, div); -bench_binop!(_bench_mat3_div_s, Mat3, f32, div); -bench_binop!(_bench_mat4_div_s, Mat4, f32, div); +bench_binop!(_bench_mat2_div_s, Matrix2, f32, div); +bench_binop!(_bench_mat3_div_s, Matrix3, f32, div); +bench_binop!(_bench_mat4_div_s, Matrix4, f32, div); -bench_unop!(_bench_mat2_inv, Mat2, inv); -bench_unop!(_bench_mat3_inv, Mat3, inv); -bench_unop!(_bench_mat4_inv, Mat4, inv); +bench_unop!(_bench_mat2_inv, Matrix2, inverse); +bench_unop!(_bench_mat3_inv, Matrix3, inverse); +bench_unop!(_bench_mat4_inv, Matrix4, inverse); -bench_unop!(_bench_mat2_transpose, Mat2, transpose); -bench_unop!(_bench_mat3_transpose, Mat3, transpose); -bench_unop!(_bench_mat4_transpose, Mat4, transpose); +bench_unop!(_bench_mat2_transpose, Matrix2, transpose); +bench_unop!(_bench_mat3_transpose, Matrix3, transpose); +bench_unop!(_bench_mat4_transpose, Matrix4, transpose); diff --git a/benches/quat.rs b/benches/quat.rs index 02737ccd..d69adc9e 100644 --- a/benches/quat.rs +++ b/benches/quat.rs @@ -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, Quat, add); -bench_binop!(_bench_quat_sub_q, Quat, Quat, sub); -bench_binop!(_bench_quat_mul_q, Quat, Quat, mul); -// bench_binop!(_bench_quat_div_q, Quat, Quat, div) -bench_binop!(_bench_quat_mul_v, UnitQuat, Vec3, mul); -bench_binop!(_bench_quat_mul_s, Quat, f32, mul); -bench_binop!(_bench_quat_div_s, Quat, f32, div); -bench_unop!(_bench_quat_inv, Quat, inv); -bench_unop_self!(_bench_quat_conjugate, Quat, conjugate); -bench_unop!(_bench_quat_normalize, Quat, normalize); +bench_binop!(_bench_quaternion_add_q, Quaternion, Quaternion, add); +bench_binop!(_bench_quaternion_sub_q, Quaternion, Quaternion, sub); +bench_binop!(_bench_quaternion_mul_q, Quaternion, Quaternion, mul); +// bench_binop!(_bench_quaternion_div_q, Quaternion, Quaternion, div) +bench_binop!(_bench_quaternion_mul_v, UnitQuaternion, Vector3, mul); +bench_binop!(_bench_quaternion_mul_s, Quaternion, f32, mul); +bench_binop!(_bench_quaternion_div_s, Quaternion, f32, div); +bench_unop!(_bench_quaternion_inv, Quaternion, inverse); +bench_unop_self!(_bench_quaternion_conjugate, Quaternion, conjugate); +bench_unop!(_bench_quaternion_normalize, Quaternion, normalize); diff --git a/benches/vec.rs b/benches/vec.rs index 2e33fa62..6bdd0392 100644 --- a/benches/vec.rs +++ b/benches/vec.rs @@ -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, Vec2, add); -bench_binop!(_bench_vec3_add_v, Vec3, Vec3, add); -bench_binop!(_bench_vec4_add_v, Vec4, Vec4, add); +bench_binop!(_bench_vec2_add_v, Vector2, Vector2, add); +bench_binop!(_bench_vec3_add_v, Vector3, Vector3, add); +bench_binop!(_bench_vec4_add_v, Vector4, Vector4, add); -bench_binop!(_bench_vec2_sub_v, Vec2, Vec2, sub); -bench_binop!(_bench_vec3_sub_v, Vec3, Vec3, sub); -bench_binop!(_bench_vec4_sub_v, Vec4, Vec4, sub); +bench_binop!(_bench_vec2_sub_v, Vector2, Vector2, sub); +bench_binop!(_bench_vec3_sub_v, Vector3, Vector3, sub); +bench_binop!(_bench_vec4_sub_v, Vector4, Vector4, sub); -bench_binop!(_bench_vec2_mul_v, Vec2, Vec2, mul); -bench_binop!(_bench_vec3_mul_v, Vec3, Vec3, mul); -bench_binop!(_bench_vec4_mul_v, Vec4, Vec4, mul); +bench_binop!(_bench_vec2_mul_v, Vector2, Vector2, mul); +bench_binop!(_bench_vec3_mul_v, Vector3, Vector3, mul); +bench_binop!(_bench_vec4_mul_v, Vector4, Vector4, mul); -bench_binop!(_bench_vec2_div_v, Vec2, Vec2, div); -bench_binop!(_bench_vec3_div_v, Vec3, Vec3, div); -bench_binop!(_bench_vec4_div_v, Vec4, Vec4, div); +bench_binop!(_bench_vec2_div_v, Vector2, Vector2, div); +bench_binop!(_bench_vec3_div_v, Vector3, Vector3, div); +bench_binop!(_bench_vec4_div_v, Vector4, Vector4, div); -bench_binop!(_bench_vec2_add_s, Vec2, f32, add); -bench_binop!(_bench_vec3_add_s, Vec3, f32, add); -bench_binop!(_bench_vec4_add_s, Vec4, f32, add); +bench_binop!(_bench_vec2_add_s, Vector2, f32, add); +bench_binop!(_bench_vec3_add_s, Vector3, f32, add); +bench_binop!(_bench_vec4_add_s, Vector4, f32, add); -bench_binop!(_bench_vec2_sub_s, Vec2, f32, sub); -bench_binop!(_bench_vec3_sub_s, Vec3, f32, sub); -bench_binop!(_bench_vec4_sub_s, Vec4, f32, sub); +bench_binop!(_bench_vec2_sub_s, Vector2, f32, sub); +bench_binop!(_bench_vec3_sub_s, Vector3, f32, sub); +bench_binop!(_bench_vec4_sub_s, Vector4, f32, sub); -bench_binop!(_bench_vec2_mul_s, Vec2, f32, mul); -bench_binop!(_bench_vec3_mul_s, Vec3, f32, mul); -bench_binop!(_bench_vec4_mul_s, Vec4, f32, mul); +bench_binop!(_bench_vec2_mul_s, Vector2, f32, mul); +bench_binop!(_bench_vec3_mul_s, Vector3, f32, mul); +bench_binop!(_bench_vec4_mul_s, Vector4, f32, mul); -bench_binop!(_bench_vec2_div_s, Vec2, f32, div); -bench_binop!(_bench_vec3_div_s, Vec3, f32, div); -bench_binop!(_bench_vec4_div_s, Vec4, f32, div); +bench_binop!(_bench_vec2_div_s, Vector2, f32, div); +bench_binop!(_bench_vec3_div_s, Vector3, f32, div); +bench_binop!(_bench_vec4_div_s, Vector4, f32, div); -bench_binop_na!(_bench_vec2_dot, Vec2, Vec2, dot); -bench_binop_na!(_bench_vec3_dot, Vec3, Vec3, dot); -bench_binop_na!(_bench_vec4_dot, Vec4, Vec4, dot); +bench_binop_na!(_bench_vec2_dot, Vector2, Vector2, dot); +bench_binop_na!(_bench_vec3_dot, Vector3, Vector3, dot); +bench_binop_na!(_bench_vec4_dot, Vector4, Vector4, dot); -bench_binop_na!(_bench_vec3_cross, Vec3, Vec3, cross); +bench_binop_na!(_bench_vec3_cross, Vector3, Vector3, cross); -bench_unop!(_bench_vec2_norm, Vec2, norm); -bench_unop!(_bench_vec3_norm, Vec3, norm); -bench_unop!(_bench_vec4_norm, Vec4, norm); +bench_unop!(_bench_vec2_norm, Vector2, norm); +bench_unop!(_bench_vec3_norm, Vector3, norm); +bench_unop!(_bench_vec4_norm, Vector4, norm); -bench_unop!(_bench_vec2_normalize, Vec2, normalize); -bench_unop!(_bench_vec3_normalize, Vec3, normalize); -bench_unop!(_bench_vec4_normalize, Vec4, normalize); +bench_unop!(_bench_vec2_normalize, Vector2, normalize); +bench_unop!(_bench_vec3_normalize, Vector3, normalize); +bench_unop!(_bench_vec4_normalize, Vector4, 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, VecN, add); - bench_binop!(_bench_vecn3_add_v, VecN, VecN, add); - bench_binop!(_bench_vecn4_add_v, VecN, VecN, add); + bench_binop!(_bench_vecn2_add_v, VectorN, VectorN, add); + bench_binop!(_bench_vecn3_add_v, VectorN, VectorN, add); + bench_binop!(_bench_vecn4_add_v, VectorN, VectorN, add); - bench_binop!(_bench_vecn2_sub_v, VecN, VecN, sub); - bench_binop!(_bench_vecn3_sub_v, VecN, VecN, sub); - bench_binop!(_bench_vecn4_sub_v, VecN, VecN, sub); + bench_binop!(_bench_vecn2_sub_v, VectorN, VectorN, sub); + bench_binop!(_bench_vecn3_sub_v, VectorN, VectorN, sub); + bench_binop!(_bench_vecn4_sub_v, VectorN, VectorN, sub); - bench_binop!(_bench_vecn2_mul_v, VecN, VecN, mul); - bench_binop!(_bench_vecn3_mul_v, VecN, VecN, mul); - bench_binop!(_bench_vecn4_mul_v, VecN, VecN, mul); + bench_binop!(_bench_vecn2_mul_v, VectorN, VectorN, mul); + bench_binop!(_bench_vecn3_mul_v, VectorN, VectorN, mul); + bench_binop!(_bench_vecn4_mul_v, VectorN, VectorN, mul); - bench_binop!(_bench_vecn2_div_v, VecN, VecN, div); - bench_binop!(_bench_vecn3_div_v, VecN, VecN, div); - bench_binop!(_bench_vecn4_div_v, VecN, VecN, div); + bench_binop!(_bench_vecn2_div_v, VectorN, VectorN, div); + bench_binop!(_bench_vecn3_div_v, VectorN, VectorN, div); + bench_binop!(_bench_vecn4_div_v, VectorN, VectorN, div); - bench_binop!(_bench_vecn2_add_s, VecN, f32, add); - bench_binop!(_bench_vecn3_add_s, VecN, f32, add); - bench_binop!(_bench_vecn4_add_s, VecN, f32, add); + bench_binop!(_bench_vecn2_add_s, VectorN, f32, add); + bench_binop!(_bench_vecn3_add_s, VectorN, f32, add); + bench_binop!(_bench_vecn4_add_s, VectorN, f32, add); - bench_binop!(_bench_vecn2_sub_s, VecN, f32, sub); - bench_binop!(_bench_vecn3_sub_s, VecN, f32, sub); - bench_binop!(_bench_vecn4_sub_s, VecN, f32, sub); + bench_binop!(_bench_vecn2_sub_s, VectorN, f32, sub); + bench_binop!(_bench_vecn3_sub_s, VectorN, f32, sub); + bench_binop!(_bench_vecn4_sub_s, VectorN, f32, sub); - bench_binop!(_bench_vecn2_mul_s, VecN, f32, mul); - bench_binop!(_bench_vecn3_mul_s, VecN, f32, mul); - bench_binop!(_bench_vecn4_mul_s, VecN, f32, mul); + bench_binop!(_bench_vecn2_mul_s, VectorN, f32, mul); + bench_binop!(_bench_vecn3_mul_s, VectorN, f32, mul); + bench_binop!(_bench_vecn4_mul_s, VectorN, f32, mul); - bench_binop!(_bench_vecn2_div_s, VecN, f32, div); - bench_binop!(_bench_vecn3_div_s, VecN, f32, div); - bench_binop!(_bench_vecn4_div_s, VecN, f32, div); + bench_binop!(_bench_vecn2_div_s, VectorN, f32, div); + bench_binop!(_bench_vecn3_div_s, VectorN, f32, div); + bench_binop!(_bench_vecn4_div_s, VectorN, f32, div); - bench_binop_na!(_bench_vecn2_dot, VecN, VecN, dot); - bench_binop_na!(_bench_vecn3_dot, VecN, VecN, dot); - bench_binop_na!(_bench_vecn4_dot, VecN, VecN, dot); + bench_binop_na!(_bench_vecn2_dot, VectorN, VectorN, dot); + bench_binop_na!(_bench_vecn3_dot, VectorN, VectorN, dot); + bench_binop_na!(_bench_vecn4_dot, VectorN, VectorN, dot); - bench_unop!(_bench_vecn2_norm, VecN, norm); - bench_unop!(_bench_vecn3_norm, VecN, norm); - bench_unop!(_bench_vecn4_norm, VecN, norm); + bench_unop!(_bench_vecn2_norm, VectorN, norm); + bench_unop!(_bench_vecn3_norm, VectorN, norm); + bench_unop!(_bench_vecn4_norm, VectorN, norm); - bench_unop!(_bench_vecn2_normalize, VecN, normalize); - bench_unop!(_bench_vecn3_normalize, VecN, normalize); - bench_unop!(_bench_vecn4_normalize, VecN, normalize); + bench_unop!(_bench_vecn2_normalize, VectorN, normalize); + bench_unop!(_bench_vecn3_normalize, VectorN, normalize); + bench_unop!(_bench_vecn4_normalize, VectorN, normalize); } diff --git a/src/lib.rs b/src/lib.rs index bf3de13d..2d14fd62 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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(a: T, b: T) -> T { /// Returns the infimum of `a` and `b`. #[inline(always)] -pub fn inf(a: &T, b: &T) -> T { - POrd::inf(a, b) +pub fn inf(a: &T, b: &T) -> T { + PartialOrder::inf(a, b) } /// Returns the supremum of `a` and `b`. #[inline(always)] -pub fn sup(a: &T, b: &T) -> T { - POrd::sup(a, b) +pub fn sup(a: &T, b: &T) -> T { + PartialOrder::sup(a, b) } /// Compare `a` and `b` using a partial ordering relation. #[inline(always)] -pub fn partial_cmp(a: &T, b: &T) -> POrdering { - POrd::partial_cmp(a, b) +pub fn partial_cmp(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(a: &T, b: &T) -> bool { - POrd::partial_lt(a, b) +pub fn partial_lt(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(a: &T, b: &T) -> bool { - POrd::partial_le(a, b) +pub fn partial_le(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(a: &T, b: &T) -> bool { - POrd::partial_gt(a, b) +pub fn partial_gt(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(a: &T, b: &T) -> bool { - POrd::partial_ge(a, b) +pub fn partial_ge(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 { /// Returns the trivial origin of an affine space. #[inline(always)] -pub fn orig() -> P { - Orig::orig() +pub fn origin() -> P { + Origin::origin() } /// Returns the center of two points. #[inline] -pub fn center>(a: &P, b: &P) -> P - where

::Vec: Norm +pub fn center>(a: &P, b: &P) -> P + where

::Vector: Norm { let _2 = one::() + one(); - (*a + b.to_vec()) / _2 + (*a + b.to_vector()) / _2 } /* - * FloatPnt + * FloatPoint */ /// Returns the distance between two points. #[inline(always)] -pub fn dist>(a: &P, b: &P) -> N where

::Vec: Norm { - a.dist(b) +pub fn distance>(a: &P, b: &P) -> N where

::Vector: Norm { + a.distance(b) } /// Returns the squared distance between two points. #[inline(always)] -pub fn sqdist>(a: &P, b: &P) -> N - where

::Vec: Norm +pub fn distance_squared>(a: &P, b: &P) -> N + where

::Vector: Norm { - a.sqdist(b) + a.distance_squared(b) } /* @@ -343,13 +343,13 @@ pub fn sqdist>(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>(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>(m: &M) -> V { - m.inv_translation() +pub fn inverse_translation>(m: &M) -> V { + m.inverse_translation() } /// Applies the translation `v` to a copy of `m`. @@ -389,15 +389,15 @@ pub fn append_translation>(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>(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>(m: &M, p: &P) -> P { - m.inv_translate(p) +pub fn inverse_translate>(m: &M, p: &P) -> P { + m.inverse_translate(p) } /* @@ -432,12 +432,12 @@ pub fn inv_translate>(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>(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>(m: &M) -> V { - m.inv_rotation() +pub fn inverse_rotation>(m: &M) -> V { + m.inverse_rotation() } // FIXME: this example is a bit shity @@ -468,14 +468,14 @@ pub fn inv_rotation>(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>(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>(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 * ::pi())); -/// let v = Vec3::new(1.0, 0.0, 0.0); +/// let t = Rotation3::new(Vector3::new(0.0f64, 0.0, 0.5 * ::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>(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 * ::pi())); -/// let v = Vec3::new(1.0, 0.0, 0.0); +/// let t = Rotation3::new(Vector3::new(0.0f64, 0.0, 0.5 * ::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>(m: &M, v: &V) -> V { - m.inv_rotate(v) +pub fn inverse_rotate>(m: &M, v: &V) -> V { + m.inverse_rotate(v) } /* @@ -594,13 +594,13 @@ pub fn rotation_between(a: &V, b: &V) -> V::DeltaRotationType { /// Builds a rotation matrix from `r`. #[inline(always)] -pub fn to_rot_mat(r: &R) -> M +pub fn to_rotation_matrix(r: &R) -> M where R: RotationMatrix, - M: SquareMat + Rotation + Copy, + M: SquareMatrix + Rotation + Copy, LV: Mul { // FIXME: rust-lang/rust#20413 - r.to_rot_mat() + r.to_rotation_matrix() } /* @@ -625,8 +625,8 @@ pub fn transformation>(m: &M) -> T { /// Gets the inverse transformation applicable by `m`. #[inline(always)] -pub fn inv_transformation>(m: &M) -> T { - m.inv_transformation() +pub fn inverse_transformation>(m: &M) -> T { + m.inverse_transformation() } /// Gets a transformed copy of `m`. @@ -647,8 +647,8 @@ pub fn transform>(m: &M, v: &V) -> V { /// Applies an inverse transformation to a vector. #[inline(always)] -pub fn inv_transform>(m: &M, v: &V) -> V { - m.inv_transform(v) +pub fn inverse_transform>(m: &M, v: &V) -> V { + m.inverse_transform(v) } /* @@ -673,8 +673,8 @@ pub fn norm, N: BaseFloat>(v: &V) -> N { /// Computes the squared L2 norm of a vector. #[inline(always)] -pub fn sqnorm, N: BaseFloat>(v: &V) -> N { - Norm::sqnorm(v) +pub fn norm_squared, N: BaseFloat>(v: &V) -> N { + Norm::norm_squared(v) } /// Gets the normalized version of a vector. @@ -684,12 +684,12 @@ pub fn normalize, N: BaseFloat>(v: &V) -> V { } /* - * Det + * Determinant */ /// Computes the determinant of a square matrix. #[inline(always)] -pub fn det, N>(m: &M) -> N { - Det::det(m) +pub fn determinant, N>(m: &M) -> N { + Determinant::determinant(m) } /* @@ -780,13 +780,13 @@ pub fn abs, Res>(m: &M) -> Res { } /* - * Inv + * Inverse */ /// Gets an inverted copy of a matrix. #[inline(always)] -pub fn inv(m: &M) -> Option { - Inv::inv(m) +pub fn inverse(m: &M) -> Option { + Inverse::inverse(m) } /* @@ -810,13 +810,13 @@ pub fn outer(a: &V, b: &V) -> V::OuterProductType { } /* - * Cov + * Covariance */ /// Computes the covariance of a set of observations. #[inline(always)] -pub fn cov, Res>(observations: &M) -> Res { - Cov::cov(observations) +pub fn covariance, Res>(observations: &M) -> Res { + Covariance::covariance(observations) } /* @@ -851,8 +851,8 @@ pub fn eigen_qr(m: &M, eps: &N, niter: usize) -> (M, V) */ /// Construct the identity matrix for a given dimension #[inline(always)] -pub fn new_identity(dim: usize) -> M { - Eye::new_identity(dim) +pub fn new_identity(dimension: usize) -> M { + Eye::new_identity(dimension) } @@ -894,27 +894,27 @@ pub fn canonical_basis_element(i: usize) -> Option { */ /* - * Col + * Column */ /* - * Diag + * Diagonal */ /// Gets the diagonal of a square matrix. #[inline(always)] -pub fn diag, V>(m: &M) -> V { - m.diag() +pub fn diagonal, V>(m: &M) -> V { + m.diagonal() } /* - * Dim + * Dimension */ /// Gets the dimension an object lives in. /// -/// Same as `Dim::dim::(None::)`. +/// Same as `Dimension::dimension::(None::)`. #[inline(always)] -pub fn dim() -> usize { - Dim::dim(None::) +pub fn dimension() -> usize { + Dimension::dimension(None::) } /// Gets the indexable range of an object. @@ -931,10 +931,10 @@ pub fn shape, 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 to Rot3 is +/// * Type-level geometric invariants cannot be broken (eg. a cast from Rotation3 to Rotation3 is /// not possible) -/// * A cast to a type with more type-level invariants cannot be done (eg. a cast from Mat to -/// Rot3 is not possible) +/// * A cast to a type with more type-level invariants cannot be done (eg. a cast from Matrix to +/// Rotation3 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). diff --git a/src/linalg/decompositions.rs b/src/linalg/decompositions.rs index d6e73322..ed6b2c1f 100644 --- a/src/linalg/decompositions.rs +++ b/src/linalg/decompositions.rs @@ -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(dim: usize, start: usize, vec: V) -> M +/// * `vector` - the vector defining the reflection. +pub fn householder_matrix(dimension: usize, start: usize, vector: V) -> M where N: BaseFloat, M: Eye + Indexable<(usize, usize), N>, V: Indexable { - 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(dim: usize, start: usize, vec: V) -> M pub fn qr(m: &M) -> (M, M) where N: BaseFloat, V: Indexable + Norm, - M: Copy + Eye + ColSlice + Transpose + Indexable<(usize, usize), N> + + M: Copy + Eye + ColumnSlice + Transpose + Indexable<(usize, usize), N> + Mul { let (rows, cols) = m.shape(); assert!(rows >= cols); @@ -76,29 +76,29 @@ pub fn eigen_qr(m: &M, eps: &N, niter: usize) -> (M, V) where N: BaseFloat, V: Mul, VS: Indexable + Norm, - M: Indexable<(usize, usize), N> + SquareMat + Add + - Sub + ColSlice + + M: Indexable<(usize, usize), N> + SquareMatrix + Add + + Sub + ColumnSlice + ApproxEq + Copy { let (mut eigenvectors, mut eigenvalues) = hessenberg(m); // Allocate arrays for Givens rotation components - let mut c = Vec::::with_capacity(::dim::() - 1); - let mut s = Vec::::with_capacity(::dim::() - 1); + let mut c = Vec::::with_capacity(::dimension::() - 1); + let mut s = Vec::::with_capacity(::dimension::() - 1); - if ::dim::() == 1 { - return (eigenvectors, eigenvalues.diag()); + if ::dimension::() == 1 { + return (eigenvectors, eigenvalues.diagonal()); } unsafe { - c.set_len(::dim::() - 1); - s.set_len(::dim::() - 1); + c.set_len(::dimension::() - 1); + s.set_len(::dimension::() - 1); } let mut iter = 0; - let mut curdim = ::dim::() - 1; + let mut curdim = ::dimension::() - 1; - for _ in 0 .. ::dim::() { + for _ in 0 .. ::dimension::() { let mut stop = false; @@ -113,12 +113,12 @@ pub fn eigen_qr(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(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::() { + for i in 0 .. ::dimension::() { unsafe { let a = eigenvectors.unsafe_at((i, k)); @@ -254,7 +254,7 @@ pub fn eigen_qr(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(m: &M) -> Result where N: BaseFloat, V: Mul, VS: Indexable + Norm, - M: Indexable<(usize, usize), N> + SquareMat + Add + - Sub + ColSlice + + M: Indexable<(usize, usize), N> + SquareMatrix + Add + + Sub + ColumnSlice + ApproxEq + Copy { let mut out = m.clone().transpose(); @@ -317,7 +317,7 @@ pub fn cholesky(m: &M) -> Result pub fn hessenberg(m: &M) -> (M, M) where N: BaseFloat, V: Indexable + Norm, - M: Copy + Eye + ColSlice + Transpose + Indexable<(usize, usize), N> + + M: Copy + Eye + ColumnSlice + Transpose + Indexable<(usize, usize), N> + Mul { let mut h = m.clone(); diff --git a/src/structs/dmat.rs b/src/structs/dmatrix.rs similarity index 72% rename from src/structs/dmat.rs rename to src/structs/dmatrix.rs index 310c7532..b38f3774 100644 --- a/src/structs/dmat.rs +++ b/src/structs/dmatrix.rs @@ -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 { +pub struct DMatrix { nrows: usize, ncols: usize, mij: Vec } -impl DMat { +impl DMatrix { /// Creates an uninitialized matrix. #[inline] - pub unsafe fn new_uninitialized(nrows: usize, ncols: usize) -> DMat { - let mut vec = Vec::with_capacity(nrows * ncols); - vec.set_len(nrows * ncols); + pub unsafe fn new_uninitialized(nrows: usize, ncols: usize) -> DMatrix { + let mut vector = Vec::with_capacity(nrows * ncols); + vector.set_len(nrows * ncols); - DMat { + DMatrix { nrows: nrows, ncols: ncols, - mij: vec + mij: vector } } } -impl DMat { +impl DMatrix { /// Builds a matrix filled with a given constant. #[inline] - pub fn from_elem(nrows: usize, ncols: usize, val: N) -> DMat { - DMat { + pub fn from_elem(nrows: usize, ncols: usize, val: N) -> DMatrix { + DMatrix { nrows: nrows, ncols: ncols, mij: repeat(val).take(nrows * ncols).collect() @@ -50,35 +50,35 @@ impl DMat { /// 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 { - DMat::from_row_iter(nrows, ncols, vec.to_vec()) + pub fn from_row_vector(nrows: usize, ncols: usize, vector: &[N]) -> DMatrix { + 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 { - DMat::from_col_iter(nrows, ncols, vec.to_vec()) + pub fn from_col_vector(nrows: usize, ncols: usize, vector: &[N]) -> DMatrix { + 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>(nrows: usize, ncols: usize, param: I) -> DMat { - let mut res = DMat::from_col_iter(ncols, nrows, param); + pub fn from_row_iter>(nrows: usize, ncols: usize, param: I) -> DMatrix { + 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 DMat { /// 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>(nrows: usize, ncols: usize, param: I) -> DMat { + pub fn from_col_iter>(nrows: usize, ncols: usize, param: I) -> DMatrix { let mij: Vec = 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 DMat { } } -impl DMat { +impl DMatrix { /// Builds a matrix filled with the results of a function applied to each of its component coordinates. #[inline(always)] - pub fn from_fn N>(nrows: usize, ncols: usize, mut f: F) -> DMat { - DMat { + pub fn from_fn N>(nrows: usize, ncols: usize, mut f: F) -> DMatrix { + 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 DMat { /// 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 { + pub fn into_vector(self) -> Vec { 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 { +pub struct DMatrix1 { 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 { +pub struct DMatrix2 { 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 { +pub struct DMatrix3 { 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 { +pub struct DMatrix4 { 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 { +pub struct DMatrix5 { 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 { +pub struct DMatrix6 { 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(), diff --git a/src/structs/dmat_macros.rs b/src/structs/dmatrix_macros.rs similarity index 64% rename from src/structs/dmat_macros.rs rename to src/structs/dmatrix_macros.rs index aaf02a2c..ab830ae5 100644 --- a/src/structs/dmat_macros.rs +++ b/src/structs/dmatrix_macros.rs @@ -1,16 +1,16 @@ #![macro_use] macro_rules! dmat_impl( - ($dmat: ident, $dvec: ident) => ( - impl $dmat { + ($dmatrix: ident, $dvector: ident) => ( + impl $dmatrix { /// Builds a matrix filled with zeros. /// /// # Arguments - /// * `dim` - The dimension of the matrix. A `dim`-dimensional matrix contains `dim * dim` + /// * `dimension` - The dimension of the matrix. A `dimension`-dimensional matrix contains `dimension * dimension` /// components. #[inline] - pub fn new_zeros(nrows: usize, ncols: usize) -> $dmat { - $dmat::from_elem(nrows, ncols, ::zero()) + pub fn new_zeros(nrows: usize, ncols: usize) -> $dmatrix { + $dmatrix::from_elem(nrows, ncols, ::zero()) } /// Tests if all components of the matrix are zeroes. @@ -28,23 +28,23 @@ macro_rules! dmat_impl( } } - impl $dmat { + impl $dmatrix { /// Builds a matrix filled with random values. #[inline] - pub fn new_random(nrows: usize, ncols: usize) -> $dmat { - $dmat::from_fn(nrows, ncols, |_, _| rand::random()) + pub fn new_random(nrows: usize, ncols: usize) -> $dmatrix { + $dmatrix::from_fn(nrows, ncols, |_, _| rand::random()) } } - impl $dmat { + impl $dmatrix { /// Builds a matrix filled with a given constant. #[inline] - pub fn new_ones(nrows: usize, ncols: usize) -> $dmat { - $dmat::from_elem(nrows, ncols, ::one()) + pub fn new_ones(nrows: usize, ncols: usize) -> $dmatrix { + $dmatrix::from_elem(nrows, ncols, ::one()) } } - impl $dmat { + impl $dmatrix { /// The number of row on the matrix. #[inline] pub fn nrows(&self) -> usize { @@ -60,31 +60,31 @@ macro_rules! dmat_impl( /// Gets a reference to this matrix data. /// The returned vector contains the matrix data in column-major order. #[inline] - pub fn as_vec(&self) -> &[N] { + pub fn as_vector(&self) -> &[N] { &self.mij } /// Gets a mutable reference to this matrix data. /// The returned vector contains the matrix data in column-major order. #[inline] - pub fn as_mut_vec(&mut self) -> &mut [N] { + pub fn as_mut_vector(&mut self) -> &mut [N] { &mut self.mij[..] } } // FIXME: add a function to modify the dimension (to avoid useless allocations)? - impl Eye for $dmat { + impl Eye for $dmatrix { /// Builds an identity matrix. /// /// # Arguments - /// * `dim` - The dimension of the matrix. A `dim`-dimensional matrix contains `dim * dim` + /// * `dimension` - The dimension of the matrix. A `dimension`-dimensional matrix contains `dimension * dimension` /// components. #[inline] - fn new_identity(dim: usize) -> $dmat { - let mut res = $dmat::new_zeros(dim, dim); + fn new_identity(dimension: usize) -> $dmatrix { + let mut res = $dmatrix::new_zeros(dimension, dimension); - for i in 0..dim { + for i in 0..dimension { let _1: N = ::one(); res[(i, i)] = _1; } @@ -93,7 +93,7 @@ macro_rules! dmat_impl( } } - impl $dmat { + impl $dmatrix { #[inline(always)] fn offset(&self, i: usize, j: usize) -> usize { i + j * self.nrows @@ -101,21 +101,21 @@ macro_rules! dmat_impl( } - impl Indexable<(usize, usize), N> for $dmat { + impl Indexable<(usize, usize), N> for $dmatrix { /// Just like `set` without bounds checking. #[inline] unsafe fn unsafe_set(&mut self, rowcol: (usize, usize), val: N) { - let (row, col) = rowcol; - let offset = self.offset(row, col); + let (row, column) = rowcol; + let offset = self.offset(row, column); *self.mij[..].get_unchecked_mut(offset) = val } /// Just like `at` without bounds checking. #[inline] unsafe fn unsafe_at(&self, rowcol: (usize, usize)) -> N { - let (row, col) = rowcol; + let (row, column) = rowcol; - *self.mij.get_unchecked(self.offset(row, col)) + *self.mij.get_unchecked(self.offset(row, column)) } #[inline] @@ -132,14 +132,14 @@ macro_rules! dmat_impl( } - impl Shape<(usize, usize)> for $dmat { + impl Shape<(usize, usize)> for $dmatrix { #[inline] fn shape(&self) -> (usize, usize) { (self.nrows, self.ncols) } } - impl Index<(usize, usize)> for $dmat { + impl Index<(usize, usize)> for $dmatrix { type Output = N; fn index(&self, (i, j): (usize, usize)) -> &N { @@ -152,7 +152,7 @@ macro_rules! dmat_impl( } } - impl IndexMut<(usize, usize)> for $dmat { + impl IndexMut<(usize, usize)> for $dmatrix { fn index_mut(&mut self, (i, j): (usize, usize)) -> &mut N { assert!(i < self.nrows); assert!(j < self.ncols); @@ -170,45 +170,45 @@ macro_rules! dmat_impl( * Multiplications matrix/matrix. * */ - impl Mul<$dmat> for $dmat + impl Mul<$dmatrix> for $dmatrix where N: Copy + Mul + Add + Zero { - type Output = $dmat; + type Output = $dmatrix; #[inline] - fn mul(self, right: $dmat) -> $dmat { + fn mul(self, right: $dmatrix) -> $dmatrix { (&self) * (&right) } } - impl<'a, N> Mul<&'a $dmat> for $dmat + impl<'a, N> Mul<&'a $dmatrix> for $dmatrix where N: Copy + Mul + Add + Zero { - type Output = $dmat; + type Output = $dmatrix; #[inline] - fn mul(self, right: &'a $dmat) -> $dmat { + fn mul(self, right: &'a $dmatrix) -> $dmatrix { (&self) * right } } - impl<'a, N> Mul<$dmat> for &'a $dmat + impl<'a, N> Mul<$dmatrix> for &'a $dmatrix where N: Copy + Mul + Add + Zero { - type Output = $dmat; + type Output = $dmatrix; #[inline] - fn mul(self, right: $dmat) -> $dmat { + fn mul(self, right: $dmatrix) -> $dmatrix { self * (&right) } } - impl<'a, 'b, N> Mul<&'b $dmat> for &'a $dmat + impl<'a, 'b, N> Mul<&'b $dmatrix> for &'a $dmatrix where N: Copy + Mul + Add + Zero { - type Output = $dmat; + type Output = $dmatrix; #[inline] - fn mul(self, right: &$dmat) -> $dmat { + fn mul(self, right: &$dmatrix) -> $dmatrix { assert!(self.ncols == right.nrows); - let mut res = unsafe { $dmat::new_uninitialized(self.nrows, right.ncols) }; + let mut res = unsafe { $dmatrix::new_uninitialized(self.nrows, right.ncols) }; for i in 0 .. self.nrows { for j in 0 .. right.ncols { @@ -228,18 +228,18 @@ macro_rules! dmat_impl( } } - impl MulAssign<$dmat> for $dmat + impl MulAssign<$dmatrix> for $dmatrix where N: Copy + Mul + Add + Zero { #[inline] - fn mul_assign(&mut self, right: $dmat) { + fn mul_assign(&mut self, right: $dmatrix) { self.mul_assign(&right) } } - impl<'a, N> MulAssign<&'a $dmat> for $dmat + impl<'a, N> MulAssign<&'a $dmatrix> for $dmatrix where N: Copy + Mul + Add + Zero { #[inline] - fn mul_assign(&mut self, right: &'a $dmat) { + fn mul_assign(&mut self, right: &'a $dmatrix) { assert!(self.ncols == right.nrows); // FIXME: optimize when both matrices have the same layout. @@ -254,41 +254,41 @@ macro_rules! dmat_impl( * Multiplication matrix/vector. * */ - impl Mul<$dvec> for $dmat + impl Mul<$dvector> for $dmatrix where N: Copy + Add + Mul + Zero { - type Output = $dvec; + type Output = $dvector; - fn mul(self, right: $dvec) -> $dvec { + fn mul(self, right: $dvector) -> $dvector { (&self) * (&right) } } - impl<'a, N> Mul<$dvec> for &'a $dmat + impl<'a, N> Mul<$dvector> for &'a $dmatrix where N: Copy + Add + Mul + Zero { - type Output = $dvec; + type Output = $dvector; - fn mul(self, right: $dvec) -> $dvec { + fn mul(self, right: $dvector) -> $dvector { self * (&right) } } - impl<'a, N> Mul<&'a $dvec> for $dmat + impl<'a, N> Mul<&'a $dvector> for $dmatrix where N: Copy + Add + Mul + Zero { - type Output = $dvec; + type Output = $dvector; - fn mul(self, right: &'a $dvec) -> $dvec { + fn mul(self, right: &'a $dvector) -> $dvector { (&self) * right } } - impl<'a, 'b, N> Mul<&'b $dvec> for &'a $dmat + impl<'a, 'b, N> Mul<&'b $dvector> for &'a $dmatrix where N: Copy + Add + Mul + Zero { - type Output = $dvec; + type Output = $dvector; - fn mul(self, right: &'b $dvec) -> $dvec { + fn mul(self, right: &'b $dvector) -> $dvector { assert!(self.ncols == right.len()); - let mut res : $dvec = unsafe { $dvec::new_uninitialized(self.nrows) }; + let mut res : $dvector = unsafe { $dvector::new_uninitialized(self.nrows) }; for i in 0..self.nrows { let mut acc: N = ::zero(); @@ -308,42 +308,42 @@ macro_rules! dmat_impl( } } - impl Mul<$dmat> for $dvec + impl Mul<$dmatrix> for $dvector where N: Copy + Add + Mul + Zero { - type Output = $dvec; + type Output = $dvector; - fn mul(self, right: $dmat) -> $dvec { + fn mul(self, right: $dmatrix) -> $dvector { (&self) * (&right) } } - impl<'a, N> Mul<$dmat> for &'a $dvec + impl<'a, N> Mul<$dmatrix> for &'a $dvector where N: Copy + Add + Mul + Zero { - type Output = $dvec; + type Output = $dvector; - fn mul(self, right: $dmat) -> $dvec { + fn mul(self, right: $dmatrix) -> $dvector { self * (&right) } } - impl<'a, N> Mul<&'a $dmat> for $dvec + impl<'a, N> Mul<&'a $dmatrix> for $dvector where N: Copy + Add + Mul + Zero { - type Output = $dvec; + type Output = $dvector; - fn mul(self, right: &'a $dmat) -> $dvec { + fn mul(self, right: &'a $dmatrix) -> $dvector { (&self) * right } } - impl<'a, 'b, N> Mul<&'b $dmat> for &'a $dvec + impl<'a, 'b, N> Mul<&'b $dmatrix> for &'a $dvector where N: Copy + Add + Mul + Zero { - type Output = $dvec; + type Output = $dvector; - fn mul(self, right: &'b $dmat) -> $dvec { + fn mul(self, right: &'b $dmatrix) -> $dvector { assert!(right.nrows == self.len()); - let mut res : $dvec = unsafe { $dvec::new_uninitialized(right.ncols) }; + let mut res : $dvector = unsafe { $dvector::new_uninitialized(right.ncols) }; for i in 0..right.ncols { let mut acc: N = ::zero(); @@ -363,18 +363,18 @@ macro_rules! dmat_impl( } } - impl MulAssign<$dmat> for $dvec + impl MulAssign<$dmatrix> for $dvector where N: Copy + Mul + Add + Zero { #[inline] - fn mul_assign(&mut self, right: $dmat) { + fn mul_assign(&mut self, right: $dmatrix) { self.mul_assign(&right) } } - impl<'a, N> MulAssign<&'a $dmat> for $dvec + impl<'a, N> MulAssign<&'a $dmatrix> for $dvector where N: Copy + Mul + Add + Zero { #[inline] - fn mul_assign(&mut self, right: &'a $dmat) { + fn mul_assign(&mut self, right: &'a $dmatrix) { assert!(right.nrows == self.len()); let res = &*self * right; @@ -387,29 +387,29 @@ macro_rules! dmat_impl( * Addition matrix/matrix. * */ - impl> Add<$dmat> for $dmat { - type Output = $dmat; + impl> Add<$dmatrix> for $dmatrix { + type Output = $dmatrix; #[inline] - fn add(self, right: $dmat) -> $dmat { + fn add(self, right: $dmatrix) -> $dmatrix { self + (&right) } } - impl<'a, N: Copy + Add> Add<$dmat> for &'a $dmat { - type Output = $dmat; + impl<'a, N: Copy + Add> Add<$dmatrix> for &'a $dmatrix { + type Output = $dmatrix; #[inline] - fn add(self, right: $dmat) -> $dmat { + fn add(self, right: $dmatrix) -> $dmatrix { right + self } } - impl<'a, N: Copy + Add> Add<&'a $dmat> for $dmat { - type Output = $dmat; + impl<'a, N: Copy + Add> Add<&'a $dmatrix> for $dmatrix { + type Output = $dmatrix; #[inline] - fn add(self, right: &'a $dmat) -> $dmat { + fn add(self, right: &'a $dmatrix) -> $dmatrix { let mut res = self; for (mij, right_ij) in res.mij.iter_mut().zip(right.mij.iter()) { @@ -420,16 +420,16 @@ macro_rules! dmat_impl( } } - impl> AddAssign<$dmat> for $dmat { + impl> AddAssign<$dmatrix> for $dmatrix { #[inline] - fn add_assign(&mut self, right: $dmat) { + fn add_assign(&mut self, right: $dmatrix) { self.add_assign(&right) } } - impl<'a, N: Copy + AddAssign> AddAssign<&'a $dmat> for $dmat { + impl<'a, N: Copy + AddAssign> AddAssign<&'a $dmatrix> for $dmatrix { #[inline] - fn add_assign(&mut self, right: &'a $dmat) { + fn add_assign(&mut self, right: &'a $dmatrix) { assert!(self.nrows == right.nrows && self.ncols == right.ncols, "Unable to add matrices with different dimensions."); @@ -444,11 +444,11 @@ macro_rules! dmat_impl( * Subtraction matrix/scalar. * */ - impl> Sub for $dmat { - type Output = $dmat; + impl> Sub for $dmatrix { + type Output = $dmatrix; #[inline] - fn sub(self, right: N) -> $dmat { + fn sub(self, right: N) -> $dmatrix { let mut res = self; for mij in res.mij.iter_mut() { @@ -459,7 +459,7 @@ macro_rules! dmat_impl( } } - impl<'a, N: Copy + SubAssign> SubAssign for $dmat { + impl<'a, N: Copy + SubAssign> SubAssign for $dmatrix { #[inline] fn sub_assign(&mut self, right: N) { for mij in self.mij.iter_mut() { @@ -468,11 +468,11 @@ macro_rules! dmat_impl( } } - impl Sub<$dmat> for f32 { - type Output = $dmat; + impl Sub<$dmatrix> for f32 { + type Output = $dmatrix; #[inline] - fn sub(self, right: $dmat) -> $dmat { + fn sub(self, right: $dmatrix) -> $dmatrix { let mut res = right; for mij in res.mij.iter_mut() { @@ -483,11 +483,11 @@ macro_rules! dmat_impl( } } - impl Sub<$dmat> for f64 { - type Output = $dmat; + impl Sub<$dmatrix> for f64 { + type Output = $dmatrix; #[inline] - fn sub(self, right: $dmat) -> $dmat { + fn sub(self, right: $dmatrix) -> $dmatrix { let mut res = right; for mij in res.mij.iter_mut() { @@ -503,29 +503,29 @@ macro_rules! dmat_impl( * Subtraction matrix/matrix. * */ - impl> Sub<$dmat> for $dmat { - type Output = $dmat; + impl> Sub<$dmatrix> for $dmatrix { + type Output = $dmatrix; #[inline] - fn sub(self, right: $dmat) -> $dmat { + fn sub(self, right: $dmatrix) -> $dmatrix { self - (&right) } } - impl<'a, N: Copy + Sub> Sub<$dmat> for &'a $dmat { - type Output = $dmat; + impl<'a, N: Copy + Sub> Sub<$dmatrix> for &'a $dmatrix { + type Output = $dmatrix; #[inline] - fn sub(self, right: $dmat) -> $dmat { + fn sub(self, right: $dmatrix) -> $dmatrix { right - self } } - impl<'a, N: Copy + Sub> Sub<&'a $dmat> for $dmat { - type Output = $dmat; + impl<'a, N: Copy + Sub> Sub<&'a $dmatrix> for $dmatrix { + type Output = $dmatrix; #[inline] - fn sub(self, right: &'a $dmat) -> $dmat { + fn sub(self, right: &'a $dmatrix) -> $dmatrix { assert!(self.nrows == right.nrows && self.ncols == right.ncols, "Unable to subtract matrices with different dimensions."); @@ -539,16 +539,16 @@ macro_rules! dmat_impl( } } - impl> SubAssign<$dmat> for $dmat { + impl> SubAssign<$dmatrix> for $dmatrix { #[inline] - fn sub_assign(&mut self, right: $dmat) { + fn sub_assign(&mut self, right: $dmatrix) { self.sub_assign(&right) } } - impl<'a, N: Copy + SubAssign> SubAssign<&'a $dmat> for $dmat { + impl<'a, N: Copy + SubAssign> SubAssign<&'a $dmatrix> for $dmatrix { #[inline] - fn sub_assign(&mut self, right: &'a $dmat) { + fn sub_assign(&mut self, right: &'a $dmatrix) { assert!(self.nrows == right.nrows && self.ncols == right.ncols, "Unable to subtract matrices with different dimensions."); @@ -563,11 +563,11 @@ macro_rules! dmat_impl( * Inversion. * */ - impl Inv for $dmat { + impl Inverse for $dmatrix { #[inline] - fn inv(&self) -> Option<$dmat> { - let mut res: $dmat = self.clone(); - if res.inv_mut() { + fn inverse(&self) -> Option<$dmatrix> { + let mut res: $dmatrix = self.clone(); + if res.inverse_mut() { Some(res) } else { @@ -575,21 +575,21 @@ macro_rules! dmat_impl( } } - fn inv_mut(&mut self) -> bool { + fn inverse_mut(&mut self) -> bool { assert!(self.nrows == self.ncols); - let dim = self.nrows; - let mut res: $dmat = Eye::new_identity(dim); + let dimension = self.nrows; + let mut res: $dmatrix = Eye::new_identity(dimension); // 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 unsafe { self.unsafe_at((n0, k)) } != ::zero() { break; } @@ -597,13 +597,13 @@ macro_rules! dmat_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 { let off_n0_j = self.offset(n0, j); let off_k_j = self.offset(k, j); @@ -615,26 +615,26 @@ macro_rules! dmat_impl( unsafe { let pivot = self.unsafe_at((k, k)); - for j in k..dim { + for j in k..dimension { let selfval = self.unsafe_at((k, j)) / pivot; self.unsafe_set((k, j), selfval); } - for j in 0..dim { + for j in 0..dimension { let resval = res.unsafe_at((k, j)) / pivot; res.unsafe_set((k, j), resval); } - for l in 0..dim { + for l in 0..dimension { if l != k { let normalizer = self.unsafe_at((l, k)); - for j in k..dim { + for j in k..dimension { let selfval = self.unsafe_at((l, j)) - self.unsafe_at((k, j)) * normalizer; self.unsafe_set((l, j), selfval); } - for j in 0..dim { + for j in 0..dimension { let resval = res.unsafe_at((l, j)) - res.unsafe_at((k, j)) * normalizer; res.unsafe_set((l, j), resval); } @@ -649,9 +649,9 @@ macro_rules! dmat_impl( } } - impl Transpose for $dmat { + impl Transpose for $dmatrix { #[inline] - fn transpose(&self) -> $dmat { + fn transpose(&self) -> $dmatrix { if self.nrows == self.ncols { let mut res = self.clone(); @@ -660,7 +660,7 @@ macro_rules! dmat_impl( res } else { - let mut res = unsafe { $dmat::new_uninitialized(self.ncols, self.nrows) }; + let mut res = unsafe { $dmatrix::new_uninitialized(self.ncols, self.nrows) }; for i in 0..self.nrows { for j in 0..self.ncols { @@ -694,9 +694,9 @@ macro_rules! dmat_impl( } } - impl + Clone> Mean<$dvec> for $dmat { - fn mean(&self) -> $dvec { - let mut res: $dvec = $dvec::new_zeros(self.ncols); + impl + Clone> Mean<$dvector> for $dmatrix { + fn mean(&self) -> $dvector { + let mut res: $dvector = $dvector::new_zeros(self.ncols); let normalizer: N = Cast::from(1.0f64 / self.nrows as f64); for i in 0 .. self.nrows { @@ -712,12 +712,12 @@ macro_rules! dmat_impl( } } - impl + Clone> Cov<$dmat> for $dmat { + impl + Clone> Covariance<$dmatrix> for $dmatrix { // FIXME: this could be heavily optimized, removing all temporaries by merging loops. - fn cov(&self) -> $dmat { + fn covariance(&self) -> $dmatrix { assert!(self.nrows > 1); - let mut centered = unsafe { $dmat::new_uninitialized(self.nrows, self.ncols) }; + let mut centered = unsafe { $dmatrix::new_uninitialized(self.nrows, self.ncols) }; let mean = self.mean(); // FIXME: use the rows iterator when available @@ -738,35 +738,35 @@ macro_rules! dmat_impl( } } - impl Col<$dvec> for $dmat { + impl Column<$dvector> for $dmatrix { #[inline] fn ncols(&self) -> usize { self.ncols } #[inline] - fn set_col(&mut self, col_id: usize, col: $dvec) { + fn set_col(&mut self, col_id: usize, column: $dvector) { assert!(col_id < self.ncols); - assert!(col.len() == self.nrows); + assert!(column.len() == self.nrows); for row_id in 0 .. self.nrows { unsafe { - self.unsafe_set((row_id, col_id), col.unsafe_at(row_id)); + self.unsafe_set((row_id, col_id), column.unsafe_at(row_id)); } } } - fn col(&self, col_id: usize) -> $dvec { + fn column(&self, col_id: usize) -> $dvector { assert!(col_id < self.ncols); let start = self.offset(0, col_id); let stop = self.offset(self.nrows, col_id); - $dvec::from_slice(self.nrows, &self.mij[start .. stop]) + $dvector::from_slice(self.nrows, &self.mij[start .. stop]) } } - impl ColSlice<$dvec> for $dmat { - fn col_slice(&self, col_id :usize, row_start: usize, row_end: usize) -> $dvec { + impl ColumnSlice<$dvector> for $dmatrix { + fn col_slice(&self, col_id :usize, row_start: usize, row_end: usize) -> $dvector { assert!(col_id < self.ncols); assert!(row_start < row_end); assert!(row_end <= self.nrows); @@ -774,20 +774,20 @@ macro_rules! dmat_impl( // We can init from slice thanks to the matrix being column-major. let start = self.offset(row_start, col_id); let stop = self.offset(row_end, col_id); - let slice = $dvec::from_slice(row_end - row_start, &self.mij[start .. stop]); + let slice = $dvector::from_slice(row_end - row_start, &self.mij[start .. stop]); slice } } - impl Row<$dvec> for $dmat { + impl Row<$dvector> for $dmatrix { #[inline] fn nrows(&self) -> usize { self.nrows } #[inline] - fn set_row(&mut self, row_id: usize, row: $dvec) { + fn set_row(&mut self, row_id: usize, row: $dvector) { assert!(row_id < self.nrows); assert!(row.len() == self.ncols); @@ -799,11 +799,11 @@ macro_rules! dmat_impl( } #[inline] - fn row(&self, row_id: usize) -> $dvec { + fn row(&self, row_id: usize) -> $dvector { assert!(row_id < self.nrows); - let mut slice : $dvec = unsafe { - $dvec::new_uninitialized(self.ncols) + let mut slice : $dvector = unsafe { + $dvector::new_uninitialized(self.ncols) }; for col_id in 0 .. self.ncols { @@ -815,14 +815,14 @@ macro_rules! dmat_impl( } } - impl RowSlice<$dvec> for $dmat { - fn row_slice(&self, row_id :usize, col_start: usize, col_end: usize) -> $dvec { + impl RowSlice<$dvector> for $dmatrix { + fn row_slice(&self, row_id :usize, col_start: usize, col_end: usize) -> $dvector { assert!(row_id < self.nrows); assert!(col_start < col_end); assert!(col_end <= self.ncols); - let mut slice : $dvec = unsafe { - $dvec::new_uninitialized(col_end - col_start) + let mut slice : $dvector = unsafe { + $dvector::new_uninitialized(col_end - col_start) }; let mut slice_idx = 0; for col_id in col_start .. col_end { @@ -836,68 +836,68 @@ macro_rules! dmat_impl( } } - impl Diag<$dvec> for $dmat { + impl Diagonal<$dvector> for $dmatrix { #[inline] - fn from_diag(diag: &$dvec) -> $dmat { - let mut res = $dmat::new_zeros(diag.len(), diag.len()); + fn from_diag(diagonal: &$dvector) -> $dmatrix { + let mut res = $dmatrix::new_zeros(diagonal.len(), diagonal.len()); - res.set_diag(diag); + res.set_diag(diagonal); res } #[inline] - fn diag(&self) -> $dvec { + fn diagonal(&self) -> $dvector { let smallest_dim = cmp::min(self.nrows, self.ncols); - let mut diag: $dvec = $dvec::new_zeros(smallest_dim); + let mut diagonal: $dvector = $dvector::new_zeros(smallest_dim); for i in 0..smallest_dim { - unsafe { diag.unsafe_set(i, self.unsafe_at((i, i))) } + unsafe { diagonal.unsafe_set(i, self.unsafe_at((i, i))) } } - diag + diagonal } } - impl DiagMut<$dvec> for $dmat { + impl DiagMut<$dvector> for $dmatrix { #[inline] - fn set_diag(&mut self, diag: &$dvec) { + fn set_diag(&mut self, diagonal: &$dvector) { let smallest_dim = cmp::min(self.nrows, self.ncols); - assert!(diag.len() == smallest_dim); + assert!(diagonal.len() == smallest_dim); for i in 0..smallest_dim { - unsafe { self.unsafe_set((i, i), diag.unsafe_at(i)) } + unsafe { self.unsafe_set((i, i), diagonal.unsafe_at(i)) } } } } - impl> ApproxEq for $dmat { + impl> ApproxEq for $dmatrix { #[inline] - fn approx_epsilon(_: Option<$dmat>) -> N { + fn approx_epsilon(_: Option<$dmatrix>) -> N { ApproxEq::approx_epsilon(None::) } #[inline] - fn approx_ulps(_: Option<$dmat>) -> u32 { + fn approx_ulps(_: Option<$dmatrix>) -> u32 { ApproxEq::approx_ulps(None::) } #[inline] - fn approx_eq_eps(&self, other: &$dmat, epsilon: &N) -> bool { + fn approx_eq_eps(&self, other: &$dmatrix, epsilon: &N) -> bool { let mut zip = self.mij.iter().zip(other.mij.iter()); zip.all(|(a, b)| ApproxEq::approx_eq_eps(a, b, epsilon)) } #[inline] - fn approx_eq_ulps(&self, other: &$dmat, ulps: u32) -> bool { + fn approx_eq_ulps(&self, other: &$dmatrix, ulps: u32) -> bool { let mut zip = self.mij.iter().zip(other.mij.iter()); zip.all(|(a, b)| ApproxEq::approx_eq_ulps(a, b, ulps)) } } - impl Debug for $dmat { + impl Debug for $dmatrix { fn fmt(&self, form:&mut Formatter) -> Result { for i in 0..self.nrows() { for j in 0..self.ncols() { @@ -914,11 +914,11 @@ macro_rules! dmat_impl( * Multpilication matrix/scalar. * */ - impl> Mul for $dmat { - type Output = $dmat; + impl> Mul for $dmatrix { + type Output = $dmatrix; #[inline] - fn mul(self, right: N) -> $dmat { + fn mul(self, right: N) -> $dmatrix { let mut res = self; for mij in res.mij.iter_mut() { @@ -929,11 +929,11 @@ macro_rules! dmat_impl( } } - impl Mul<$dmat> for f32 { - type Output = $dmat; + impl Mul<$dmatrix> for f32 { + type Output = $dmatrix; #[inline] - fn mul(self, right: $dmat) -> $dmat { + fn mul(self, right: $dmatrix) -> $dmatrix { let mut res = right; for mij in res.mij.iter_mut() { @@ -944,11 +944,11 @@ macro_rules! dmat_impl( } } - impl Mul<$dmat> for f64 { - type Output = $dmat; + impl Mul<$dmatrix> for f64 { + type Output = $dmatrix; #[inline] - fn mul(self, right: $dmat) -> $dmat { + fn mul(self, right: $dmatrix) -> $dmatrix { let mut res = right; for mij in res.mij.iter_mut() { @@ -964,11 +964,11 @@ macro_rules! dmat_impl( * Division matrix/scalar. * */ - impl> Div for $dmat { - type Output = $dmat; + impl> Div for $dmatrix { + type Output = $dmatrix; #[inline] - fn div(self, right: N) -> $dmat { + fn div(self, right: N) -> $dmatrix { let mut res = self; for mij in res.mij.iter_mut() { @@ -985,11 +985,11 @@ macro_rules! dmat_impl( * Addition matrix/scalar. * */ - impl> Add for $dmat { - type Output = $dmat; + impl> Add for $dmatrix { + type Output = $dmatrix; #[inline] - fn add(self, right: N) -> $dmat { + fn add(self, right: N) -> $dmatrix { let mut res = self; for mij in res.mij.iter_mut() { @@ -1000,11 +1000,11 @@ macro_rules! dmat_impl( } } - impl Add<$dmat> for f32 { - type Output = $dmat; + impl Add<$dmatrix> for f32 { + type Output = $dmatrix; #[inline] - fn add(self, right: $dmat) -> $dmat { + fn add(self, right: $dmatrix) -> $dmatrix { let mut res = right; for mij in res.mij.iter_mut() { @@ -1015,11 +1015,11 @@ macro_rules! dmat_impl( } } - impl Add<$dmat> for f64 { - type Output = $dmat; + impl Add<$dmatrix> for f64 { + type Output = $dmatrix; #[inline] - fn add(self, right: $dmat) -> $dmat { + fn add(self, right: $dmatrix) -> $dmatrix { let mut res = right; for mij in res.mij.iter_mut() { @@ -1031,9 +1031,9 @@ macro_rules! dmat_impl( } #[cfg(feature="arbitrary")] - impl Arbitrary for $dmat { - fn arbitrary(g: &mut G) -> $dmat { - $dmat::from_fn( + impl Arbitrary for $dmatrix { + fn arbitrary(g: &mut G) -> $dmatrix { + $dmatrix::from_fn( Arbitrary::arbitrary(g), Arbitrary::arbitrary(g), |_, _| Arbitrary::arbitrary(g) ) @@ -1043,10 +1043,10 @@ macro_rules! dmat_impl( ); macro_rules! small_dmat_impl ( - ($dmat: ident, $dvec: ident, $dim: expr, $($idx: expr),*) => ( - impl PartialEq for $dmat { + ($dmatrix: ident, $dvector: ident, $dimension: expr, $($idx: expr),*) => ( + impl PartialEq for $dmatrix { #[inline] - fn eq(&self, other: &$dmat) -> bool { + fn eq(&self, other: &$dmatrix) -> bool { if self.nrows() != other.nrows() || self.ncols() != other.ncols() { return false; // FIXME: fail instead? } @@ -1062,11 +1062,11 @@ macro_rules! small_dmat_impl ( } } - impl Clone for $dmat { - fn clone(&self) -> $dmat { - let mij: [N; $dim * $dim] = [ $( self.mij[$idx].clone(), )* ]; + impl Clone for $dmatrix { + fn clone(&self) -> $dmatrix { + let mij: [N; $dimension * $dimension] = [ $( self.mij[$idx].clone(), )* ]; - $dmat { + $dmatrix { nrows: self.nrows, ncols: self.ncols, mij: mij, @@ -1074,26 +1074,26 @@ macro_rules! small_dmat_impl ( } } - dmat_impl!($dmat, $dvec); + dmat_impl!($dmatrix, $dvector); ) ); macro_rules! small_dmat_from_impl( - ($dmat: ident, $dim: expr, $($zeros: expr),*) => ( - impl $dmat { + ($dmatrix: ident, $dimension: expr, $($zeros: expr),*) => ( + impl $dmatrix { /// Builds a matrix filled with a given constant. #[inline] - pub fn from_elem(nrows: usize, ncols: usize, elem: N) -> $dmat { - assert!(nrows <= $dim); - assert!(ncols <= $dim); + pub fn from_elem(nrows: usize, ncols: usize, elem: N) -> $dmatrix { + assert!(nrows <= $dimension); + assert!(ncols <= $dimension); - let mut mij: [N; $dim * $dim] = [ $( $zeros, )* ]; + let mut mij: [N; $dimension * $dimension] = [ $( $zeros, )* ]; for n in &mut mij[.. nrows * ncols] { *n = elem; } - $dmat { + $dmatrix { nrows: nrows, ncols: ncols, mij: mij @@ -1102,13 +1102,13 @@ macro_rules! small_dmat_from_impl( /// 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 a lot faster than `from_row_vec` since a `$dmat` stores its data + /// Note that `from_col_vector` is a lot faster than `from_row_vector` since a `$dmatrix` stores its data /// in column-major order. /// /// The vector must have at least `nrows * ncols` elements. #[inline] - pub fn from_row_vec(nrows: usize, ncols: usize, vec: &[N]) -> $dmat { - let mut res = $dmat::from_col_vec(ncols, nrows, vec); + pub fn from_row_vector(nrows: usize, ncols: usize, vector: &[N]) -> $dmatrix { + let mut res = $dmatrix::from_col_vector(ncols, nrows, vector); // we transpose because the buffer is row_major res.transpose_mut(); @@ -1118,21 +1118,21 @@ macro_rules! small_dmat_from_impl( /// 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 a lot faster than `from_row_vec` since a `$dmat` stores its data + /// Note that `from_col_vector` is a lot faster than `from_row_vector` since a `$dmatrix` stores its data /// in column-major order. /// /// The vector must have at least `nrows * ncols` elements. #[inline] - pub fn from_col_vec(nrows: usize, ncols: usize, vec: &[N]) -> $dmat { - assert!(nrows * ncols == vec.len()); + pub fn from_col_vector(nrows: usize, ncols: usize, vector: &[N]) -> $dmatrix { + assert!(nrows * ncols == vector.len()); - let mut mij: [N; $dim * $dim] = [ $( $zeros, )* ]; + let mut mij: [N; $dimension * $dimension] = [ $( $zeros, )* ]; - for (n, val) in mij[.. nrows * ncols].iter_mut().zip(vec.iter()) { + for (n, val) in mij[.. nrows * ncols].iter_mut().zip(vector.iter()) { *n = *val; } - $dmat { + $dmatrix { nrows: nrows, ncols: ncols, mij: mij @@ -1141,11 +1141,11 @@ macro_rules! small_dmat_from_impl( /// Builds a matrix using an initialization function. #[inline(always)] - pub fn from_fn N>(nrows: usize, ncols: usize, mut f: F) -> $dmat { - assert!(nrows <= $dim); - assert!(ncols <= $dim); + pub fn from_fn N>(nrows: usize, ncols: usize, mut f: F) -> $dmatrix { + assert!(nrows <= $dimension); + assert!(ncols <= $dimension); - let mut mij: [N; $dim * $dim] = [ $( $zeros, )* ]; + let mut mij: [N; $dimension * $dimension] = [ $( $zeros, )* ]; for i in 0 .. nrows { for j in 0 .. ncols { @@ -1153,7 +1153,7 @@ macro_rules! small_dmat_from_impl( } } - $dmat { + $dmatrix { nrows: nrows, ncols: ncols, mij: mij @@ -1161,14 +1161,14 @@ macro_rules! small_dmat_from_impl( } } - impl $dmat { + impl $dmatrix { /// Creates a new matrix with uninitialized components (with `mem::uninitialized()`). #[inline] - pub unsafe fn new_uninitialized(nrows: usize, ncols: usize) -> $dmat { - assert!(nrows <= $dim); - assert!(ncols <= $dim); + pub unsafe fn new_uninitialized(nrows: usize, ncols: usize) -> $dmatrix { + assert!(nrows <= $dimension); + assert!(ncols <= $dimension); - $dmat { + $dmatrix { nrows: nrows, ncols: ncols, mij: mem::uninitialized() diff --git a/src/structs/dvec.rs b/src/structs/dvec.rs deleted file mode 100644 index ba8b27ec..00000000 --- a/src/structs/dvec.rs +++ /dev/null @@ -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 { - /// Components of the vector. Contains as much elements as the vector dimension. - pub at: Vec -} - -impl DVec { - /// Creates an uninitialized vec. - #[inline] - pub unsafe fn new_uninitialized(dim: usize) -> DVec { - let mut vec = Vec::with_capacity(dim); - vec.set_len(dim); - - DVec { - at: vec - } - } -} - -impl DVec { - /// Builds a vector filled with a constant. - #[inline] - pub fn from_elem(dim: usize, elem: N) -> DVec { - 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 { - assert!(dim <= vec.len()); - - DVec { - at: vec[.. dim].to_vec() - } - } -} - -impl DVec { - /// Builds a vector filled with the results of a function applied to each of its component coordinates. - #[inline(always)] - pub fn from_fn N>(dim: usize, mut f: F) -> DVec { - DVec { at: (0 .. dim).map(|i| f(i)).collect() } - } - - /// The vector length. - #[inline] - pub fn len(&self) -> usize { - self.at.len() - } -} - -impl FromIterator for DVec { - #[inline] - fn from_iter>(param: I) -> DVec { - DVec { at: param.into_iter().collect() } - } -} - -impl Outer for DVec { - type OuterProductType = DMat; - - #[inline] - fn outer(&self, other: &DVec) -> DMat { - 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 Arbitrary for DVec { - fn arbitrary(g: &mut G) -> DVec { - DVec { at: Arbitrary::arbitrary(g) } - } -} - - -dvec_impl!(DVec); - -/// Stack-allocated, dynamically sized vector with a maximum size of 1. -pub struct DVec1 { - 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 { - 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 { - 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 { - 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 { - 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 { - 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()); diff --git a/src/structs/dvec_macros.rs b/src/structs/dvec_macros.rs deleted file mode 100644 index 76d54f2e..00000000 --- a/src/structs/dvec_macros.rs +++ /dev/null @@ -1,243 +0,0 @@ -#![macro_use] - -macro_rules! dvec_impl( - ($dvec: ident) => ( - vecn_dvec_common_impl!($dvec); - - impl $dvec { - /// Builds a vector filled with zeros. - /// - /// # Arguments - /// * `dim` - The dimension of the vector. - #[inline] - pub fn new_zeros(dim: usize) -> $dvec { - $dvec::from_elem(dim, ::zero()) - } - } - - impl $dvec { - /// Builds a vector filled with ones. - /// - /// # Arguments - /// * `dim` - The dimension of the vector. - #[inline] - pub fn new_ones(dim: usize) -> $dvec { - $dvec::from_elem(dim, ::one()) - } - } - - impl $dvec { - /// Builds a vector filled with random values. - #[inline] - pub fn new_random(dim: usize) -> $dvec { - $dvec::from_fn(dim, |_| rand::random()) - } - } - - impl> $dvec { - /// 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> { - let mut res : Vec<$dvec> = Vec::new(); - - for i in 0 .. dim { - let mut basis_element : $dvec = $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> { - // compute the basis of the orthogonal subspace using Gram-Schmidt - // orthogonalization algorithm - let dim = self.len(); - let mut res : Vec<$dvec> = Vec::new(); - - for i in 0 .. dim { - let mut basis_element : $dvec = $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 $dvec { - /// 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 { - 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 PartialEq for $dvec { - #[inline] - fn eq(&self, other: &$dvec) -> 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 Clone for $dvec { - fn clone(&self) -> $dvec { - 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 $dvec { - /// Builds a vector filled with a constant. - #[inline] - pub fn from_elem(dim: usize, elem: N) -> $dvec { - assert!(dim <= $dim); - - let mut at: [N; $dim] = [ $( $zeros, )* ]; - - for n in &mut at[.. dim] { - *n = elem; - } - - $dvec { - at: at, - dim: dim - } - } - } - - impl $dvec { - /// 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 { - 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 $dvec { - /// Builds a vector filled with the result of a function. - #[inline(always)] - pub fn from_fn N>(dim: usize, mut f: F) -> $dvec { - assert!(dim <= $dim); - - let mut at: [N; $dim] = [ $( $zeros, )* ]; - - for i in 0 .. dim { - at[i] = f(i); - } - - $dvec { - at: at, - dim: dim - } - } - } - - impl FromIterator for $dvec { - #[inline] - fn from_iter>(param: I) -> $dvec { - 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 Arbitrary for $dvec { - #[inline] - fn arbitrary(g: &mut G) -> $dvec { - $dvec::from_fn(g.gen_range(0, $dim), |_| Arbitrary::arbitrary(g)) - } - } - ) -); diff --git a/src/structs/dvector.rs b/src/structs/dvector.rs new file mode 100644 index 00000000..7f857d94 --- /dev/null +++ b/src/structs/dvector.rs @@ -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 { + /// Components of the vector. Contains as much elements as the vector dimension. + pub at: Vec +} + +impl DVector { + /// Creates an uninitialized vector. + #[inline] + pub unsafe fn new_uninitialized(dimension: usize) -> DVector { + let mut vector = Vec::with_capacity(dimension); + vector.set_len(dimension); + + DVector { + at: vector + } + } +} + +impl DVector { + /// Builds a vector filled with a constant. + #[inline] + pub fn from_elem(dimension: usize, elem: N) -> DVector { + 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 { + assert!(dimension <= vector.len()); + + DVector { + at: vector[.. dimension].to_vec() + } + } +} + +impl DVector { + /// Builds a vector filled with the results of a function applied to each of its component coordinates. + #[inline(always)] + pub fn from_fn N>(dimension: usize, mut f: F) -> DVector { + DVector { at: (0 .. dimension).map(|i| f(i)).collect() } + } + + /// The vector length. + #[inline] + pub fn len(&self) -> usize { + self.at.len() + } +} + +impl FromIterator for DVector { + #[inline] + fn from_iter>(param: I) -> DVector { + DVector { at: param.into_iter().collect() } + } +} + +impl Outer for DVector { + type OuterProductType = DMatrix; + + #[inline] + fn outer(&self, other: &DVector) -> DMatrix { + 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 Arbitrary for DVector { + fn arbitrary(g: &mut G) -> DVector { + DVector { at: Arbitrary::arbitrary(g) } + } +} + + +dvec_impl!(DVector); + +/// Stack-allocated, dynamically sized vector with a maximum size of 1. +pub struct DVector1 { + 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 { + 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 { + 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 { + 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 { + 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 { + 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()); diff --git a/src/structs/dvector_macros.rs b/src/structs/dvector_macros.rs new file mode 100644 index 00000000..f7242b9a --- /dev/null +++ b/src/structs/dvector_macros.rs @@ -0,0 +1,243 @@ +#![macro_use] + +macro_rules! dvec_impl( + ($dvector: ident) => ( + vecn_dvec_common_impl!($dvector); + + impl $dvector { + /// Builds a vector filled with zeros. + /// + /// # Arguments + /// * `dimension` - The dimension of the vector. + #[inline] + pub fn new_zeros(dimension: usize) -> $dvector { + $dvector::from_elem(dimension, ::zero()) + } + } + + impl $dvector { + /// Builds a vector filled with ones. + /// + /// # Arguments + /// * `dimension` - The dimension of the vector. + #[inline] + pub fn new_ones(dimension: usize) -> $dvector { + $dvector::from_elem(dimension, ::one()) + } + } + + impl $dvector { + /// Builds a vector filled with random values. + #[inline] + pub fn new_random(dimension: usize) -> $dvector { + $dvector::from_fn(dimension, |_| rand::random()) + } + } + + impl> $dvector { + /// 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> { + let mut res : Vec<$dvector> = Vec::new(); + + for i in 0 .. dimension { + let mut basis_element : $dvector = $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> { + // compute the basis of the orthogonal subspace using Gram-Schmidt + // orthogonalization algorithm + let dimension = self.len(); + let mut res : Vec<$dvector> = Vec::new(); + + for i in 0 .. dimension { + let mut basis_element : $dvector = $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 $dvector { + /// 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 { + 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 PartialEq for $dvector { + #[inline] + fn eq(&self, other: &$dvector) -> 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 Clone for $dvector { + fn clone(&self) -> $dvector { + 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 $dvector { + /// Builds a vector filled with a constant. + #[inline] + pub fn from_elem(dimension: usize, elem: N) -> $dvector { + assert!(dimension <= $dimension); + + let mut at: [N; $dimension] = [ $( $zeros, )* ]; + + for n in &mut at[.. dimension] { + *n = elem; + } + + $dvector { + at: at, + dimension: dimension + } + } + } + + impl $dvector { + /// 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 { + 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 $dvector { + /// Builds a vector filled with the result of a function. + #[inline(always)] + pub fn from_fn N>(dimension: usize, mut f: F) -> $dvector { + assert!(dimension <= $dimension); + + let mut at: [N; $dimension] = [ $( $zeros, )* ]; + + for i in 0 .. dimension { + at[i] = f(i); + } + + $dvector { + at: at, + dimension: dimension + } + } + } + + impl FromIterator for $dvector { + #[inline] + fn from_iter>(param: I) -> $dvector { + 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 Arbitrary for $dvector { + #[inline] + fn arbitrary(g: &mut G) -> $dvector { + $dvector::from_fn(g.gen_range(0, $dimension), |_| Arbitrary::arbitrary(g)) + } + } + ) +); diff --git a/src/structs/iso.rs b/src/structs/iso.rs deleted file mode 100644 index f69c8eef..00000000 --- a/src/structs/iso.rs +++ /dev/null @@ -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 { - /// The rotation applicable by this isometry. - pub rotation: Rot2, - /// The translation applicable by this isometry. - pub translation: Vec2 -} - -/// 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 { - /// The rotation applicable by this isometry. - pub rotation: Rot3, - /// The translation applicable by this isometry. - pub translation: Vec3 -} - -impl Iso3 { - /// 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, target: &Pnt3, up: &Vec3) -> Iso3 { - 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, target: &Pnt3, up: &Vec3) -> Iso3 { - 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, target: &Pnt3, up: &Vec3) -> Iso3 { - 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); diff --git a/src/structs/isometry.rs b/src/structs/isometry.rs new file mode 100644 index 00000000..60269b99 --- /dev/null +++ b/src/structs/isometry.rs @@ -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 { + /// The rotation applicable by this isometry. + pub rotation: Rotation2, + /// The translation applicable by this isometry. + pub translation: Vector2 +} + +/// 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 { + /// The rotation applicable by this isometry. + pub rotation: Rotation3, + /// The translation applicable by this isometry. + pub translation: Vector3 +} + +impl Isometry3 { + /// 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, target: &Point3, up: &Vector3) -> Isometry3 { + 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, target: &Point3, up: &Vector3) -> Isometry3 { + 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, target: &Point3, up: &Vector3) -> Isometry3 { + 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); diff --git a/src/structs/iso_macros.rs b/src/structs/isometry_macros.rs similarity index 71% rename from src/structs/iso_macros.rs rename to src/structs/isometry_macros.rs index 1ba52291..5af92616 100644 --- a/src/structs/iso_macros.rs +++ b/src/structs/isometry_macros.rs @@ -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 $t { /// Creates a new isometry from an axis-angle rotation, and a vector. #[inline] - pub fn new(translation: $subvec, rotation: $subrotvec) -> $t { + pub fn new(translation: $subvector, rotation: $subrotvector) -> $t { $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, rotation: $submat) -> $t { + pub fn new_with_rotation_matrix(translation: $subvector, rotation: $submatrix) -> $t { $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 + BaseFloat> RotationMatrix, $tav> for $t { - type Output = $trot; + type Output = $trotation; #[inline] - fn to_rot_mat(&self) -> $trot { + fn to_rotation_matrix(&self) -> $trotation { self.rotation } } @@ -40,11 +40,11 @@ macro_rules! rotation_matrix_impl( macro_rules! dim_impl( - ($t: ident, $dim: expr) => ( - impl Dim for $t { + ($t: ident, $dimension: expr) => ( + impl Dimension for $t { #[inline] - fn dim(_: Option<$t>) -> usize { - $dim + fn dimension(_: Option<$t>) -> usize { + $dimension } } ) @@ -55,20 +55,20 @@ macro_rules! one_impl( impl One for $t { #[inline] fn one() -> $t { - $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 Mul<$t> for $t { type Output = $t; #[inline] fn mul(self, right: $t) -> $t { - $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 Mul<$rot> for $t { +macro_rules! isometry_mul_rotation_impl( + ($t: ident, $rotation: ident) => ( + impl Mul<$rotation> for $t { type Output = $t; #[inline] - fn mul(self, right: $rot) -> $t { - $t::new_with_rotmat(self.translation, self.rotation * right) + fn mul(self, right: $rotation) -> $t { + $t::new_with_rotation_matrix(self.translation, self.rotation * right) } } - impl Mul<$t> for $rot { + impl Mul<$t> for $rotation { type Output = $t; #[inline] fn mul(self, right: $t) -> $t { - $t::new_with_rotmat( + $t::new_with_rotation_matrix( self * right.translation, self * right.rotation) } } - impl MulAssign<$rot> for $t { + impl MulAssign<$rotation> for $t { #[inline] - fn mul_assign(&mut self, right: $rot) { + fn mul_assign(&mut self, right: $rotation) { self.rotation *= right } } ) ); -macro_rules! iso_mul_pnt_impl( +macro_rules! isometry_mul_point_impl( ($t: ident, $tv: ident) => ( impl Mul<$tv> for $t { type Output = $tv; @@ -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 Mul<$tv> for $t { type Output = $tv; @@ -150,7 +150,7 @@ macro_rules! translation_impl( } #[inline] - fn inv_translation(&self) -> $tv { + fn inverse_translation(&self) -> $tv { -self.translation } @@ -161,7 +161,7 @@ macro_rules! translation_impl( #[inline] fn append_translation(&self, t: &$tv) -> $t { - $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) -> $t { - $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) -> $tv { + fn inverse_translate(&self, v: &$tv) -> $tv { *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 + BaseFloat> Rotation<$tav> for $t { #[inline] fn rotation(&self) -> $tav { @@ -207,43 +207,43 @@ macro_rules! rotation_impl( } #[inline] - fn inv_rotation(&self) -> $tav { - self.rotation.inv_rotation() + fn inverse_rotation(&self) -> $tav { + self.rotation.inverse_rotation() } #[inline] - fn append_rotation_mut(&mut self, rot: &$tav) { - let delta = $trot::new(*rot); + fn append_rotation_mut(&mut self, rotation: &$tav) { + let delta = $trotation::new(*rotation); self.rotation = delta * self.rotation; self.translation = delta * self.translation; } #[inline] - fn append_rotation(&self, rot: &$tav) -> $t { - let delta = $trot::new(*rot); + fn append_rotation(&self, rotation: &$tav) -> $t { + 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) { - let delta = $trot::new(*rot); + fn prepend_rotation_mut(&mut self, rotation: &$tav) { + let delta = $trotation::new(*rotation); self.rotation = self.rotation * delta; } #[inline] - fn prepend_rotation(&self, rot: &$tav) -> $t { - let delta = $trot::new(*rot); + fn prepend_rotation(&self, rotation: &$tav) -> $t { + 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) { + fn set_rotation(&mut self, rotation: $tav) { // 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) -> $tv { - self.rotation.inv_rotate(v) + fn inverse_rotate(&self, v: &$tv) -> $tv { + self.rotation.inverse_rotate(v) } } ) @@ -272,9 +272,9 @@ macro_rules! transformation_impl( *self } - fn inv_transformation(&self) -> $t { + fn inverse_transformation(&self) -> $t { // inversion will never fails - Inv::inv(self).unwrap() + Inverse::inverse(self).unwrap() } fn append_transformation_mut(&mut self, t: &$t) { @@ -309,28 +309,28 @@ macro_rules! transform_impl( } #[inline] - fn inv_transform(&self, p: &$tp) -> $tp { - self.rotation.inv_transform(&(*p - self.translation)) + fn inverse_transform(&self, p: &$tp) -> $tp { + self.rotation.inverse_transform(&(*p - self.translation)) } } ) ); -macro_rules! inv_impl( +macro_rules! inverse_impl( ($t: ident) => ( - impl> Inv for $t { + impl> Inverse for $t { #[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> { + fn inverse(&self) -> Option<$t> { 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>); + let dimension = Dimension::dimension(None::<$th>); - 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 Arbitrary for $t { fn arbitrary(g: &mut G) -> $t { - $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 fmt::Display for $t { 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, "}}") diff --git a/src/structs/mat.rs b/src/structs/matrix.rs similarity index 52% rename from src/structs/mat.rs rename to src/structs/matrix.rs index 3285e539..75f78a61 100644 --- a/src/structs/mat.rs +++ b/src/structs/matrix.rs @@ -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 { +pub struct Matrix1 { 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 { +pub struct Matrix2 { 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 { +pub struct Matrix3 { 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 { +pub struct Matrix4 { 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 { +pub struct Matrix5 { 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 { 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 { +pub struct Matrix6 { 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 { 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); diff --git a/src/structs/mat_macros.rs b/src/structs/matrix_macros.rs similarity index 76% rename from src/structs/mat_macros.rs rename to src/structs/matrix_macros.rs index a1fff8cd..504f1397 100644 --- a/src/structs/mat_macros.rs +++ b/src/structs/matrix_macros.rs @@ -14,37 +14,37 @@ macro_rules! mat_impl( ); macro_rules! conversion_impl( - ($t: ident, $dim: expr) => ( - impl AsRef<[[N; $dim]; $dim]> for $t { + ($t: ident, $dimension: expr) => ( + impl AsRef<[[N; $dimension]; $dimension]> for $t { #[inline] - fn as_ref(&self) -> &[[N; $dim]; $dim] { + fn as_ref(&self) -> &[[N; $dimension]; $dimension] { unsafe { mem::transmute(self) } } } - impl AsMut<[[N; $dim]; $dim]> for $t { + impl AsMut<[[N; $dimension]; $dimension]> for $t { #[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 { + impl<'a, N> From<&'a [[N; $dimension]; $dimension]> for &'a $t { #[inline] - fn from(arr: &'a [[N; $dim]; $dim]) -> &'a $t { + fn from(arr: &'a [[N; $dimension]; $dimension]) -> &'a $t { unsafe { mem::transmute(arr) } } } - impl<'a, N> From<&'a mut [[N; $dim]; $dim]> for &'a mut $t { + impl<'a, N> From<&'a mut [[N; $dimension]; $dimension]> for &'a mut $t { #[inline] - fn from(arr: &'a mut [[N; $dim]; $dim]) -> &'a mut $t { + fn from(arr: &'a mut [[N; $dimension]; $dimension]) -> &'a mut $t { 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 $t { #[inline] pub unsafe fn at_fast(&self, (i, j): (usize, usize)) -> N { - (*mem::transmute::<&$t, &[N; $dim * $dim]>(self) - .get_unchecked(i + j * $dim)) + (*mem::transmute::<&$t, &[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, &mut [N; $dim * $dim]>(self) - .get_unchecked_mut(i + j * $dim)) = val + (*mem::transmute::<&mut $t, &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 Eye for $t { - fn new_identity(dim: usize) -> $t { - assert!(dim == $dim); + fn new_identity(dimension: usize) -> $t { + assert!(dimension == $dimension); let mut eye: $t = ::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 Iterable for $t { #[inline] fn iter<'l>(&'l self) -> Iter<'l, N> { unsafe { - mem::transmute::<&'l $t, &'l [N; $dim * $dim]>(self).iter() + mem::transmute::<&'l $t, &'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 IterableMut for $t { #[inline] fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> { unsafe { - mem::transmute::<&'l mut $t, &'l mut [N; $dim * $dim]>(self).iter_mut() + mem::transmute::<&'l mut $t, &'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 Dim for $t { + ($t: ident, $dimension: expr) => ( + impl Dimension for $t { #[inline] - fn dim(_: Option<$t>) -> usize { - $dim + fn dimension(_: Option<$t>) -> usize { + $dimension } } ) ); macro_rules! indexable_impl( - ($t: ident, $dim: expr) => ( + ($t: ident, $dimension: expr) => ( impl Shape<(usize, usize)> for $t { #[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, &mut [N; $dim * $dim]>(self) - .swap(i1 + j1 * $dim, i2 + j2 * $dim) + mem::transmute::<&mut $t, &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; $dim * $dim]>(self).get_unchecked(i + j * $dim)) + (*mem::transmute::<&$t, &[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, &mut [N; $dim * $dim]>(self).get_unchecked_mut(i + j * $dim)) = val + (*mem::transmute::<&mut $t, &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 Index<(usize, usize)> for $t { type Output = N; fn index(&self, (i, j): (usize, usize)) -> &N { unsafe { - &mem::transmute::<&$t, & [N; $dim * $dim]>(self)[i + j * $dim] + &mem::transmute::<&$t, & [N; $dimension * $dimension]>(self)[i + j * $dimension] } } } @@ -406,7 +406,7 @@ macro_rules! index_impl( impl IndexMut<(usize, usize)> for $t { fn index_mut(&mut self, (i, j): (usize, usize)) -> &mut N { unsafe { - &mut mem::transmute::<&mut $t, &mut [N; $dim * $dim]>(self)[i + j * $dim] + &mut mem::transmute::<&mut $t, &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 ColSlice<$slice> for $t { + ($t: ident, $tv: ident, $slice: ident, $dimension: expr) => ( + impl ColumnSlice<$slice> for $t { fn col_slice(&self, cid: usize, rstart: usize, rend: usize) -> $slice { - 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 Row<$tv> for $t { #[inline] fn nrows(&self) -> usize { - Dim::dim(None::<$t>) + Dimension::dimension(None::<$t>) } #[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 RowSlice<$slice> for $t { fn row_slice(&self, rid: usize, cstart: usize, cend: usize) -> $slice { 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 Col<$tv> for $t { + ($t: ident, $tv: ident, $dimension: expr) => ( + impl Column<$tv> for $t { #[inline] fn ncols(&self) -> usize { - Dim::dim(None::<$t>) + Dimension::dimension(None::<$t>) } #[inline] - fn set_col(&mut self, col: usize, v: $tv) { + fn set_col(&mut self, column: usize, v: $tv) { for (i, e) in v.iter().enumerate() { - self[(i, col)] = *e; + self[(i, column)] = *e; } } #[inline] - fn col(&self, col: usize) -> $tv { + fn column(&self, column: usize) -> $tv { let mut res: $tv = ::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 Diag<$tv> for $t { + ($t: ident, $tv: ident, $dimension: expr) => ( + impl Diagonal<$tv> for $t { #[inline] - fn from_diag(diag: &$tv) -> $t { + fn from_diag(diagonal: &$tv) -> $t { let mut res: $t = ::zero(); - res.set_diag(diag); + res.set_diag(diagonal); res } #[inline] - fn diag(&self) -> $tv { - let mut diag: $tv = ::zero(); + fn diagonal(&self) -> $tv { + let mut diagonal: $tv = ::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 DiagMut<$tv> for $t { #[inline] - fn set_diag(&mut self, diag: &$tv) { - for i in 0 .. $dim { - unsafe { self.unsafe_set((i, i), diag.unsafe_at(i)) } + fn set_diag(&mut self, diagonal: &$tv) { + 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 Mul<$t> for $t { type Output = $t; #[inline] fn mul(self, right: $t) -> $t { let mut res: $t = ::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 Mul<$t> for $v { type Output = $v; @@ -576,8 +576,8 @@ macro_rules! vec_mul_mat_impl( fn mul(self, right: $t) -> $v { let mut res : $v = $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 Mul<$v> for $t { type Output = $v; @@ -609,8 +609,8 @@ macro_rules! mat_mul_vec_impl( fn mul(self, right: $v) -> $v { let mut res : $v = $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 - Inv for $t { + Inverse for $t { #[inline] - fn inv(&self) -> Option<$t> { + fn inverse(&self) -> Option<$t> { let mut res : $t = *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 = ::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 Transpose for $t { #[inline] fn transpose(&self) -> $t { @@ -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 ToHomogeneous<$t2> for $t { #[inline] fn to_homogeneous(&self) -> $t2 { let mut res: $t2 = ::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 FromHomogeneous<$t2> for $t { #[inline] fn from(m: &$t2) -> $t { let mut res: $t = ::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) -> $m { let mut res: $m = ::zero(); - for i in 0..Dim::dim(None::<$t>) { - for j in 0..Dim::dim(None::<$t>) { + for i in 0..Dimension::dimension(None::<$t>) { + for j in 0..Dimension::dimension(None::<$t>) { 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 + Clone> Mean<$v> for $t { fn mean(&self) -> $v { let mut res: $v = ::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 fmt::Display for $t { // 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 = ::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) } } ) diff --git a/src/structs/mod.rs b/src/structs/mod.rs index 00d818bd..5eae0cbf 100644 --- a/src/structs/mod.rs +++ b/src/structs/mod.rs @@ -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; } diff --git a/src/structs/ortho.rs b/src/structs/orthographic.rs similarity index 72% rename from src/structs/ortho.rs rename to src/structs/orthographic.rs index f5ac882f..12b27cc8 100644 --- a/src/structs/ortho.rs +++ b/src/structs/orthographic.rs @@ -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 { +pub struct Orthographic3 { left: N, right: N, bottom: N, @@ -26,18 +26,18 @@ pub struct Ortho3 { /// `(-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 { - mat: Mat4 +pub struct OrthographicMatrix3 { + matrix: Matrix4 } -impl Ortho3 { +impl Orthographic3 { /// Creates a new 3D orthographic projection. - pub fn new(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Ortho3 { + pub fn new(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Orthographic3 { 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 Ortho3 { } /// Builds a 4D projection matrix (using homogeneous coordinates) for this projection. - pub fn to_mat(&self) -> Mat4 { - self.to_persp_mat().mat + pub fn to_matrix(&self) -> Matrix4 { + self.to_orthographic_matrix().matrix } - /// Build a `OrthoMat3` representing this projection. - pub fn to_persp_mat(&self) -> OrthoMat3 { - 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 { + OrthographicMatrix3::new(self.left, self.right, self.bottom, self.top, self.znear, self.zfar) } } #[cfg(feature="arbitrary")] -impl Arbitrary for Ortho3 { - fn arbitrary(g: &mut G) -> Ortho3 { +impl Arbitrary for Orthographic3 { + fn arbitrary(g: &mut G) -> Orthographic3 { 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 Ortho3 { +impl Orthographic3 { /// The smallest x-coordinate of the view cuboid. #[inline] pub fn left(&self) -> N { @@ -152,29 +152,29 @@ impl Ortho3 { /// Projects a point. #[inline] - pub fn project_pnt(&self, p: &Pnt3) -> Pnt3 { + pub fn project_point(&self, p: &Point3) -> Point3 { // 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) -> Vec3 { + pub fn project_vector(&self, p: &Vector3) -> Vector3 { // FIXME: optimize that - self.to_persp_mat().project_vec(p) + self.to_orthographic_matrix().project_vector(p) } } -impl OrthoMat3 { +impl OrthographicMatrix3 { /// Creates a new orthographic projection matrix. - pub fn new(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> OrthoMat3 { + pub fn new(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> OrthographicMatrix3 { 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 = ::one(); + let matrix: Matrix4 = ::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 OrthoMat3 { } /// 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 { + pub fn new_with_fov(aspect: N, vfov: N, znear: N, zfar: N) -> OrthographicMatrix3 { assert!(znear < zfar, "The far plane must be farther than the near plane."); assert!(!::is_zero(&aspect)); @@ -192,59 +192,59 @@ impl OrthoMat3 { 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) -> OrthoMat3 { - OrthoMat3 { - mat: mat + pub unsafe fn new_with_matrix(matrix: Matrix4) -> OrthographicMatrix3 { + 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 { - &self.mat + pub fn as_matrix<'a>(&'a self) -> &'a Matrix4 { + &self.matrix } /// The smallest x-coordinate of the view cuboid. #[inline] pub fn left(&self) -> N { - (-::one::() - self.mat.m14) / self.mat.m11 + (-::one::() - self.matrix.m14) / self.matrix.m11 } /// The largest x-coordinate of the view cuboid. #[inline] pub fn right(&self) -> N { - (::one::() - self.mat.m14) / self.mat.m11 + (::one::() - self.matrix.m14) / self.matrix.m11 } /// The smallest y-coordinate of the view cuboid. #[inline] pub fn bottom(&self) -> N { - (-::one::() - self.mat.m24) / self.mat.m22 + (-::one::() - self.matrix.m24) / self.matrix.m22 } /// The largest y-coordinate of the view cuboid. #[inline] pub fn top(&self) -> N { - (::one::() - self.mat.m24) / self.mat.m22 + (::one::() - self.matrix.m24) / self.matrix.m22 } /// The near plane offset of the view cuboid. #[inline] pub fn znear(&self) -> N { - (::one::() + self.mat.m34) / self.mat.m33 + (::one::() + self.matrix.m34) / self.matrix.m33 } /// The far plane offset of the view cuboid. #[inline] pub fn zfar(&self) -> N { - (-::one::() + self.mat.m34) / self.mat.m33 + (-::one::() + self.matrix.m34) / self.matrix.m33 } /// Sets the smallest x-coordinate of the view cuboid. @@ -293,65 +293,65 @@ impl OrthoMat3 { #[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 = >::from(2.0) / (right - left); - self.mat.m14 = -(right + left) / (right - left); + self.matrix.m11 = >::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 = >::from(2.0) / (top - bottom); - self.mat.m24 = -(top + bottom) / (top - bottom); + self.matrix.m22 = >::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 = ->::from(2.0) / (zfar - znear); - self.mat.m34 = -(zfar + znear) / (zfar - znear); + self.matrix.m33 = ->::from(2.0) / (zfar - znear); + self.matrix.m34 = -(zfar + znear) / (zfar - znear); } /// Projects a point. #[inline] - pub fn project_pnt(&self, p: &Pnt3) -> Pnt3 { - 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) -> Point3 { + 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) -> Vec3 { - Vec3::new( - self.mat.m11 * p.x, - self.mat.m22 * p.y, - self.mat.m33 * p.z + pub fn project_vector(&self, p: &Vector3) -> Vector3 { + Vector3::new( + self.matrix.m11 * p.x, + self.matrix.m22 * p.y, + self.matrix.m33 * p.z ) } } -impl OrthoMat3 { +impl OrthographicMatrix3 { /// Returns the 4D matrix (using homogeneous coordinates) of this projection. #[inline] - pub fn to_mat<'a>(&'a self) -> Mat4 { - self.mat.clone() + pub fn to_matrix<'a>(&'a self) -> Matrix4 { + self.matrix.clone() } } #[cfg(feature="arbitrary")] -impl Arbitrary for OrthoMat3 { - fn arbitrary(g: &mut G) -> OrthoMat3 { - let x: Ortho3 = Arbitrary::arbitrary(g); - x.to_persp_mat() +impl Arbitrary for OrthographicMatrix3 { + fn arbitrary(g: &mut G) -> OrthographicMatrix3 { + let x: Orthographic3 = 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 bool, T: Arbitrary>(g: &mut G, f: F) -> T { diff --git a/src/structs/persp.rs b/src/structs/perspective.rs similarity index 63% rename from src/structs/persp.rs rename to src/structs/perspective.rs index b9d70dda..f3a7f213 100644 --- a/src/structs/persp.rs +++ b/src/structs/perspective.rs @@ -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 { +pub struct Perspective3 { aspect: N, - fovy: N, + fovy: N, znear: N, zfar: N } @@ -24,46 +24,46 @@ pub struct Persp3 { /// `(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 { - mat: Mat4 +pub struct PerspectiveMatrix3 { + matrix: Matrix4 } -impl Persp3 { +impl Perspective3 { /// Creates a new 3D perspective projection. - pub fn new(aspect: N, fovy: N, znear: N, zfar: N) -> Persp3 { + pub fn new(aspect: N, fovy: N, znear: N, zfar: N) -> Perspective3 { 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 { - self.to_persp_mat().mat + pub fn to_matrix(&self) -> Matrix4 { + self.to_perspective_matrix().matrix } - /// Build a `PerspMat3` representing this projection. - pub fn to_persp_mat(&self) -> PerspMat3 { - PerspMat3::new(self.aspect, self.fovy, self.znear, self.zfar) + /// Build a `PerspectiveMatrix3` representing this projection. + pub fn to_perspective_matrix(&self) -> PerspectiveMatrix3 { + PerspectiveMatrix3::new(self.aspect, self.fovy, self.znear, self.zfar) } } #[cfg(feature="arbitrary")] -impl Arbitrary for Persp3 { - fn arbitrary(g: &mut G) -> Persp3 { - use structs::ortho::reject; +impl Arbitrary for Perspective3 { + fn arbitrary(g: &mut G) -> Perspective3 { + 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 Persp3 { +impl Perspective3 { /// Gets the `width / height` aspect ratio. #[inline] pub fn aspect(&self) -> N { @@ -122,33 +122,33 @@ impl Persp3 { /// Projects a point. #[inline] - pub fn project_pnt(&self, p: &Pnt3) -> Pnt3 { + pub fn project_point(&self, p: &Point3) -> Point3 { // 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) -> Vec3 { + pub fn project_vector(&self, p: &Vector3) -> Vector3 { // FIXME: optimize that - self.to_persp_mat().project_vec(p) + self.to_perspective_matrix().project_vector(p) } } -impl PerspMat3 { +impl PerspectiveMatrix3 { /// 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 { + pub fn new(aspect: N, fovy: N, znear: N, zfar: N) -> PerspectiveMatrix3 { assert!(!::is_zero(&(znear - zfar))); assert!(!::is_zero(&aspect)); - let mat: Mat4 = ::one(); + let matrix: Matrix4 = ::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::(); + res.matrix.m44 = ::zero(); + res.matrix.m43 = -::one::(); res } @@ -157,22 +157,22 @@ impl PerspMat3 { /// /// This is unsafe because the input matrix is not checked to be a perspective projection. #[inline] - pub unsafe fn new_with_mat(mat: Mat4) -> PerspMat3 { - PerspMat3 { - mat: mat + pub unsafe fn new_with_matrix(matrix: Matrix4) -> PerspectiveMatrix3 { + 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 { - &self.mat + pub fn as_matrix<'a>(&'a self) -> &'a Matrix4 { + &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 PerspMat3 { 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 PerspMat3 { 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 PerspMat3 { 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 PerspMat3 { #[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 PerspMat3 { 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 PerspMat3 { 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) -> Pnt3 { + pub fn project_point(&self, p: &Point3) -> Point3 { 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) -> Vec3 { + pub fn project_vector(&self, p: &Vector3) -> Vector3 { 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 PerspMat3 { +impl PerspectiveMatrix3 { /// Returns the 4D matrix (using homogeneous coordinates) of this projection. #[inline] - pub fn to_mat<'a>(&'a self) -> Mat4 { - self.mat.clone() + pub fn to_matrix<'a>(&'a self) -> Matrix4 { + self.matrix.clone() } } #[cfg(feature="arbitrary")] -impl Arbitrary for PerspMat3 { - fn arbitrary(g: &mut G) -> PerspMat3 { - let x: Persp3 = Arbitrary::arbitrary(g); - x.to_persp_mat() +impl Arbitrary for PerspectiveMatrix3 { + fn arbitrary(g: &mut G) -> PerspectiveMatrix3 { + let x: Perspective3 = Arbitrary::arbitrary(g); + x.to_perspective_matrix() } } diff --git a/src/structs/pnt.rs b/src/structs/pnt.rs deleted file mode 100644 index 2b5a9b74..00000000 --- a/src/structs/pnt.rs +++ /dev/null @@ -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 { - /// 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 { - /// 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 { - /// 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 { - /// 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 { - /// 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 { - /// 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); diff --git a/src/structs/point.rs b/src/structs/point.rs new file mode 100644 index 00000000..442e1ab3 --- /dev/null +++ b/src/structs/point.rs @@ -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 { + /// 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 { + /// 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 { + /// 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 { + /// 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 { + /// 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 { + /// 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); diff --git a/src/structs/pnt_macros.rs b/src/structs/point_macros.rs similarity index 79% rename from src/structs/pnt_macros.rs rename to src/structs/point_macros.rs index 5d294fc4..6e549111 100644 --- a/src/structs/pnt_macros.rs +++ b/src/structs/point_macros.rs @@ -1,37 +1,37 @@ #![macro_use] -macro_rules! orig_impl( +macro_rules! origin_impl( ($t: ident, $($compN: ident),+) => ( - impl Orig for $t { + impl Origin for $t { #[inline] - fn orig() -> $t { + fn origin() -> $t { $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> Sub<$t> for $t { type Output = $tv; #[inline] fn sub(self, right: $t) -> $tv { - *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> Add<$tv> for $t { type Output = $t; @@ -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> Sub<$tv> for $t { type Output = $t; @@ -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 $t { /// Converts this point to its associated vector. #[inline] - pub fn to_vec(self) -> $tv { + pub fn to_vector(self) -> $tv { $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 { + pub fn as_vector<'a>(&'a self) -> &'a $tv { unsafe { mem::transmute(self) } @@ -96,17 +96,17 @@ macro_rules! pnt_as_vec_impl( } } - impl PntAsVec for $t { - type Vec = $tv; + impl PointAsVector for $t { + type Vector = $tv; #[inline] - fn to_vec(self) -> $tv { - self.to_vec() + fn to_vector(self) -> $tv { + self.to_vector() } #[inline] - fn as_vec<'a>(&'a self) -> &'a $tv { - self.as_vec() + fn as_vector<'a>(&'a self) -> &'a $tv { + 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 ToHomogeneous<$t2> for $t { fn to_homogeneous(&self) -> $t2 { - let mut res: $t2 = Orig::orig(); + let mut res: $t2 = 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 + One + Zero> FromHomogeneous<$t2> for $t { fn from(v: &$t2) -> $t { - let mut res: $t = Orig::orig(); + let mut res: $t = 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 NumPnt for $t + impl NumPoint for $t where N: BaseNum { } - impl FloatPnt for $t + impl FloatPoint for $t where N: BaseFloat + ApproxEq { } ) ); -macro_rules! arbitrary_pnt_impl( +macro_rules! arbitrary_point_impl( ($t: ident, $($compN: ident),*) => ( #[cfg(feature="arbitrary")] impl Arbitrary for $t { @@ -172,7 +172,7 @@ macro_rules! arbitrary_pnt_impl( ) ); -macro_rules! pnt_display_impl( +macro_rules! point_display_impl( ($t: ident) => ( impl fmt::Display for $t { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { diff --git a/src/structs/quat.rs b/src/structs/quat.rs deleted file mode 100644 index a4d835d2..00000000 --- a/src/structs/quat.rs +++ /dev/null @@ -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 { - /// 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 Quat { - /// Creates a new quaternion from its components. - #[inline] - pub fn new(w: N, i: N, j: N, k: N) -> Quat { - 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 { - // 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 + Copy> Quat { - /// Compute the conjugate of this quaternion. - #[inline] - pub fn conjugate(&self) -> Quat { - 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> Inv for Quat { - #[inline] - fn inv(&self) -> Option> { - 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 Norm for Quat { - #[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 { - 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 Mul> for Quat - where N: Copy + Mul + Sub + Add { - type Output = Quat; - - #[inline] - fn mul(self, right: Quat) -> Quat { - 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 MulAssign> for Quat - where N: Copy + Mul + Sub + Add { - #[inline] - fn mul_assign(&mut self, right: Quat) { - *self = *self * right; - } -} - -impl + BaseFloat> Div> for Quat { - type Output = Quat; - - #[inline] - fn div(self, right: Quat) -> Quat { - self * right.inv().expect("Unable to invert the denominator.") - } -} - -impl + BaseFloat> DivAssign> for Quat { - #[inline] - fn div_assign(&mut self, right: Quat) { - *self *= right.inv().expect("Unable to invert the denominator.") - } -} - -impl fmt::Display for Quat { - 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 { - q: Quat -} - -impl UnitQuat { - /// Creates a new unit quaternion from the axis-angle representation of a rotation. - #[inline] - pub fn new(axisangle: Vec3) -> UnitQuat { - 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) -> UnitQuat { - 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 { - 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 { - 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 UnitQuat { - /// 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) -> UnitQuat { - UnitQuat { - q: q - } - } - - /// The `Quat` representation of this unit quaternion. - #[inline] - pub fn quat<'a>(&'a self) -> &'a Quat { - &self.q - } -} - -impl One for UnitQuat { - #[inline] - fn one() -> UnitQuat { - unsafe { - UnitQuat::new_with_unit_quat(Quat::new(::one(), ::zero(), ::zero(), ::zero())) - } - } -} - -impl> Inv for UnitQuat { - #[inline] - fn inv(&self) -> Option> { - let mut cpy = *self; - - cpy.inv_mut(); - Some(cpy) - } - - #[inline] - fn inv_mut(&mut self) -> bool { - self.q.conjugate_mut(); - - true - } -} - -impl Rand for UnitQuat { - #[inline] - fn rand(rng: &mut R) -> UnitQuat { - UnitQuat::new(rng.gen()) - } -} - -impl> ApproxEq for UnitQuat { - #[inline] - fn approx_epsilon(_: Option>) -> N { - ApproxEq::approx_epsilon(None::) - } - - #[inline] - fn approx_ulps(_: Option>) -> u32 { - ApproxEq::approx_ulps(None::) - } - - #[inline] - fn approx_eq_eps(&self, other: &UnitQuat, eps: &N) -> bool { - ApproxEq::approx_eq_eps(&self.q, &other.q, eps) - } - - #[inline] - fn approx_eq_ulps(&self, other: &UnitQuat, ulps: u32) -> bool { - ApproxEq::approx_eq_ulps(&self.q, &other.q, ulps) - } -} - -impl> Div> for UnitQuat { - type Output = UnitQuat; - - #[inline] - fn div(self, other: UnitQuat) -> UnitQuat { - UnitQuat { q: self.q / other.q } - } -} - -impl> DivAssign> for UnitQuat { - #[inline] - fn div_assign(&mut self, other: UnitQuat) { - self.q /= other.q - } -} - -impl Mul> for UnitQuat { - type Output = UnitQuat; - - #[inline] - fn mul(self, right: UnitQuat) -> UnitQuat { - UnitQuat { q: self.q * right.q } - } -} - -impl MulAssign> for UnitQuat { - #[inline] - fn mul_assign(&mut self, right: UnitQuat) { - self.q *= right.q - } -} - -impl Mul> for UnitQuat { - type Output = Vec3; - - #[inline] - fn mul(self, right: Vec3) -> Vec3 { - let _2: N = ::one::() + ::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 Mul> for UnitQuat { - type Output = Pnt3; - - #[inline] - fn mul(self, right: Pnt3) -> Pnt3 { - ::orig::>() + self * *right.as_vec() - } -} - -impl> Mul> for Vec3 { - type Output = Vec3; - - #[inline] - fn mul(self, right: UnitQuat) -> Vec3 { - let mut inv_quat = right; - - inv_quat.inv_mut(); - - inv_quat * self - } -} - -impl> Mul> for Pnt3 { - type Output = Pnt3; - - #[inline] - fn mul(self, right: UnitQuat) -> Pnt3 { - ::orig::>() + *self.as_vec() * right - } -} - -impl> MulAssign> for Vec3 { - #[inline] - fn mul_assign(&mut self, right: UnitQuat) { - *self = *self * right - } -} - -impl> MulAssign> for Pnt3 { - #[inline] - fn mul_assign(&mut self, right: UnitQuat) { - *self = *self * right - } -} - -impl Rotation> for UnitQuat { - #[inline] - fn rotation(&self) -> Vec3 { - let _2 = ::one::() + ::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 { - -self.rotation() - } - - #[inline] - fn append_rotation_mut(&mut self, amount: &Vec3) { - *self = Rotation::append_rotation(self, amount) - } - - #[inline] - fn append_rotation(&self, amount: &Vec3) -> UnitQuat { - *self * UnitQuat::new(*amount) - } - - #[inline] - fn prepend_rotation_mut(&mut self, amount: &Vec3) { - *self = Rotation::prepend_rotation(self, amount) - } - - #[inline] - fn prepend_rotation(&self, amount: &Vec3) -> UnitQuat { - UnitQuat::new(*amount) * *self - } - - #[inline] - fn set_rotation(&mut self, v: Vec3) { - *self = UnitQuat::new(v) - } -} - -impl RotationMatrix, Vec3> for UnitQuat { - type Output = Rot3; - - #[inline] - fn to_rot_mat(&self) -> Rot3 { - self.to_rot() - } -} - -impl> Rotate> for UnitQuat { - #[inline] - fn rotate(&self, v: &Vec3) -> Vec3 { - *self * *v - } - - #[inline] - fn inv_rotate(&self, v: &Vec3) -> Vec3 { - *v * *self - } -} - -impl> Rotate> for UnitQuat { - #[inline] - fn rotate(&self, p: &Pnt3) -> Pnt3 { - *self * *p - } - - #[inline] - fn inv_rotate(&self, p: &Pnt3) -> Pnt3 { - *p * *self - } -} - -impl> RotationTo for UnitQuat { - type AngleType = N; - type DeltaRotationType = UnitQuat; - - #[inline] - fn angle_to(&self, other: &Self) -> N { - let delta = self.rotation_to(other); - let _2 = ::one::() + ::one(); - - _2 * delta.q.vector().norm().atan2(delta.q.w) - } - - #[inline] - fn rotation_to(&self, other: &Self) -> UnitQuat { - *other / *self - } -} - -impl> Transform> for UnitQuat { - #[inline] - fn transform(&self, v: &Vec3) -> Vec3 { - *self * *v - } - - #[inline] - fn inv_transform(&self, v: &Vec3) -> Vec3 { - *v * *self - } -} - -impl> Transform> for UnitQuat { - #[inline] - fn transform(&self, p: &Pnt3) -> Pnt3 { - *self * *p - } - - #[inline] - fn inv_transform(&self, p: &Pnt3) -> Pnt3 { - *p * *self - } -} - -impl fmt::Display for UnitQuat { - 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 Arbitrary for UnitQuat { - fn arbitrary(g: &mut G) -> UnitQuat { - 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); diff --git a/src/structs/quaternion.rs b/src/structs/quaternion.rs new file mode 100644 index 00000000..d785321a --- /dev/null +++ b/src/structs/quaternion.rs @@ -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 { + /// 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 Quaternion { + /// Creates a new quaternion from its components. + #[inline] + pub fn new(w: N, i: N, j: N, k: N) -> Quaternion { + 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 { + // 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 + Copy> Quaternion { + /// Compute the conjugate of this quaternion. + #[inline] + pub fn conjugate(&self) -> Quaternion { + 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> Inverse for Quaternion { + #[inline] + fn inverse(&self) -> Option> { + 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 Norm for Quaternion { + #[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 { + 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 Mul> for Quaternion + where N: Copy + Mul + Sub + Add { + type Output = Quaternion; + + #[inline] + fn mul(self, right: Quaternion) -> Quaternion { + 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 MulAssign> for Quaternion + where N: Copy + Mul + Sub + Add { + #[inline] + fn mul_assign(&mut self, right: Quaternion) { + *self = *self * right; + } +} + +impl + BaseFloat> Div> for Quaternion { + type Output = Quaternion; + + #[inline] + fn div(self, right: Quaternion) -> Quaternion { + self * right.inverse().expect("Unable to invert the denominator.") + } +} + +impl + BaseFloat> DivAssign> for Quaternion { + #[inline] + fn div_assign(&mut self, right: Quaternion) { + *self *= right.inverse().expect("Unable to invert the denominator.") + } +} + +impl fmt::Display for Quaternion { + 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 { + q: Quaternion +} + +impl UnitQuaternion { + /// Creates a new unit quaternion from the axis-angle representation of a rotation. + #[inline] + pub fn new(axisangle: Vector3) -> UnitQuaternion { + 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) -> UnitQuaternion { + 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 { + 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 { + 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 UnitQuaternion { + /// 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) -> UnitQuaternion { + UnitQuaternion { + q: q + } + } + + /// The `Quaternion` representation of this unit quaternion. + #[inline] + pub fn quaternion<'a>(&'a self) -> &'a Quaternion { + &self.q + } +} + +impl One for UnitQuaternion { + #[inline] + fn one() -> UnitQuaternion { + unsafe { + UnitQuaternion::new_with_unit_quaternion(Quaternion::new(::one(), ::zero(), ::zero(), ::zero())) + } + } +} + +impl> Inverse for UnitQuaternion { + #[inline] + fn inverse(&self) -> Option> { + let mut cpy = *self; + + cpy.inverse_mut(); + Some(cpy) + } + + #[inline] + fn inverse_mut(&mut self) -> bool { + self.q.conjugate_mut(); + + true + } +} + +impl Rand for UnitQuaternion { + #[inline] + fn rand(rng: &mut R) -> UnitQuaternion { + UnitQuaternion::new(rng.gen()) + } +} + +impl> ApproxEq for UnitQuaternion { + #[inline] + fn approx_epsilon(_: Option>) -> N { + ApproxEq::approx_epsilon(None::) + } + + #[inline] + fn approx_ulps(_: Option>) -> u32 { + ApproxEq::approx_ulps(None::) + } + + #[inline] + fn approx_eq_eps(&self, other: &UnitQuaternion, eps: &N) -> bool { + ApproxEq::approx_eq_eps(&self.q, &other.q, eps) + } + + #[inline] + fn approx_eq_ulps(&self, other: &UnitQuaternion, ulps: u32) -> bool { + ApproxEq::approx_eq_ulps(&self.q, &other.q, ulps) + } +} + +impl> Div> for UnitQuaternion { + type Output = UnitQuaternion; + + #[inline] + fn div(self, other: UnitQuaternion) -> UnitQuaternion { + UnitQuaternion { q: self.q / other.q } + } +} + +impl> DivAssign> for UnitQuaternion { + #[inline] + fn div_assign(&mut self, other: UnitQuaternion) { + self.q /= other.q + } +} + +impl Mul> for UnitQuaternion { + type Output = UnitQuaternion; + + #[inline] + fn mul(self, right: UnitQuaternion) -> UnitQuaternion { + UnitQuaternion { q: self.q * right.q } + } +} + +impl MulAssign> for UnitQuaternion { + #[inline] + fn mul_assign(&mut self, right: UnitQuaternion) { + self.q *= right.q + } +} + +impl Mul> for UnitQuaternion { + type Output = Vector3; + + #[inline] + fn mul(self, right: Vector3) -> Vector3 { + let _2: N = ::one::() + ::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 Mul> for UnitQuaternion { + type Output = Point3; + + #[inline] + fn mul(self, right: Point3) -> Point3 { + ::origin::>() + self * *right.as_vector() + } +} + +impl> Mul> for Vector3 { + type Output = Vector3; + + #[inline] + fn mul(self, right: UnitQuaternion) -> Vector3 { + let mut inverse_quaternion = right; + + inverse_quaternion.inverse_mut(); + + inverse_quaternion * self + } +} + +impl> Mul> for Point3 { + type Output = Point3; + + #[inline] + fn mul(self, right: UnitQuaternion) -> Point3 { + ::origin::>() + *self.as_vector() * right + } +} + +impl> MulAssign> for Vector3 { + #[inline] + fn mul_assign(&mut self, right: UnitQuaternion) { + *self = *self * right + } +} + +impl> MulAssign> for Point3 { + #[inline] + fn mul_assign(&mut self, right: UnitQuaternion) { + *self = *self * right + } +} + +impl Rotation> for UnitQuaternion { + #[inline] + fn rotation(&self) -> Vector3 { + let _2 = ::one::() + ::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 { + -self.rotation() + } + + #[inline] + fn append_rotation_mut(&mut self, amount: &Vector3) { + *self = Rotation::append_rotation(self, amount) + } + + #[inline] + fn append_rotation(&self, amount: &Vector3) -> UnitQuaternion { + *self * UnitQuaternion::new(*amount) + } + + #[inline] + fn prepend_rotation_mut(&mut self, amount: &Vector3) { + *self = Rotation::prepend_rotation(self, amount) + } + + #[inline] + fn prepend_rotation(&self, amount: &Vector3) -> UnitQuaternion { + UnitQuaternion::new(*amount) * *self + } + + #[inline] + fn set_rotation(&mut self, v: Vector3) { + *self = UnitQuaternion::new(v) + } +} + +impl RotationMatrix, Vector3> for UnitQuaternion { + type Output = Rotation3; + + #[inline] + fn to_rotation_matrix(&self) -> Rotation3 { + self.to_rotation_matrix() + } +} + +impl> Rotate> for UnitQuaternion { + #[inline] + fn rotate(&self, v: &Vector3) -> Vector3 { + *self * *v + } + + #[inline] + fn inverse_rotate(&self, v: &Vector3) -> Vector3 { + *v * *self + } +} + +impl> Rotate> for UnitQuaternion { + #[inline] + fn rotate(&self, p: &Point3) -> Point3 { + *self * *p + } + + #[inline] + fn inverse_rotate(&self, p: &Point3) -> Point3 { + *p * *self + } +} + +impl> RotationTo for UnitQuaternion { + type AngleType = N; + type DeltaRotationType = UnitQuaternion; + + #[inline] + fn angle_to(&self, other: &Self) -> N { + let delta = self.rotation_to(other); + let _2 = ::one::() + ::one(); + + _2 * delta.q.vector().norm().atan2(delta.q.w) + } + + #[inline] + fn rotation_to(&self, other: &Self) -> UnitQuaternion { + *other / *self + } +} + +impl> Transform> for UnitQuaternion { + #[inline] + fn transform(&self, v: &Vector3) -> Vector3 { + *self * *v + } + + #[inline] + fn inverse_transform(&self, v: &Vector3) -> Vector3 { + *v * *self + } +} + +impl> Transform> for UnitQuaternion { + #[inline] + fn transform(&self, p: &Point3) -> Point3 { + *self * *p + } + + #[inline] + fn inverse_transform(&self, p: &Point3) -> Point3 { + *p * *self + } +} + +impl fmt::Display for UnitQuaternion { + 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 Arbitrary for UnitQuaternion { + fn arbitrary(g: &mut G) -> UnitQuaternion { + 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); diff --git a/src/structs/rot.rs b/src/structs/rot.rs deleted file mode 100644 index 7b87a9d9..00000000 --- a/src/structs/rot.rs +++ /dev/null @@ -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 { - submat: Mat2 -} - -impl> Rot2 { - /// Builds a 2 dimensional rotation matrix from an angle in radian. - pub fn new(angle: Vec1) -> Rot2 { - let (sia, coa) = angle.x.sin_cos(); - - Rot2 { - submat: Mat2::new(coa.clone(), -sia, sia, coa) - } - } -} - -impl Rotation> for Rot2 { - #[inline] - fn rotation(&self) -> Vec1 { - Vec1::new((-self.submat.m12).atan2(self.submat.m11.clone())) - } - - #[inline] - fn inv_rotation(&self) -> Vec1 { - -self.rotation() - } - - #[inline] - fn append_rotation_mut(&mut self, rot: &Vec1) { - *self = Rotation::append_rotation(self, rot) - } - - #[inline] - fn append_rotation(&self, rot: &Vec1) -> Rot2 { - Rot2::new(rot.clone()) * *self - } - - #[inline] - fn prepend_rotation_mut(&mut self, rot: &Vec1) { - *self = Rotation::prepend_rotation(self, rot) - } - - #[inline] - fn prepend_rotation(&self, rot: &Vec1) -> Rot2 { - *self * Rot2::new(rot.clone()) - } - - #[inline] - fn set_rotation(&mut self, rot: Vec1) { - *self = Rot2::new(rot) - } -} - -impl RotationTo for Rot2 { - type AngleType = N; - type DeltaRotationType = Rot2; - - #[inline] - fn angle_to(&self, other: &Self) -> N { - self.rotation_to(other).rotation().norm() - } - - #[inline] - fn rotation_to(&self, other: &Self) -> Rot2 { - *other * ::inv(self).unwrap() - } -} - -impl Rand for Rot2 { - #[inline] - fn rand(rng: &mut R) -> Rot2 { - Rot2::new(rng.gen()) - } -} - -impl AbsoluteRotate> for Rot2 { - #[inline] - fn absolute_rotate(&self, v: &Vec2) -> Vec2 { - // 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> Arbitrary for Rot2 { - fn arbitrary(g: &mut G) -> Rot2 { - 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 { - submat: Mat3 -} - - -impl Rot3 { - /// 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) -> Rot3 { - 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) -> Rot3 { - 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 { - 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 Rot3 { - /// 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, up: &Vec3) -> Rot3 { - 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, up: &Vec3) -> Rot3 { - 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, up: &Vec3) -> Rot3 { - Rot3::new_observer_frame(&(*dir), up).inv().unwrap() - } -} - -impl> -Rotation> for Rot3 { - #[inline] - fn rotation(&self) -> Vec3 { - 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 { - -self.rotation() - } - - - #[inline] - fn append_rotation_mut(&mut self, rot: &Vec3) { - *self = Rotation::append_rotation(self, rot) - } - - #[inline] - fn append_rotation(&self, axisangle: &Vec3) -> Rot3 { - Rot3::new(axisangle.clone()) * *self - } - - #[inline] - fn prepend_rotation_mut(&mut self, rot: &Vec3) { - *self = Rotation::prepend_rotation(self, rot) - } - - #[inline] - fn prepend_rotation(&self, axisangle: &Vec3) -> Rot3 { - *self * Rot3::new(axisangle.clone()) - } - - #[inline] - fn set_rotation(&mut self, axisangle: Vec3) { - *self = Rot3::new(axisangle) - } -} - -impl RotationTo for Rot3 { - type AngleType = N; - type DeltaRotationType = Rot3; - - #[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 { - *other * ::inv(self).unwrap() - } -} - -impl Rand for Rot3 { - #[inline] - fn rand(rng: &mut R) -> Rot3 { - Rot3::new(rng.gen()) - } -} - -impl AbsoluteRotate> for Rot3 { - #[inline] - fn absolute_rotate(&self, v: &Vec3) -> Vec3 { - 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 Arbitrary for Rot3 { - fn arbitrary(g: &mut G) -> Rot3 { - 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); diff --git a/src/structs/rotation.rs b/src/structs/rotation.rs new file mode 100644 index 00000000..98d71acb --- /dev/null +++ b/src/structs/rotation.rs @@ -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 { + submatrix: Matrix2 +} + +impl> Rotation2 { + /// Builds a 2 dimensional rotation matrix from an angle in radian. + pub fn new(angle: Vector1) -> Rotation2 { + let (sia, coa) = angle.x.sin_cos(); + + Rotation2 { + submatrix: Matrix2::new(coa.clone(), -sia, sia, coa) + } + } +} + +impl Rotation> for Rotation2 { + #[inline] + fn rotation(&self) -> Vector1 { + Vector1::new((-self.submatrix.m12).atan2(self.submatrix.m11.clone())) + } + + #[inline] + fn inverse_rotation(&self) -> Vector1 { + -self.rotation() + } + + #[inline] + fn append_rotation_mut(&mut self, rotation: &Vector1) { + *self = Rotation::append_rotation(self, rotation) + } + + #[inline] + fn append_rotation(&self, rotation: &Vector1) -> Rotation2 { + Rotation2::new(rotation.clone()) * *self + } + + #[inline] + fn prepend_rotation_mut(&mut self, rotation: &Vector1) { + *self = Rotation::prepend_rotation(self, rotation) + } + + #[inline] + fn prepend_rotation(&self, rotation: &Vector1) -> Rotation2 { + *self * Rotation2::new(rotation.clone()) + } + + #[inline] + fn set_rotation(&mut self, rotation: Vector1) { + *self = Rotation2::new(rotation) + } +} + +impl RotationTo for Rotation2 { + type AngleType = N; + type DeltaRotationType = Rotation2; + + #[inline] + fn angle_to(&self, other: &Self) -> N { + self.rotation_to(other).rotation().norm() + } + + #[inline] + fn rotation_to(&self, other: &Self) -> Rotation2 { + *other * ::inverse(self).unwrap() + } +} + +impl Rand for Rotation2 { + #[inline] + fn rand(rng: &mut R) -> Rotation2 { + Rotation2::new(rng.gen()) + } +} + +impl AbsoluteRotate> for Rotation2 { + #[inline] + fn absolute_rotate(&self, v: &Vector2) -> Vector2 { + // 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> Arbitrary for Rotation2 { + fn arbitrary(g: &mut G) -> Rotation2 { + 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 { + submatrix: Matrix3 +} + + +impl Rotation3 { + /// 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) -> Rotation3 { + 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) -> Rotation3 { + 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 { + 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 Rotation3 { + /// 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, up: &Vector3) -> Rotation3 { + 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, up: &Vector3) -> Rotation3 { + 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, up: &Vector3) -> Rotation3 { + Rotation3::new_observer_frame(&(*dir), up).inverse().unwrap() + } +} + +impl> +Rotation> for Rotation3 { + #[inline] + fn rotation(&self) -> Vector3 { + 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 { + -self.rotation() + } + + + #[inline] + fn append_rotation_mut(&mut self, rotation: &Vector3) { + *self = Rotation::append_rotation(self, rotation) + } + + #[inline] + fn append_rotation(&self, axisangle: &Vector3) -> Rotation3 { + Rotation3::new(axisangle.clone()) * *self + } + + #[inline] + fn prepend_rotation_mut(&mut self, rotation: &Vector3) { + *self = Rotation::prepend_rotation(self, rotation) + } + + #[inline] + fn prepend_rotation(&self, axisangle: &Vector3) -> Rotation3 { + *self * Rotation3::new(axisangle.clone()) + } + + #[inline] + fn set_rotation(&mut self, axisangle: Vector3) { + *self = Rotation3::new(axisangle) + } +} + +impl RotationTo for Rotation3 { + type AngleType = N; + type DeltaRotationType = Rotation3; + + #[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 { + *other * ::inverse(self).unwrap() + } +} + +impl Rand for Rotation3 { + #[inline] + fn rand(rng: &mut R) -> Rotation3 { + Rotation3::new(rng.gen()) + } +} + +impl AbsoluteRotate> for Rotation3 { + #[inline] + fn absolute_rotate(&self, v: &Vector3) -> Vector3 { + 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 Arbitrary for Rotation3 { + fn arbitrary(g: &mut G) -> Rotation3 { + 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); diff --git a/src/structs/rot_macros.rs b/src/structs/rotation_macros.rs similarity index 68% rename from src/structs/rot_macros.rs rename to src/structs/rotation_macros.rs index 043baf39..9f21deb7 100644 --- a/src/structs/rot_macros.rs +++ b/src/structs/rotation_macros.rs @@ -1,12 +1,12 @@ #![macro_use] macro_rules! submat_impl( - ($t: ident, $submat: ident) => ( + ($t: ident, $submatrix: ident) => ( impl $t { /// This rotation's underlying matrix. #[inline] - pub fn submat<'r>(&'r self) -> &'r $submat { - &self.submat + pub fn submatrix<'r>(&'r self) -> &'r $submatrix { + &self.submatrix } } ) @@ -21,7 +21,7 @@ macro_rules! rotate_impl( } #[inline] - fn inv_rotate(&self, v: &$tv) -> $tv { + fn inverse_rotate(&self, v: &$tv) -> $tv { *v * *self } } @@ -33,7 +33,7 @@ macro_rules! rotate_impl( } #[inline] - fn inv_rotate(&self, p: &$tp) -> $tp { + fn inverse_rotate(&self, p: &$tp) -> $tp { *p * *self } } @@ -49,8 +49,8 @@ macro_rules! transform_impl( } #[inline] - fn inv_transform(&self, v: &$tv) -> $tv { - self.inv_rotate(v) + fn inverse_transform(&self, v: &$tv) -> $tv { + self.inverse_rotate(v) } } @@ -61,19 +61,19 @@ macro_rules! transform_impl( } #[inline] - fn inv_transform(&self, p: &$tp) -> $tp { - self.inv_rotate(p) + fn inverse_transform(&self, p: &$tp) -> $tp { + self.inverse_rotate(p) } } ) ); macro_rules! dim_impl( - ($t: ident, $dim: expr) => ( - impl Dim for $t { + ($t: ident, $dimension: expr) => ( + impl Dimension for $t { #[inline] - fn dim(_: Option<$t>) -> usize { - $dim + fn dimension(_: Option<$t>) -> usize { + $dimension } } ) @@ -85,7 +85,7 @@ macro_rules! rotation_matrix_impl( type Output = $t; #[inline] - fn to_rot_mat(&self) -> $t { + fn to_rotation_matrix(&self) -> $t { self.clone() } } @@ -97,7 +97,7 @@ macro_rules! one_impl( impl One for $t { #[inline] fn one() -> $t { - $t { submat: ::one() } + $t { submatrix: ::one() } } } ) @@ -107,9 +107,9 @@ macro_rules! eye_impl( ($t: ident) => ( impl Eye for $t { #[inline] - fn new_identity(dim: usize) -> $t { - if dim != ::dim::<$t>() { - panic!("Dimension mismatch: should be {}, got {}.", ::dim::<$t>(), dim); + fn new_identity(dimension: usize) -> $t { + if dimension != ::dimension::<$t>() { + panic!("Dimension mismatch: should be {}, got {}.", ::dimension::<$t>(), dimension); } else { ::one() @@ -121,90 +121,90 @@ macro_rules! eye_impl( macro_rules! diag_impl( ($t: ident, $tv: ident) => ( - impl Diag<$tv> for $t { + impl Diagonal<$tv> for $t { #[inline] - fn from_diag(diag: &$tv) -> $t { - $t { submat: Diag::from_diag(diag) } + fn from_diag(diagonal: &$tv) -> $t { + $t { submatrix: Diagonal::from_diag(diagonal) } } #[inline] - fn diag(&self) -> $tv { - self.submat.diag() + fn diagonal(&self) -> $tv { + self.submatrix.diagonal() } } ) ); -macro_rules! rot_mul_rot_impl( +macro_rules! rotation_mul_rotation_impl( ($t: ident) => ( impl Mul<$t> for $t { type Output = $t; #[inline] fn mul(self, right: $t) -> $t { - $t { submat: self.submat * right.submat } + $t { submatrix: self.submatrix * right.submatrix } } } impl MulAssign<$t> for $t { #[inline] fn mul_assign(&mut self, right: $t) { - 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 Mul<$tv> for $t { type Output = $tv; #[inline] fn mul(self, right: $tv) -> $tv { - 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 Mul<$t> for $tv { type Output = $tv; #[inline] fn mul(self, right: $t) -> $tv { - self * right.submat + self * right.submatrix } } impl MulAssign<$t> for $tv { #[inline] fn mul_assign(&mut self, right: $t) { - *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 Inv for $t { + impl Inverse for $t { #[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> { + fn inverse(&self) -> Option<$t> { // always succeed Some(self.transpose()) } @@ -225,12 +225,12 @@ macro_rules! transpose_impl( impl Transpose for $t { #[inline] fn transpose(&self) -> $t { - $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 Row<$tv> for $t { #[inline] fn nrows(&self) -> usize { - self.submat.nrows() + self.submatrix.nrows() } #[inline] fn row(&self, i: usize) -> $tv { - self.submat.row(i) + self.submatrix.row(i) } #[inline] fn set_row(&mut self, i: usize, row: $tv) { - 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 Col<$tv> for $t { + impl Column<$tv> for $t { #[inline] fn ncols(&self) -> usize { - self.submat.ncols() + self.submatrix.ncols() } #[inline] - fn col(&self, i: usize) -> $tv { - self.submat.col(i) + fn column(&self, i: usize) -> $tv { + self.submatrix.column(i) } #[inline] - fn set_col(&mut self, i: usize, col: $tv) { - self.submat.set_col(i, col); + fn set_col(&mut self, i: usize, column: $tv) { + 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 ToHomogeneous<$tm> for $t { #[inline] fn to_homogeneous(&self) -> $tm { - self.submat.to_homogeneous() + self.submatrix.to_homogeneous() } } ) @@ -314,17 +314,17 @@ macro_rules! approx_eq_impl( #[inline] fn approx_eq(&self, other: &$t) -> bool { - ApproxEq::approx_eq(&self.submat, &other.submat) + ApproxEq::approx_eq(&self.submatrix, &other.submatrix) } #[inline] fn approx_eq_eps(&self, other: &$t, 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, 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> Absolute<$tm> for $t { #[inline] fn abs(m: &$t) -> $tm { - Absolute::abs(&m.submat) + Absolute::abs(&m.submatrix) } } ) ); -macro_rules! rot_display_impl( +macro_rules! rotation_display_impl( ($t: ident) => ( impl fmt::Display for $t { 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, "}}") } } diff --git a/src/structs/sim.rs b/src/structs/sim.rs deleted file mode 100644 index 28345bcf..00000000 --- a/src/structs/sim.rs +++ /dev/null @@ -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 { - /// The uniform scale applicable by this similarity transformation. - scale: N, - /// The isometry applicable by this similarity transformation. - pub isometry: Iso2 -} - -/// 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 { - /// The uniform scale applicable by this similarity transformation. - scale: N, - /// The isometry applicable by this similarity transformation. - pub isometry: Iso3 -} - -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); diff --git a/src/structs/similarity.rs b/src/structs/similarity.rs new file mode 100644 index 00000000..1fb6eb1d --- /dev/null +++ b/src/structs/similarity.rs @@ -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 { + /// The uniform scale applicable by this similarity transformation. + scale: N, + /// The isometry applicable by this similarity transformation. + pub isometry: Isometry2 +} + +/// 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 { + /// The uniform scale applicable by this similarity transformation. + scale: N, + /// The isometry applicable by this similarity transformation. + pub isometry: Isometry3 +} + +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); diff --git a/src/structs/sim_macros.rs b/src/structs/similarity_macros.rs similarity index 83% rename from src/structs/sim_macros.rs rename to src/structs/similarity_macros.rs index b82aaf0f..d05f07e7 100644 --- a/src/structs/sim_macros.rs +++ b/src/structs/similarity_macros.rs @@ -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 $t { /// 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, rotation: $subrotvec, scale: N) -> $t { + pub fn new(translation: $subvector, rotation: $subrotvector, scale: N) -> $t { 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, rotation: $rotmat, scale: N) -> $t { + pub fn new_with_rotation_matrix(translation: $subvector, rotation: $rotation_matrix, scale: N) -> $t { 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, scale: N) -> $t { + pub fn new_with_isometry(isometry: $isometry, scale: N) -> $t { 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::() / self.scale } @@ -72,7 +72,7 @@ macro_rules! sim_scale_impl( #[inline] pub fn append_scale(&self, s: &N) -> $t { 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 { 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 One for $t { #[inline] fn one() -> $t { - $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) -> $t { - $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 Mul<$ti> for $t { type Output = $t; #[inline] fn mul(self, right: $ti) -> $t { - $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) -> $t { - $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 Mul<$tr> for $t { type Output = $t; #[inline] fn mul(self, right: $tr) -> $t { - $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) -> $t { - $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 Mul<$tv> for $t { type Output = $tv; @@ -232,20 +232,20 @@ macro_rules! sim_transform_impl( } #[inline] - fn inv_transform(&self, p: &$tp) -> $tp { - self.isometry.inv_transform(p) / self.scale + fn inverse_transform(&self, p: &$tp) -> $tp { + self.isometry.inverse_transform(p) / self.scale } } ) ); -macro_rules! sim_inv_impl( +macro_rules! sim_inverse_impl( ($t: ident) => ( - impl> Inv for $t { + impl> Inverse for $t { #[inline] - fn inv_mut(&mut self) -> bool { + fn inverse_mut(&mut self) -> bool { self.scale = ::one::() / 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> { + fn inverse(&self) -> Option<$t> { 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 ToHomogeneous<$th> for $t { fn to_homogeneous(&self) -> $th { - 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>); + let dimension = Dimension::dimension(None::<$th>); - 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 Arbitrary for $t { fn arbitrary(g: &mut G) -> $t { - $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, "}}") diff --git a/src/structs/spec/vec.rs b/src/structs/spec/vec.rs deleted file mode 100644 index 09e8f63a..00000000 --- a/src/structs/spec/vec.rs +++ /dev/null @@ -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 RotationTo for Vec2 { - type AngleType = N; - type DeltaRotationType = Rot2; - - #[inline] - fn angle_to(&self, other: &Self) -> N { - ::cross(self, other).x.atan2(::dot(self, other)) - } - - #[inline] - fn rotation_to(&self, other: &Self) -> Rot2 { - Rot2::new(Vec1::new(self.angle_to(other))) - } -} - -impl RotationTo for Vec3 { - type AngleType = N; - type DeltaRotationType = Rot3; - - #[inline] - fn angle_to(&self, other: &Self) -> N { - ::cross(self, other).norm().atan2(::dot(self, other)) - } - - #[inline] - fn rotation_to(&self, other: &Self) -> Rot3 { - 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 + Sub> Cross for Vec2 { - type CrossProductType = Vec1; - - #[inline] - fn cross(&self, other: &Vec2) -> Vec1 { - Vec1::new(self.x * other.y - self.y * other.x) - } -} - -// FIXME: instead of returning a Vec2, define a Mat2x1 matrix? -impl + Copy> CrossMatrix> for Vec2 { - #[inline] - fn cross_matrix(&self) -> Vec2 { - Vec2::new(-self.y, self.x) - } -} - -impl + Sub> Cross for Vec3 { - type CrossProductType = Vec3; - - #[inline] - fn cross(&self, other: &Vec3) -> Vec3 { - 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 + Zero + Copy> CrossMatrix> for Vec3 { - #[inline] - fn cross_matrix(&self) -> Mat3 { - 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 Row> for Vec2 { - #[inline] - fn nrows(&self) -> usize { - 2 - } - - #[inline] - fn row(&self, i: usize) -> Vec1 { - 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) { - 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 Basis for Vec1 { - #[inline(always)] - fn canonical_basis) -> bool>(mut f: F) { - f(Vec1::new(::one())); - } - - #[inline(always)] - fn orthonormal_subspace_basis) -> bool>(_: &Vec1, _: F) { } - - #[inline] - fn canonical_basis_element(i: usize) -> Option> { - if i == 0 { - Some(Vec1::new(::one())) - } - else { - None - } - } -} - -impl> Basis for Vec2 { - #[inline(always)] - fn canonical_basis) -> bool>(mut f: F) { - if !f(Vec2::new(::one(), ::zero())) { return }; - f(Vec2::new(::zero(), ::one())); - } - - #[inline] - fn orthonormal_subspace_basis) -> bool>(n: &Vec2, mut f: F) { - f(Vec2::new(-n.y, n.x)); - } - - #[inline] - fn canonical_basis_element(i: usize) -> Option> { - if i == 0 { - Some(Vec2::new(::one(), ::zero())) - } - else if i == 1 { - Some(Vec2::new(::zero(), ::one())) - } - else { - None - } - } -} - -impl Basis for Vec3 { - #[inline(always)] - fn canonical_basis) -> 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) -> bool>(n: &Vec3, 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> { - 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; 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; 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 UniformSphereSample for Vec1 - where Vec1: One { - #[inline(always)] - fn sample)>(mut f: F) { - f(::one()) - } -} - -impl + Copy> UniformSphereSample for Vec2 { - #[inline(always)] - fn sample)>(mut f: F) { - for sample in SAMPLES_2_F64.iter() { - f(Cast::from(*sample)) - } - } -} - -impl + Copy> UniformSphereSample for Vec3 { - #[inline(always)] - fn sample)>(mut f: F) { - for sample in SAMPLES_3_F64.iter() { - f(Cast::from(*sample)) - } - } -} - -impl + Copy> UniformSphereSample for Vec4 { - #[inline(always)] - fn sample)>(_: F) { - panic!("UniformSphereSample::>::sample : Not yet implemented.") - // for sample in SAMPLES_3_F32.iter() { - // f(Cast::from(*sample)) - // } - } -} diff --git a/src/structs/spec/complex.rs b/src/structs/specializations/complex.rs similarity index 65% rename from src/structs/spec/complex.rs rename to src/structs/specializations/complex.rs index 9acb9027..5be05373 100644 --- a/src/structs/spec/complex.rs +++ b/src/structs/specializations/complex.rs @@ -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 Absolute> for Cmplx { #[inline] @@ -12,7 +12,7 @@ impl Absolute> for Cmplx { } } -impl Inv for Cmplx { +impl Inverse for Cmplx { #[inline] fn inverse(&self) -> Option> { if self.is_zero() { @@ -43,55 +43,55 @@ impl Inv for Cmplx { } } -impl Dim for Cmplx { +impl Dimension for Cmplx { #[inline] - fn dim(unsused_mut: Option>) -> usize { + fn dimension(unsused_mut: Option>) -> usize { 2 } } -impl Rotation> for Cmplx { +impl Rotation> for Cmplx { #[inline] - fn rotation(&self) -> Vec2 { + fn rotation(&self) -> Vector2 { } #[inline] - fn inv_rotation(&self) -> Vec2 { + fn inverse_rotation(&self) -> Vector2 { -self.rotation(); } #[inline] - fn rotate_by(&mut self, rotation: &Vec2) { + fn rotate_by(&mut self, rotation: &Vector2) { } #[inline] - fn rotated(&self, rotation: &Vec2) -> Cmplx { + fn rotated(&self, rotation: &Vector2) -> Cmplx { } #[inline] - fn set_rotation(&mut self, rotation: Vec2) { + fn set_rotation(&mut self, rotation: Vector2) { } } -impl Rotate> for Cmplx { +impl Rotate> for Cmplx { #[inline] fn rotate(&self, rotation: &V) -> V { } #[inline] - fn inv_rotate(&self, rotation: &V) -> V { + fn inverse_rotate(&self, rotation: &V) -> V { } } -impl RotationMatrix, Vec2, Rotmat>> for Cmplx { +impl RotationMatrix, Vector2, Rotationmatrix>> for Cmplx { #[inline] - fn to_rot_mat(&self) -> Rotmat> { + fn to_rotation_matrix(&self) -> Rotationmatrix> { } } impl Norm for Cmplx { #[inline] - fn sqnorm(&self) -> N { + fn norm_squared(&self) -> N { } #[inline] diff --git a/src/structs/spec/identity.rs b/src/structs/specializations/identity.rs similarity index 50% rename from src/structs/spec/identity.rs rename to src/structs/specializations/identity.rs index 36314f0d..3e410702 100644 --- a/src/structs/spec/identity.rs +++ b/src/structs/specializations/identity.rs @@ -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 { - Some(mat::Identity::new()) +impl Inverse for Identity { + fn inverse(&self) -> Option { + Some(Identity::new()) } - fn inv_mut(&mut self) -> bool { + fn inverse_mut(&mut self) -> bool { true } } -impl Mul for mat::Identity { +impl Mul for Identity { type Output = T; #[inline] @@ -30,10 +30,10 @@ impl Mul 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 Translate for mat::Identity { +impl Translate 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 Rotate for mat::Identity { +impl Rotate 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 AbsoluteRotate for mat::Identity { +impl AbsoluteRotate for Identity { #[inline] fn absolute_rotate(&self, v: &V) -> V { v.clone() } } -impl Transform for mat::Identity { +impl Transform 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() } } diff --git a/src/structs/spec/mat.rs b/src/structs/specializations/matrix.rs similarity index 58% rename from src/structs/spec/mat.rs rename to src/structs/specializations/matrix.rs index c5a8e4c3..883fb651 100644 --- a/src/structs/spec/mat.rs +++ b/src/structs/specializations/matrix.rs @@ -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> Inv for Mat1 { +impl> Inverse for Matrix1 { #[inline] - fn inv(&self) -> Option> { + fn inverse(&self) -> Option> { let mut res = *self; - if res.inv_mut() { + if res.inverse_mut() { Some(res) } else { @@ -19,24 +19,24 @@ impl> Inv for Mat1 { } #[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 + ApproxEq> Inv for Mat2 { +impl + ApproxEq> Inverse for Matrix2 { #[inline] - fn inv(&self) -> Option> { + fn inverse(&self) -> Option> { let mut res = *self; - if res.inv_mut() { + if res.inverse_mut() { Some(res) } else { @@ -45,28 +45,28 @@ impl + ApproxEq> Inv for Mat2 { } #[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 + ApproxEq> Inv for Mat3 { +impl + ApproxEq> Inverse for Matrix3 { #[inline] - fn inv(&self) -> Option> { + fn inverse(&self) -> Option> { let mut res = *self; - if res.inv_mut() { + if res.inverse_mut() { Some(res) } else { @@ -75,29 +75,29 @@ impl + ApproxEq> Inv for Mat3 { } #[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 + ApproxEq> Inv for Mat3 { } } -impl Det for Mat1 { +impl Determinant for Matrix1 { #[inline] - fn det(&self) -> N { + fn determinant(&self) -> N { self.m11 } } -impl Det for Mat2 { +impl Determinant for Matrix2 { #[inline] - fn det(&self) -> N { + fn determinant(&self) -> N { self.m11 * self.m22 - self.m21 * self.m12 } } -impl Det for Mat3 { +impl Determinant for Matrix3 { #[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 Det for Mat3 { } } -impl Row> for Mat3 { +impl Row> for Matrix3 { #[inline] fn nrows(&self) -> usize { 3 } #[inline] - fn row(&self, i: usize) -> Vec3 { + fn row(&self, i: usize) -> Vector3 { 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) { + fn set_row(&mut self, i: usize, r: Vector3) { match i { 0 => { self.m11 = r.x; @@ -170,24 +170,24 @@ impl Row> for Mat3 { } } -impl Col> for Mat3 { +impl Column> for Matrix3 { #[inline] fn ncols(&self) -> usize { 3 } #[inline] - fn col(&self, i: usize) -> Vec3 { + fn column(&self, i: usize) -> Vector3 { 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) { + fn set_col(&mut self, i: usize, r: Vector3) { match i { 0 => { self.m11 = r.x; @@ -210,12 +210,12 @@ impl Col> for Mat3 { } } -impl + Add> Mul> for Mat3 { - type Output = Mat3; +impl + Add> Mul> for Matrix3 { + type Output = Matrix3; #[inline] - fn mul(self, right: Mat3) -> Mat3 { - Mat3::new( + fn mul(self, right: Matrix3) -> Matrix3 { + 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 + Add> Mul> for Mat3 } } -impl + Add> Mul> for Mat2 { - type Output = Mat2; +impl + Add> Mul> for Matrix2 { + type Output = Matrix2; #[inline(always)] - fn mul(self, right: Mat2) -> Mat2 { - Mat2::new( + fn mul(self, right: Matrix2) -> Matrix2 { + Matrix2::new( self.m11 * right.m11 + self.m12 * right.m21, self.m11 * right.m12 + self.m12 * right.m22, @@ -246,12 +246,12 @@ impl + Add> Mul> for Mat2 } } -impl + Add> Mul> for Mat3 { - type Output = Vec3; +impl + Add> Mul> for Matrix3 { + type Output = Vector3; #[inline(always)] - fn mul(self, right: Vec3) -> Vec3 { - Vec3::new( + fn mul(self, right: Vector3) -> Vector3 { + 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 + Add> Mul> for Mat3 } } -impl + Add> Mul> for Vec3 { - type Output = Vec3; +impl + Add> Mul> for Vector3 { + type Output = Vector3; #[inline(always)] - fn mul(self, right: Mat3) -> Vec3 { - Vec3::new( + fn mul(self, right: Matrix3) -> Vector3 { + 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 + Add> Mul> for Vec3 } } -impl + Add> Mul> for Vec2 { - type Output = Vec2; +impl + Add> Mul> for Vector2 { + type Output = Vector2; #[inline(always)] - fn mul(self, right: Mat2) -> Vec2 { - Vec2::new( + fn mul(self, right: Matrix2) -> Vector2 { + Vector2::new( self.x * right.m11 + self.y * right.m21, self.x * right.m12 + self.y * right.m22 ) } } -impl + Add> Mul> for Mat2 { - type Output = Vec2; +impl + Add> Mul> for Matrix2 { + type Output = Vector2; #[inline(always)] - fn mul(self, right: Vec2) -> Vec2 { - Vec2::new( + fn mul(self, right: Vector2) -> Vector2 { + Vector2::new( self.m11 * right.x + self.m12 * right.y, self.m21 * right.x + self.m22 * right.y ) } } -impl + Add> Mul> for Mat3 { - type Output = Pnt3; +impl + Add> Mul> for Matrix3 { + type Output = Point3; #[inline(always)] - fn mul(self, right: Pnt3) -> Pnt3 { - Pnt3::new( + fn mul(self, right: Point3) -> Point3 { + 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 + Add> Mul> for Mat3 } } -impl + Add> Mul> for Pnt3 { - type Output = Pnt3; +impl + Add> Mul> for Point3 { + type Output = Point3; #[inline(always)] - fn mul(self, right: Mat3) -> Pnt3 { - Pnt3::new( + fn mul(self, right: Matrix3) -> Point3 { + 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 + Add> Mul> for Pnt3 } } -impl + Add> Mul> for Pnt2 { - type Output = Pnt2; +impl + Add> Mul> for Point2 { + type Output = Point2; #[inline(always)] - fn mul(self, right: Mat2) -> Pnt2 { - Pnt2::new( + fn mul(self, right: Matrix2) -> Point2 { + Point2::new( self.x * right.m11 + self.y * right.m21, self.x * right.m12 + self.y * right.m22 ) } } -impl + Add> Mul> for Mat2 { - type Output = Pnt2; +impl + Add> Mul> for Matrix2 { + type Output = Point2; #[inline(always)] - fn mul(self, right: Pnt2) -> Pnt2 { - Pnt2::new( + fn mul(self, right: Point2) -> Point2 { + 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); diff --git a/src/structs/spec/primitives.rs b/src/structs/specializations/primitives.rs similarity index 100% rename from src/structs/spec/primitives.rs rename to src/structs/specializations/primitives.rs diff --git a/src/structs/specializations/vector.rs b/src/structs/specializations/vector.rs new file mode 100644 index 00000000..c5367e94 --- /dev/null +++ b/src/structs/specializations/vector.rs @@ -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 RotationTo for Vector2 { + type AngleType = N; + type DeltaRotationType = Rotation2; + + #[inline] + fn angle_to(&self, other: &Self) -> N { + ::cross(self, other).x.atan2(::dot(self, other)) + } + + #[inline] + fn rotation_to(&self, other: &Self) -> Rotation2 { + Rotation2::new(Vector1::new(self.angle_to(other))) + } +} + +impl RotationTo for Vector3 { + type AngleType = N; + type DeltaRotationType = Rotation3; + + #[inline] + fn angle_to(&self, other: &Self) -> N { + ::cross(self, other).norm().atan2(::dot(self, other)) + } + + #[inline] + fn rotation_to(&self, other: &Self) -> Rotation3 { + 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 + Sub> Cross for Vector2 { + type CrossProductType = Vector1; + + #[inline] + fn cross(&self, other: &Vector2) -> Vector1 { + Vector1::new(self.x * other.y - self.y * other.x) + } +} + +// FIXME: instead of returning a Vector2, define a Matrix2x1 matrix? +impl + Copy> CrossMatrix> for Vector2 { + #[inline] + fn cross_matrix(&self) -> Vector2 { + Vector2::new(-self.y, self.x) + } +} + +impl + Sub> Cross for Vector3 { + type CrossProductType = Vector3; + + #[inline] + fn cross(&self, other: &Vector3) -> Vector3 { + 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 + Zero + Copy> CrossMatrix> for Vector3 { + #[inline] + fn cross_matrix(&self) -> Matrix3 { + 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 Row> for Vector2 { + #[inline] + fn nrows(&self) -> usize { + 2 + } + + #[inline] + fn row(&self, i: usize) -> Vector1 { + 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) { + 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 Basis for Vector1 { + #[inline(always)] + fn canonical_basis) -> bool>(mut f: F) { + f(Vector1::new(::one())); + } + + #[inline(always)] + fn orthonormal_subspace_basis) -> bool>(_: &Vector1, _: F) { } + + #[inline] + fn canonical_basis_element(i: usize) -> Option> { + if i == 0 { + Some(Vector1::new(::one())) + } + else { + None + } + } +} + +impl> Basis for Vector2 { + #[inline(always)] + fn canonical_basis) -> bool>(mut f: F) { + if !f(Vector2::new(::one(), ::zero())) { return }; + f(Vector2::new(::zero(), ::one())); + } + + #[inline] + fn orthonormal_subspace_basis) -> bool>(n: &Vector2, mut f: F) { + f(Vector2::new(-n.y, n.x)); + } + + #[inline] + fn canonical_basis_element(i: usize) -> Option> { + if i == 0 { + Some(Vector2::new(::one(), ::zero())) + } + else if i == 1 { + Some(Vector2::new(::zero(), ::one())) + } + else { + None + } + } +} + +impl Basis for Vector3 { + #[inline(always)] + fn canonical_basis) -> 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) -> bool>(n: &Vector3, 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> { + 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; 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; 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 UniformSphereSample for Vector1 + where Vector1: One { + #[inline(always)] + fn sample)>(mut f: F) { + f(::one()) + } +} + +impl + Copy> UniformSphereSample for Vector2 { + #[inline(always)] + fn sample)>(mut f: F) { + for sample in SAMPLES_2_F64.iter() { + f(Cast::from(*sample)) + } + } +} + +impl + Copy> UniformSphereSample for Vector3 { + #[inline(always)] + fn sample)>(mut f: F) { + for sample in SAMPLES_3_F64.iter() { + f(Cast::from(*sample)) + } + } +} + +impl + Copy> UniformSphereSample for Vector4 { + #[inline(always)] + fn sample)>(_: F) { + panic!("UniformSphereSample::>::sample : Not yet implemented.") + // for sample in SAMPLES_3_F32.iter() { + // f(Cast::from(*sample)) + // } + } +} diff --git a/src/structs/vec.rs b/src/structs/vec.rs deleted file mode 100644 index 93ec73b2..00000000 --- a/src/structs/vec.rs +++ /dev/null @@ -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 { - /// 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 { - /// 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 { - /// 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 { - /// 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 { - /// 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 { - /// 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); diff --git a/src/structs/vector.rs b/src/structs/vector.rs new file mode 100644 index 00000000..f18ac8e4 --- /dev/null +++ b/src/structs/vector.rs @@ -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 { + /// 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 { + /// 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 { + /// 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 { + /// 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 { + /// 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 { + /// 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); diff --git a/src/structs/vec_macros.rs b/src/structs/vector_macros.rs similarity index 90% rename from src/structs/vec_macros.rs rename to src/structs/vector_macros.rs index 58c2161c..99c6e980 100644 --- a/src/structs/vec_macros.rs +++ b/src/structs/vector_macros.rs @@ -15,37 +15,37 @@ macro_rules! new_impl( ); macro_rules! conversion_impl( - ($t: ident, $dim: expr) => ( - impl AsRef<[N; $dim]> for $t { + ($t: ident, $dimension: expr) => ( + impl AsRef<[N; $dimension]> for $t { #[inline] - fn as_ref(&self) -> &[N; $dim] { + fn as_ref(&self) -> &[N; $dimension] { unsafe { mem::transmute(self) } } } - impl AsMut<[N; $dim]> for $t { + impl AsMut<[N; $dimension]> for $t { #[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 { + impl<'a, N> From<&'a [N; $dimension]> for &'a $t { #[inline] - fn from(arr: &'a [N; $dim]) -> &'a $t { + fn from(arr: &'a [N; $dimension]) -> &'a $t { unsafe { mem::transmute(arr) } } } - impl<'a, N> From<&'a mut [N; $dim]> for &'a mut $t { + impl<'a, N> From<&'a mut [N; $dimension]> for &'a mut $t { #[inline] - fn from(arr: &'a mut [N; $dim]) -> &'a mut $t { + fn from(arr: &'a mut [N; $dimension]) -> &'a mut $t { 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 $t { /// 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 POrd for $t { + impl PartialOrder for $t { #[inline] fn inf(&self, other: &$t) -> $t { $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) -> POrdering { + #[allow(unused_mut)] // otherwise there will be a warning for is_eq or Vector1. + fn partial_cmp(&self, other: &$t) -> 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 Shape for $t { #[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, &mut [N; $dim]>(self).swap(i1, i2) + mem::transmute::<&mut $t, &mut [N; $dimension]>(self).swap(i1, i2) } } #[inline] unsafe fn unsafe_at(&self, i: usize) -> N { - (*mem::transmute::<&$t, &[N; $dim]>(self).get_unchecked(i)) + (*mem::transmute::<&$t, &[N; $dimension]>(self).get_unchecked(i)) } #[inline] unsafe fn unsafe_set(&mut self, i: usize, val: N) { - (*mem::transmute::<&mut $t, &mut [N; $dim]>(self).get_unchecked_mut(i)) = val + (*mem::transmute::<&mut $t, &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 Iterable for $t { #[inline] fn iter<'l>(&'l self) -> Iter<'l, N> { unsafe { - mem::transmute::<&'l $t, &'l [N; $dim]>(self).iter() + mem::transmute::<&'l $t, &'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 IterableMut for $t { #[inline] fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> { unsafe { - mem::transmute::<&'l mut $t, &'l mut [N; $dim]>(self).iter_mut() + mem::transmute::<&'l mut $t, &'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 Dim for $t { + ($t: ident, $dimension: expr) => ( + impl Dimension for $t { #[inline] - fn dim(_: Option<$t>) -> usize { - $dim + fn dimension(_: Option<$t>) -> 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>) + Dimension::dimension(None::<$t>) } } ) ); macro_rules! basis_impl( - ($t: ident, $dim: expr) => ( + ($t: ident, $dimension: expr) => ( impl> Basis for $t { #[inline] fn canonical_basis) -> 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> = Vec::new(); - for i in 0 .. $dim { + for i in 0 .. $dimension { let mut basis_element : $t = ::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> { - if i < $dim { + if i < $dimension { let mut basis_element : $t = ::zero(); unsafe { @@ -621,7 +621,7 @@ macro_rules! translation_impl( } #[inline] - fn inv_translation(&self) -> $t { + fn inverse_translation(&self) -> $t { -*self } @@ -657,7 +657,7 @@ macro_rules! norm_impl( ($t: ident, $($compN: ident),+) => ( impl Norm for $t { #[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) -> $t { + fn inverse_translate(&self, other: &$t) -> $t { *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) -> $t { - self.inv_translate(other) + fn inverse_transform(&self, other: &$t) -> $t { + self.inverse_translate(other) } } ) ); -macro_rules! vec_as_pnt_impl( +macro_rules! vec_as_point_impl( ($tv: ident, $t: ident, $($compN: ident),+) => ( impl $tv { /// Converts this vector to a point. #[inline] - pub fn to_pnt(self) -> $t { + pub fn to_point(self) -> $t { $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 { + pub fn as_point(&self) -> &$t { unsafe { mem::transmute(self) } @@ -875,11 +875,11 @@ macro_rules! vec_as_pnt_impl( macro_rules! num_float_vec_impl( ($t: ident) => ( - impl NumVec for $t + impl NumVector for $t where N: BaseNum { } - impl FloatVec for $t + impl FloatVector for $t where N: BaseFloat + ApproxEq { } ) diff --git a/src/structs/vecn.rs b/src/structs/vectorn.rs similarity index 55% rename from src/structs/vecn.rs rename to src/structs/vectorn.rs index bb896d22..7b7e073b 100644 --- a/src/structs/vecn.rs +++ b/src/structs/vectorn.rs @@ -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> { +pub struct VectorN> { /// The underlying data of the vector. pub at: GenericArray } -unsafe impl> Send for VecN { +unsafe impl> Send for VectorN { } -impl> Clone for VecN { - fn clone(&self) -> VecN { - VecN::new(self.at.clone()) +impl> Clone for VectorN { + fn clone(&self) -> VectorN { + VectorN::new(self.at.clone()) } } -impl> Copy for VecN +impl> Copy for VectorN where D::ArrayType: Copy { } -impl> VecN { +impl> VectorN { /// Creates a new vector from a given arbirtarily-sized array. #[inline] - pub fn new(components: GenericArray) -> VecN { - VecN { + pub fn new(components: GenericArray) -> VectorN { + VectorN { at: components } } @@ -47,31 +47,31 @@ impl> VecN { } } -impl> Dim for VecN { - fn dim(_unused: Option) -> usize { +impl> Dimension for VectorN { + fn dimension(_unused: Option) -> usize { D::to_usize() } } -impl> FromIterator for VecN { +impl> FromIterator for VectorN { #[inline] - fn from_iter>(param: I) -> VecN { - let mut res: VecN = unsafe { mem::uninitialized() }; + fn from_iter>(param: I) -> VectorN { + let mut res: VectorN = 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> Rand for VecN { +impl> Rand for VectorN { #[inline] - fn rand(rng: &mut R) -> VecN { - let mut res: VecN = unsafe { mem::uninitialized() }; + fn rand(rng: &mut R) -> VectorN { + let mut res: VectorN = unsafe { mem::uninitialized() }; for e in res.iter_mut() { *e = Rand::rand(rng) @@ -81,10 +81,10 @@ impl> Rand for VecN { } } -impl> One for VecN { +impl> One for VectorN { #[inline] - fn one() -> VecN { - let mut res: VecN = unsafe { mem::uninitialized() }; + fn one() -> VectorN { + let mut res: VectorN = unsafe { mem::uninitialized() }; for e in res.iter_mut() { *e = ::one() @@ -94,10 +94,10 @@ impl> One for VecN { } } -impl> Zero for VecN { +impl> Zero for VectorN { #[inline] - fn zero() -> VecN { - let mut res: VecN = unsafe { mem::uninitialized() }; + fn zero() -> VectorN { + let mut res: VectorN = unsafe { mem::uninitialized() }; for e in res.iter_mut() { *e = ::zero() @@ -113,11 +113,11 @@ impl> Zero for VecN { } #[cfg(feature="arbitrary")] -impl> Arbitrary for VecN { +impl> Arbitrary for VectorN { #[inline] - fn arbitrary(g: &mut G) -> VecN { + fn arbitrary(g: &mut G) -> VectorN { (0 .. D::to_usize()).map(|_| Arbitrary::arbitrary(g)).collect() } } -vecn_dvec_common_impl!(VecN, D); +vecn_dvec_common_impl!(VectorN, D); diff --git a/src/structs/vecn_macros.rs b/src/structs/vectorn_macros.rs similarity index 99% rename from src/structs/vecn_macros.rs rename to src/structs/vectorn_macros.rs index bdc80f3e..ce202bb3 100644 --- a/src/structs/vecn_macros.rs +++ b/src/structs/vectorn_macros.rs @@ -497,7 +497,7 @@ macro_rules! vecn_dvec_common_impl( */ impl)*> Norm for $vecn { #[inline] - fn sqnorm(&self) -> N { + fn norm_squared(&self) -> N { Dot::dot(self, self) } diff --git a/src/traits/geometry.rs b/src/traits/geometry.rs index e4b996a7..8c41ae33 100644 --- a/src/traits/geometry.rs +++ b/src/traits/geometry.rs @@ -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 { 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 { 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 { 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 { 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 + Copy, AV, M: Rotation + Translation> Rotatio /// be implemented by quaternions to convert them to a rotation matrix. pub trait RotationMatrix, AV> : Rotation { /// The output rotation matrix type. - type Output: SquareMat + Rotation; + type Output: SquareMatrix + Rotation; /// 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 { 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 { 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 { /// 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; } diff --git a/src/traits/mod.rs b/src/traits/mod.rs index 1594064d..ea31e696 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -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; diff --git a/src/traits/operations.rs b/src/traits/operations.rs index 38f17b0b..10ae7947 100644 --- a/src/traits/operations.rs +++ b/src/traits/operations.rs @@ -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 { 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 { } /// 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; + fn inverse(&self) -> Option; /// 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 { +pub trait Determinant { /// 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 { +pub trait Covariance { /// 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 { } /// Trait for computing the eigenvector and eigenvalues of a square matrix usin the QR algorithm. -pub trait EigenQR>: SquareMat { +pub trait EigenQR>: SquareMatrix { /// Computes the eigenvectors and eigenvalues of this matrix. fn eigen_qr(&self, eps: &N, niter: usize) -> (Self, V); } diff --git a/src/traits/structure.rs b/src/traits/structure.rs index 479a1a92..a88d8c2b 100644 --- a/src/traits/structure.rs +++ b/src/traits/structure.rs @@ -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 { /// Trait of matrices. /// /// A matrix has rows and columns and are able to multiply them. -pub trait Mat>: Sized + - Row + Col + Mul + +pub trait Matrix>: Sized + + Row + Column + Mul + Index<(usize, usize), Output = N> { } -impl Mat for M - where M: Row + Col + Mul + Index<(usize, usize), Output = N>, +impl Matrix for M + where M: Row + Column + Mul + Index<(usize, usize), Output = N>, C: Mul, { } /// Trait implemented by square matrices. -pub trait SquareMat>: Mat + +pub trait SquareMatrix>: Matrix + Mul + - Eye + Transpose + Diag + Inv + Dim + One { + Eye + Transpose + Diagonal + Inverse + Dimension + One { } -impl SquareMat for M - where M: Mat + Mul + Eye + Transpose + Diag + Inv + Dim + One, +impl SquareMatrix for M + where M: Matrix + Mul + Eye + Transpose + Diagonal + Inverse + Dimension + One, V: Mul { } /// 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 { } /// Trait to access columns of a matrix or vector. -pub trait Col { +pub trait Column { /// 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 { } /// Trait to access part of a column of a matrix -pub trait ColSlice { +pub trait ColumnSlice { /// 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 { } /// 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) -> usize; + fn dimension(_unused: Option) -> usize; } /// Trait to get the diagonal of square matrices. -pub trait Diag { +pub trait Diagonal { /// Creates a new matrix with the given diagonal. - fn from_diag(diag: &V) -> Self; + fn from_diag(diagonal: &V) -> Self; /// The diagonal of this matrix. - fn diag(&self) -> V; + fn diagonal(&self) -> V; } /// Trait to set the diagonal of square matrices. -pub trait DiagMut: Diag { +pub trait DiagMut: Diagonal { /// 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 { } /* - * Vec related traits. + * Vector related traits. */ /// Trait grouping most common operations on vectors. -pub trait NumVec: Add + Sub + +pub trait NumVector: Add + Sub + Mul + Div + Add + Sub + @@ -238,67 +238,67 @@ pub trait NumVec: Add + Sub + AddAssign + SubAssign + MulAssign + DivAssign + - Dim + Index + + Dimension + Index + Zero + PartialEq + Dot + Axpy { } /// Trait of vector with components implementing the `BaseFloat` trait. -pub trait FloatVec: NumVec + Norm + Neg + Basis { +pub trait FloatVector: NumVector + Norm + Neg + 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: +pub trait NumPoint: Copy + - PntAsVec + - Dim + - Orig + + PointAsVector + + Dimension + + Origin + PartialEq + Axpy + - Sub::Vec> + + Sub::Vector> + Mul + Div + - Add<::Vec, Output = Self> + + Add<::Vector, Output = Self> + MulAssign + DivAssign + - AddAssign<::Vec> + + AddAssign<::Vector> + Index { // FIXME: + Sub } /// Trait of points with components implementing the `BaseFloat` trait. -pub trait FloatPnt: NumPnt + Sized -where ::Vec: Norm { +pub trait FloatPoint: NumPoint + Sized + where ::Vector: Norm { /// 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() } } diff --git a/tests/arbitrary.rs b/tests/arbitrary.rs index 34886f42..f54af223 100644 --- a/tests/arbitrary.rs +++ b/tests/arbitrary.rs @@ -18,47 +18,47 @@ macro_rules! trivial_arb_test( ) ); -trivial_arb_test!(Vec1, arb_vec1); -trivial_arb_test!(Vec2, arb_vec2); -trivial_arb_test!(Vec3, arb_vec3); -trivial_arb_test!(Vec4, arb_vec4); -trivial_arb_test!(Vec5, arb_vec5); -trivial_arb_test!(Vec6, arb_vec6); +trivial_arb_test!(Vector1, arb_vec1); +trivial_arb_test!(Vector2, arb_vec2); +trivial_arb_test!(Vector3, arb_vec3); +trivial_arb_test!(Vector4, arb_vec4); +trivial_arb_test!(Vector5, arb_vec5); +trivial_arb_test!(Vector6, arb_vec6); -trivial_arb_test!(Pnt1, arb_pnt1); -trivial_arb_test!(Pnt2, arb_pnt2); -trivial_arb_test!(Pnt3, arb_pnt3); -trivial_arb_test!(Pnt4, arb_pnt4); -trivial_arb_test!(Pnt5, arb_pnt5); -trivial_arb_test!(Pnt6, arb_pnt6); +trivial_arb_test!(Point1, arb_point1); +trivial_arb_test!(Point2, arb_point2); +trivial_arb_test!(Point3, arb_point3); +trivial_arb_test!(Point4, arb_point4); +trivial_arb_test!(Point5, arb_point5); +trivial_arb_test!(Point6, arb_point6); -trivial_arb_test!(Mat1, arb_mat1); -trivial_arb_test!(Mat2, arb_mat2); -trivial_arb_test!(Mat3, arb_mat3); -trivial_arb_test!(Mat4, arb_mat4); -trivial_arb_test!(Mat5, arb_mat5); -trivial_arb_test!(Mat6, arb_mat6); +trivial_arb_test!(Matrix1, arb_mat1); +trivial_arb_test!(Matrix2, arb_mat2); +trivial_arb_test!(Matrix3, arb_mat3); +trivial_arb_test!(Matrix4, arb_mat4); +trivial_arb_test!(Matrix5, arb_mat5); +trivial_arb_test!(Matrix6, arb_mat6); -trivial_arb_test!(DVec1, arb_dvec1); -trivial_arb_test!(DVec2, arb_dvec2); -trivial_arb_test!(DVec3, arb_dvec3); -trivial_arb_test!(DVec4, arb_dvec4); -trivial_arb_test!(DVec5, arb_dvec5); -trivial_arb_test!(DVec6, arb_dvec6); +trivial_arb_test!(DVector1, arb_dvec1); +trivial_arb_test!(DVector2, arb_dvec2); +trivial_arb_test!(DVector3, arb_dvec3); +trivial_arb_test!(DVector4, arb_dvec4); +trivial_arb_test!(DVector5, arb_dvec5); +trivial_arb_test!(DVector6, arb_dvec6); -trivial_arb_test!(DMat, arb_dmat); -trivial_arb_test!(DVec, arb_dvec); +trivial_arb_test!(DMatrix, arb_dmatrix); +trivial_arb_test!(DVector, arb_dvector); -trivial_arb_test!(Quat, arb_quat); -trivial_arb_test!(UnitQuat, arb_unit_quat); +trivial_arb_test!(Quaternion, arb_quaternion); +trivial_arb_test!(UnitQuaternion, arb_unit_quaternion); -trivial_arb_test!(Iso2, arb_iso2); -trivial_arb_test!(Iso3, arb_iso3); +trivial_arb_test!(Isometry2, arb_iso2); +trivial_arb_test!(Isometry3, arb_iso3); -trivial_arb_test!(Rot2, arb_rot2); -trivial_arb_test!(Rot3, arb_rot3); +trivial_arb_test!(Rotation2, arb_rot2); +trivial_arb_test!(Rotation3, arb_rot3); -trivial_arb_test!(Ortho3, arb_ortho3); -trivial_arb_test!(OrthoMat3, arb_ortho_mat3); -trivial_arb_test!(Persp3, arb_persp3); -trivial_arb_test!(PerspMat3, arb_persp_mat3); +trivial_arb_test!(Orthographic3, arb_ortho3); +trivial_arb_test!(OrthographicMatrix3, arb_ortho_mat3); +trivial_arb_test!(Perspective3, arb_persp3); +trivial_arb_test!(PerspectiveMatrix3, arb_perspective_mat3); diff --git a/tests/assert.rs b/tests/assert.rs index a0b3a8c1..bb538cb3 100644 --- a/tests/assert.rs +++ b/tests/assert.rs @@ -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); } diff --git a/tests/mat.rs b/tests/mat.rs index fce64edc..c1187c17 100644 --- a/tests/mat.rs +++ b/tests/mat.rs @@ -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); + test_transpose_mat_impl!(Matrix1); } #[test] fn test_transpose_mat2() { - test_transpose_mat_impl!(Mat2); + test_transpose_mat_impl!(Matrix2); } #[test] fn test_transpose_mat3() { - test_transpose_mat_impl!(Mat3); + test_transpose_mat_impl!(Matrix3); } #[test] fn test_transpose_mat4() { - test_transpose_mat_impl!(Mat4); + test_transpose_mat_impl!(Matrix4); } #[test] fn test_transpose_mat5() { - test_transpose_mat_impl!(Mat5); + test_transpose_mat_impl!(Matrix5); } #[test] fn test_transpose_mat6() { - test_transpose_mat_impl!(Mat6); + test_transpose_mat_impl!(Matrix6); } #[test] -fn test_inv_mat1() { - test_inv_mat_impl!(Mat1); +fn test_inverse_mat1() { + test_inverse_mat_impl!(Matrix1); } #[test] -fn test_inv_mat2() { - test_inv_mat_impl!(Mat2); +fn test_inverse_mat2() { + test_inverse_mat_impl!(Matrix2); } #[test] -fn test_inv_mat3() { - test_inv_mat_impl!(Mat3); +fn test_inverse_mat3() { + test_inverse_mat_impl!(Matrix3); } #[test] -fn test_inv_mat4() { - test_inv_mat_impl!(Mat4); +fn test_inverse_mat4() { + test_inverse_mat_impl!(Matrix4); } #[test] -fn test_inv_mat5() { - test_inv_mat_impl!(Mat5); +fn test_inverse_mat5() { + test_inverse_mat_impl!(Matrix5); } #[test] -fn test_inv_mat6() { - test_inv_mat_impl!(Mat6); +fn test_inverse_mat6() { + test_inverse_mat_impl!(Matrix6); } #[test] -fn test_inv_rot2() { - test_inv_mat_impl!(Rot2); +fn test_inverse_rot2() { + test_inverse_mat_impl!(Rotation2); } #[test] -fn test_inv_rot3() { - test_inv_mat_impl!(Rot3); +fn test_inverse_rot3() { + test_inverse_mat_impl!(Rotation3); } #[test] -fn test_inv_iso2() { - test_inv_mat_impl!(Iso2); +fn test_inverse_iso2() { + test_inverse_mat_impl!(Isometry2); } #[test] -fn test_inv_iso3() { - test_inv_mat_impl!(Iso3); +fn test_inverse_iso3() { + test_inverse_mat_impl!(Isometry3); } #[test] -fn test_inv_sim2() { - test_inv_mat_impl!(Sim2); +fn test_inverse_sim2() { + test_inverse_mat_impl!(Similarity2); } #[test] -fn test_inv_sim3() { - test_inv_mat_impl!(Sim3); +fn test_inverse_sim3() { + test_inverse_mat_impl!(Similarity3); } #[test] fn test_index_mat2() { - let mat: Mat2 = random(); + let matrix: Matrix2 = 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 = DMat::new_random(rows, cols); - let (q, r) = na::qr(&randmat); + let randmatrix: DMatrix = 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); + test_qr_impl!(Matrix1); } #[test] fn test_qr_mat2() { - test_qr_impl!(Mat2); + test_qr_impl!(Matrix2); } #[test] fn test_qr_mat3() { - test_qr_impl!(Mat3); + test_qr_impl!(Matrix3); } #[test] fn test_qr_mat4() { - test_qr_impl!(Mat4); + test_qr_impl!(Matrix4); } #[test] fn test_qr_mat5() { - test_qr_impl!(Mat5); + test_qr_impl!(Matrix5); } #[test] fn test_qr_mat6() { - test_qr_impl!(Mat6); + test_qr_impl!(Matrix6); } #[test] fn test_eigen_qr_mat1() { - test_eigen_qr_impl!(Mat1); + test_eigen_qr_impl!(Matrix1); } #[test] fn test_eigen_qr_mat2() { - test_eigen_qr_impl!(Mat2); + test_eigen_qr_impl!(Matrix2); } #[test] fn test_eigen_qr_mat3() { - test_eigen_qr_impl!(Mat3); + test_eigen_qr_impl!(Matrix3); } #[test] fn test_eigen_qr_mat4() { - test_eigen_qr_impl!(Mat4); + test_eigen_qr_impl!(Matrix4); } #[test] fn test_eigen_qr_mat5() { - test_eigen_qr_impl!(Mat5); + test_eigen_qr_impl!(Matrix5); } #[test] fn test_eigen_qr_mat6() { - test_eigen_qr_impl!(Mat6); + test_eigen_qr_impl!(Matrix6); } #[test] fn test_from_fn() { - let actual: DMat = DMat::from_fn(3, 4, |i, j| 10 * i + j); - let expected: DMat = DMat::from_row_vec(3, 4, + let actual: DMatrix = DMatrix::from_fn(3, 4, |i, j| 10 * i + j); + let expected: DMatrix = 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 = Mat3::::new(1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 1.0, 2.0, 3.0); - let g : Mat3 = Mat3::::new(1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0); + let a : Matrix3 = Matrix3::::new(1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 1.0, 2.0, 3.0); + let g : Matrix3 = Matrix3::::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 = Mat3::::new(1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 1.0, 1.0, 1.0); + let a : Matrix3 = Matrix3::::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 = Mat2::::new(1.0, 1.0, -1.0, 1.0); + let a : Matrix2 = Matrix2::::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); + test_cholesky_impl!(Matrix1); } #[test] fn test_cholesky_mat2() { - test_cholesky_impl!(Mat2); + test_cholesky_impl!(Matrix2); } #[test] fn test_cholesky_mat3() { - test_cholesky_impl!(Mat3); + test_cholesky_impl!(Matrix3); } #[test] fn test_cholesky_mat4() { - test_cholesky_impl!(Mat4); + test_cholesky_impl!(Matrix4); } #[test] fn test_cholesky_mat5() { - test_cholesky_impl!(Mat5); + test_cholesky_impl!(Matrix5); } #[test] fn test_cholesky_mat6() { - test_cholesky_impl!(Mat6); + test_cholesky_impl!(Matrix6); } #[test] fn test_hessenberg_mat1() { - test_hessenberg_impl!(Mat1); + test_hessenberg_impl!(Matrix1); } #[test] fn test_hessenberg_mat2() { - test_hessenberg_impl!(Mat2); + test_hessenberg_impl!(Matrix2); } #[test] fn test_hessenberg_mat3() { - test_hessenberg_impl!(Mat3); + test_hessenberg_impl!(Matrix3); } #[test] fn test_hessenberg_mat4() { - test_hessenberg_impl!(Mat4); + test_hessenberg_impl!(Matrix4); } #[test] fn test_hessenberg_mat5() { - test_hessenberg_impl!(Mat5); + test_hessenberg_impl!(Matrix5); } #[test] fn test_hessenberg_mat6() { - test_hessenberg_impl!(Mat6); + test_hessenberg_impl!(Matrix6); } #[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)) } diff --git a/tests/op_assign.rs b/tests/op_assign.rs index e4d62657..970d682c 100644 --- a/tests/op_assign.rs +++ b/tests/op_assign.rs @@ -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, mul, mul_assign); -test_op_vs_op_assign!(test_mat3_f32_mul_assign, Mat3, f32, mul, mul_assign); -test_op_vs_op_assign!(test_quat_f32_mul_assign, Quat, f32, mul, mul_assign); +test_op_vs_op_assign!(test_vec3_f32_mul_assign, Vector3, f32, mul, mul_assign); +test_op_vs_op_assign!(test_mat3_f32_mul_assign, Matrix3, f32, mul, mul_assign); +test_op_vs_op_assign!(test_quaternion_f32_mul_assign, Quaternion, f32, mul, mul_assign); -test_op_vs_op_assign!(test_vec3_vec3_mul_assign, Vec3, Vec3, mul, mul_assign); -test_op_vs_op_assign!(test_quat_quat_mul_assign, Quat, Quat, mul, mul_assign); -test_op_vs_op_assign!(test_unit_quat_unit_quat_mul_assign, UnitQuat, UnitQuat, mul, mul_assign); +test_op_vs_op_assign!(test_vec3_vec3_mul_assign, Vector3, Vector3, mul, mul_assign); +test_op_vs_op_assign!(test_quaternion_quaternion_mul_assign, Quaternion, Quaternion, mul, mul_assign); +test_op_vs_op_assign!(test_unit_quaternion_unit_quaternion_mul_assign, UnitQuaternion, UnitQuaternion, mul, mul_assign); -test_op_vs_op_assign!(test_vec3_unit_quat_mul_assign, Vec3, UnitQuat, mul, mul_assign); -test_op_vs_op_assign!(test_pnt3_unit_quat_mul_assign, Pnt3, UnitQuat, mul, mul_assign); +test_op_vs_op_assign!(test_vec3_unit_quaternion_mul_assign, Vector3, UnitQuaternion, mul, mul_assign); +test_op_vs_op_assign!(test_point3_unit_quaternion_mul_assign, Point3, UnitQuaternion, mul, mul_assign); -test_op_vs_op_assign!(test_mat3_mat3_mul_assign, Mat3, Mat3, mul, mul_assign); -test_op_vs_op_assign!(test_vec3_mat3_mul_assign, Vec3, Mat3, mul, mul_assign); -test_op_vs_op_assign!(test_pnt3_mat3_mul_assign, Pnt3, Mat3, mul, mul_assign); +test_op_vs_op_assign!(test_mat3_mat3_mul_assign, Matrix3, Matrix3, mul, mul_assign); +test_op_vs_op_assign!(test_vec3_mat3_mul_assign, Vector3, Matrix3, mul, mul_assign); +test_op_vs_op_assign!(test_point3_mat3_mul_assign, Point3, Matrix3, mul, mul_assign); -test_op_vs_op_assign!(test_rot3_rot3_mul_assign, Rot3, Rot3, mul, mul_assign); -test_op_vs_op_assign!(test_vec3_rot3_mul_assign, Vec3, Rot3, mul, mul_assign); -test_op_vs_op_assign!(test_pnt3_rot3_mul_assign, Pnt3, Rot3, mul, mul_assign); +test_op_vs_op_assign!(test_rot3_rot3_mul_assign, Rotation3, Rotation3, mul, mul_assign); +test_op_vs_op_assign!(test_vec3_rot3_mul_assign, Vector3, Rotation3, mul, mul_assign); +test_op_vs_op_assign!(test_point3_rot3_mul_assign, Point3, Rotation3, mul, mul_assign); -test_op_vs_op_assign!(test_iso3_iso3_mul_assign, Iso3, Iso3, mul, mul_assign); -test_op_vs_op_assign!(test_iso3_rot3_mul_assign, Iso3, Rot3, mul, mul_assign); +test_op_vs_op_assign!(test_iso3_iso3_mul_assign, Isometry3, Isometry3, mul, mul_assign); +test_op_vs_op_assign!(test_iso3_rot3_mul_assign, Isometry3, Rotation3, mul, mul_assign); -test_op_vs_op_assign!(test_sim3_sim3_mul_assign, Sim3, Sim3, mul, mul_assign); -test_op_vs_op_assign!(test_sim3_iso3_mul_assign, Sim3, Iso3, mul, mul_assign); -test_op_vs_op_assign!(test_sim3_rot3_mul_assign, Sim3, Rot3, mul, mul_assign); +test_op_vs_op_assign!(test_sim3_sim3_mul_assign, Similarity3, Similarity3, mul, mul_assign); +test_op_vs_op_assign!(test_sim3_iso3_mul_assign, Similarity3, Isometry3, mul, mul_assign); +test_op_vs_op_assign!(test_sim3_rot3_mul_assign, Similarity3, Rotation3, mul, mul_assign); // Division. -test_op_vs_op_assign!(test_vec3_vec3_div_assign, Vec3, Vec3, div, div_assign); -test_op_vs_op_assign!(test_quat_quat_div_assign, Quat, Quat, div, div_assign); -test_op_vs_op_assign!(test_unit_quat_unit_quat_div_assign, UnitQuat, UnitQuat, div, div_assign); +test_op_vs_op_assign!(test_vec3_vec3_div_assign, Vector3, Vector3, div, div_assign); +test_op_vs_op_assign!(test_quaternion_quaternion_div_assign, Quaternion, Quaternion, div, div_assign); +test_op_vs_op_assign!(test_unit_quaternion_unit_quaternion_div_assign, UnitQuaternion, UnitQuaternion, div, div_assign); -test_op_vs_op_assign!(test_vec3_f32_div_assign, Vec3, f32, div, div_assign); -test_op_vs_op_assign!(test_mat3_f32_div_assign, Mat3, f32, div, div_assign); +test_op_vs_op_assign!(test_vec3_f32_div_assign, Vector3, f32, div, div_assign); +test_op_vs_op_assign!(test_mat3_f32_div_assign, Matrix3, f32, div, div_assign); // Addition. -test_op_vs_op_assign!(test_vec3_vec3_add_assign, Vec3, Vec3, add, add_assign); -test_op_vs_op_assign!(test_mat3_mat3_add_assign, Mat3, Mat3, add, add_assign); -test_op_vs_op_assign!(test_quat_quat_add_assign, Quat, Quat, add, add_assign); +test_op_vs_op_assign!(test_vec3_vec3_add_assign, Vector3, Vector3, add, add_assign); +test_op_vs_op_assign!(test_mat3_mat3_add_assign, Matrix3, Matrix3, add, add_assign); +test_op_vs_op_assign!(test_quaternion_quaternion_add_assign, Quaternion, Quaternion, add, add_assign); -test_op_vs_op_assign!(test_vec3_f32_add_assign, Vec3, f32, add, add_assign); -test_op_vs_op_assign!(test_mat3_f32_add_assign, Mat3, f32, add, add_assign); +test_op_vs_op_assign!(test_vec3_f32_add_assign, Vector3, f32, add, add_assign); +test_op_vs_op_assign!(test_mat3_f32_add_assign, Matrix3, f32, add, add_assign); // Subtraction. -test_op_vs_op_assign!(test_vec3_vec3_sub_assign, Vec3, Vec3, sub, sub_assign); -test_op_vs_op_assign!(test_mat3_mat3_sub_assign, Mat3, Mat3, sub, sub_assign); -test_op_vs_op_assign!(test_quat_quat_sub_assign, Quat, Quat, sub, sub_assign); +test_op_vs_op_assign!(test_vec3_vec3_sub_assign, Vector3, Vector3, sub, sub_assign); +test_op_vs_op_assign!(test_mat3_mat3_sub_assign, Matrix3, Matrix3, sub, sub_assign); +test_op_vs_op_assign!(test_quaternion_quaternion_sub_assign, Quaternion, Quaternion, sub, sub_assign); -test_op_vs_op_assign!(test_vec3_f32_sub_assign, Vec3, f32, sub, sub_assign); -test_op_vs_op_assign!(test_mat3_f32_sub_assign, Mat3, f32, sub, sub_assign); +test_op_vs_op_assign!(test_vec3_f32_sub_assign, Vector3, f32, sub, sub_assign); +test_op_vs_op_assign!(test_mat3_f32_sub_assign, Matrix3, f32, sub, sub_assign); diff --git a/tests/quat.rs b/tests/quat.rs index 84864721..251fabfc 100644 --- a/tests/quat.rs +++ b/tests/quat.rs @@ -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 = random(); + let axis_angle: Vector3 = 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 = random(); - let vec: Vec3 = random(); - let pnt: Pnt3 = random(); + let axis_angle: Vector3 = random(); + let vector: Vector3 = random(); + let point: Point3 = 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 = random(); - let axis_angle2: Vec3 = random(); + let axis_angle1: Vector3 = random(); + let axis_angle2: Vector3 = 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 = random(); + let axis_angle: Vector3 = 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 = random(); + let angles: Vector3 = 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 = random(); - let q2: UnitQuat = random(); +fn test_quaternion_rotation_between() { + let q1: UnitQuaternion = random(); + let q2: UnitQuaternion = 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 = random(); - let q2: UnitQuat = random(); +fn test_quaternion_angle_between() { + let q1: UnitQuaternion = random(); + let q2: UnitQuaternion = random(); let delta = na::rotation_between(&q1, &q2); let delta_angle = na::angle_between(&q1, &q2); diff --git a/tests/transforms.rs b/tests/transforms.rs index 8db23131..20c9391e 100644 --- a/tests/transforms.rs +++ b/tests/transforms.rs @@ -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 = na::one(); - let ang = Vec1::new(na::abs(&random::()) % ::pi()); + let randmatrix: na::Rotation2 = na::one(); + let ang = Vector1::new(na::abs(&random::()) % ::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 = na::one(); - let dir: Vec3 = random(); + let randmatrix: Rotation3 = na::one(); + let dir: Vector3 = random(); let ang = na::normalize(&dir) * (na::abs(&random::()) % ::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 = random(); - let r2: Rot3 = random(); + let r1: Rotation3 = random(); + let r2: Rotation3 = 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 = random(); - let r2: Rot3 = random(); + let r1: Rotation3 = random(); + let r2: Rotation3 = 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 = random(); - let r2: Rot2 = random(); + let r1: Rotation2 = random(); + let r2: Rotation2 = 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 = random(); - let r2: Rot2 = random(); + let r1: Rotation2 = random(); + let r2: Rotation2 = 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::>(); - let target = random::>(); - let up = random::>(); - let viewmat = Iso3::look_at_rh(&eye, &target, &up); + let eye = random::>(); + let target = random::>(); + let up = random::>(); + let viewmatrix = Isometry3::look_at_rh(&eye, &target, &up); - let origin: Pnt3 = na::orig(); - assert_eq!(&(viewmat * eye), &origin); - assert!(na::approx_eq(&na::normalize(&(viewmat * (target - eye))), &-Vec3::z())); + let origin: Point3 = 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::>(); - let up = random::>(); - let viewmat = Rot3::look_at_rh(&dir, &up); + let dir = random::>(); + let up = random::>(); + 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::>(); - let target = random::>(); - let up = random::>(); - let observer = Iso3::new_observer_frame(&eye, &target, &up); + let eye = random::>(); + let target = random::>(); + let up = random::>(); + let observer = Isometry3::new_observer_frame(&eye, &target, &up); - assert_eq!(&(observer * na::orig::>()), &eye); - assert!(na::approx_eq(&(observer * Vec3::z()), &na::normalize(&(target - eye)))); + assert_eq!(&(observer * na::origin::>()), &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::>(); - let up = random::>(); - let observer = Rot3::new_observer_frame(&dir, &up); + let dir = random::>(); + let up = random::>(); + 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, Pnt2); -test_transform_inv_transform_impl!(test_transform_inv_transform_rot3, Rot3, Pnt3); -test_transform_inv_transform_impl!(test_transform_inv_transform_iso2, Iso2, Pnt2); -test_transform_inv_transform_impl!(test_transform_inv_transform_iso3, Iso3, Pnt3); -test_transform_inv_transform_impl!(test_transform_inv_transform_sim2, Sim2, Pnt2); -test_transform_inv_transform_impl!(test_transform_inv_transform_sim3, Sim3, Pnt3); +test_transform_inverse_transform_impl!(test_transform_inverse_transform_rot2, Rotation2, Point2); +test_transform_inverse_transform_impl!(test_transform_inverse_transform_rot3, Rotation3, Point3); +test_transform_inverse_transform_impl!(test_transform_inverse_transform_iso2, Isometry2, Point2); +test_transform_inverse_transform_impl!(test_transform_inverse_transform_iso3, Isometry3, Point3); +test_transform_inverse_transform_impl!(test_transform_inverse_transform_sim2, Similarity2, Point2); +test_transform_inverse_transform_impl!(test_transform_inverse_transform_sim3, Similarity3, Point3); 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, Sim3, Pnt3); -test_transform_mul_assoc!(test_transform_inv_transform_sim3_iso3_pnt3, Sim3, Iso3, Pnt3); -test_transform_mul_assoc!(test_transform_inv_transform_sim3_rot3_pnt3, Sim3, Rot3, Pnt3); -test_transform_mul_assoc!(test_transform_inv_transform_iso3_iso3_pnt3, Iso3, Iso3, Pnt3); -test_transform_mul_assoc!(test_transform_inv_transform_iso3_rot3_pnt3, Iso3, Rot3, Pnt3); -test_transform_mul_assoc!(test_transform_inv_transform_rot3_rot3_pnt3, Rot3, Rot3, Pnt3); -test_transform_mul_assoc!(test_transform_inv_transform_sim3_sim3_vec3, Sim3, Sim3, Vec3); -test_transform_mul_assoc!(test_transform_inv_transform_sim3_iso3_vec3, Sim3, Iso3, Vec3); -test_transform_mul_assoc!(test_transform_inv_transform_sim3_rot3_vec3, Sim3, Rot3, Vec3); -test_transform_mul_assoc!(test_transform_inv_transform_iso3_iso3_vec3, Iso3, Iso3, Vec3); -test_transform_mul_assoc!(test_transform_inv_transform_iso3_rot3_vec3, Iso3, Rot3, Vec3); -test_transform_mul_assoc!(test_transform_inv_transform_rot3_rot3_vec3, Rot3, Rot3, Vec3); +test_transform_mul_assoc!(test_transform_inverse_transform_sim3_sim3_point3, Similarity3, Similarity3, Point3); +test_transform_mul_assoc!(test_transform_inverse_transform_sim3_iso3_point3, Similarity3, Isometry3, Point3); +test_transform_mul_assoc!(test_transform_inverse_transform_sim3_rot3_point3, Similarity3, Rotation3, Point3); +test_transform_mul_assoc!(test_transform_inverse_transform_iso3_iso3_point3, Isometry3, Isometry3, Point3); +test_transform_mul_assoc!(test_transform_inverse_transform_iso3_rot3_point3, Isometry3, Rotation3, Point3); +test_transform_mul_assoc!(test_transform_inverse_transform_rot3_rot3_point3, Rotation3, Rotation3, Point3); +test_transform_mul_assoc!(test_transform_inverse_transform_sim3_sim3_vec3, Similarity3, Similarity3, Vector3); +test_transform_mul_assoc!(test_transform_inverse_transform_sim3_iso3_vec3, Similarity3, Isometry3, Vector3); +test_transform_mul_assoc!(test_transform_inverse_transform_sim3_rot3_vec3, Similarity3, Rotation3, Vector3); +test_transform_mul_assoc!(test_transform_inverse_transform_iso3_iso3_vec3, Isometry3, Isometry3, Vector3); +test_transform_mul_assoc!(test_transform_inverse_transform_iso3_rot3_vec3, Isometry3, Rotation3, Vector3); +test_transform_mul_assoc!(test_transform_inverse_transform_rot3_rot3_vec3, Rotation3, Rotation3, Vector3); -test_transform_mul_assoc!(test_transform_inv_transform_sim2_sim2_pnt2, Sim2, Sim2, Pnt2); -test_transform_mul_assoc!(test_transform_inv_transform_sim2_iso2_pnt2, Sim2, Iso2, Pnt2); -test_transform_mul_assoc!(test_transform_inv_transform_sim2_rot2_pnt2, Sim2, Rot2, Pnt2); -test_transform_mul_assoc!(test_transform_inv_transform_iso2_iso2_pnt2, Iso2, Iso2, Pnt2); -test_transform_mul_assoc!(test_transform_inv_transform_iso2_rot2_pnt2, Iso2, Rot2, Pnt2); -test_transform_mul_assoc!(test_transform_inv_transform_rot2_rot2_pnt2, Rot2, Rot2, Pnt2); -test_transform_mul_assoc!(test_transform_inv_transform_sim2_sim2_vec2, Sim2, Sim2, Vec2); -test_transform_mul_assoc!(test_transform_inv_transform_sim2_iso2_vec2, Sim2, Iso2, Vec2); -test_transform_mul_assoc!(test_transform_inv_transform_sim2_rot2_vec2, Sim2, Rot2, Vec2); -test_transform_mul_assoc!(test_transform_inv_transform_iso2_iso2_vec2, Iso2, Iso2, Vec2); -test_transform_mul_assoc!(test_transform_inv_transform_iso2_rot2_vec2, Iso2, Rot2, Vec2); -test_transform_mul_assoc!(test_transform_inv_transform_rot2_rot2_vec2, Rot2, Rot2, Vec2); +test_transform_mul_assoc!(test_transform_inverse_transform_sim2_sim2_point2, Similarity2, Similarity2, Point2); +test_transform_mul_assoc!(test_transform_inverse_transform_sim2_iso2_point2, Similarity2, Isometry2, Point2); +test_transform_mul_assoc!(test_transform_inverse_transform_sim2_rot2_point2, Similarity2, Rotation2, Point2); +test_transform_mul_assoc!(test_transform_inverse_transform_iso2_iso2_point2, Isometry2, Isometry2, Point2); +test_transform_mul_assoc!(test_transform_inverse_transform_iso2_rot2_point2, Isometry2, Rotation2, Point2); +test_transform_mul_assoc!(test_transform_inverse_transform_rot2_rot2_point2, Rotation2, Rotation2, Point2); +test_transform_mul_assoc!(test_transform_inverse_transform_sim2_sim2_vec2, Similarity2, Similarity2, Vector2); +test_transform_mul_assoc!(test_transform_inverse_transform_sim2_iso2_vec2, Similarity2, Isometry2, Vector2); +test_transform_mul_assoc!(test_transform_inverse_transform_sim2_rot2_vec2, Similarity2, Rotation2, Vector2); +test_transform_mul_assoc!(test_transform_inverse_transform_iso2_iso2_vec2, Isometry2, Isometry2, Vector2); +test_transform_mul_assoc!(test_transform_inverse_transform_iso2_rot2_vec2, Isometry2, Rotation2, Vector2); +test_transform_mul_assoc!(test_transform_inverse_transform_rot2_rot2_vec2, Rotation2, Rotation2, Vector2); diff --git a/tests/vec.rs b/tests/vec.rs index aab6d7d1..dfa69dc6 100644 --- a/tests/vec.rs +++ b/tests/vec.rs @@ -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 = random(); - let v2 : Vec3 = random(); - let v3 : Vec3 = na::cross(&v1, &v2); + let v1 : Vector3 = random(); + let v2 : Vector3 = random(); + let v3 : Vector3 = 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); + test_commut_dot_impl!(Vector1); } #[test] fn test_commut_dot_vec2() { - test_commut_dot_impl!(Vec2); + test_commut_dot_impl!(Vector2); } #[test] fn test_commut_dot_vec3() { - test_commut_dot_impl!(Vec3); + test_commut_dot_impl!(Vector3); } #[test] fn test_commut_dot_vec4() { - test_commut_dot_impl!(Vec4); + test_commut_dot_impl!(Vector4); } #[test] fn test_commut_dot_vec5() { - test_commut_dot_impl!(Vec5); + test_commut_dot_impl!(Vector5); } #[test] fn test_commut_dot_vec6() { - test_commut_dot_impl!(Vec6); + test_commut_dot_impl!(Vector6); } #[test] fn test_basis_vec1() { - test_basis_impl!(Vec1); + test_basis_impl!(Vector1); } #[test] fn test_basis_vec2() { - test_basis_impl!(Vec2); + test_basis_impl!(Vector2); } #[test] fn test_basis_vec3() { - test_basis_impl!(Vec3); + test_basis_impl!(Vector3); } #[test] fn test_basis_vec4() { - test_basis_impl!(Vec4); + test_basis_impl!(Vector4); } #[test] fn test_basis_vec5() { - test_basis_impl!(Vec5); + test_basis_impl!(Vector5); } #[test] fn test_basis_vec6() { - test_basis_impl!(Vec6); + test_basis_impl!(Vector6); } #[test] fn test_subspace_basis_vec1() { - test_subspace_basis_impl!(Vec1); + test_subspace_basis_impl!(Vector1); } #[test] fn test_subspace_basis_vec2() { - test_subspace_basis_impl!(Vec2); + test_subspace_basis_impl!(Vector2); } #[test] fn test_subspace_basis_vec3() { - test_subspace_basis_impl!(Vec3); + test_subspace_basis_impl!(Vector3); } #[test] fn test_subspace_basis_vec4() { - test_subspace_basis_impl!(Vec4); + test_subspace_basis_impl!(Vector4); } #[test] fn test_subspace_basis_vec5() { - test_subspace_basis_impl!(Vec5); + test_subspace_basis_impl!(Vector5); } #[test] fn test_subspace_basis_vec6() { - test_subspace_basis_impl!(Vec6); + test_subspace_basis_impl!(Vector6); } #[test] fn test_scalar_op_vec1() { - test_scalar_op_impl!(Vec1, f64); + test_scalar_op_impl!(Vector1, f64); } #[test] fn test_scalar_op_vec2() { - test_scalar_op_impl!(Vec2, f64); + test_scalar_op_impl!(Vector2, f64); } #[test] fn test_scalar_op_vec3() { - test_scalar_op_impl!(Vec3, f64); + test_scalar_op_impl!(Vector3, f64); } #[test] fn test_scalar_op_vec4() { - test_scalar_op_impl!(Vec4, f64); + test_scalar_op_impl!(Vector4, f64); } #[test] fn test_scalar_op_vec5() { - test_scalar_op_impl!(Vec5, f64); + test_scalar_op_impl!(Vector5, f64); } #[test] fn test_scalar_op_vec6() { - test_scalar_op_impl!(Vec6, f64); + test_scalar_op_impl!(Vector6, f64); } #[test] fn test_iterator_vec1() { - test_iterator_impl!(Vec1, f64); + test_iterator_impl!(Vector1, f64); } #[test] fn test_iterator_vec2() { - test_iterator_impl!(Vec2, f64); + test_iterator_impl!(Vector2, f64); } #[test] fn test_iterator_vec3() { - test_iterator_impl!(Vec3, f64); + test_iterator_impl!(Vector3, f64); } #[test] fn test_iterator_vec4() { - test_iterator_impl!(Vec4, f64); + test_iterator_impl!(Vector4, f64); } #[test] fn test_iterator_vec5() { - test_iterator_impl!(Vec5, f64); + test_iterator_impl!(Vector5, f64); } #[test] fn test_iterator_vec6() { - test_iterator_impl!(Vec6, f64); + test_iterator_impl!(Vector6, 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 = random(); + let v1: VectorN = 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 = random(); + let v1: Vector3 = random(); - let mut v2: Vec3 = random(); + let mut v2: Vector3 = 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 = random(); - let other: Vec3 = random(); + let vector: Vector3 = random(); + let other: Vector3 = 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 = random(); + let v1: Vector2 = random(); - let mut v2: Vec2 = random(); + let mut v2: Vector2 = 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 = random(); + let axis_ang: Vector1 = random(); let ang = na::norm(&axis_ang); - let rot: Rot2 = Rot2::new(axis_ang); - let vec: Vec2 = random(); + let rotation: Rotation2 = Rotation2::new(axis_ang); + let vector: Vector2 = random(); - let delta = na::angle_between(&vec, &(rot * vec)); + let delta = na::angle_between(&vector, &(rotation * vector)); assert!(na::approx_eq(&ang, &delta)) }