Use full names for everything.
Note that `sqdist` becomes `distance_squared` and `sqnorm` becomes `norm_squared`. Fix #176.
This commit is contained in:
parent
353d36639d
commit
e6156727f2
14
CHANGELOG.md
14
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.
|
||||
|
|
38
README.md
38
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.
|
||||
|
|
|
@ -6,14 +6,14 @@ extern crate nalgebra as na;
|
|||
|
||||
use rand::{IsaacRng, Rng};
|
||||
use test::Bencher;
|
||||
use na::{UnitQuat, Rot2, Rot3, Vec1, Vec3};
|
||||
use na::{UnitQuaternion, Rotation2, Rotation3, Vector1, Vector3};
|
||||
|
||||
#[path="common/macros.rs"]
|
||||
mod macros;
|
||||
|
||||
bench_construction!(_bench_quat_from_axisangle, UnitQuat::new, axisangle: Vec3<f32>);
|
||||
bench_construction!(_bench_rot2_from_axisangle, Rot2::new, axisangle: Vec1<f32>);
|
||||
bench_construction!(_bench_rot3_from_axisangle, Rot3::new, axisangle: Vec3<f32>);
|
||||
bench_construction!(_bench_quaternion_from_axisangle, UnitQuaternion::new, axisangle: Vector3<f32>);
|
||||
bench_construction!(_bench_rot2_from_axisangle, Rotation2::new, axisangle: Vector1<f32>);
|
||||
bench_construction!(_bench_rot3_from_axisangle, Rotation3::new, axisangle: Vector3<f32>);
|
||||
|
||||
bench_construction!(_bench_quat_from_euler_angles, UnitQuat::new_with_euler_angles, roll: f32, pitch: f32, yaw: f32);
|
||||
bench_construction!(_bench_rot3_from_euler_angles, Rot3::new_with_euler_angles, roll: f32, pitch: f32, yaw: f32);
|
||||
bench_construction!(_bench_quaternion_from_euler_angles, UnitQuaternion::new_with_euler_angles, roll: f32, pitch: f32, yaw: f32);
|
||||
bench_construction!(_bench_rot3_from_euler_angles, Rotation3::new_with_euler_angles, roll: f32, pitch: f32, yaw: f32);
|
||||
|
|
|
@ -4,14 +4,14 @@ extern crate test;
|
|||
extern crate nalgebra as na;
|
||||
|
||||
use test::Bencher;
|
||||
use na::{DVec, DMat};
|
||||
use na::{DVector, DMatrix};
|
||||
|
||||
macro_rules! bench_mul_dmat(
|
||||
macro_rules! bench_mul_dmatrix(
|
||||
($bh: expr, $nrows: expr, $ncols: expr) => {
|
||||
{
|
||||
$bh.iter(|| {
|
||||
let a: DMat<f64> = DMat::new_random($nrows, $ncols);
|
||||
let mut b: DMat<f64> = DMat::new_random($nrows, $ncols);
|
||||
let a: DMatrix<f64> = DMatrix::new_random($nrows, $ncols);
|
||||
let mut b: DMatrix<f64> = DMatrix::new_random($nrows, $ncols);
|
||||
|
||||
for _ in 0usize .. 1000 {
|
||||
// XXX: the clone here is highly undesirable!
|
||||
|
@ -24,36 +24,36 @@ macro_rules! bench_mul_dmat(
|
|||
|
||||
#[bench]
|
||||
fn bench_mul_dmat2(bh: &mut Bencher) {
|
||||
bench_mul_dmat!(bh, 2, 2);
|
||||
bench_mul_dmatrix!(bh, 2, 2);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_mul_dmat3(bh: &mut Bencher) {
|
||||
bench_mul_dmat!(bh, 3, 3);
|
||||
bench_mul_dmatrix!(bh, 3, 3);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_mul_dmat4(bh: &mut Bencher) {
|
||||
bench_mul_dmat!(bh, 4, 4);
|
||||
bench_mul_dmatrix!(bh, 4, 4);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_mul_dmat5(bh: &mut Bencher) {
|
||||
bench_mul_dmat!(bh, 5, 5);
|
||||
bench_mul_dmatrix!(bh, 5, 5);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_mul_dmat6(bh: &mut Bencher) {
|
||||
bench_mul_dmat!(bh, 6, 6);
|
||||
bench_mul_dmatrix!(bh, 6, 6);
|
||||
}
|
||||
|
||||
macro_rules! bench_mul_dmat_dvec(
|
||||
macro_rules! bench_mul_dmat_dvector(
|
||||
($bh: expr, $nrows: expr, $ncols: expr) => {
|
||||
{
|
||||
|
||||
$bh.iter(|| {
|
||||
let m : DMat<f64> = DMat::new_random($nrows, $ncols);
|
||||
let mut v : DVec<f64> = DVec::new_random($ncols);
|
||||
let m : DMatrix<f64> = DMatrix::new_random($nrows, $ncols);
|
||||
let mut v : DVector<f64> = DVector::new_random($ncols);
|
||||
|
||||
for _ in 0usize .. 1000 {
|
||||
// XXX: the clone here is highly undesirable!
|
||||
|
@ -66,25 +66,25 @@ macro_rules! bench_mul_dmat_dvec(
|
|||
|
||||
#[bench]
|
||||
fn bench_mul_dmat_dvec2(bh: &mut Bencher) {
|
||||
bench_mul_dmat_dvec!(bh, 2, 2);
|
||||
bench_mul_dmat_dvector!(bh, 2, 2);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_mul_dmat_dvec3(bh: &mut Bencher) {
|
||||
bench_mul_dmat_dvec!(bh, 3, 3);
|
||||
bench_mul_dmat_dvector!(bh, 3, 3);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_mul_dmat_dvec4(bh: &mut Bencher) {
|
||||
bench_mul_dmat_dvec!(bh, 4, 4);
|
||||
bench_mul_dmat_dvector!(bh, 4, 4);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_mul_dmat_dvec5(bh: &mut Bencher) {
|
||||
bench_mul_dmat_dvec!(bh, 5, 5);
|
||||
bench_mul_dmat_dvector!(bh, 5, 5);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_mul_dmat_dvec6(bh: &mut Bencher) {
|
||||
bench_mul_dmat_dvec!(bh, 6, 6);
|
||||
bench_mul_dmat_dvector!(bh, 6, 6);
|
||||
}
|
||||
|
|
|
@ -6,40 +6,40 @@ extern crate nalgebra as na;
|
|||
|
||||
use rand::{IsaacRng, Rng};
|
||||
use test::Bencher;
|
||||
use na::{Vec2, Vec3, Vec4, Mat2, Mat3, Mat4};
|
||||
use na::{Vector2, Vector3, Vector4, Matrix2, Matrix3, Matrix4};
|
||||
use std::ops::{Add, Sub, Mul, Div};
|
||||
|
||||
#[path="common/macros.rs"]
|
||||
mod macros;
|
||||
|
||||
bench_binop!(_bench_mat2_mul_m, Mat2<f32>, Mat2<f32>, mul);
|
||||
bench_binop!(_bench_mat3_mul_m, Mat3<f32>, Mat3<f32>, mul);
|
||||
bench_binop!(_bench_mat4_mul_m, Mat4<f32>, Mat4<f32>, mul);
|
||||
bench_binop!(_bench_mat2_mul_m, Matrix2<f32>, Matrix2<f32>, mul);
|
||||
bench_binop!(_bench_mat3_mul_m, Matrix3<f32>, Matrix3<f32>, mul);
|
||||
bench_binop!(_bench_mat4_mul_m, Matrix4<f32>, Matrix4<f32>, mul);
|
||||
|
||||
bench_binop!(_bench_mat2_add_m, Mat2<f32>, Mat2<f32>, add);
|
||||
bench_binop!(_bench_mat3_add_m, Mat3<f32>, Mat3<f32>, add);
|
||||
bench_binop!(_bench_mat4_add_m, Mat4<f32>, Mat4<f32>, add);
|
||||
bench_binop!(_bench_mat2_add_m, Matrix2<f32>, Matrix2<f32>, add);
|
||||
bench_binop!(_bench_mat3_add_m, Matrix3<f32>, Matrix3<f32>, add);
|
||||
bench_binop!(_bench_mat4_add_m, Matrix4<f32>, Matrix4<f32>, add);
|
||||
|
||||
bench_binop!(_bench_mat2_sub_m, Mat2<f32>, Mat2<f32>, sub);
|
||||
bench_binop!(_bench_mat3_sub_m, Mat3<f32>, Mat3<f32>, sub);
|
||||
bench_binop!(_bench_mat4_sub_m, Mat4<f32>, Mat4<f32>, sub);
|
||||
bench_binop!(_bench_mat2_sub_m, Matrix2<f32>, Matrix2<f32>, sub);
|
||||
bench_binop!(_bench_mat3_sub_m, Matrix3<f32>, Matrix3<f32>, sub);
|
||||
bench_binop!(_bench_mat4_sub_m, Matrix4<f32>, Matrix4<f32>, sub);
|
||||
|
||||
bench_binop!(_bench_mat2_mul_v, Mat2<f32>, Vec2<f32>, mul);
|
||||
bench_binop!(_bench_mat3_mul_v, Mat3<f32>, Vec3<f32>, mul);
|
||||
bench_binop!(_bench_mat4_mul_v, Mat4<f32>, Vec4<f32>, mul);
|
||||
bench_binop!(_bench_mat2_mul_v, Matrix2<f32>, Vector2<f32>, mul);
|
||||
bench_binop!(_bench_mat3_mul_v, Matrix3<f32>, Vector3<f32>, mul);
|
||||
bench_binop!(_bench_mat4_mul_v, Matrix4<f32>, Vector4<f32>, mul);
|
||||
|
||||
bench_binop!(_bench_mat2_mul_s, Mat2<f32>, f32, mul);
|
||||
bench_binop!(_bench_mat3_mul_s, Mat3<f32>, f32, mul);
|
||||
bench_binop!(_bench_mat4_mul_s, Mat4<f32>, f32, mul);
|
||||
bench_binop!(_bench_mat2_mul_s, Matrix2<f32>, f32, mul);
|
||||
bench_binop!(_bench_mat3_mul_s, Matrix3<f32>, f32, mul);
|
||||
bench_binop!(_bench_mat4_mul_s, Matrix4<f32>, f32, mul);
|
||||
|
||||
bench_binop!(_bench_mat2_div_s, Mat2<f32>, f32, div);
|
||||
bench_binop!(_bench_mat3_div_s, Mat3<f32>, f32, div);
|
||||
bench_binop!(_bench_mat4_div_s, Mat4<f32>, f32, div);
|
||||
bench_binop!(_bench_mat2_div_s, Matrix2<f32>, f32, div);
|
||||
bench_binop!(_bench_mat3_div_s, Matrix3<f32>, f32, div);
|
||||
bench_binop!(_bench_mat4_div_s, Matrix4<f32>, f32, div);
|
||||
|
||||
bench_unop!(_bench_mat2_inv, Mat2<f32>, inv);
|
||||
bench_unop!(_bench_mat3_inv, Mat3<f32>, inv);
|
||||
bench_unop!(_bench_mat4_inv, Mat4<f32>, inv);
|
||||
bench_unop!(_bench_mat2_inv, Matrix2<f32>, inverse);
|
||||
bench_unop!(_bench_mat3_inv, Matrix3<f32>, inverse);
|
||||
bench_unop!(_bench_mat4_inv, Matrix4<f32>, inverse);
|
||||
|
||||
bench_unop!(_bench_mat2_transpose, Mat2<f32>, transpose);
|
||||
bench_unop!(_bench_mat3_transpose, Mat3<f32>, transpose);
|
||||
bench_unop!(_bench_mat4_transpose, Mat4<f32>, transpose);
|
||||
bench_unop!(_bench_mat2_transpose, Matrix2<f32>, transpose);
|
||||
bench_unop!(_bench_mat3_transpose, Matrix3<f32>, transpose);
|
||||
bench_unop!(_bench_mat4_transpose, Matrix4<f32>, transpose);
|
||||
|
|
|
@ -6,19 +6,19 @@ extern crate nalgebra as na;
|
|||
|
||||
use rand::{IsaacRng, Rng};
|
||||
use test::Bencher;
|
||||
use na::{Quat, UnitQuat, Vec3};
|
||||
use na::{Quaternion, UnitQuaternion, Vector3};
|
||||
use std::ops::{Add, Sub, Mul, Div};
|
||||
|
||||
#[path="common/macros.rs"]
|
||||
mod macros;
|
||||
|
||||
bench_binop!(_bench_quat_add_q, Quat<f32>, Quat<f32>, add);
|
||||
bench_binop!(_bench_quat_sub_q, Quat<f32>, Quat<f32>, sub);
|
||||
bench_binop!(_bench_quat_mul_q, Quat<f32>, Quat<f32>, mul);
|
||||
// bench_binop!(_bench_quat_div_q, Quat<f32>, Quat<f32>, div)
|
||||
bench_binop!(_bench_quat_mul_v, UnitQuat<f32>, Vec3<f32>, mul);
|
||||
bench_binop!(_bench_quat_mul_s, Quat<f32>, f32, mul);
|
||||
bench_binop!(_bench_quat_div_s, Quat<f32>, f32, div);
|
||||
bench_unop!(_bench_quat_inv, Quat<f32>, inv);
|
||||
bench_unop_self!(_bench_quat_conjugate, Quat<f32>, conjugate);
|
||||
bench_unop!(_bench_quat_normalize, Quat<f32>, normalize);
|
||||
bench_binop!(_bench_quaternion_add_q, Quaternion<f32>, Quaternion<f32>, add);
|
||||
bench_binop!(_bench_quaternion_sub_q, Quaternion<f32>, Quaternion<f32>, sub);
|
||||
bench_binop!(_bench_quaternion_mul_q, Quaternion<f32>, Quaternion<f32>, mul);
|
||||
// bench_binop!(_bench_quaternion_div_q, Quaternion<f32>, Quaternion<f32>, div)
|
||||
bench_binop!(_bench_quaternion_mul_v, UnitQuaternion<f32>, Vector3<f32>, mul);
|
||||
bench_binop!(_bench_quaternion_mul_s, Quaternion<f32>, f32, mul);
|
||||
bench_binop!(_bench_quaternion_div_s, Quaternion<f32>, f32, div);
|
||||
bench_unop!(_bench_quaternion_inv, Quaternion<f32>, inverse);
|
||||
bench_unop_self!(_bench_quaternion_conjugate, Quaternion<f32>, conjugate);
|
||||
bench_unop!(_bench_quaternion_normalize, Quaternion<f32>, normalize);
|
||||
|
|
138
benches/vec.rs
138
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<f32>, Vec2<f32>, add);
|
||||
bench_binop!(_bench_vec3_add_v, Vec3<f32>, Vec3<f32>, add);
|
||||
bench_binop!(_bench_vec4_add_v, Vec4<f32>, Vec4<f32>, add);
|
||||
bench_binop!(_bench_vec2_add_v, Vector2<f32>, Vector2<f32>, add);
|
||||
bench_binop!(_bench_vec3_add_v, Vector3<f32>, Vector3<f32>, add);
|
||||
bench_binop!(_bench_vec4_add_v, Vector4<f32>, Vector4<f32>, add);
|
||||
|
||||
bench_binop!(_bench_vec2_sub_v, Vec2<f32>, Vec2<f32>, sub);
|
||||
bench_binop!(_bench_vec3_sub_v, Vec3<f32>, Vec3<f32>, sub);
|
||||
bench_binop!(_bench_vec4_sub_v, Vec4<f32>, Vec4<f32>, sub);
|
||||
bench_binop!(_bench_vec2_sub_v, Vector2<f32>, Vector2<f32>, sub);
|
||||
bench_binop!(_bench_vec3_sub_v, Vector3<f32>, Vector3<f32>, sub);
|
||||
bench_binop!(_bench_vec4_sub_v, Vector4<f32>, Vector4<f32>, sub);
|
||||
|
||||
bench_binop!(_bench_vec2_mul_v, Vec2<f32>, Vec2<f32>, mul);
|
||||
bench_binop!(_bench_vec3_mul_v, Vec3<f32>, Vec3<f32>, mul);
|
||||
bench_binop!(_bench_vec4_mul_v, Vec4<f32>, Vec4<f32>, mul);
|
||||
bench_binop!(_bench_vec2_mul_v, Vector2<f32>, Vector2<f32>, mul);
|
||||
bench_binop!(_bench_vec3_mul_v, Vector3<f32>, Vector3<f32>, mul);
|
||||
bench_binop!(_bench_vec4_mul_v, Vector4<f32>, Vector4<f32>, mul);
|
||||
|
||||
bench_binop!(_bench_vec2_div_v, Vec2<f32>, Vec2<f32>, div);
|
||||
bench_binop!(_bench_vec3_div_v, Vec3<f32>, Vec3<f32>, div);
|
||||
bench_binop!(_bench_vec4_div_v, Vec4<f32>, Vec4<f32>, div);
|
||||
bench_binop!(_bench_vec2_div_v, Vector2<f32>, Vector2<f32>, div);
|
||||
bench_binop!(_bench_vec3_div_v, Vector3<f32>, Vector3<f32>, div);
|
||||
bench_binop!(_bench_vec4_div_v, Vector4<f32>, Vector4<f32>, div);
|
||||
|
||||
bench_binop!(_bench_vec2_add_s, Vec2<f32>, f32, add);
|
||||
bench_binop!(_bench_vec3_add_s, Vec3<f32>, f32, add);
|
||||
bench_binop!(_bench_vec4_add_s, Vec4<f32>, f32, add);
|
||||
bench_binop!(_bench_vec2_add_s, Vector2<f32>, f32, add);
|
||||
bench_binop!(_bench_vec3_add_s, Vector3<f32>, f32, add);
|
||||
bench_binop!(_bench_vec4_add_s, Vector4<f32>, f32, add);
|
||||
|
||||
bench_binop!(_bench_vec2_sub_s, Vec2<f32>, f32, sub);
|
||||
bench_binop!(_bench_vec3_sub_s, Vec3<f32>, f32, sub);
|
||||
bench_binop!(_bench_vec4_sub_s, Vec4<f32>, f32, sub);
|
||||
bench_binop!(_bench_vec2_sub_s, Vector2<f32>, f32, sub);
|
||||
bench_binop!(_bench_vec3_sub_s, Vector3<f32>, f32, sub);
|
||||
bench_binop!(_bench_vec4_sub_s, Vector4<f32>, f32, sub);
|
||||
|
||||
bench_binop!(_bench_vec2_mul_s, Vec2<f32>, f32, mul);
|
||||
bench_binop!(_bench_vec3_mul_s, Vec3<f32>, f32, mul);
|
||||
bench_binop!(_bench_vec4_mul_s, Vec4<f32>, f32, mul);
|
||||
bench_binop!(_bench_vec2_mul_s, Vector2<f32>, f32, mul);
|
||||
bench_binop!(_bench_vec3_mul_s, Vector3<f32>, f32, mul);
|
||||
bench_binop!(_bench_vec4_mul_s, Vector4<f32>, f32, mul);
|
||||
|
||||
bench_binop!(_bench_vec2_div_s, Vec2<f32>, f32, div);
|
||||
bench_binop!(_bench_vec3_div_s, Vec3<f32>, f32, div);
|
||||
bench_binop!(_bench_vec4_div_s, Vec4<f32>, f32, div);
|
||||
bench_binop!(_bench_vec2_div_s, Vector2<f32>, f32, div);
|
||||
bench_binop!(_bench_vec3_div_s, Vector3<f32>, f32, div);
|
||||
bench_binop!(_bench_vec4_div_s, Vector4<f32>, f32, div);
|
||||
|
||||
bench_binop_na!(_bench_vec2_dot, Vec2<f32>, Vec2<f32>, dot);
|
||||
bench_binop_na!(_bench_vec3_dot, Vec3<f32>, Vec3<f32>, dot);
|
||||
bench_binop_na!(_bench_vec4_dot, Vec4<f32>, Vec4<f32>, dot);
|
||||
bench_binop_na!(_bench_vec2_dot, Vector2<f32>, Vector2<f32>, dot);
|
||||
bench_binop_na!(_bench_vec3_dot, Vector3<f32>, Vector3<f32>, dot);
|
||||
bench_binop_na!(_bench_vec4_dot, Vector4<f32>, Vector4<f32>, dot);
|
||||
|
||||
bench_binop_na!(_bench_vec3_cross, Vec3<f32>, Vec3<f32>, cross);
|
||||
bench_binop_na!(_bench_vec3_cross, Vector3<f32>, Vector3<f32>, cross);
|
||||
|
||||
bench_unop!(_bench_vec2_norm, Vec2<f32>, norm);
|
||||
bench_unop!(_bench_vec3_norm, Vec3<f32>, norm);
|
||||
bench_unop!(_bench_vec4_norm, Vec4<f32>, norm);
|
||||
bench_unop!(_bench_vec2_norm, Vector2<f32>, norm);
|
||||
bench_unop!(_bench_vec3_norm, Vector3<f32>, norm);
|
||||
bench_unop!(_bench_vec4_norm, Vector4<f32>, norm);
|
||||
|
||||
bench_unop!(_bench_vec2_normalize, Vec2<f32>, normalize);
|
||||
bench_unop!(_bench_vec3_normalize, Vec3<f32>, normalize);
|
||||
bench_unop!(_bench_vec4_normalize, Vec4<f32>, normalize);
|
||||
bench_unop!(_bench_vec2_normalize, Vector2<f32>, normalize);
|
||||
bench_unop!(_bench_vec3_normalize, Vector3<f32>, normalize);
|
||||
bench_unop!(_bench_vec4_normalize, Vector4<f32>, normalize);
|
||||
|
||||
#[cfg(feature = "generic_sizes")]
|
||||
mod bench_vecn {
|
||||
use typenum::{U2, U3, U4};
|
||||
use na::VecN;
|
||||
use na::VectorN;
|
||||
|
||||
bench_binop!(_bench_vecn2_add_v, VecN<f32, U2>, VecN<f32, U2>, add);
|
||||
bench_binop!(_bench_vecn3_add_v, VecN<f32, U3>, VecN<f32, U3>, add);
|
||||
bench_binop!(_bench_vecn4_add_v, VecN<f32, U4>, VecN<f32, U4>, add);
|
||||
bench_binop!(_bench_vecn2_add_v, VectorN<f32, U2>, VectorN<f32, U2>, add);
|
||||
bench_binop!(_bench_vecn3_add_v, VectorN<f32, U3>, VectorN<f32, U3>, add);
|
||||
bench_binop!(_bench_vecn4_add_v, VectorN<f32, U4>, VectorN<f32, U4>, add);
|
||||
|
||||
bench_binop!(_bench_vecn2_sub_v, VecN<f32, U2>, VecN<f32, U2>, sub);
|
||||
bench_binop!(_bench_vecn3_sub_v, VecN<f32, U3>, VecN<f32, U3>, sub);
|
||||
bench_binop!(_bench_vecn4_sub_v, VecN<f32, U4>, VecN<f32, U4>, sub);
|
||||
bench_binop!(_bench_vecn2_sub_v, VectorN<f32, U2>, VectorN<f32, U2>, sub);
|
||||
bench_binop!(_bench_vecn3_sub_v, VectorN<f32, U3>, VectorN<f32, U3>, sub);
|
||||
bench_binop!(_bench_vecn4_sub_v, VectorN<f32, U4>, VectorN<f32, U4>, sub);
|
||||
|
||||
bench_binop!(_bench_vecn2_mul_v, VecN<f32, U2>, VecN<f32, U2>, mul);
|
||||
bench_binop!(_bench_vecn3_mul_v, VecN<f32, U3>, VecN<f32, U3>, mul);
|
||||
bench_binop!(_bench_vecn4_mul_v, VecN<f32, U4>, VecN<f32, U4>, mul);
|
||||
bench_binop!(_bench_vecn2_mul_v, VectorN<f32, U2>, VectorN<f32, U2>, mul);
|
||||
bench_binop!(_bench_vecn3_mul_v, VectorN<f32, U3>, VectorN<f32, U3>, mul);
|
||||
bench_binop!(_bench_vecn4_mul_v, VectorN<f32, U4>, VectorN<f32, U4>, mul);
|
||||
|
||||
bench_binop!(_bench_vecn2_div_v, VecN<f32, U2>, VecN<f32, U2>, div);
|
||||
bench_binop!(_bench_vecn3_div_v, VecN<f32, U3>, VecN<f32, U3>, div);
|
||||
bench_binop!(_bench_vecn4_div_v, VecN<f32, U4>, VecN<f32, U4>, div);
|
||||
bench_binop!(_bench_vecn2_div_v, VectorN<f32, U2>, VectorN<f32, U2>, div);
|
||||
bench_binop!(_bench_vecn3_div_v, VectorN<f32, U3>, VectorN<f32, U3>, div);
|
||||
bench_binop!(_bench_vecn4_div_v, VectorN<f32, U4>, VectorN<f32, U4>, div);
|
||||
|
||||
bench_binop!(_bench_vecn2_add_s, VecN<f32, U2>, f32, add);
|
||||
bench_binop!(_bench_vecn3_add_s, VecN<f32, U3>, f32, add);
|
||||
bench_binop!(_bench_vecn4_add_s, VecN<f32, U4>, f32, add);
|
||||
bench_binop!(_bench_vecn2_add_s, VectorN<f32, U2>, f32, add);
|
||||
bench_binop!(_bench_vecn3_add_s, VectorN<f32, U3>, f32, add);
|
||||
bench_binop!(_bench_vecn4_add_s, VectorN<f32, U4>, f32, add);
|
||||
|
||||
bench_binop!(_bench_vecn2_sub_s, VecN<f32, U2>, f32, sub);
|
||||
bench_binop!(_bench_vecn3_sub_s, VecN<f32, U3>, f32, sub);
|
||||
bench_binop!(_bench_vecn4_sub_s, VecN<f32, U4>, f32, sub);
|
||||
bench_binop!(_bench_vecn2_sub_s, VectorN<f32, U2>, f32, sub);
|
||||
bench_binop!(_bench_vecn3_sub_s, VectorN<f32, U3>, f32, sub);
|
||||
bench_binop!(_bench_vecn4_sub_s, VectorN<f32, U4>, f32, sub);
|
||||
|
||||
bench_binop!(_bench_vecn2_mul_s, VecN<f32, U2>, f32, mul);
|
||||
bench_binop!(_bench_vecn3_mul_s, VecN<f32, U3>, f32, mul);
|
||||
bench_binop!(_bench_vecn4_mul_s, VecN<f32, U4>, f32, mul);
|
||||
bench_binop!(_bench_vecn2_mul_s, VectorN<f32, U2>, f32, mul);
|
||||
bench_binop!(_bench_vecn3_mul_s, VectorN<f32, U3>, f32, mul);
|
||||
bench_binop!(_bench_vecn4_mul_s, VectorN<f32, U4>, f32, mul);
|
||||
|
||||
bench_binop!(_bench_vecn2_div_s, VecN<f32, U2>, f32, div);
|
||||
bench_binop!(_bench_vecn3_div_s, VecN<f32, U3>, f32, div);
|
||||
bench_binop!(_bench_vecn4_div_s, VecN<f32, U4>, f32, div);
|
||||
bench_binop!(_bench_vecn2_div_s, VectorN<f32, U2>, f32, div);
|
||||
bench_binop!(_bench_vecn3_div_s, VectorN<f32, U3>, f32, div);
|
||||
bench_binop!(_bench_vecn4_div_s, VectorN<f32, U4>, f32, div);
|
||||
|
||||
bench_binop_na!(_bench_vecn2_dot, VecN<f32, U2>, VecN<f32, U2>, dot);
|
||||
bench_binop_na!(_bench_vecn3_dot, VecN<f32, U3>, VecN<f32, U3>, dot);
|
||||
bench_binop_na!(_bench_vecn4_dot, VecN<f32, U4>, VecN<f32, U4>, dot);
|
||||
bench_binop_na!(_bench_vecn2_dot, VectorN<f32, U2>, VectorN<f32, U2>, dot);
|
||||
bench_binop_na!(_bench_vecn3_dot, VectorN<f32, U3>, VectorN<f32, U3>, dot);
|
||||
bench_binop_na!(_bench_vecn4_dot, VectorN<f32, U4>, VectorN<f32, U4>, dot);
|
||||
|
||||
bench_unop!(_bench_vecn2_norm, VecN<f32, U2>, norm);
|
||||
bench_unop!(_bench_vecn3_norm, VecN<f32, U3>, norm);
|
||||
bench_unop!(_bench_vecn4_norm, VecN<f32, U4>, norm);
|
||||
bench_unop!(_bench_vecn2_norm, VectorN<f32, U2>, norm);
|
||||
bench_unop!(_bench_vecn3_norm, VectorN<f32, U3>, norm);
|
||||
bench_unop!(_bench_vecn4_norm, VectorN<f32, U4>, norm);
|
||||
|
||||
bench_unop!(_bench_vecn2_normalize, VecN<f32, U2>, normalize);
|
||||
bench_unop!(_bench_vecn3_normalize, VecN<f32, U3>, normalize);
|
||||
bench_unop!(_bench_vecn4_normalize, VecN<f32, U4>, normalize);
|
||||
bench_unop!(_bench_vecn2_normalize, VectorN<f32, U2>, normalize);
|
||||
bench_unop!(_bench_vecn3_normalize, VectorN<f32, U3>, normalize);
|
||||
bench_unop!(_bench_vecn4_normalize, VectorN<f32, U4>, normalize);
|
||||
}
|
||||
|
|
314
src/lib.rs
314
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<T: Ord>(a: T, b: T) -> T {
|
|||
|
||||
/// Returns the infimum of `a` and `b`.
|
||||
#[inline(always)]
|
||||
pub fn inf<T: POrd>(a: &T, b: &T) -> T {
|
||||
POrd::inf(a, b)
|
||||
pub fn inf<T: PartialOrder>(a: &T, b: &T) -> T {
|
||||
PartialOrder::inf(a, b)
|
||||
}
|
||||
|
||||
/// Returns the supremum of `a` and `b`.
|
||||
#[inline(always)]
|
||||
pub fn sup<T: POrd>(a: &T, b: &T) -> T {
|
||||
POrd::sup(a, b)
|
||||
pub fn sup<T: PartialOrder>(a: &T, b: &T) -> T {
|
||||
PartialOrder::sup(a, b)
|
||||
}
|
||||
|
||||
/// Compare `a` and `b` using a partial ordering relation.
|
||||
#[inline(always)]
|
||||
pub fn partial_cmp<T: POrd>(a: &T, b: &T) -> POrdering {
|
||||
POrd::partial_cmp(a, b)
|
||||
pub fn partial_cmp<T: PartialOrder>(a: &T, b: &T) -> PartialOrdering {
|
||||
PartialOrder::partial_cmp(a, b)
|
||||
}
|
||||
|
||||
/// Returns `true` iff `a` and `b` are comparable and `a < b`.
|
||||
#[inline(always)]
|
||||
pub fn partial_lt<T: POrd>(a: &T, b: &T) -> bool {
|
||||
POrd::partial_lt(a, b)
|
||||
pub fn partial_lt<T: PartialOrder>(a: &T, b: &T) -> bool {
|
||||
PartialOrder::partial_lt(a, b)
|
||||
}
|
||||
|
||||
/// Returns `true` iff `a` and `b` are comparable and `a <= b`.
|
||||
#[inline(always)]
|
||||
pub fn partial_le<T: POrd>(a: &T, b: &T) -> bool {
|
||||
POrd::partial_le(a, b)
|
||||
pub fn partial_le<T: PartialOrder>(a: &T, b: &T) -> bool {
|
||||
PartialOrder::partial_le(a, b)
|
||||
}
|
||||
|
||||
/// Returns `true` iff `a` and `b` are comparable and `a > b`.
|
||||
#[inline(always)]
|
||||
pub fn partial_gt<T: POrd>(a: &T, b: &T) -> bool {
|
||||
POrd::partial_gt(a, b)
|
||||
pub fn partial_gt<T: PartialOrder>(a: &T, b: &T) -> bool {
|
||||
PartialOrder::partial_gt(a, b)
|
||||
}
|
||||
|
||||
/// Returns `true` iff `a` and `b` are comparable and `a >= b`.
|
||||
#[inline(always)]
|
||||
pub fn partial_ge<T: POrd>(a: &T, b: &T) -> bool {
|
||||
POrd::partial_ge(a, b)
|
||||
pub fn partial_ge<T: PartialOrder>(a: &T, b: &T) -> bool {
|
||||
PartialOrder::partial_ge(a, b)
|
||||
}
|
||||
|
||||
/// Return the minimum of `a` and `b` if they are comparable.
|
||||
#[inline(always)]
|
||||
pub fn partial_min<'a, T: POrd>(a: &'a T, b: &'a T) -> Option<&'a T> {
|
||||
POrd::partial_min(a, b)
|
||||
pub fn partial_min<'a, T: PartialOrder>(a: &'a T, b: &'a T) -> Option<&'a T> {
|
||||
PartialOrder::partial_min(a, b)
|
||||
}
|
||||
|
||||
/// Return the maximum of `a` and `b` if they are comparable.
|
||||
#[inline(always)]
|
||||
pub fn partial_max<'a, T: POrd>(a: &'a T, b: &'a T) -> Option<&'a T> {
|
||||
POrd::partial_max(a, b)
|
||||
pub fn partial_max<'a, T: PartialOrder>(a: &'a T, b: &'a T) -> Option<&'a T> {
|
||||
PartialOrder::partial_max(a, b)
|
||||
}
|
||||
|
||||
/// Clamp `value` between `min` and `max`. Returns `None` if `value` is not comparable to
|
||||
/// `min` or `max`.
|
||||
#[inline(always)]
|
||||
pub fn partial_clamp<'a, T: POrd>(value: &'a T, min: &'a T, max: &'a T) -> Option<&'a T> {
|
||||
POrd::partial_clamp(value, min, max)
|
||||
pub fn partial_clamp<'a, T: PartialOrder>(value: &'a T, min: &'a T, max: &'a T) -> Option<&'a T> {
|
||||
PartialOrder::partial_clamp(value, min, max)
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -305,34 +305,34 @@ pub fn one<T: One>() -> T {
|
|||
|
||||
/// Returns the trivial origin of an affine space.
|
||||
#[inline(always)]
|
||||
pub fn orig<P: Orig>() -> P {
|
||||
Orig::orig()
|
||||
pub fn origin<P: Origin>() -> P {
|
||||
Origin::origin()
|
||||
}
|
||||
|
||||
/// Returns the center of two points.
|
||||
#[inline]
|
||||
pub fn center<N: BaseFloat, P: FloatPnt<N>>(a: &P, b: &P) -> P
|
||||
where <P as PntAsVec>::Vec: Norm<N>
|
||||
pub fn center<N: BaseFloat, P: FloatPoint<N>>(a: &P, b: &P) -> P
|
||||
where <P as PointAsVector>::Vector: Norm<N>
|
||||
{
|
||||
let _2 = one::<N>() + one();
|
||||
(*a + b.to_vec()) / _2
|
||||
(*a + b.to_vector()) / _2
|
||||
}
|
||||
|
||||
/*
|
||||
* FloatPnt
|
||||
* FloatPoint
|
||||
*/
|
||||
/// Returns the distance between two points.
|
||||
#[inline(always)]
|
||||
pub fn dist<N: BaseFloat, P: FloatPnt<N>>(a: &P, b: &P) -> N where <P as PntAsVec>::Vec: Norm<N> {
|
||||
a.dist(b)
|
||||
pub fn distance<N: BaseFloat, P: FloatPoint<N>>(a: &P, b: &P) -> N where <P as PointAsVector>::Vector: Norm<N> {
|
||||
a.distance(b)
|
||||
}
|
||||
|
||||
/// Returns the squared distance between two points.
|
||||
#[inline(always)]
|
||||
pub fn sqdist<N: BaseFloat, P: FloatPnt<N>>(a: &P, b: &P) -> N
|
||||
where <P as PntAsVec>::Vec: Norm<N>
|
||||
pub fn distance_squared<N: BaseFloat, P: FloatPoint<N>>(a: &P, b: &P) -> N
|
||||
where <P as PointAsVector>::Vector: Norm<N>
|
||||
{
|
||||
a.sqdist(b)
|
||||
a.distance_squared(b)
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -343,13 +343,13 @@ pub fn sqdist<N: BaseFloat, P: FloatPnt<N>>(a: &P, b: &P) -> N
|
|||
///
|
||||
/// ```rust
|
||||
/// extern crate nalgebra as na;
|
||||
/// use na::{Vec3, Iso3};
|
||||
/// use na::{Vector3, Isometry3};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
|
||||
/// let t = Isometry3::new(Vector3::new(1.0f64, 1.0, 1.0), na::zero());
|
||||
/// let trans = na::translation(&t);
|
||||
///
|
||||
/// assert!(trans == Vec3::new(1.0, 1.0, 1.0));
|
||||
/// assert!(trans == Vector3::new(1.0, 1.0, 1.0));
|
||||
/// }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
|
@ -361,18 +361,18 @@ pub fn translation<V, M: Translation<V>>(m: &M) -> V {
|
|||
///
|
||||
/// ```rust
|
||||
/// extern crate nalgebra as na;
|
||||
/// use na::{Vec3, Iso3};
|
||||
/// use na::{Vector3, Isometry3};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
|
||||
/// let itrans = na::inv_translation(&t);
|
||||
/// let t = Isometry3::new(Vector3::new(1.0f64, 1.0, 1.0), na::zero());
|
||||
/// let itrans = na::inverse_translation(&t);
|
||||
///
|
||||
/// assert!(itrans == Vec3::new(-1.0, -1.0, -1.0));
|
||||
/// assert!(itrans == Vector3::new(-1.0, -1.0, -1.0));
|
||||
/// }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn inv_translation<V, M: Translation<V>>(m: &M) -> V {
|
||||
m.inv_translation()
|
||||
pub fn inverse_translation<V, M: Translation<V>>(m: &M) -> V {
|
||||
m.inverse_translation()
|
||||
}
|
||||
|
||||
/// Applies the translation `v` to a copy of `m`.
|
||||
|
@ -389,15 +389,15 @@ pub fn append_translation<V, M: Translation<V>>(m: &M, v: &V) -> M {
|
|||
///
|
||||
/// ```rust
|
||||
/// extern crate nalgebra as na;
|
||||
/// use na::{Pnt3, Vec3, Iso3};
|
||||
/// use na::{Point3, Vector3, Isometry3};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
|
||||
/// let p = Pnt3::new(2.0, 2.0, 2.0);
|
||||
/// let t = Isometry3::new(Vector3::new(1.0f64, 1.0, 1.0), na::zero());
|
||||
/// let p = Point3::new(2.0, 2.0, 2.0);
|
||||
///
|
||||
/// let tp = na::translate(&t, &p);
|
||||
///
|
||||
/// assert!(tp == Pnt3::new(3.0, 3.0, 3.0))
|
||||
/// assert!(tp == Point3::new(3.0, 3.0, 3.0))
|
||||
/// }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
|
@ -409,19 +409,19 @@ pub fn translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
|
|||
///
|
||||
/// ```rust
|
||||
/// extern crate nalgebra as na;
|
||||
/// use na::{Pnt3, Vec3, Iso3};
|
||||
/// use na::{Point3, Vector3, Isometry3};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
|
||||
/// let p = Pnt3::new(2.0, 2.0, 2.0);
|
||||
/// let t = Isometry3::new(Vector3::new(1.0f64, 1.0, 1.0), na::zero());
|
||||
/// let p = Point3::new(2.0, 2.0, 2.0);
|
||||
///
|
||||
/// let tp = na::inv_translate(&t, &p);
|
||||
/// let tp = na::inverse_translate(&t, &p);
|
||||
///
|
||||
/// assert!(na::approx_eq(&tp, &Pnt3::new(1.0, 1.0, 1.0)))
|
||||
/// assert!(na::approx_eq(&tp, &Point3::new(1.0, 1.0, 1.0)))
|
||||
/// }
|
||||
#[inline(always)]
|
||||
pub fn inv_translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
|
||||
m.inv_translate(p)
|
||||
pub fn inverse_translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
|
||||
m.inverse_translate(p)
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -432,12 +432,12 @@ pub fn inv_translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
|
|||
///
|
||||
/// ```rust
|
||||
/// extern crate nalgebra as na;
|
||||
/// use na::{Vec3, Rot3};
|
||||
/// use na::{Vector3, Rotation3};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let t = Rot3::new(Vec3::new(1.0f64, 1.0, 1.0));
|
||||
/// let t = Rotation3::new(Vector3::new(1.0f64, 1.0, 1.0));
|
||||
///
|
||||
/// assert!(na::approx_eq(&na::rotation(&t), &Vec3::new(1.0, 1.0, 1.0)));
|
||||
/// assert!(na::approx_eq(&na::rotation(&t), &Vector3::new(1.0, 1.0, 1.0)));
|
||||
/// }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
|
@ -450,17 +450,17 @@ pub fn rotation<V, M: Rotation<V>>(m: &M) -> V {
|
|||
///
|
||||
/// ```rust
|
||||
/// extern crate nalgebra as na;
|
||||
/// use na::{Vec3, Rot3};
|
||||
/// use na::{Vector3, Rotation3};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let t = Rot3::new(Vec3::new(1.0f64, 1.0, 1.0));
|
||||
/// let t = Rotation3::new(Vector3::new(1.0f64, 1.0, 1.0));
|
||||
///
|
||||
/// assert!(na::approx_eq(&na::inv_rotation(&t), &Vec3::new(-1.0, -1.0, -1.0)));
|
||||
/// assert!(na::approx_eq(&na::inverse_rotation(&t), &Vector3::new(-1.0, -1.0, -1.0)));
|
||||
/// }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn inv_rotation<V, M: Rotation<V>>(m: &M) -> V {
|
||||
m.inv_rotation()
|
||||
pub fn inverse_rotation<V, M: Rotation<V>>(m: &M) -> V {
|
||||
m.inverse_rotation()
|
||||
}
|
||||
|
||||
// FIXME: this example is a bit shity
|
||||
|
@ -468,14 +468,14 @@ pub fn inv_rotation<V, M: Rotation<V>>(m: &M) -> V {
|
|||
///
|
||||
/// ```rust
|
||||
/// extern crate nalgebra as na;
|
||||
/// use na::{Vec3, Rot3};
|
||||
/// use na::{Vector3, Rotation3};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.0));
|
||||
/// let v = Vec3::new(1.0, 1.0, 1.0);
|
||||
/// let t = Rotation3::new(Vector3::new(0.0f64, 0.0, 0.0));
|
||||
/// let v = Vector3::new(1.0, 1.0, 1.0);
|
||||
/// let rt = na::append_rotation(&t, &v);
|
||||
///
|
||||
/// assert!(na::approx_eq(&na::rotation(&rt), &Vec3::new(1.0, 1.0, 1.0)))
|
||||
/// assert!(na::approx_eq(&na::rotation(&rt), &Vector3::new(1.0, 1.0, 1.0)))
|
||||
/// }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
|
@ -488,14 +488,14 @@ pub fn append_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
|
|||
///
|
||||
/// ```rust
|
||||
/// extern crate nalgebra as na;
|
||||
/// use na::{Vec3, Rot3};
|
||||
/// use na::{Vector3, Rotation3};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.0));
|
||||
/// let v = Vec3::new(1.0, 1.0, 1.0);
|
||||
/// let t = Rotation3::new(Vector3::new(0.0f64, 0.0, 0.0));
|
||||
/// let v = Vector3::new(1.0, 1.0, 1.0);
|
||||
/// let rt = na::prepend_rotation(&t, &v);
|
||||
///
|
||||
/// assert!(na::approx_eq(&na::rotation(&rt), &Vec3::new(1.0, 1.0, 1.0)))
|
||||
/// assert!(na::approx_eq(&na::rotation(&rt), &Vector3::new(1.0, 1.0, 1.0)))
|
||||
/// }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
|
@ -511,15 +511,15 @@ pub fn prepend_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
|
|||
///
|
||||
/// ```rust
|
||||
/// extern crate nalgebra as na;
|
||||
/// use na::{BaseFloat, Rot3, Vec3};
|
||||
/// use na::{BaseFloat, Rotation3, Vector3};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.5 * <f64 as BaseFloat>::pi()));
|
||||
/// let v = Vec3::new(1.0, 0.0, 0.0);
|
||||
/// let t = Rotation3::new(Vector3::new(0.0f64, 0.0, 0.5 * <f64 as BaseFloat>::pi()));
|
||||
/// let v = Vector3::new(1.0, 0.0, 0.0);
|
||||
///
|
||||
/// let tv = na::rotate(&t, &v);
|
||||
///
|
||||
/// assert!(na::approx_eq(&tv, &Vec3::new(0.0, 1.0, 0.0)))
|
||||
/// assert!(na::approx_eq(&tv, &Vector3::new(0.0, 1.0, 0.0)))
|
||||
/// }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
|
@ -532,20 +532,20 @@ pub fn rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
|
|||
///
|
||||
/// ```rust
|
||||
/// extern crate nalgebra as na;
|
||||
/// use na::{BaseFloat, Rot3, Vec3};
|
||||
/// use na::{BaseFloat, Rotation3, Vector3};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.5 * <f64 as BaseFloat>::pi()));
|
||||
/// let v = Vec3::new(1.0, 0.0, 0.0);
|
||||
/// let t = Rotation3::new(Vector3::new(0.0f64, 0.0, 0.5 * <f64 as BaseFloat>::pi()));
|
||||
/// let v = Vector3::new(1.0, 0.0, 0.0);
|
||||
///
|
||||
/// let tv = na::inv_rotate(&t, &v);
|
||||
/// let tv = na::inverse_rotate(&t, &v);
|
||||
///
|
||||
/// assert!(na::approx_eq(&tv, &Vec3::new(0.0, -1.0, 0.0)))
|
||||
/// assert!(na::approx_eq(&tv, &Vector3::new(0.0, -1.0, 0.0)))
|
||||
/// }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn inv_rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
|
||||
m.inv_rotate(v)
|
||||
pub fn inverse_rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
|
||||
m.inverse_rotate(v)
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -594,13 +594,13 @@ pub fn rotation_between<V: RotationTo>(a: &V, b: &V) -> V::DeltaRotationType {
|
|||
|
||||
/// Builds a rotation matrix from `r`.
|
||||
#[inline(always)]
|
||||
pub fn to_rot_mat<N, LV, AV, R, M>(r: &R) -> M
|
||||
pub fn to_rotation_matrix<N, LV, AV, R, M>(r: &R) -> M
|
||||
where R: RotationMatrix<N, LV, AV, Output = M>,
|
||||
M: SquareMat<N, LV> + Rotation<AV> + Copy,
|
||||
M: SquareMatrix<N, LV> + Rotation<AV> + Copy,
|
||||
LV: Mul<M, Output = LV>
|
||||
{
|
||||
// FIXME: rust-lang/rust#20413
|
||||
r.to_rot_mat()
|
||||
r.to_rotation_matrix()
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -625,8 +625,8 @@ pub fn transformation<T, M: Transformation<T>>(m: &M) -> T {
|
|||
|
||||
/// Gets the inverse transformation applicable by `m`.
|
||||
#[inline(always)]
|
||||
pub fn inv_transformation<T, M: Transformation<T>>(m: &M) -> T {
|
||||
m.inv_transformation()
|
||||
pub fn inverse_transformation<T, M: Transformation<T>>(m: &M) -> T {
|
||||
m.inverse_transformation()
|
||||
}
|
||||
|
||||
/// Gets a transformed copy of `m`.
|
||||
|
@ -647,8 +647,8 @@ pub fn transform<V, M: Transform<V>>(m: &M, v: &V) -> V {
|
|||
|
||||
/// Applies an inverse transformation to a vector.
|
||||
#[inline(always)]
|
||||
pub fn inv_transform<V, M: Transform<V>>(m: &M, v: &V) -> V {
|
||||
m.inv_transform(v)
|
||||
pub fn inverse_transform<V, M: Transform<V>>(m: &M, v: &V) -> V {
|
||||
m.inverse_transform(v)
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -673,8 +673,8 @@ pub fn norm<V: Norm<N>, N: BaseFloat>(v: &V) -> N {
|
|||
|
||||
/// Computes the squared L2 norm of a vector.
|
||||
#[inline(always)]
|
||||
pub fn sqnorm<V: Norm<N>, N: BaseFloat>(v: &V) -> N {
|
||||
Norm::sqnorm(v)
|
||||
pub fn norm_squared<V: Norm<N>, N: BaseFloat>(v: &V) -> N {
|
||||
Norm::norm_squared(v)
|
||||
}
|
||||
|
||||
/// Gets the normalized version of a vector.
|
||||
|
@ -684,12 +684,12 @@ pub fn normalize<V: Norm<N>, N: BaseFloat>(v: &V) -> V {
|
|||
}
|
||||
|
||||
/*
|
||||
* Det<N>
|
||||
* Determinant<N>
|
||||
*/
|
||||
/// Computes the determinant of a square matrix.
|
||||
#[inline(always)]
|
||||
pub fn det<M: Det<N>, N>(m: &M) -> N {
|
||||
Det::det(m)
|
||||
pub fn determinant<M: Determinant<N>, N>(m: &M) -> N {
|
||||
Determinant::determinant(m)
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -780,13 +780,13 @@ pub fn abs<M: Absolute<Res>, Res>(m: &M) -> Res {
|
|||
}
|
||||
|
||||
/*
|
||||
* Inv
|
||||
* Inverse
|
||||
*/
|
||||
|
||||
/// Gets an inverted copy of a matrix.
|
||||
#[inline(always)]
|
||||
pub fn inv<M: Inv>(m: &M) -> Option<M> {
|
||||
Inv::inv(m)
|
||||
pub fn inverse<M: Inverse>(m: &M) -> Option<M> {
|
||||
Inverse::inverse(m)
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -810,13 +810,13 @@ pub fn outer<V: Outer>(a: &V, b: &V) -> V::OuterProductType {
|
|||
}
|
||||
|
||||
/*
|
||||
* Cov<M>
|
||||
* Covariance<M>
|
||||
*/
|
||||
|
||||
/// Computes the covariance of a set of observations.
|
||||
#[inline(always)]
|
||||
pub fn cov<M: Cov<Res>, Res>(observations: &M) -> Res {
|
||||
Cov::cov(observations)
|
||||
pub fn covariance<M: Covariance<Res>, Res>(observations: &M) -> Res {
|
||||
Covariance::covariance(observations)
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -851,8 +851,8 @@ pub fn eigen_qr<N, V, M>(m: &M, eps: &N, niter: usize) -> (M, V)
|
|||
*/
|
||||
/// Construct the identity matrix for a given dimension
|
||||
#[inline(always)]
|
||||
pub fn new_identity<M: Eye>(dim: usize) -> M {
|
||||
Eye::new_identity(dim)
|
||||
pub fn new_identity<M: Eye>(dimension: usize) -> M {
|
||||
Eye::new_identity(dimension)
|
||||
}
|
||||
|
||||
|
||||
|
@ -894,27 +894,27 @@ pub fn canonical_basis_element<V: Basis>(i: usize) -> Option<V> {
|
|||
*/
|
||||
|
||||
/*
|
||||
* Col<C>
|
||||
* Column<C>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Diag<V>
|
||||
* Diagonal<V>
|
||||
*/
|
||||
/// Gets the diagonal of a square matrix.
|
||||
#[inline(always)]
|
||||
pub fn diag<M: Diag<V>, V>(m: &M) -> V {
|
||||
m.diag()
|
||||
pub fn diagonal<M: Diagonal<V>, V>(m: &M) -> V {
|
||||
m.diagonal()
|
||||
}
|
||||
|
||||
/*
|
||||
* Dim
|
||||
* Dimension
|
||||
*/
|
||||
/// Gets the dimension an object lives in.
|
||||
///
|
||||
/// Same as `Dim::dim::(None::<V>)`.
|
||||
/// Same as `Dimension::dimension::(None::<V>)`.
|
||||
#[inline(always)]
|
||||
pub fn dim<V: Dim>() -> usize {
|
||||
Dim::dim(None::<V>)
|
||||
pub fn dimension<V: Dimension>() -> usize {
|
||||
Dimension::dimension(None::<V>)
|
||||
}
|
||||
|
||||
/// Gets the indexable range of an object.
|
||||
|
@ -931,10 +931,10 @@ pub fn shape<V: Shape<I>, I>(v: &V) -> I {
|
|||
/// For primitive types, this is the same as the `as` keywords.
|
||||
/// The following properties are preserved by a cast:
|
||||
///
|
||||
/// * Type-level geometric invariants cannot be broken (eg. a cast from Rot3<f64> to Rot3<i64> is
|
||||
/// * Type-level geometric invariants cannot be broken (eg. a cast from Rotation3<f64> to Rotation3<i64> is
|
||||
/// not possible)
|
||||
/// * A cast to a type with more type-level invariants cannot be done (eg. a cast from Mat<f64> to
|
||||
/// Rot3<f64> is not possible)
|
||||
/// * A cast to a type with more type-level invariants cannot be done (eg. a cast from Matrix<f64> to
|
||||
/// Rotation3<f64> is not possible)
|
||||
/// * For primitive types an unbounded cast is done using the `as` keyword (this is different from
|
||||
/// the standard library which makes bound-checking to ensure eg. that a i64 is not out of the
|
||||
/// range of an i32 when a cast from i64 to i32 is done).
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
use traits::operations::{Transpose, ApproxEq};
|
||||
use traits::structure::{ColSlice, Eye, Indexable, Diag, SquareMat, BaseFloat, Cast};
|
||||
use traits::structure::{ColumnSlice, Eye, Indexable, Diagonal, SquareMatrix, BaseFloat, Cast};
|
||||
use traits::geometry::Norm;
|
||||
use std::cmp;
|
||||
use std::ops::{Mul, Add, Sub};
|
||||
|
||||
/// Get the householder matrix corresponding to a reflexion to the hyperplane
|
||||
/// defined by `vec`. It can be a reflexion contained in a subspace.
|
||||
/// defined by `vector`. It can be a reflexion contained in a subspace.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `dim` - the dimension of the space the resulting matrix operates in
|
||||
/// * `dimension` - the dimension of the space the resulting matrix operates in
|
||||
/// * `start` - the starting dimension of the subspace of the reflexion
|
||||
/// * `vec` - the vector defining the reflection.
|
||||
pub fn householder_matrix<N, V, M>(dim: usize, start: usize, vec: V) -> M
|
||||
/// * `vector` - the vector defining the reflection.
|
||||
pub fn householder_matrix<N, V, M>(dimension: usize, start: usize, vector: V) -> M
|
||||
where N: BaseFloat,
|
||||
M: Eye + Indexable<(usize, usize), N>,
|
||||
V: Indexable<usize, N> {
|
||||
let mut qk : M = Eye::new_identity(dim);
|
||||
let subdim = vec.shape();
|
||||
let mut qk : M = Eye::new_identity(dimension);
|
||||
let subdim = vector.shape();
|
||||
|
||||
let stop = subdim + start;
|
||||
|
||||
assert!(dim >= stop);
|
||||
assert!(dimension >= stop);
|
||||
|
||||
for j in start .. stop {
|
||||
for i in start .. stop {
|
||||
unsafe {
|
||||
let vv = vec.unsafe_at(i - start) * vec.unsafe_at(j - start);
|
||||
let vv = vector.unsafe_at(i - start) * vector.unsafe_at(j - start);
|
||||
let qkij = qk.unsafe_at((i, j));
|
||||
qk.unsafe_set((i, j), qkij - vv - vv);
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ pub fn householder_matrix<N, V, M>(dim: usize, start: usize, vec: V) -> M
|
|||
pub fn qr<N, V, M>(m: &M) -> (M, M)
|
||||
where N: BaseFloat,
|
||||
V: Indexable<usize, N> + Norm<N>,
|
||||
M: Copy + Eye + ColSlice<V> + Transpose + Indexable<(usize, usize), N> +
|
||||
M: Copy + Eye + ColumnSlice<V> + Transpose + Indexable<(usize, usize), N> +
|
||||
Mul<M, Output = M> {
|
||||
let (rows, cols) = m.shape();
|
||||
assert!(rows >= cols);
|
||||
|
@ -76,29 +76,29 @@ pub fn eigen_qr<N, V, VS, M>(m: &M, eps: &N, niter: usize) -> (M, V)
|
|||
where N: BaseFloat,
|
||||
V: Mul<M, Output = V>,
|
||||
VS: Indexable<usize, N> + Norm<N>,
|
||||
M: Indexable<(usize, usize), N> + SquareMat<N, V> + Add<M, Output = M> +
|
||||
Sub<M, Output = M> + ColSlice<VS> +
|
||||
M: Indexable<(usize, usize), N> + SquareMatrix<N, V> + Add<M, Output = M> +
|
||||
Sub<M, Output = M> + ColumnSlice<VS> +
|
||||
ApproxEq<N> + Copy {
|
||||
|
||||
let (mut eigenvectors, mut eigenvalues) = hessenberg(m);
|
||||
|
||||
// Allocate arrays for Givens rotation components
|
||||
let mut c = Vec::<N>::with_capacity(::dim::<M>() - 1);
|
||||
let mut s = Vec::<N>::with_capacity(::dim::<M>() - 1);
|
||||
let mut c = Vec::<N>::with_capacity(::dimension::<M>() - 1);
|
||||
let mut s = Vec::<N>::with_capacity(::dimension::<M>() - 1);
|
||||
|
||||
if ::dim::<M>() == 1 {
|
||||
return (eigenvectors, eigenvalues.diag());
|
||||
if ::dimension::<M>() == 1 {
|
||||
return (eigenvectors, eigenvalues.diagonal());
|
||||
}
|
||||
|
||||
unsafe {
|
||||
c.set_len(::dim::<M>() - 1);
|
||||
s.set_len(::dim::<M>() - 1);
|
||||
c.set_len(::dimension::<M>() - 1);
|
||||
s.set_len(::dimension::<M>() - 1);
|
||||
}
|
||||
|
||||
let mut iter = 0;
|
||||
let mut curdim = ::dim::<M>() - 1;
|
||||
let mut curdim = ::dimension::<M>() - 1;
|
||||
|
||||
for _ in 0 .. ::dim::<M>() {
|
||||
for _ in 0 .. ::dimension::<M>() {
|
||||
|
||||
let mut stop = false;
|
||||
|
||||
|
@ -113,12 +113,12 @@ pub fn eigen_qr<N, V, VS, M>(m: &M, eps: &N, niter: usize) -> (M, V)
|
|||
let d = eigenvalues.unsafe_at((curdim, curdim));
|
||||
|
||||
let trace = a + d;
|
||||
let det = a * d - b * c;
|
||||
let determinant = a * d - b * c;
|
||||
|
||||
let constquarter: N = Cast::from(0.25f64);
|
||||
let consthalf: N = Cast::from(0.5f64);
|
||||
|
||||
let e = (constquarter * trace * trace - det).sqrt();
|
||||
let e = (constquarter * trace * trace - determinant).sqrt();
|
||||
|
||||
let lambda1 = consthalf * trace + e;
|
||||
let lambda2 = consthalf * trace - e;
|
||||
|
@ -207,7 +207,7 @@ pub fn eigen_qr<N, V, VS, M>(m: &M, eps: &N, niter: usize) -> (M, V)
|
|||
|
||||
// Givens rotation from right applied to eigenvectors
|
||||
for k in 0 .. curdim {
|
||||
for i in 0 .. ::dim::<M>() {
|
||||
for i in 0 .. ::dimension::<M>() {
|
||||
|
||||
unsafe {
|
||||
let a = eigenvectors.unsafe_at((i, k));
|
||||
|
@ -254,7 +254,7 @@ pub fn eigen_qr<N, V, VS, M>(m: &M, eps: &N, niter: usize) -> (M, V)
|
|||
|
||||
}
|
||||
|
||||
(eigenvectors, eigenvalues.diag())
|
||||
(eigenvectors, eigenvalues.diagonal())
|
||||
}
|
||||
|
||||
/// Cholesky decomposition G of a square symmetric positive definite matrix A, such that A = G * G^T
|
||||
|
@ -265,8 +265,8 @@ pub fn cholesky<N, V, VS, M>(m: &M) -> Result<M, &'static str>
|
|||
where N: BaseFloat,
|
||||
V: Mul<M, Output = V>,
|
||||
VS: Indexable<usize, N> + Norm<N>,
|
||||
M: Indexable<(usize, usize), N> + SquareMat<N, V> + Add<M, Output = M> +
|
||||
Sub<M, Output = M> + ColSlice<VS> +
|
||||
M: Indexable<(usize, usize), N> + SquareMatrix<N, V> + Add<M, Output = M> +
|
||||
Sub<M, Output = M> + ColumnSlice<VS> +
|
||||
ApproxEq<N> + Copy {
|
||||
|
||||
let mut out = m.clone().transpose();
|
||||
|
@ -317,7 +317,7 @@ pub fn cholesky<N, V, VS, M>(m: &M) -> Result<M, &'static str>
|
|||
pub fn hessenberg<N, V, M>(m: &M) -> (M, M)
|
||||
where N: BaseFloat,
|
||||
V: Indexable<usize, N> + Norm<N>,
|
||||
M: Copy + Eye + ColSlice<V> + Transpose + Indexable<(usize, usize), N> +
|
||||
M: Copy + Eye + ColumnSlice<V> + Transpose + Indexable<(usize, usize), N> +
|
||||
Mul<M, Output = M> {
|
||||
|
||||
let mut h = m.clone();
|
||||
|
|
|
@ -7,41 +7,41 @@ use std::ops::{Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, Index, Index
|
|||
use std::fmt::{Debug, Formatter, Result};
|
||||
use rand::{self, Rand};
|
||||
use num::{Zero, One};
|
||||
use structs::dvec::{DVec, DVec1, DVec2, DVec3, DVec4, DVec5, DVec6};
|
||||
use traits::operations::{ApproxEq, Inv, Transpose, Mean, Cov};
|
||||
use traits::structure::{Cast, Col, ColSlice, Row, RowSlice, Diag, DiagMut, Eye, Indexable, Shape, BaseNum};
|
||||
use structs::dvector::{DVector, DVector1, DVector2, DVector3, DVector4, DVector5, DVector6};
|
||||
use traits::operations::{ApproxEq, Inverse, Transpose, Mean, Covariance};
|
||||
use traits::structure::{Cast, Column, ColumnSlice, Row, RowSlice, Diagonal, DiagMut, Eye, Indexable, Shape, BaseNum};
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// Matrix with dimensions unknown at compile-time.
|
||||
#[derive(Eq, PartialEq, Clone)]
|
||||
pub struct DMat<N> {
|
||||
pub struct DMatrix<N> {
|
||||
nrows: usize,
|
||||
ncols: usize,
|
||||
mij: Vec<N>
|
||||
}
|
||||
|
||||
impl<N> DMat<N> {
|
||||
impl<N> DMatrix<N> {
|
||||
/// Creates an uninitialized matrix.
|
||||
#[inline]
|
||||
pub unsafe fn new_uninitialized(nrows: usize, ncols: usize) -> DMat<N> {
|
||||
let mut vec = Vec::with_capacity(nrows * ncols);
|
||||
vec.set_len(nrows * ncols);
|
||||
pub unsafe fn new_uninitialized(nrows: usize, ncols: usize) -> DMatrix<N> {
|
||||
let mut vector = Vec::with_capacity(nrows * ncols);
|
||||
vector.set_len(nrows * ncols);
|
||||
|
||||
DMat {
|
||||
DMatrix {
|
||||
nrows: nrows,
|
||||
ncols: ncols,
|
||||
mij: vec
|
||||
mij: vector
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Copy> DMat<N> {
|
||||
impl<N: Clone + Copy> DMatrix<N> {
|
||||
/// Builds a matrix filled with a given constant.
|
||||
#[inline]
|
||||
pub fn from_elem(nrows: usize, ncols: usize, val: N) -> DMat<N> {
|
||||
DMat {
|
||||
pub fn from_elem(nrows: usize, ncols: usize, val: N) -> DMatrix<N> {
|
||||
DMatrix {
|
||||
nrows: nrows,
|
||||
ncols: ncols,
|
||||
mij: repeat(val).take(nrows * ncols).collect()
|
||||
|
@ -50,35 +50,35 @@ impl<N: Clone + Copy> DMat<N> {
|
|||
|
||||
/// Builds a matrix filled with the components provided by a vector.
|
||||
/// The vector contains the matrix data in row-major order.
|
||||
/// Note that `from_col_vec` is much faster than `from_row_vec` since a `DMat` stores its data
|
||||
/// Note that `from_col_vector` is much faster than `from_row_vector` since a `DMatrix` stores its data
|
||||
/// in column-major order.
|
||||
///
|
||||
/// The vector must have exactly `nrows * ncols` elements.
|
||||
#[inline]
|
||||
pub fn from_row_vec(nrows: usize, ncols: usize, vec: &[N]) -> DMat<N> {
|
||||
DMat::from_row_iter(nrows, ncols, vec.to_vec())
|
||||
pub fn from_row_vector(nrows: usize, ncols: usize, vector: &[N]) -> DMatrix<N> {
|
||||
DMatrix::from_row_iter(nrows, ncols, vector.to_vec())
|
||||
}
|
||||
|
||||
/// Builds a matrix filled with the components provided by a vector.
|
||||
/// The vector contains the matrix data in column-major order.
|
||||
/// Note that `from_col_vec` is much faster than `from_row_vec` since a `DMat` stores its data
|
||||
/// Note that `from_col_vector` is much faster than `from_row_vector` since a `DMatrix` stores its data
|
||||
/// in column-major order.
|
||||
///
|
||||
/// The vector must have exactly `nrows * ncols` elements.
|
||||
#[inline]
|
||||
pub fn from_col_vec(nrows: usize, ncols: usize, vec: &[N]) -> DMat<N> {
|
||||
DMat::from_col_iter(nrows, ncols, vec.to_vec())
|
||||
pub fn from_col_vector(nrows: usize, ncols: usize, vector: &[N]) -> DMatrix<N> {
|
||||
DMatrix::from_col_iter(nrows, ncols, vector.to_vec())
|
||||
}
|
||||
|
||||
/// Builds a matrix filled with the components provided by a source that may be moved into an iterator.
|
||||
/// The source contains the matrix data in row-major order.
|
||||
/// Note that `from_col_iter` is much faster than `from_row_iter` since a `DMat` stores its data
|
||||
/// Note that `from_col_iter` is much faster than `from_row_iter` since a `DMatrix` stores its data
|
||||
/// in column-major order.
|
||||
///
|
||||
/// The source must have exactly `nrows * ncols` elements.
|
||||
#[inline]
|
||||
pub fn from_row_iter<I: IntoIterator<Item = N>>(nrows: usize, ncols: usize, param: I) -> DMat<N> {
|
||||
let mut res = DMat::from_col_iter(ncols, nrows, param);
|
||||
pub fn from_row_iter<I: IntoIterator<Item = N>>(nrows: usize, ncols: usize, param: I) -> DMatrix<N> {
|
||||
let mut res = DMatrix::from_col_iter(ncols, nrows, param);
|
||||
|
||||
// we transpose because the buffer is row_major
|
||||
res.transpose_mut();
|
||||
|
@ -89,17 +89,17 @@ impl<N: Clone + Copy> DMat<N> {
|
|||
|
||||
/// Builds a matrix filled with the components provided by a source that may be moved into an iterator.
|
||||
/// The source contains the matrix data in column-major order.
|
||||
/// Note that `from_col_iter` is much faster than `from_row_iter` since a `DMat` stores its data
|
||||
/// Note that `from_col_iter` is much faster than `from_row_iter` since a `DMatrix` stores its data
|
||||
/// in column-major order.
|
||||
///
|
||||
/// The source must have exactly `nrows * ncols` elements.
|
||||
#[inline]
|
||||
pub fn from_col_iter<I: IntoIterator<Item = N>>(nrows: usize, ncols: usize, param: I) -> DMat<N> {
|
||||
pub fn from_col_iter<I: IntoIterator<Item = N>>(nrows: usize, ncols: usize, param: I) -> DMatrix<N> {
|
||||
let mij: Vec<N> = param.into_iter().collect();
|
||||
|
||||
assert!(nrows * ncols == mij.len(), "The ammount of data provided does not matches the matrix size.");
|
||||
|
||||
DMat {
|
||||
DMatrix {
|
||||
nrows: nrows,
|
||||
ncols: ncols,
|
||||
mij: mij
|
||||
|
@ -107,11 +107,11 @@ impl<N: Clone + Copy> DMat<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N> DMat<N> {
|
||||
impl<N> DMatrix<N> {
|
||||
/// Builds a matrix filled with the results of a function applied to each of its component coordinates.
|
||||
#[inline(always)]
|
||||
pub fn from_fn<F: FnMut(usize, usize) -> N>(nrows: usize, ncols: usize, mut f: F) -> DMat<N> {
|
||||
DMat {
|
||||
pub fn from_fn<F: FnMut(usize, usize) -> N>(nrows: usize, ncols: usize, mut f: F) -> DMatrix<N> {
|
||||
DMatrix {
|
||||
nrows: nrows,
|
||||
ncols: ncols,
|
||||
mij: (0 .. nrows * ncols).map(|i| { let m = i / nrows; f(i - m * nrows, m) }).collect()
|
||||
|
@ -121,83 +121,83 @@ impl<N> DMat<N> {
|
|||
/// Transforms this matrix into an array. This consumes the matrix and is O(1).
|
||||
/// The returned vector contains the matrix data in column-major order.
|
||||
#[inline]
|
||||
pub fn into_vec(self) -> Vec<N> {
|
||||
pub fn into_vector(self) -> Vec<N> {
|
||||
self.mij
|
||||
}
|
||||
}
|
||||
|
||||
dmat_impl!(DMat, DVec);
|
||||
dmat_impl!(DMatrix, DVector);
|
||||
|
||||
|
||||
/// A stack-allocated dynamically sized matrix with at most one row and column.
|
||||
pub struct DMat1<N> {
|
||||
pub struct DMatrix1<N> {
|
||||
nrows: usize,
|
||||
ncols: usize,
|
||||
mij: [N; 1 * 1],
|
||||
}
|
||||
|
||||
small_dmat_impl!(DMat1, DVec1, 1, 0);
|
||||
small_dmat_from_impl!(DMat1, 1, ::zero());
|
||||
small_dmat_impl!(DMatrix1, DVector1, 1, 0);
|
||||
small_dmat_from_impl!(DMatrix1, 1, ::zero());
|
||||
|
||||
|
||||
/// A stack-allocated dynamically sized square or rectangular matrix with at most 2 rows and columns.
|
||||
pub struct DMat2<N> {
|
||||
pub struct DMatrix2<N> {
|
||||
nrows: usize,
|
||||
ncols: usize,
|
||||
mij: [N; 2 * 2],
|
||||
}
|
||||
|
||||
small_dmat_impl!(DMat2, DVec2, 2, 0, 1,
|
||||
small_dmat_impl!(DMatrix2, DVector2, 2, 0, 1,
|
||||
2, 3);
|
||||
small_dmat_from_impl!(DMat2, 2, ::zero(), ::zero(),
|
||||
small_dmat_from_impl!(DMatrix2, 2, ::zero(), ::zero(),
|
||||
::zero(), ::zero());
|
||||
|
||||
|
||||
/// A stack-allocated dynamically sized square or rectangular matrix with at most 3 rows and columns.
|
||||
pub struct DMat3<N> {
|
||||
pub struct DMatrix3<N> {
|
||||
nrows: usize,
|
||||
ncols: usize,
|
||||
mij: [N; 3 * 3],
|
||||
}
|
||||
|
||||
small_dmat_impl!(DMat3, DVec3, 3, 0, 1, 2,
|
||||
small_dmat_impl!(DMatrix3, DVector3, 3, 0, 1, 2,
|
||||
3, 4, 5,
|
||||
6, 7, 8);
|
||||
small_dmat_from_impl!(DMat3, 3, ::zero(), ::zero(), ::zero(),
|
||||
small_dmat_from_impl!(DMatrix3, 3, ::zero(), ::zero(), ::zero(),
|
||||
::zero(), ::zero(), ::zero(),
|
||||
::zero(), ::zero(), ::zero());
|
||||
|
||||
|
||||
/// A stack-allocated dynamically sized square or rectangular matrix with at most 4 rows and columns.
|
||||
pub struct DMat4<N> {
|
||||
pub struct DMatrix4<N> {
|
||||
nrows: usize,
|
||||
ncols: usize,
|
||||
mij: [N; 4 * 4],
|
||||
}
|
||||
|
||||
small_dmat_impl!(DMat4, DVec4, 4, 0, 1, 2, 3,
|
||||
small_dmat_impl!(DMatrix4, DVector4, 4, 0, 1, 2, 3,
|
||||
4, 5, 6, 7,
|
||||
8, 9, 10, 11,
|
||||
12, 13, 14, 15);
|
||||
small_dmat_from_impl!(DMat4, 4, ::zero(), ::zero(), ::zero(), ::zero(),
|
||||
small_dmat_from_impl!(DMatrix4, 4, ::zero(), ::zero(), ::zero(), ::zero(),
|
||||
::zero(), ::zero(), ::zero(), ::zero(),
|
||||
::zero(), ::zero(), ::zero(), ::zero(),
|
||||
::zero(), ::zero(), ::zero(), ::zero());
|
||||
|
||||
|
||||
/// A stack-allocated dynamically sized square or rectangular matrix with at most 5 rows and columns.
|
||||
pub struct DMat5<N> {
|
||||
pub struct DMatrix5<N> {
|
||||
nrows: usize,
|
||||
ncols: usize,
|
||||
mij: [N; 5 * 5],
|
||||
}
|
||||
|
||||
small_dmat_impl!(DMat5, DVec5, 5, 0, 1, 2, 3, 4,
|
||||
small_dmat_impl!(DMatrix5, DVector5, 5, 0, 1, 2, 3, 4,
|
||||
5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24);
|
||||
small_dmat_from_impl!(DMat5, 5, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
|
||||
small_dmat_from_impl!(DMatrix5, 5, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
|
||||
::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
|
||||
::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
|
||||
::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
|
||||
|
@ -205,19 +205,19 @@ small_dmat_from_impl!(DMat5, 5, ::zero(), ::zero(), ::zero(), ::zero(), ::zero()
|
|||
|
||||
|
||||
/// A stack-allocated dynamically sized square or rectangular matrix with at most 6 rows and columns.
|
||||
pub struct DMat6<N> {
|
||||
pub struct DMatrix6<N> {
|
||||
nrows: usize,
|
||||
ncols: usize,
|
||||
mij: [N; 6 * 6],
|
||||
}
|
||||
|
||||
small_dmat_impl!(DMat6, DVec6, 6, 0, 1, 2, 3, 4, 5,
|
||||
small_dmat_impl!(DMatrix6, DVector6, 6, 0, 1, 2, 3, 4, 5,
|
||||
6, 7, 8, 9, 10, 11,
|
||||
12, 13, 14, 15, 16, 17,
|
||||
18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35);
|
||||
small_dmat_from_impl!(DMat6, 6, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
|
||||
small_dmat_from_impl!(DMatrix6, 6, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
|
||||
::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
|
||||
::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
|
||||
::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(),
|
File diff suppressed because it is too large
Load Diff
|
@ -1,164 +0,0 @@
|
|||
//! Vector with dimensions unknown at compile-time.
|
||||
|
||||
use std::slice::{Iter, IterMut};
|
||||
use std::iter::{FromIterator, IntoIterator};
|
||||
use std::iter::repeat;
|
||||
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
|
||||
use std::mem;
|
||||
use rand::{self, Rand};
|
||||
use num::{Zero, One};
|
||||
use structs::DMat;
|
||||
use traits::operations::{ApproxEq, Axpy, Mean, Outer};
|
||||
use traits::geometry::{Dot, Norm};
|
||||
use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat, BaseNum, Cast};
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
/// Heap allocated, dynamically sized vector.
|
||||
#[derive(Eq, PartialEq, Debug, Clone)]
|
||||
pub struct DVec<N> {
|
||||
/// Components of the vector. Contains as much elements as the vector dimension.
|
||||
pub at: Vec<N>
|
||||
}
|
||||
|
||||
impl<N> DVec<N> {
|
||||
/// Creates an uninitialized vec.
|
||||
#[inline]
|
||||
pub unsafe fn new_uninitialized(dim: usize) -> DVec<N> {
|
||||
let mut vec = Vec::with_capacity(dim);
|
||||
vec.set_len(dim);
|
||||
|
||||
DVec {
|
||||
at: vec
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone> DVec<N> {
|
||||
/// Builds a vector filled with a constant.
|
||||
#[inline]
|
||||
pub fn from_elem(dim: usize, elem: N) -> DVec<N> {
|
||||
DVec { at: repeat(elem).take(dim).collect() }
|
||||
}
|
||||
|
||||
/// Builds a vector filled with the components provided by a vector.
|
||||
///
|
||||
/// The vector must have at least `dim` elements.
|
||||
#[inline]
|
||||
pub fn from_slice(dim: usize, vec: &[N]) -> DVec<N> {
|
||||
assert!(dim <= vec.len());
|
||||
|
||||
DVec {
|
||||
at: vec[.. dim].to_vec()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> DVec<N> {
|
||||
/// Builds a vector filled with the results of a function applied to each of its component coordinates.
|
||||
#[inline(always)]
|
||||
pub fn from_fn<F: FnMut(usize) -> N>(dim: usize, mut f: F) -> DVec<N> {
|
||||
DVec { at: (0 .. dim).map(|i| f(i)).collect() }
|
||||
}
|
||||
|
||||
/// The vector length.
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
self.at.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> FromIterator<N> for DVec<N> {
|
||||
#[inline]
|
||||
fn from_iter<I: IntoIterator<Item = N>>(param: I) -> DVec<N> {
|
||||
DVec { at: param.into_iter().collect() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + BaseNum> Outer for DVec<N> {
|
||||
type OuterProductType = DMat<N>;
|
||||
|
||||
#[inline]
|
||||
fn outer(&self, other: &DVec<N>) -> DMat<N> {
|
||||
let mut res = unsafe { DMat::new_uninitialized(self.at.len(), other.at.len()) };
|
||||
|
||||
for i in 0 .. self.at.len() {
|
||||
for j in 0 .. other.at.len() {
|
||||
unsafe {
|
||||
res.unsafe_set((i, j), self.unsafe_at(i) * other.unsafe_at(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary> Arbitrary for DVec<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> DVec<N> {
|
||||
DVec { at: Arbitrary::arbitrary(g) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dvec_impl!(DVec);
|
||||
|
||||
/// Stack-allocated, dynamically sized vector with a maximum size of 1.
|
||||
pub struct DVec1<N> {
|
||||
at: [N; 1],
|
||||
dim: usize
|
||||
}
|
||||
|
||||
small_dvec_impl!(DVec1, 1, 0);
|
||||
small_dvec_from_impl!(DVec1, 1, ::zero());
|
||||
|
||||
|
||||
/// Stack-allocated, dynamically sized vector with a maximum size of 2.
|
||||
pub struct DVec2<N> {
|
||||
at: [N; 2],
|
||||
dim: usize
|
||||
}
|
||||
|
||||
small_dvec_impl!(DVec2, 2, 0, 1);
|
||||
small_dvec_from_impl!(DVec2, 2, ::zero(), ::zero());
|
||||
|
||||
|
||||
/// Stack-allocated, dynamically sized vector with a maximum size of 3.
|
||||
pub struct DVec3<N> {
|
||||
at: [N; 3],
|
||||
dim: usize
|
||||
}
|
||||
|
||||
small_dvec_impl!(DVec3, 3, 0, 1, 2);
|
||||
small_dvec_from_impl!(DVec3, 3, ::zero(), ::zero(), ::zero());
|
||||
|
||||
|
||||
/// Stack-allocated, dynamically sized vector with a maximum size of 4.
|
||||
pub struct DVec4<N> {
|
||||
at: [N; 4],
|
||||
dim: usize
|
||||
}
|
||||
|
||||
small_dvec_impl!(DVec4, 4, 0, 1, 2, 3);
|
||||
small_dvec_from_impl!(DVec4, 4, ::zero(), ::zero(), ::zero(), ::zero());
|
||||
|
||||
|
||||
/// Stack-allocated, dynamically sized vector with a maximum size of 5.
|
||||
pub struct DVec5<N> {
|
||||
at: [N; 5],
|
||||
dim: usize
|
||||
}
|
||||
|
||||
small_dvec_impl!(DVec5, 5, 0, 1, 2, 3, 4);
|
||||
small_dvec_from_impl!(DVec5, 5, ::zero(), ::zero(), ::zero(), ::zero(), ::zero());
|
||||
|
||||
|
||||
/// Stack-allocated, dynamically sized vector with a maximum size of 6.
|
||||
pub struct DVec6<N> {
|
||||
at: [N; 6],
|
||||
dim: usize
|
||||
}
|
||||
|
||||
small_dvec_impl!(DVec6, 6, 0, 1, 2, 3, 4, 5);
|
||||
small_dvec_from_impl!(DVec6, 6, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero());
|
|
@ -1,243 +0,0 @@
|
|||
#![macro_use]
|
||||
|
||||
macro_rules! dvec_impl(
|
||||
($dvec: ident) => (
|
||||
vecn_dvec_common_impl!($dvec);
|
||||
|
||||
impl<N: Zero + Copy + Clone> $dvec<N> {
|
||||
/// Builds a vector filled with zeros.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `dim` - The dimension of the vector.
|
||||
#[inline]
|
||||
pub fn new_zeros(dim: usize) -> $dvec<N> {
|
||||
$dvec::from_elem(dim, ::zero())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: One + Zero + Copy + Clone> $dvec<N> {
|
||||
/// Builds a vector filled with ones.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `dim` - The dimension of the vector.
|
||||
#[inline]
|
||||
pub fn new_ones(dim: usize) -> $dvec<N> {
|
||||
$dvec::from_elem(dim, ::one())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Rand + Zero> $dvec<N> {
|
||||
/// Builds a vector filled with random values.
|
||||
#[inline]
|
||||
pub fn new_random(dim: usize) -> $dvec<N> {
|
||||
$dvec::from_fn(dim, |_| rand::random())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + ApproxEq<N>> $dvec<N> {
|
||||
/// Computes the canonical basis for the given dimension. A canonical basis is a set of
|
||||
/// vectors, mutually orthogonal, with all its component equal to 0.0 except one which is equal
|
||||
/// to 1.0.
|
||||
pub fn canonical_basis_with_dim(dim: usize) -> Vec<$dvec<N>> {
|
||||
let mut res : Vec<$dvec<N>> = Vec::new();
|
||||
|
||||
for i in 0 .. dim {
|
||||
let mut basis_element : $dvec<N> = $dvec::new_zeros(dim);
|
||||
|
||||
basis_element[i] = ::one();
|
||||
|
||||
res.push(basis_element);
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
/// Computes a basis of the space orthogonal to the vector. If the input vector is of dimension
|
||||
/// `n`, this will return `n - 1` vectors.
|
||||
pub fn orthogonal_subspace_basis(&self) -> Vec<$dvec<N>> {
|
||||
// compute the basis of the orthogonal subspace using Gram-Schmidt
|
||||
// orthogonalization algorithm
|
||||
let dim = self.len();
|
||||
let mut res : Vec<$dvec<N>> = Vec::new();
|
||||
|
||||
for i in 0 .. dim {
|
||||
let mut basis_element : $dvec<N> = $dvec::new_zeros(self.len());
|
||||
|
||||
basis_element[i] = ::one();
|
||||
|
||||
if res.len() == dim - 1 {
|
||||
break;
|
||||
}
|
||||
|
||||
let mut elt = basis_element.clone();
|
||||
|
||||
elt.axpy(&-::dot(&basis_element, self), self);
|
||||
|
||||
for v in res.iter() {
|
||||
let proj = ::dot(&elt, v);
|
||||
elt.axpy(&-proj, v)
|
||||
};
|
||||
|
||||
if !ApproxEq::approx_eq(&Norm::sqnorm(&elt), &::zero()) {
|
||||
res.push(Norm::normalize(&elt));
|
||||
}
|
||||
}
|
||||
|
||||
assert!(res.len() == dim - 1);
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! small_dvec_impl (
|
||||
($dvec: ident, $dim: expr, $($idx: expr),*) => (
|
||||
dvec_impl!($dvec);
|
||||
|
||||
impl<N> $dvec<N> {
|
||||
/// The number of elements of this vector.
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
self.dim
|
||||
}
|
||||
|
||||
/// Creates an uninitialized vec of dimension `dim`.
|
||||
#[inline]
|
||||
pub unsafe fn new_uninitialized(dim: usize) -> $dvec<N> {
|
||||
assert!(dim <= $dim, "The chosen dimension is too high for that type of \
|
||||
stack-allocated dynamic vector. Consider using the \
|
||||
heap-allocated vector: DVec.");
|
||||
|
||||
$dvec {
|
||||
at: mem::uninitialized(),
|
||||
dim: dim
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: PartialEq> PartialEq for $dvec<N> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &$dvec<N>) -> bool {
|
||||
if self.len() != other.len() {
|
||||
return false; // FIXME: fail instead?
|
||||
}
|
||||
|
||||
for (a, b) in self.as_ref().iter().zip(other.as_ref().iter()) {
|
||||
if *a != *b {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone> Clone for $dvec<N> {
|
||||
fn clone(&self) -> $dvec<N> {
|
||||
let at: [N; $dim] = [ $( self.at[$idx].clone(), )* ];
|
||||
|
||||
$dvec {
|
||||
at: at,
|
||||
dim: self.dim
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! small_dvec_from_impl (
|
||||
($dvec: ident, $dim: expr, $($zeros: expr),*) => (
|
||||
impl<N: Copy + Zero> $dvec<N> {
|
||||
/// Builds a vector filled with a constant.
|
||||
#[inline]
|
||||
pub fn from_elem(dim: usize, elem: N) -> $dvec<N> {
|
||||
assert!(dim <= $dim);
|
||||
|
||||
let mut at: [N; $dim] = [ $( $zeros, )* ];
|
||||
|
||||
for n in &mut at[.. dim] {
|
||||
*n = elem;
|
||||
}
|
||||
|
||||
$dvec {
|
||||
at: at,
|
||||
dim: dim
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Zero> $dvec<N> {
|
||||
/// Builds a vector filled with the components provided by a vector.
|
||||
///
|
||||
/// The vector must have at least `dim` elements.
|
||||
#[inline]
|
||||
pub fn from_slice(dim: usize, vec: &[N]) -> $dvec<N> {
|
||||
assert!(dim <= vec.len() && dim <= $dim);
|
||||
|
||||
// FIXME: not safe.
|
||||
let mut at: [N; $dim] = [ $( $zeros, )* ];
|
||||
|
||||
for (curr, other) in vec.iter().zip(at.iter_mut()) {
|
||||
*other = *curr;
|
||||
}
|
||||
|
||||
$dvec {
|
||||
at: at,
|
||||
dim: dim
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Zero> $dvec<N> {
|
||||
/// Builds a vector filled with the result of a function.
|
||||
#[inline(always)]
|
||||
pub fn from_fn<F: FnMut(usize) -> N>(dim: usize, mut f: F) -> $dvec<N> {
|
||||
assert!(dim <= $dim);
|
||||
|
||||
let mut at: [N; $dim] = [ $( $zeros, )* ];
|
||||
|
||||
for i in 0 .. dim {
|
||||
at[i] = f(i);
|
||||
}
|
||||
|
||||
$dvec {
|
||||
at: at,
|
||||
dim: dim
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Zero> FromIterator<N> for $dvec<N> {
|
||||
#[inline]
|
||||
fn from_iter<I: IntoIterator<Item = N>>(param: I) -> $dvec<N> {
|
||||
let mut at: [N; $dim] = [ $( $zeros, )* ];
|
||||
|
||||
let mut dim = 0;
|
||||
|
||||
for n in param.into_iter() {
|
||||
if dim == $dim {
|
||||
break;
|
||||
}
|
||||
|
||||
at[dim] = n;
|
||||
|
||||
dim = dim + 1;
|
||||
}
|
||||
|
||||
$dvec {
|
||||
at: at,
|
||||
dim: dim
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + Zero> Arbitrary for $dvec<N> {
|
||||
#[inline]
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> $dvec<N> {
|
||||
$dvec::from_fn(g.gen_range(0, $dim), |_| Arbitrary::arbitrary(g))
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
|
@ -0,0 +1,164 @@
|
|||
//! Vector with dimensions unknown at compile-time.
|
||||
|
||||
use std::slice::{Iter, IterMut};
|
||||
use std::iter::{FromIterator, IntoIterator};
|
||||
use std::iter::repeat;
|
||||
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
|
||||
use std::mem;
|
||||
use rand::{self, Rand};
|
||||
use num::{Zero, One};
|
||||
use structs::DMatrix;
|
||||
use traits::operations::{ApproxEq, Axpy, Mean, Outer};
|
||||
use traits::geometry::{Dot, Norm};
|
||||
use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat, BaseNum, Cast};
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
/// Heap allocated, dynamically sized vector.
|
||||
#[derive(Eq, PartialEq, Debug, Clone)]
|
||||
pub struct DVector<N> {
|
||||
/// Components of the vector. Contains as much elements as the vector dimension.
|
||||
pub at: Vec<N>
|
||||
}
|
||||
|
||||
impl<N> DVector<N> {
|
||||
/// Creates an uninitialized vector.
|
||||
#[inline]
|
||||
pub unsafe fn new_uninitialized(dimension: usize) -> DVector<N> {
|
||||
let mut vector = Vec::with_capacity(dimension);
|
||||
vector.set_len(dimension);
|
||||
|
||||
DVector {
|
||||
at: vector
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone> DVector<N> {
|
||||
/// Builds a vector filled with a constant.
|
||||
#[inline]
|
||||
pub fn from_elem(dimension: usize, elem: N) -> DVector<N> {
|
||||
DVector { at: repeat(elem).take(dimension).collect() }
|
||||
}
|
||||
|
||||
/// Builds a vector filled with the components provided by a vector.
|
||||
///
|
||||
/// The vector must have at least `dimension` elements.
|
||||
#[inline]
|
||||
pub fn from_slice(dimension: usize, vector: &[N]) -> DVector<N> {
|
||||
assert!(dimension <= vector.len());
|
||||
|
||||
DVector {
|
||||
at: vector[.. dimension].to_vec()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> DVector<N> {
|
||||
/// Builds a vector filled with the results of a function applied to each of its component coordinates.
|
||||
#[inline(always)]
|
||||
pub fn from_fn<F: FnMut(usize) -> N>(dimension: usize, mut f: F) -> DVector<N> {
|
||||
DVector { at: (0 .. dimension).map(|i| f(i)).collect() }
|
||||
}
|
||||
|
||||
/// The vector length.
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
self.at.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> FromIterator<N> for DVector<N> {
|
||||
#[inline]
|
||||
fn from_iter<I: IntoIterator<Item = N>>(param: I) -> DVector<N> {
|
||||
DVector { at: param.into_iter().collect() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + BaseNum> Outer for DVector<N> {
|
||||
type OuterProductType = DMatrix<N>;
|
||||
|
||||
#[inline]
|
||||
fn outer(&self, other: &DVector<N>) -> DMatrix<N> {
|
||||
let mut res = unsafe { DMatrix::new_uninitialized(self.at.len(), other.at.len()) };
|
||||
|
||||
for i in 0 .. self.at.len() {
|
||||
for j in 0 .. other.at.len() {
|
||||
unsafe {
|
||||
res.unsafe_set((i, j), self.unsafe_at(i) * other.unsafe_at(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary> Arbitrary for DVector<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> DVector<N> {
|
||||
DVector { at: Arbitrary::arbitrary(g) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dvec_impl!(DVector);
|
||||
|
||||
/// Stack-allocated, dynamically sized vector with a maximum size of 1.
|
||||
pub struct DVector1<N> {
|
||||
at: [N; 1],
|
||||
dimension: usize
|
||||
}
|
||||
|
||||
small_dvec_impl!(DVector1, 1, 0);
|
||||
small_dvec_from_impl!(DVector1, 1, ::zero());
|
||||
|
||||
|
||||
/// Stack-allocated, dynamically sized vector with a maximum size of 2.
|
||||
pub struct DVector2<N> {
|
||||
at: [N; 2],
|
||||
dimension: usize
|
||||
}
|
||||
|
||||
small_dvec_impl!(DVector2, 2, 0, 1);
|
||||
small_dvec_from_impl!(DVector2, 2, ::zero(), ::zero());
|
||||
|
||||
|
||||
/// Stack-allocated, dynamically sized vector with a maximum size of 3.
|
||||
pub struct DVector3<N> {
|
||||
at: [N; 3],
|
||||
dimension: usize
|
||||
}
|
||||
|
||||
small_dvec_impl!(DVector3, 3, 0, 1, 2);
|
||||
small_dvec_from_impl!(DVector3, 3, ::zero(), ::zero(), ::zero());
|
||||
|
||||
|
||||
/// Stack-allocated, dynamically sized vector with a maximum size of 4.
|
||||
pub struct DVector4<N> {
|
||||
at: [N; 4],
|
||||
dimension: usize
|
||||
}
|
||||
|
||||
small_dvec_impl!(DVector4, 4, 0, 1, 2, 3);
|
||||
small_dvec_from_impl!(DVector4, 4, ::zero(), ::zero(), ::zero(), ::zero());
|
||||
|
||||
|
||||
/// Stack-allocated, dynamically sized vector with a maximum size of 5.
|
||||
pub struct DVector5<N> {
|
||||
at: [N; 5],
|
||||
dimension: usize
|
||||
}
|
||||
|
||||
small_dvec_impl!(DVector5, 5, 0, 1, 2, 3, 4);
|
||||
small_dvec_from_impl!(DVector5, 5, ::zero(), ::zero(), ::zero(), ::zero(), ::zero());
|
||||
|
||||
|
||||
/// Stack-allocated, dynamically sized vector with a maximum size of 6.
|
||||
pub struct DVector6<N> {
|
||||
at: [N; 6],
|
||||
dimension: usize
|
||||
}
|
||||
|
||||
small_dvec_impl!(DVector6, 6, 0, 1, 2, 3, 4, 5);
|
||||
small_dvec_from_impl!(DVector6, 6, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero());
|
|
@ -0,0 +1,243 @@
|
|||
#![macro_use]
|
||||
|
||||
macro_rules! dvec_impl(
|
||||
($dvector: ident) => (
|
||||
vecn_dvec_common_impl!($dvector);
|
||||
|
||||
impl<N: Zero + Copy + Clone> $dvector<N> {
|
||||
/// Builds a vector filled with zeros.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `dimension` - The dimension of the vector.
|
||||
#[inline]
|
||||
pub fn new_zeros(dimension: usize) -> $dvector<N> {
|
||||
$dvector::from_elem(dimension, ::zero())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: One + Zero + Copy + Clone> $dvector<N> {
|
||||
/// Builds a vector filled with ones.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `dimension` - The dimension of the vector.
|
||||
#[inline]
|
||||
pub fn new_ones(dimension: usize) -> $dvector<N> {
|
||||
$dvector::from_elem(dimension, ::one())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Rand + Zero> $dvector<N> {
|
||||
/// Builds a vector filled with random values.
|
||||
#[inline]
|
||||
pub fn new_random(dimension: usize) -> $dvector<N> {
|
||||
$dvector::from_fn(dimension, |_| rand::random())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + ApproxEq<N>> $dvector<N> {
|
||||
/// Computes the canonical basis for the given dimension. A canonical basis is a set of
|
||||
/// vectors, mutually orthogonal, with all its component equal to 0.0 except one which is equal
|
||||
/// to 1.0.
|
||||
pub fn canonical_basis_with_dim(dimension: usize) -> Vec<$dvector<N>> {
|
||||
let mut res : Vec<$dvector<N>> = Vec::new();
|
||||
|
||||
for i in 0 .. dimension {
|
||||
let mut basis_element : $dvector<N> = $dvector::new_zeros(dimension);
|
||||
|
||||
basis_element[i] = ::one();
|
||||
|
||||
res.push(basis_element);
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
/// Computes a basis of the space orthogonal to the vector. If the input vector is of dimension
|
||||
/// `n`, this will return `n - 1` vectors.
|
||||
pub fn orthogonal_subspace_basis(&self) -> Vec<$dvector<N>> {
|
||||
// compute the basis of the orthogonal subspace using Gram-Schmidt
|
||||
// orthogonalization algorithm
|
||||
let dimension = self.len();
|
||||
let mut res : Vec<$dvector<N>> = Vec::new();
|
||||
|
||||
for i in 0 .. dimension {
|
||||
let mut basis_element : $dvector<N> = $dvector::new_zeros(self.len());
|
||||
|
||||
basis_element[i] = ::one();
|
||||
|
||||
if res.len() == dimension - 1 {
|
||||
break;
|
||||
}
|
||||
|
||||
let mut elt = basis_element.clone();
|
||||
|
||||
elt.axpy(&-::dot(&basis_element, self), self);
|
||||
|
||||
for v in res.iter() {
|
||||
let proj = ::dot(&elt, v);
|
||||
elt.axpy(&-proj, v)
|
||||
};
|
||||
|
||||
if !ApproxEq::approx_eq(&Norm::norm_squared(&elt), &::zero()) {
|
||||
res.push(Norm::normalize(&elt));
|
||||
}
|
||||
}
|
||||
|
||||
assert!(res.len() == dimension - 1);
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! small_dvec_impl (
|
||||
($dvector: ident, $dimension: expr, $($idx: expr),*) => (
|
||||
dvec_impl!($dvector);
|
||||
|
||||
impl<N> $dvector<N> {
|
||||
/// The number of elements of this vector.
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
self.dimension
|
||||
}
|
||||
|
||||
/// Creates an uninitialized vector of dimension `dimension`.
|
||||
#[inline]
|
||||
pub unsafe fn new_uninitialized(dimension: usize) -> $dvector<N> {
|
||||
assert!(dimension <= $dimension, "The chosen dimension is too high for that type of \
|
||||
stack-allocated dynamic vector. Consider using the \
|
||||
heap-allocated vector: DVector.");
|
||||
|
||||
$dvector {
|
||||
at: mem::uninitialized(),
|
||||
dimension: dimension
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: PartialEq> PartialEq for $dvector<N> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &$dvector<N>) -> bool {
|
||||
if self.len() != other.len() {
|
||||
return false; // FIXME: fail instead?
|
||||
}
|
||||
|
||||
for (a, b) in self.as_ref().iter().zip(other.as_ref().iter()) {
|
||||
if *a != *b {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone> Clone for $dvector<N> {
|
||||
fn clone(&self) -> $dvector<N> {
|
||||
let at: [N; $dimension] = [ $( self.at[$idx].clone(), )* ];
|
||||
|
||||
$dvector {
|
||||
at: at,
|
||||
dimension: self.dimension
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! small_dvec_from_impl (
|
||||
($dvector: ident, $dimension: expr, $($zeros: expr),*) => (
|
||||
impl<N: Copy + Zero> $dvector<N> {
|
||||
/// Builds a vector filled with a constant.
|
||||
#[inline]
|
||||
pub fn from_elem(dimension: usize, elem: N) -> $dvector<N> {
|
||||
assert!(dimension <= $dimension);
|
||||
|
||||
let mut at: [N; $dimension] = [ $( $zeros, )* ];
|
||||
|
||||
for n in &mut at[.. dimension] {
|
||||
*n = elem;
|
||||
}
|
||||
|
||||
$dvector {
|
||||
at: at,
|
||||
dimension: dimension
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Zero> $dvector<N> {
|
||||
/// Builds a vector filled with the components provided by a vector.
|
||||
///
|
||||
/// The vector must have at least `dimension` elements.
|
||||
#[inline]
|
||||
pub fn from_slice(dimension: usize, vector: &[N]) -> $dvector<N> {
|
||||
assert!(dimension <= vector.len() && dimension <= $dimension);
|
||||
|
||||
// FIXME: not safe.
|
||||
let mut at: [N; $dimension] = [ $( $zeros, )* ];
|
||||
|
||||
for (curr, other) in vector.iter().zip(at.iter_mut()) {
|
||||
*other = *curr;
|
||||
}
|
||||
|
||||
$dvector {
|
||||
at: at,
|
||||
dimension: dimension
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Zero> $dvector<N> {
|
||||
/// Builds a vector filled with the result of a function.
|
||||
#[inline(always)]
|
||||
pub fn from_fn<F: FnMut(usize) -> N>(dimension: usize, mut f: F) -> $dvector<N> {
|
||||
assert!(dimension <= $dimension);
|
||||
|
||||
let mut at: [N; $dimension] = [ $( $zeros, )* ];
|
||||
|
||||
for i in 0 .. dimension {
|
||||
at[i] = f(i);
|
||||
}
|
||||
|
||||
$dvector {
|
||||
at: at,
|
||||
dimension: dimension
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Zero> FromIterator<N> for $dvector<N> {
|
||||
#[inline]
|
||||
fn from_iter<I: IntoIterator<Item = N>>(param: I) -> $dvector<N> {
|
||||
let mut at: [N; $dimension] = [ $( $zeros, )* ];
|
||||
|
||||
let mut dimension = 0;
|
||||
|
||||
for n in param.into_iter() {
|
||||
if dimension == $dimension {
|
||||
break;
|
||||
}
|
||||
|
||||
at[dimension] = n;
|
||||
|
||||
dimension = dimension + 1;
|
||||
}
|
||||
|
||||
$dvector {
|
||||
at: at,
|
||||
dimension: dimension
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + Zero> Arbitrary for $dvector<N> {
|
||||
#[inline]
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> $dvector<N> {
|
||||
$dvector::from_fn(g.gen_range(0, $dimension), |_| Arbitrary::arbitrary(g))
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
|
@ -1,144 +0,0 @@
|
|||
use std::fmt;
|
||||
use std::ops::{Add, Sub, Mul, Neg, MulAssign};
|
||||
|
||||
use rand::{Rand, Rng};
|
||||
use num::One;
|
||||
use structs::mat::{Mat3, Mat4};
|
||||
use traits::structure::{Cast, Dim, Col, BaseFloat, BaseNum};
|
||||
use traits::operations::{Inv, ApproxEq};
|
||||
use traits::geometry::{RotationMatrix, Rotation, Rotate, AbsoluteRotate, Transform, Transformation,
|
||||
Translate, Translation, ToHomogeneous};
|
||||
use structs::vec::{Vec1, Vec2, Vec3};
|
||||
use structs::pnt::{Pnt2, Pnt3};
|
||||
use structs::rot::{Rot2, Rot3};
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// Two dimensional **direct** isometry.
|
||||
///
|
||||
/// This is the composition of a rotation followed by a translation. Vectors `Vec2` are not
|
||||
/// affected by the translational component of this transformation while points `Pnt2` are.
|
||||
/// Isometries conserve angles and distances, hence do not allow shearing nor scaling.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
|
||||
pub struct Iso2<N> {
|
||||
/// The rotation applicable by this isometry.
|
||||
pub rotation: Rot2<N>,
|
||||
/// The translation applicable by this isometry.
|
||||
pub translation: Vec2<N>
|
||||
}
|
||||
|
||||
/// Three dimensional **direct** isometry.
|
||||
///
|
||||
/// This is the composition of a rotation followed by a translation. Vectors `Vec3` are not
|
||||
/// affected by the translational component of this transformation while points `Pnt3` are.
|
||||
/// Isometries conserve angles and distances, hence do not allow shearing nor scaling.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
|
||||
pub struct Iso3<N> {
|
||||
/// The rotation applicable by this isometry.
|
||||
pub rotation: Rot3<N>,
|
||||
/// The translation applicable by this isometry.
|
||||
pub translation: Vec3<N>
|
||||
}
|
||||
|
||||
impl<N: Clone + BaseFloat> Iso3<N> {
|
||||
/// Creates an isometry that corresponds to the local frame of an observer standing at the
|
||||
/// point `eye` and looking toward `target`.
|
||||
///
|
||||
/// It maps the view direction `target - eye` to the positive `z` axis and the origin to the
|
||||
/// `eye`.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * eye - The observer position.
|
||||
/// * target - The target position.
|
||||
/// * up - Vertical direction. The only requirement of this parameter is to not be collinear
|
||||
/// to `eye - at`. Non-collinearity is not checked.
|
||||
#[inline]
|
||||
pub fn new_observer_frame(eye: &Pnt3<N>, target: &Pnt3<N>, up: &Vec3<N>) -> Iso3<N> {
|
||||
let new_rotmat = Rot3::new_observer_frame(&(*target - *eye), up);
|
||||
Iso3::new_with_rotmat(eye.as_vec().clone(), new_rotmat)
|
||||
}
|
||||
|
||||
/// Builds a right-handed look-at view matrix.
|
||||
///
|
||||
/// This conforms to the common notion of right handed look-at matrix from the computer
|
||||
/// graphics community.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * eye - The eye position.
|
||||
/// * target - The target position.
|
||||
/// * up - A vector approximately aligned with required the vertical axis. The only
|
||||
/// requirement of this parameter is to not be collinear to `target - eye`.
|
||||
#[inline]
|
||||
pub fn look_at_rh(eye: &Pnt3<N>, target: &Pnt3<N>, up: &Vec3<N>) -> Iso3<N> {
|
||||
let rot = Rot3::look_at_rh(&(*target - *eye), up);
|
||||
let trans = rot * (-*eye);
|
||||
|
||||
Iso3::new_with_rotmat(trans.to_vec(), rot)
|
||||
}
|
||||
|
||||
/// Builds a left-handed look-at view matrix.
|
||||
///
|
||||
/// This conforms to the common notion of left handed look-at matrix from the computer
|
||||
/// graphics community.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * eye - The eye position.
|
||||
/// * target - The target position.
|
||||
/// * up - A vector approximately aligned with required the vertical axis. The only
|
||||
/// requirement of this parameter is to not be collinear to `target - eye`.
|
||||
#[inline]
|
||||
pub fn look_at_lh(eye: &Pnt3<N>, target: &Pnt3<N>, up: &Vec3<N>) -> Iso3<N> {
|
||||
let rot = Rot3::look_at_lh(&(*target - *eye), up);
|
||||
let trans = rot * (-*eye);
|
||||
|
||||
Iso3::new_with_rotmat(trans.to_vec(), rot)
|
||||
}
|
||||
}
|
||||
|
||||
iso_impl!(Iso2, Rot2, Vec2, Vec1);
|
||||
rotation_matrix_impl!(Iso2, Rot2, Vec2, Vec1);
|
||||
rotation_impl!(Iso2, Rot2, Vec1);
|
||||
dim_impl!(Iso2, 2);
|
||||
one_impl!(Iso2);
|
||||
absolute_rotate_impl!(Iso2, Vec2);
|
||||
rand_impl!(Iso2);
|
||||
approx_eq_impl!(Iso2);
|
||||
to_homogeneous_impl!(Iso2, Mat3);
|
||||
inv_impl!(Iso2);
|
||||
transform_impl!(Iso2, Pnt2);
|
||||
transformation_impl!(Iso2);
|
||||
rotate_impl!(Iso2, Vec2);
|
||||
translation_impl!(Iso2, Vec2);
|
||||
translate_impl!(Iso2, Pnt2);
|
||||
iso_mul_iso_impl!(Iso2);
|
||||
iso_mul_rot_impl!(Iso2, Rot2);
|
||||
iso_mul_pnt_impl!(Iso2, Pnt2);
|
||||
iso_mul_vec_impl!(Iso2, Vec2);
|
||||
arbitrary_iso_impl!(Iso2);
|
||||
iso_display_impl!(Iso2);
|
||||
|
||||
iso_impl!(Iso3, Rot3, Vec3, Vec3);
|
||||
rotation_matrix_impl!(Iso3, Rot3, Vec3, Vec3);
|
||||
rotation_impl!(Iso3, Rot3, Vec3);
|
||||
dim_impl!(Iso3, 3);
|
||||
one_impl!(Iso3);
|
||||
absolute_rotate_impl!(Iso3, Vec3);
|
||||
rand_impl!(Iso3);
|
||||
approx_eq_impl!(Iso3);
|
||||
to_homogeneous_impl!(Iso3, Mat4);
|
||||
inv_impl!(Iso3);
|
||||
transform_impl!(Iso3, Pnt3);
|
||||
transformation_impl!(Iso3);
|
||||
rotate_impl!(Iso3, Vec3);
|
||||
translation_impl!(Iso3, Vec3);
|
||||
translate_impl!(Iso3, Pnt3);
|
||||
iso_mul_iso_impl!(Iso3);
|
||||
iso_mul_rot_impl!(Iso3, Rot3);
|
||||
iso_mul_pnt_impl!(Iso3, Pnt3);
|
||||
iso_mul_vec_impl!(Iso3, Vec3);
|
||||
arbitrary_iso_impl!(Iso3);
|
||||
iso_display_impl!(Iso3);
|
|
@ -0,0 +1,144 @@
|
|||
use std::fmt;
|
||||
use std::ops::{Add, Sub, Mul, Neg, MulAssign};
|
||||
|
||||
use rand::{Rand, Rng};
|
||||
use num::One;
|
||||
use structs::matrix::{Matrix3, Matrix4};
|
||||
use traits::structure::{Cast, Dimension, Column, BaseFloat, BaseNum};
|
||||
use traits::operations::{Inverse, ApproxEq};
|
||||
use traits::geometry::{RotationMatrix, Rotation, Rotate, AbsoluteRotate, Transform, Transformation,
|
||||
Translate, Translation, ToHomogeneous};
|
||||
use structs::vector::{Vector1, Vector2, Vector3};
|
||||
use structs::point::{Point2, Point3};
|
||||
use structs::rotation::{Rotation2, Rotation3};
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// Two dimensional **direct** isometry.
|
||||
///
|
||||
/// This is the composition of a rotation followed by a translation. Vectors `Vector2` are not
|
||||
/// affected by the translational component of this transformation while points `Point2` are.
|
||||
/// Isometrymetries conserve angles and distances, hence do not allow shearing nor scaling.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
|
||||
pub struct Isometry2<N> {
|
||||
/// The rotation applicable by this isometry.
|
||||
pub rotation: Rotation2<N>,
|
||||
/// The translation applicable by this isometry.
|
||||
pub translation: Vector2<N>
|
||||
}
|
||||
|
||||
/// Three dimensional **direct** isometry.
|
||||
///
|
||||
/// This is the composition of a rotation followed by a translation. Vectors `Vector3` are not
|
||||
/// affected by the translational component of this transformation while points `Point3` are.
|
||||
/// Isometrymetries conserve angles and distances, hence do not allow shearing nor scaling.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
|
||||
pub struct Isometry3<N> {
|
||||
/// The rotation applicable by this isometry.
|
||||
pub rotation: Rotation3<N>,
|
||||
/// The translation applicable by this isometry.
|
||||
pub translation: Vector3<N>
|
||||
}
|
||||
|
||||
impl<N: Clone + BaseFloat> Isometry3<N> {
|
||||
/// Creates an isometry that corresponds to the local frame of an observer standing at the
|
||||
/// point `eye` and looking toward `target`.
|
||||
///
|
||||
/// It maps the view direction `target - eye` to the positive `z` axis and the origin to the
|
||||
/// `eye`.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * eye - The observer position.
|
||||
/// * target - The target position.
|
||||
/// * up - Vertical direction. The only requirement of this parameter is to not be collinear
|
||||
/// to `eye - at`. Non-collinearity is not checked.
|
||||
#[inline]
|
||||
pub fn new_observer_frame(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Isometry3<N> {
|
||||
let new_rotation_matrix = Rotation3::new_observer_frame(&(*target - *eye), up);
|
||||
Isometry3::new_with_rotation_matrix(eye.as_vector().clone(), new_rotation_matrix)
|
||||
}
|
||||
|
||||
/// Builds a right-handed look-at view matrix.
|
||||
///
|
||||
/// This conforms to the common notion of right handed look-at matrix from the computer
|
||||
/// graphics community.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * eye - The eye position.
|
||||
/// * target - The target position.
|
||||
/// * up - A vector approximately aligned with required the vertical axis. The only
|
||||
/// requirement of this parameter is to not be collinear to `target - eye`.
|
||||
#[inline]
|
||||
pub fn look_at_rh(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Isometry3<N> {
|
||||
let rotation = Rotation3::look_at_rh(&(*target - *eye), up);
|
||||
let trans = rotation * (-*eye);
|
||||
|
||||
Isometry3::new_with_rotation_matrix(trans.to_vector(), rotation)
|
||||
}
|
||||
|
||||
/// Builds a left-handed look-at view matrix.
|
||||
///
|
||||
/// This conforms to the common notion of left handed look-at matrix from the computer
|
||||
/// graphics community.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * eye - The eye position.
|
||||
/// * target - The target position.
|
||||
/// * up - A vector approximately aligned with required the vertical axis. The only
|
||||
/// requirement of this parameter is to not be collinear to `target - eye`.
|
||||
#[inline]
|
||||
pub fn look_at_lh(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Isometry3<N> {
|
||||
let rotation = Rotation3::look_at_lh(&(*target - *eye), up);
|
||||
let trans = rotation * (-*eye);
|
||||
|
||||
Isometry3::new_with_rotation_matrix(trans.to_vector(), rotation)
|
||||
}
|
||||
}
|
||||
|
||||
isometry_impl!(Isometry2, Rotation2, Vector2, Vector1);
|
||||
rotation_matrix_impl!(Isometry2, Rotation2, Vector2, Vector1);
|
||||
rotation_impl!(Isometry2, Rotation2, Vector1);
|
||||
dim_impl!(Isometry2, 2);
|
||||
one_impl!(Isometry2);
|
||||
absolute_rotate_impl!(Isometry2, Vector2);
|
||||
rand_impl!(Isometry2);
|
||||
approx_eq_impl!(Isometry2);
|
||||
to_homogeneous_impl!(Isometry2, Matrix3);
|
||||
inverse_impl!(Isometry2);
|
||||
transform_impl!(Isometry2, Point2);
|
||||
transformation_impl!(Isometry2);
|
||||
rotate_impl!(Isometry2, Vector2);
|
||||
translation_impl!(Isometry2, Vector2);
|
||||
translate_impl!(Isometry2, Point2);
|
||||
isometry_mul_isometry_impl!(Isometry2);
|
||||
isometry_mul_rotation_impl!(Isometry2, Rotation2);
|
||||
isometry_mul_point_impl!(Isometry2, Point2);
|
||||
isometry_mul_vec_impl!(Isometry2, Vector2);
|
||||
arbitrary_isometry_impl!(Isometry2);
|
||||
isometry_display_impl!(Isometry2);
|
||||
|
||||
isometry_impl!(Isometry3, Rotation3, Vector3, Vector3);
|
||||
rotation_matrix_impl!(Isometry3, Rotation3, Vector3, Vector3);
|
||||
rotation_impl!(Isometry3, Rotation3, Vector3);
|
||||
dim_impl!(Isometry3, 3);
|
||||
one_impl!(Isometry3);
|
||||
absolute_rotate_impl!(Isometry3, Vector3);
|
||||
rand_impl!(Isometry3);
|
||||
approx_eq_impl!(Isometry3);
|
||||
to_homogeneous_impl!(Isometry3, Matrix4);
|
||||
inverse_impl!(Isometry3);
|
||||
transform_impl!(Isometry3, Point3);
|
||||
transformation_impl!(Isometry3);
|
||||
rotate_impl!(Isometry3, Vector3);
|
||||
translation_impl!(Isometry3, Vector3);
|
||||
translate_impl!(Isometry3, Point3);
|
||||
isometry_mul_isometry_impl!(Isometry3);
|
||||
isometry_mul_rotation_impl!(Isometry3, Rotation3);
|
||||
isometry_mul_point_impl!(Isometry3, Point3);
|
||||
isometry_mul_vec_impl!(Isometry3, Vector3);
|
||||
arbitrary_isometry_impl!(Isometry3);
|
||||
isometry_display_impl!(Isometry3);
|
|
@ -1,20 +1,20 @@
|
|||
#![macro_use]
|
||||
|
||||
macro_rules! iso_impl(
|
||||
($t: ident, $submat: ident, $subvec: ident, $subrotvec: ident) => (
|
||||
macro_rules! isometry_impl(
|
||||
($t: ident, $submatrix: ident, $subvector: ident, $subrotvector: ident) => (
|
||||
impl<N: BaseFloat> $t<N> {
|
||||
/// Creates a new isometry from an axis-angle rotation, and a vector.
|
||||
#[inline]
|
||||
pub fn new(translation: $subvec<N>, rotation: $subrotvec<N>) -> $t<N> {
|
||||
pub fn new(translation: $subvector<N>, rotation: $subrotvector<N>) -> $t<N> {
|
||||
$t {
|
||||
rotation: $submat::new(rotation),
|
||||
rotation: $submatrix::new(rotation),
|
||||
translation: translation
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new isometry from a rotation matrix and a vector.
|
||||
#[inline]
|
||||
pub fn new_with_rotmat(translation: $subvec<N>, rotation: $submat<N>) -> $t<N> {
|
||||
pub fn new_with_rotation_matrix(translation: $subvector<N>, rotation: $submatrix<N>) -> $t<N> {
|
||||
$t {
|
||||
rotation: rotation,
|
||||
translation: translation
|
||||
|
@ -25,13 +25,13 @@ macro_rules! iso_impl(
|
|||
);
|
||||
|
||||
macro_rules! rotation_matrix_impl(
|
||||
($t: ident, $trot: ident, $tlv: ident, $tav: ident) => (
|
||||
($t: ident, $trotation: ident, $tlv: ident, $tav: ident) => (
|
||||
impl<N: Cast<f64> + BaseFloat>
|
||||
RotationMatrix<N, $tlv<N>, $tav<N>> for $t<N> {
|
||||
type Output = $trot<N>;
|
||||
type Output = $trotation<N>;
|
||||
|
||||
#[inline]
|
||||
fn to_rot_mat(&self) -> $trot<N> {
|
||||
fn to_rotation_matrix(&self) -> $trotation<N> {
|
||||
self.rotation
|
||||
}
|
||||
}
|
||||
|
@ -40,11 +40,11 @@ macro_rules! rotation_matrix_impl(
|
|||
|
||||
|
||||
macro_rules! dim_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N> Dim for $t<N> {
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N> Dimension for $t<N> {
|
||||
#[inline]
|
||||
fn dim(_: Option<$t<N>>) -> usize {
|
||||
$dim
|
||||
fn dimension(_: Option<$t<N>>) -> usize {
|
||||
$dimension
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -55,20 +55,20 @@ macro_rules! one_impl(
|
|||
impl<N: BaseFloat> One for $t<N> {
|
||||
#[inline]
|
||||
fn one() -> $t<N> {
|
||||
$t::new_with_rotmat(::zero(), ::one())
|
||||
$t::new_with_rotation_matrix(::zero(), ::one())
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! iso_mul_iso_impl(
|
||||
macro_rules! isometry_mul_isometry_impl(
|
||||
($t: ident) => (
|
||||
impl<N: BaseFloat> Mul<$t<N>> for $t<N> {
|
||||
type Output = $t<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: $t<N>) -> $t<N> {
|
||||
$t::new_with_rotmat(
|
||||
$t::new_with_rotation_matrix(
|
||||
self.translation + self.rotation * right.translation,
|
||||
self.rotation * right.rotation)
|
||||
}
|
||||
|
@ -84,38 +84,38 @@ macro_rules! iso_mul_iso_impl(
|
|||
)
|
||||
);
|
||||
|
||||
macro_rules! iso_mul_rot_impl(
|
||||
($t: ident, $rot: ident) => (
|
||||
impl<N: BaseFloat> Mul<$rot<N>> for $t<N> {
|
||||
macro_rules! isometry_mul_rotation_impl(
|
||||
($t: ident, $rotation: ident) => (
|
||||
impl<N: BaseFloat> Mul<$rotation<N>> for $t<N> {
|
||||
type Output = $t<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: $rot<N>) -> $t<N> {
|
||||
$t::new_with_rotmat(self.translation, self.rotation * right)
|
||||
fn mul(self, right: $rotation<N>) -> $t<N> {
|
||||
$t::new_with_rotation_matrix(self.translation, self.rotation * right)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> Mul<$t<N>> for $rot<N> {
|
||||
impl<N: BaseFloat> Mul<$t<N>> for $rotation<N> {
|
||||
type Output = $t<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: $t<N>) -> $t<N> {
|
||||
$t::new_with_rotmat(
|
||||
$t::new_with_rotation_matrix(
|
||||
self * right.translation,
|
||||
self * right.rotation)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> MulAssign<$rot<N>> for $t<N> {
|
||||
impl<N: BaseFloat> MulAssign<$rotation<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, right: $rot<N>) {
|
||||
fn mul_assign(&mut self, right: $rotation<N>) {
|
||||
self.rotation *= right
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! iso_mul_pnt_impl(
|
||||
macro_rules! isometry_mul_point_impl(
|
||||
($t: ident, $tv: ident) => (
|
||||
impl<N: BaseNum> Mul<$tv<N>> for $t<N> {
|
||||
type Output = $tv<N>;
|
||||
|
@ -128,7 +128,7 @@ macro_rules! iso_mul_pnt_impl(
|
|||
)
|
||||
);
|
||||
|
||||
macro_rules! iso_mul_vec_impl(
|
||||
macro_rules! isometry_mul_vec_impl(
|
||||
($t: ident, $tv: ident) => (
|
||||
impl<N: BaseNum> Mul<$tv<N>> for $t<N> {
|
||||
type Output = $tv<N>;
|
||||
|
@ -150,7 +150,7 @@ macro_rules! translation_impl(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_translation(&self) -> $tv<N> {
|
||||
fn inverse_translation(&self) -> $tv<N> {
|
||||
-self.translation
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ macro_rules! translation_impl(
|
|||
|
||||
#[inline]
|
||||
fn append_translation(&self, t: &$tv<N>) -> $t<N> {
|
||||
$t::new_with_rotmat(*t + self.translation, self.rotation)
|
||||
$t::new_with_rotation_matrix(*t + self.translation, self.rotation)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -171,7 +171,7 @@ macro_rules! translation_impl(
|
|||
|
||||
#[inline]
|
||||
fn prepend_translation(&self, t: &$tv<N>) -> $t<N> {
|
||||
$t::new_with_rotmat(self.translation + self.rotation * *t, self.rotation)
|
||||
$t::new_with_rotation_matrix(self.translation + self.rotation * *t, self.rotation)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -191,7 +191,7 @@ macro_rules! translate_impl(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_translate(&self, v: &$tv<N>) -> $tv<N> {
|
||||
fn inverse_translate(&self, v: &$tv<N>) -> $tv<N> {
|
||||
*v - self.translation
|
||||
}
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ macro_rules! translate_impl(
|
|||
);
|
||||
|
||||
macro_rules! rotation_impl(
|
||||
($t: ident, $trot: ident, $tav: ident) => (
|
||||
($t: ident, $trotation: ident, $tav: ident) => (
|
||||
impl<N: Cast<f64> + BaseFloat> Rotation<$tav<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn rotation(&self) -> $tav<N> {
|
||||
|
@ -207,43 +207,43 @@ macro_rules! rotation_impl(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_rotation(&self) -> $tav<N> {
|
||||
self.rotation.inv_rotation()
|
||||
fn inverse_rotation(&self) -> $tav<N> {
|
||||
self.rotation.inverse_rotation()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn append_rotation_mut(&mut self, rot: &$tav<N>) {
|
||||
let delta = $trot::new(*rot);
|
||||
fn append_rotation_mut(&mut self, rotation: &$tav<N>) {
|
||||
let delta = $trotation::new(*rotation);
|
||||
|
||||
self.rotation = delta * self.rotation;
|
||||
self.translation = delta * self.translation;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn append_rotation(&self, rot: &$tav<N>) -> $t<N> {
|
||||
let delta = $trot::new(*rot);
|
||||
fn append_rotation(&self, rotation: &$tav<N>) -> $t<N> {
|
||||
let delta = $trotation::new(*rotation);
|
||||
|
||||
$t::new_with_rotmat(delta * self.translation, delta * self.rotation)
|
||||
$t::new_with_rotation_matrix(delta * self.translation, delta * self.rotation)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prepend_rotation_mut(&mut self, rot: &$tav<N>) {
|
||||
let delta = $trot::new(*rot);
|
||||
fn prepend_rotation_mut(&mut self, rotation: &$tav<N>) {
|
||||
let delta = $trotation::new(*rotation);
|
||||
|
||||
self.rotation = self.rotation * delta;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prepend_rotation(&self, rot: &$tav<N>) -> $t<N> {
|
||||
let delta = $trot::new(*rot);
|
||||
fn prepend_rotation(&self, rotation: &$tav<N>) -> $t<N> {
|
||||
let delta = $trotation::new(*rotation);
|
||||
|
||||
$t::new_with_rotmat(self.translation, self.rotation * delta)
|
||||
$t::new_with_rotation_matrix(self.translation, self.rotation * delta)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_rotation(&mut self, rot: $tav<N>) {
|
||||
fn set_rotation(&mut self, rotation: $tav<N>) {
|
||||
// FIXME: should the translation be changed too?
|
||||
self.rotation.set_rotation(rot)
|
||||
self.rotation.set_rotation(rotation)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -258,8 +258,8 @@ macro_rules! rotate_impl(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_rotate(&self, v: &$tv<N>) -> $tv<N> {
|
||||
self.rotation.inv_rotate(v)
|
||||
fn inverse_rotate(&self, v: &$tv<N>) -> $tv<N> {
|
||||
self.rotation.inverse_rotate(v)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -272,9 +272,9 @@ macro_rules! transformation_impl(
|
|||
*self
|
||||
}
|
||||
|
||||
fn inv_transformation(&self) -> $t<N> {
|
||||
fn inverse_transformation(&self) -> $t<N> {
|
||||
// inversion will never fails
|
||||
Inv::inv(self).unwrap()
|
||||
Inverse::inverse(self).unwrap()
|
||||
}
|
||||
|
||||
fn append_transformation_mut(&mut self, t: &$t<N>) {
|
||||
|
@ -309,28 +309,28 @@ macro_rules! transform_impl(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_transform(&self, p: &$tp<N>) -> $tp<N> {
|
||||
self.rotation.inv_transform(&(*p - self.translation))
|
||||
fn inverse_transform(&self, p: &$tp<N>) -> $tp<N> {
|
||||
self.rotation.inverse_transform(&(*p - self.translation))
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! inv_impl(
|
||||
macro_rules! inverse_impl(
|
||||
($t: ident) => (
|
||||
impl<N: BaseNum + Neg<Output = N>> Inv for $t<N> {
|
||||
impl<N: BaseNum + Neg<Output = N>> Inverse for $t<N> {
|
||||
#[inline]
|
||||
fn inv_mut(&mut self) -> bool {
|
||||
self.rotation.inv_mut();
|
||||
fn inverse_mut(&mut self) -> bool {
|
||||
self.rotation.inverse_mut();
|
||||
self.translation = self.rotation * -self.translation;
|
||||
// always succeed
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inv(&self) -> Option<$t<N>> {
|
||||
fn inverse(&self) -> Option<$t<N>> {
|
||||
let mut res = *self;
|
||||
res.inv_mut();
|
||||
res.inverse_mut();
|
||||
// always succeed
|
||||
Some(res)
|
||||
}
|
||||
|
@ -345,9 +345,9 @@ macro_rules! to_homogeneous_impl(
|
|||
let mut res = self.rotation.to_homogeneous();
|
||||
|
||||
// copy the translation
|
||||
let dim = Dim::dim(None::<$th<N>>);
|
||||
let dimension = Dimension::dimension(None::<$th<N>>);
|
||||
|
||||
res.set_col(dim - 1, self.translation.as_pnt().to_homogeneous().to_vec());
|
||||
res.set_col(dimension - 1, self.translation.as_point().to_homogeneous().to_vector());
|
||||
|
||||
res
|
||||
}
|
||||
|
@ -405,12 +405,12 @@ macro_rules! absolute_rotate_impl(
|
|||
)
|
||||
);
|
||||
|
||||
macro_rules! arbitrary_iso_impl(
|
||||
macro_rules! arbitrary_isometry_impl(
|
||||
($t: ident) => (
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for $t<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> $t<N> {
|
||||
$t::new_with_rotmat(
|
||||
$t::new_with_rotation_matrix(
|
||||
Arbitrary::arbitrary(g),
|
||||
Arbitrary::arbitrary(g)
|
||||
)
|
||||
|
@ -419,7 +419,7 @@ macro_rules! arbitrary_iso_impl(
|
|||
)
|
||||
);
|
||||
|
||||
macro_rules! iso_display_impl(
|
||||
macro_rules! isometry_display_impl(
|
||||
($t: ident) => (
|
||||
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
@ -428,12 +428,12 @@ macro_rules! iso_display_impl(
|
|||
if let Some(precision) = f.precision() {
|
||||
try!(writeln!(f, "... translation: {:.*}", precision, self.translation));
|
||||
try!(writeln!(f, "... rotation matrix:"));
|
||||
try!(write!(f, "{:.*}", precision, *self.rotation.submat()));
|
||||
try!(write!(f, "{:.*}", precision, *self.rotation.submatrix()));
|
||||
}
|
||||
else {
|
||||
try!(writeln!(f, "... translation: {}", self.translation));
|
||||
try!(writeln!(f, "... rotation matrix:"));
|
||||
try!(write!(f, "{}", *self.rotation.submat()));
|
||||
try!(write!(f, "{}", *self.rotation.submatrix()));
|
||||
}
|
||||
|
||||
writeln!(f, "}}")
|
|
@ -1,4 +1,4 @@
|
|||
//! Matrices with dimensions known at compile-time.
|
||||
//! Matrixrices with dimensions known at compile-time.
|
||||
|
||||
#![allow(missing_docs)] // we allow missing to avoid having to document the mij components.
|
||||
|
||||
|
@ -9,14 +9,14 @@ use std::slice::{Iter, IterMut};
|
|||
use rand::{Rand, Rng};
|
||||
use num::{Zero, One};
|
||||
use traits::operations::ApproxEq;
|
||||
use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6};
|
||||
use structs::pnt::{Pnt1, Pnt4, Pnt5, Pnt6};
|
||||
use structs::dvec::{DVec1, DVec2, DVec3, DVec4, DVec5, DVec6};
|
||||
use structs::vector::{Vector1, Vector2, Vector3, Vector4, Vector5, Vector6};
|
||||
use structs::point::{Point1, Point4, Point5, Point6};
|
||||
use structs::dvector::{DVector1, DVector2, DVector3, DVector4, DVector5, DVector6};
|
||||
|
||||
use traits::structure::{Cast, Row, Col, Iterable, IterableMut, Dim, Indexable, Eye, ColSlice,
|
||||
RowSlice, Diag, DiagMut, Shape, BaseFloat, BaseNum, Repeat};
|
||||
use traits::operations::{Absolute, Transpose, Inv, Outer, EigenQR, Mean};
|
||||
use traits::geometry::{ToHomogeneous, FromHomogeneous, Orig};
|
||||
use traits::structure::{Cast, Row, Column, Iterable, IterableMut, Dimension, Indexable, Eye, ColumnSlice,
|
||||
RowSlice, Diagonal, DiagMut, Shape, BaseFloat, BaseNum, Repeat};
|
||||
use traits::operations::{Absolute, Transpose, Inverse, Outer, EigenQR, Mean};
|
||||
use traits::geometry::{ToHomogeneous, FromHomogeneous, Origin};
|
||||
use linalg;
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
@ -38,331 +38,331 @@ impl Identity {
|
|||
/// Square matrix of dimension 1.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Mat1<N> {
|
||||
pub struct Matrix1<N> {
|
||||
pub m11: N
|
||||
}
|
||||
|
||||
eye_impl!(Mat1, 1, m11);
|
||||
eye_impl!(Matrix1, 1, m11);
|
||||
|
||||
mat_impl!(Mat1, m11);
|
||||
repeat_impl!(Mat1, m11);
|
||||
conversion_impl!(Mat1, 1);
|
||||
mat_cast_impl!(Mat1, m11);
|
||||
add_impl!(Mat1, m11);
|
||||
sub_impl!(Mat1, m11);
|
||||
scalar_add_impl!(Mat1, m11);
|
||||
scalar_sub_impl!(Mat1, m11);
|
||||
scalar_mul_impl!(Mat1, m11);
|
||||
scalar_div_impl!(Mat1, m11);
|
||||
absolute_impl!(Mat1, m11);
|
||||
zero_impl!(Mat1, m11);
|
||||
one_impl!(Mat1, ::one);
|
||||
iterable_impl!(Mat1, 1);
|
||||
iterable_mut_impl!(Mat1, 1);
|
||||
at_fast_impl!(Mat1, 1);
|
||||
dim_impl!(Mat1, 1);
|
||||
indexable_impl!(Mat1, 1);
|
||||
index_impl!(Mat1, 1);
|
||||
mat_mul_mat_impl!(Mat1, 1);
|
||||
mat_mul_vec_impl!(Mat1, Vec1, 1, ::zero);
|
||||
vec_mul_mat_impl!(Mat1, Vec1, 1, ::zero);
|
||||
mat_mul_pnt_impl!(Mat1, Pnt1, 1, Orig::orig);
|
||||
pnt_mul_mat_impl!(Mat1, Pnt1, 1, Orig::orig);
|
||||
// (specialized); inv_impl!(Mat1, 1);
|
||||
transpose_impl!(Mat1, 1);
|
||||
approx_eq_impl!(Mat1);
|
||||
row_impl!(Mat1, Vec1, 1);
|
||||
col_impl!(Mat1, Vec1, 1);
|
||||
col_slice_impl!(Mat1, Vec1, DVec1, 1);
|
||||
row_slice_impl!(Mat1, Vec1, DVec1, 1);
|
||||
diag_impl!(Mat1, Vec1, 1);
|
||||
to_homogeneous_impl!(Mat1, Mat2, 1, 2);
|
||||
from_homogeneous_impl!(Mat1, Mat2, 1, 2);
|
||||
outer_impl!(Vec1, Mat1);
|
||||
eigen_qr_impl!(Mat1, Vec1);
|
||||
arbitrary_impl!(Mat1, m11);
|
||||
rand_impl!(Mat1, m11);
|
||||
mean_impl!(Mat1, Vec1, 1);
|
||||
mat_display_impl!(Mat1, 1);
|
||||
mat_impl!(Matrix1, m11);
|
||||
repeat_impl!(Matrix1, m11);
|
||||
conversion_impl!(Matrix1, 1);
|
||||
mat_cast_impl!(Matrix1, m11);
|
||||
add_impl!(Matrix1, m11);
|
||||
sub_impl!(Matrix1, m11);
|
||||
scalar_add_impl!(Matrix1, m11);
|
||||
scalar_sub_impl!(Matrix1, m11);
|
||||
scalar_mul_impl!(Matrix1, m11);
|
||||
scalar_div_impl!(Matrix1, m11);
|
||||
absolute_impl!(Matrix1, m11);
|
||||
zero_impl!(Matrix1, m11);
|
||||
one_impl!(Matrix1, ::one);
|
||||
iterable_impl!(Matrix1, 1);
|
||||
iterable_mut_impl!(Matrix1, 1);
|
||||
at_fast_impl!(Matrix1, 1);
|
||||
dim_impl!(Matrix1, 1);
|
||||
indexable_impl!(Matrix1, 1);
|
||||
index_impl!(Matrix1, 1);
|
||||
mat_mul_mat_impl!(Matrix1, 1);
|
||||
mat_mul_vec_impl!(Matrix1, Vector1, 1, ::zero);
|
||||
vec_mul_mat_impl!(Matrix1, Vector1, 1, ::zero);
|
||||
mat_mul_point_impl!(Matrix1, Point1, 1, Origin::origin);
|
||||
point_mul_mat_impl!(Matrix1, Point1, 1, Origin::origin);
|
||||
// (specialized); inverse_impl!(Matrix1, 1);
|
||||
transpose_impl!(Matrix1, 1);
|
||||
approx_eq_impl!(Matrix1);
|
||||
row_impl!(Matrix1, Vector1, 1);
|
||||
col_impl!(Matrix1, Vector1, 1);
|
||||
col_slice_impl!(Matrix1, Vector1, DVector1, 1);
|
||||
row_slice_impl!(Matrix1, Vector1, DVector1, 1);
|
||||
diag_impl!(Matrix1, Vector1, 1);
|
||||
to_homogeneous_impl!(Matrix1, Matrix2, 1, 2);
|
||||
from_homogeneous_impl!(Matrix1, Matrix2, 1, 2);
|
||||
outer_impl!(Vector1, Matrix1);
|
||||
eigen_qr_impl!(Matrix1, Vector1);
|
||||
arbitrary_impl!(Matrix1, m11);
|
||||
rand_impl!(Matrix1, m11);
|
||||
mean_impl!(Matrix1, Vector1, 1);
|
||||
mat_display_impl!(Matrix1, 1);
|
||||
|
||||
/// Square matrix of dimension 2.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Mat2<N> {
|
||||
pub struct Matrix2<N> {
|
||||
pub m11: N, pub m21: N,
|
||||
pub m12: N, pub m22: N
|
||||
}
|
||||
|
||||
eye_impl!(Mat2, 2, m11, m22);
|
||||
eye_impl!(Matrix2, 2, m11, m22);
|
||||
|
||||
mat_impl!(Mat2, m11, m12,
|
||||
mat_impl!(Matrix2, m11, m12,
|
||||
m21, m22);
|
||||
repeat_impl!(Mat2, m11, m12,
|
||||
repeat_impl!(Matrix2, m11, m12,
|
||||
m21, m22);
|
||||
conversion_impl!(Mat2, 2);
|
||||
mat_cast_impl!(Mat2, m11, m12,
|
||||
conversion_impl!(Matrix2, 2);
|
||||
mat_cast_impl!(Matrix2, m11, m12,
|
||||
m21, m22);
|
||||
add_impl!(Mat2, m11, m12, m21, m22);
|
||||
sub_impl!(Mat2, m11, m12, m21, m22);
|
||||
scalar_add_impl!(Mat2, m11, m12, m21, m22);
|
||||
scalar_sub_impl!(Mat2, m11, m12, m21, m22);
|
||||
scalar_mul_impl!(Mat2, m11, m12, m21, m22);
|
||||
scalar_div_impl!(Mat2, m11, m12, m21, m22);
|
||||
absolute_impl!(Mat2, m11, m12,
|
||||
add_impl!(Matrix2, m11, m12, m21, m22);
|
||||
sub_impl!(Matrix2, m11, m12, m21, m22);
|
||||
scalar_add_impl!(Matrix2, m11, m12, m21, m22);
|
||||
scalar_sub_impl!(Matrix2, m11, m12, m21, m22);
|
||||
scalar_mul_impl!(Matrix2, m11, m12, m21, m22);
|
||||
scalar_div_impl!(Matrix2, m11, m12, m21, m22);
|
||||
absolute_impl!(Matrix2, m11, m12,
|
||||
m21, m22);
|
||||
zero_impl!(Mat2, m11, m12,
|
||||
zero_impl!(Matrix2, m11, m12,
|
||||
m21, m22);
|
||||
one_impl!(Mat2, ::one, ::zero,
|
||||
one_impl!(Matrix2, ::one, ::zero,
|
||||
::zero, ::one);
|
||||
iterable_impl!(Mat2, 2);
|
||||
iterable_mut_impl!(Mat2, 2);
|
||||
dim_impl!(Mat2, 2);
|
||||
indexable_impl!(Mat2, 2);
|
||||
index_impl!(Mat2, 2);
|
||||
at_fast_impl!(Mat2, 2);
|
||||
// (specialized); mul_impl!(Mat2, 2);
|
||||
// (specialized); rmul_impl!(Mat2, Vec2, 2);
|
||||
// (specialized); lmul_impl!(Mat2, Vec2, 2);
|
||||
// (specialized); inv_impl!(Mat2, 2);
|
||||
transpose_impl!(Mat2, 2);
|
||||
approx_eq_impl!(Mat2);
|
||||
row_impl!(Mat2, Vec2, 2);
|
||||
col_impl!(Mat2, Vec2, 2);
|
||||
col_slice_impl!(Mat2, Vec2, DVec2, 2);
|
||||
row_slice_impl!(Mat2, Vec2, DVec2, 2);
|
||||
diag_impl!(Mat2, Vec2, 2);
|
||||
to_homogeneous_impl!(Mat2, Mat3, 2, 3);
|
||||
from_homogeneous_impl!(Mat2, Mat3, 2, 3);
|
||||
outer_impl!(Vec2, Mat2);
|
||||
eigen_qr_impl!(Mat2, Vec2);
|
||||
arbitrary_impl!(Mat2, m11, m12, m21, m22);
|
||||
rand_impl!(Mat2, m11, m12, m21, m22);
|
||||
mean_impl!(Mat2, Vec2, 2);
|
||||
mat_display_impl!(Mat2, 2);
|
||||
iterable_impl!(Matrix2, 2);
|
||||
iterable_mut_impl!(Matrix2, 2);
|
||||
dim_impl!(Matrix2, 2);
|
||||
indexable_impl!(Matrix2, 2);
|
||||
index_impl!(Matrix2, 2);
|
||||
at_fast_impl!(Matrix2, 2);
|
||||
// (specialized); mul_impl!(Matrix2, 2);
|
||||
// (specialized); rmul_impl!(Matrix2, Vector2, 2);
|
||||
// (specialized); lmul_impl!(Matrix2, Vector2, 2);
|
||||
// (specialized); inverse_impl!(Matrix2, 2);
|
||||
transpose_impl!(Matrix2, 2);
|
||||
approx_eq_impl!(Matrix2);
|
||||
row_impl!(Matrix2, Vector2, 2);
|
||||
col_impl!(Matrix2, Vector2, 2);
|
||||
col_slice_impl!(Matrix2, Vector2, DVector2, 2);
|
||||
row_slice_impl!(Matrix2, Vector2, DVector2, 2);
|
||||
diag_impl!(Matrix2, Vector2, 2);
|
||||
to_homogeneous_impl!(Matrix2, Matrix3, 2, 3);
|
||||
from_homogeneous_impl!(Matrix2, Matrix3, 2, 3);
|
||||
outer_impl!(Vector2, Matrix2);
|
||||
eigen_qr_impl!(Matrix2, Vector2);
|
||||
arbitrary_impl!(Matrix2, m11, m12, m21, m22);
|
||||
rand_impl!(Matrix2, m11, m12, m21, m22);
|
||||
mean_impl!(Matrix2, Vector2, 2);
|
||||
mat_display_impl!(Matrix2, 2);
|
||||
|
||||
/// Square matrix of dimension 3.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Mat3<N> {
|
||||
pub struct Matrix3<N> {
|
||||
pub m11: N, pub m21: N, pub m31: N,
|
||||
pub m12: N, pub m22: N, pub m32: N,
|
||||
pub m13: N, pub m23: N, pub m33: N
|
||||
}
|
||||
|
||||
eye_impl!(Mat3, 3, m11, m22, m33);
|
||||
eye_impl!(Matrix3, 3, m11, m22, m33);
|
||||
|
||||
mat_impl!(Mat3, m11, m12, m13,
|
||||
mat_impl!(Matrix3, m11, m12, m13,
|
||||
m21, m22, m23,
|
||||
m31, m32, m33);
|
||||
repeat_impl!(Mat3, m11, m12, m13,
|
||||
repeat_impl!(Matrix3, m11, m12, m13,
|
||||
m21, m22, m23,
|
||||
m31, m32, m33);
|
||||
conversion_impl!(Mat3, 3);
|
||||
mat_cast_impl!(Mat3, m11, m12, m13,
|
||||
conversion_impl!(Matrix3, 3);
|
||||
mat_cast_impl!(Matrix3, m11, m12, m13,
|
||||
m21, m22, m23,
|
||||
m31, m32, m33);
|
||||
add_impl!(Mat3,
|
||||
add_impl!(Matrix3,
|
||||
m11, m12, m13,
|
||||
m21, m22, m23,
|
||||
m31, m32, m33
|
||||
);
|
||||
sub_impl!(Mat3,
|
||||
sub_impl!(Matrix3,
|
||||
m11, m12, m13,
|
||||
m21, m22, m23,
|
||||
m31, m32, m33
|
||||
);
|
||||
scalar_add_impl!(Mat3,
|
||||
scalar_add_impl!(Matrix3,
|
||||
m11, m12, m13,
|
||||
m21, m22, m23,
|
||||
m31, m32, m33
|
||||
);
|
||||
scalar_sub_impl!(Mat3,
|
||||
scalar_sub_impl!(Matrix3,
|
||||
m11, m12, m13,
|
||||
m21, m22, m23,
|
||||
m31, m32, m33
|
||||
);
|
||||
scalar_mul_impl!(Mat3,
|
||||
scalar_mul_impl!(Matrix3,
|
||||
m11, m12, m13,
|
||||
m21, m22, m23,
|
||||
m31, m32, m33
|
||||
);
|
||||
scalar_div_impl!(Mat3,
|
||||
scalar_div_impl!(Matrix3,
|
||||
m11, m12, m13,
|
||||
m21, m22, m23,
|
||||
m31, m32, m33
|
||||
);
|
||||
absolute_impl!(Mat3,
|
||||
absolute_impl!(Matrix3,
|
||||
m11, m12, m13,
|
||||
m21, m22, m23,
|
||||
m31, m32, m33
|
||||
);
|
||||
zero_impl!(Mat3,
|
||||
zero_impl!(Matrix3,
|
||||
m11, m12, m13,
|
||||
m21, m22, m23,
|
||||
m31, m32, m33
|
||||
);
|
||||
one_impl!(Mat3, ::one , ::zero, ::zero,
|
||||
one_impl!(Matrix3, ::one , ::zero, ::zero,
|
||||
::zero, ::one , ::zero,
|
||||
::zero, ::zero, ::one);
|
||||
iterable_impl!(Mat3, 3);
|
||||
iterable_mut_impl!(Mat3, 3);
|
||||
dim_impl!(Mat3, 3);
|
||||
indexable_impl!(Mat3, 3);
|
||||
index_impl!(Mat3, 3);
|
||||
at_fast_impl!(Mat3, 3);
|
||||
// (specialized); mul_impl!(Mat3, 3);
|
||||
// (specialized); rmul_impl!(Mat3, Vec3, 3);
|
||||
// (specialized); lmul_impl!(Mat3, Vec3, 3);
|
||||
// (specialized); inv_impl!(Mat3, 3);
|
||||
transpose_impl!(Mat3, 3);
|
||||
approx_eq_impl!(Mat3);
|
||||
// (specialized); row_impl!(Mat3, Vec3, 3);
|
||||
// (specialized); col_impl!(Mat3, Vec3, 3);
|
||||
col_slice_impl!(Mat3, Vec3, DVec3, 3);
|
||||
row_slice_impl!(Mat3, Vec3, DVec3, 3);
|
||||
diag_impl!(Mat3, Vec3, 3);
|
||||
to_homogeneous_impl!(Mat3, Mat4, 3, 4);
|
||||
from_homogeneous_impl!(Mat3, Mat4, 3, 4);
|
||||
outer_impl!(Vec3, Mat3);
|
||||
eigen_qr_impl!(Mat3, Vec3);
|
||||
arbitrary_impl!(Mat3,
|
||||
iterable_impl!(Matrix3, 3);
|
||||
iterable_mut_impl!(Matrix3, 3);
|
||||
dim_impl!(Matrix3, 3);
|
||||
indexable_impl!(Matrix3, 3);
|
||||
index_impl!(Matrix3, 3);
|
||||
at_fast_impl!(Matrix3, 3);
|
||||
// (specialized); mul_impl!(Matrix3, 3);
|
||||
// (specialized); rmul_impl!(Matrix3, Vector3, 3);
|
||||
// (specialized); lmul_impl!(Matrix3, Vector3, 3);
|
||||
// (specialized); inverse_impl!(Matrix3, 3);
|
||||
transpose_impl!(Matrix3, 3);
|
||||
approx_eq_impl!(Matrix3);
|
||||
// (specialized); row_impl!(Matrix3, Vector3, 3);
|
||||
// (specialized); col_impl!(Matrix3, Vector3, 3);
|
||||
col_slice_impl!(Matrix3, Vector3, DVector3, 3);
|
||||
row_slice_impl!(Matrix3, Vector3, DVector3, 3);
|
||||
diag_impl!(Matrix3, Vector3, 3);
|
||||
to_homogeneous_impl!(Matrix3, Matrix4, 3, 4);
|
||||
from_homogeneous_impl!(Matrix3, Matrix4, 3, 4);
|
||||
outer_impl!(Vector3, Matrix3);
|
||||
eigen_qr_impl!(Matrix3, Vector3);
|
||||
arbitrary_impl!(Matrix3,
|
||||
m11, m12, m13,
|
||||
m21, m22, m23,
|
||||
m31, m32, m33
|
||||
);
|
||||
rand_impl!(Mat3,
|
||||
rand_impl!(Matrix3,
|
||||
m11, m12, m13,
|
||||
m21, m22, m23,
|
||||
m31, m32, m33
|
||||
);
|
||||
mean_impl!(Mat3, Vec3, 3);
|
||||
mat_display_impl!(Mat3, 3);
|
||||
mean_impl!(Matrix3, Vector3, 3);
|
||||
mat_display_impl!(Matrix3, 3);
|
||||
|
||||
/// Square matrix of dimension 4.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Mat4<N> {
|
||||
pub struct Matrix4<N> {
|
||||
pub m11: N, pub m21: N, pub m31: N, pub m41: N,
|
||||
pub m12: N, pub m22: N, pub m32: N, pub m42: N,
|
||||
pub m13: N, pub m23: N, pub m33: N, pub m43: N,
|
||||
pub m14: N, pub m24: N, pub m34: N, pub m44: N
|
||||
}
|
||||
|
||||
eye_impl!(Mat4, 4, m11, m22, m33, m44);
|
||||
eye_impl!(Matrix4, 4, m11, m22, m33, m44);
|
||||
|
||||
mat_impl!(Mat4,
|
||||
mat_impl!(Matrix4,
|
||||
m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44
|
||||
);
|
||||
repeat_impl!(Mat4,
|
||||
repeat_impl!(Matrix4,
|
||||
m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44
|
||||
);
|
||||
conversion_impl!(Mat4, 4);
|
||||
mat_cast_impl!(Mat4,
|
||||
conversion_impl!(Matrix4, 4);
|
||||
mat_cast_impl!(Matrix4,
|
||||
m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44
|
||||
);
|
||||
add_impl!(Mat4,
|
||||
add_impl!(Matrix4,
|
||||
m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44
|
||||
);
|
||||
sub_impl!(Mat4,
|
||||
sub_impl!(Matrix4,
|
||||
m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44
|
||||
);
|
||||
scalar_add_impl!(Mat4,
|
||||
scalar_add_impl!(Matrix4,
|
||||
m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44
|
||||
);
|
||||
scalar_sub_impl!(Mat4,
|
||||
scalar_sub_impl!(Matrix4,
|
||||
m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44
|
||||
);
|
||||
scalar_mul_impl!(Mat4,
|
||||
scalar_mul_impl!(Matrix4,
|
||||
m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44
|
||||
);
|
||||
scalar_div_impl!(Mat4,
|
||||
scalar_div_impl!(Matrix4,
|
||||
m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44
|
||||
);
|
||||
absolute_impl!(Mat4,
|
||||
absolute_impl!(Matrix4,
|
||||
m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44
|
||||
);
|
||||
zero_impl!(Mat4,
|
||||
zero_impl!(Matrix4,
|
||||
m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44
|
||||
);
|
||||
one_impl!(Mat4, ::one , ::zero, ::zero, ::zero,
|
||||
one_impl!(Matrix4, ::one , ::zero, ::zero, ::zero,
|
||||
::zero, ::one , ::zero, ::zero,
|
||||
::zero, ::zero, ::one , ::zero,
|
||||
::zero, ::zero, ::zero, ::one);
|
||||
iterable_impl!(Mat4, 4);
|
||||
iterable_mut_impl!(Mat4, 4);
|
||||
dim_impl!(Mat4, 4);
|
||||
indexable_impl!(Mat4, 4);
|
||||
index_impl!(Mat4, 4);
|
||||
at_fast_impl!(Mat4, 4);
|
||||
mat_mul_mat_impl!(Mat4, 4);
|
||||
mat_mul_vec_impl!(Mat4, Vec4, 4, ::zero);
|
||||
vec_mul_mat_impl!(Mat4, Vec4, 4, ::zero);
|
||||
mat_mul_pnt_impl!(Mat4, Pnt4, 4, Orig::orig);
|
||||
pnt_mul_mat_impl!(Mat4, Pnt4, 4, Orig::orig);
|
||||
inv_impl!(Mat4, 4);
|
||||
transpose_impl!(Mat4, 4);
|
||||
approx_eq_impl!(Mat4);
|
||||
row_impl!(Mat4, Vec4, 4);
|
||||
col_impl!(Mat4, Vec4, 4);
|
||||
col_slice_impl!(Mat4, Vec4, DVec4, 4);
|
||||
row_slice_impl!(Mat4, Vec4, DVec4, 4);
|
||||
diag_impl!(Mat4, Vec4, 4);
|
||||
to_homogeneous_impl!(Mat4, Mat5, 4, 5);
|
||||
from_homogeneous_impl!(Mat4, Mat5, 4, 5);
|
||||
outer_impl!(Vec4, Mat4);
|
||||
eigen_qr_impl!(Mat4, Vec4);
|
||||
arbitrary_impl!(Mat4,
|
||||
iterable_impl!(Matrix4, 4);
|
||||
iterable_mut_impl!(Matrix4, 4);
|
||||
dim_impl!(Matrix4, 4);
|
||||
indexable_impl!(Matrix4, 4);
|
||||
index_impl!(Matrix4, 4);
|
||||
at_fast_impl!(Matrix4, 4);
|
||||
mat_mul_mat_impl!(Matrix4, 4);
|
||||
mat_mul_vec_impl!(Matrix4, Vector4, 4, ::zero);
|
||||
vec_mul_mat_impl!(Matrix4, Vector4, 4, ::zero);
|
||||
mat_mul_point_impl!(Matrix4, Point4, 4, Origin::origin);
|
||||
point_mul_mat_impl!(Matrix4, Point4, 4, Origin::origin);
|
||||
inverse_impl!(Matrix4, 4);
|
||||
transpose_impl!(Matrix4, 4);
|
||||
approx_eq_impl!(Matrix4);
|
||||
row_impl!(Matrix4, Vector4, 4);
|
||||
col_impl!(Matrix4, Vector4, 4);
|
||||
col_slice_impl!(Matrix4, Vector4, DVector4, 4);
|
||||
row_slice_impl!(Matrix4, Vector4, DVector4, 4);
|
||||
diag_impl!(Matrix4, Vector4, 4);
|
||||
to_homogeneous_impl!(Matrix4, Matrix5, 4, 5);
|
||||
from_homogeneous_impl!(Matrix4, Matrix5, 4, 5);
|
||||
outer_impl!(Vector4, Matrix4);
|
||||
eigen_qr_impl!(Matrix4, Vector4);
|
||||
arbitrary_impl!(Matrix4,
|
||||
m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44
|
||||
);
|
||||
rand_impl!(Mat4,
|
||||
rand_impl!(Matrix4,
|
||||
m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44
|
||||
);
|
||||
mean_impl!(Mat4, Vec4, 4);
|
||||
mat_display_impl!(Mat4, 4);
|
||||
mean_impl!(Matrix4, Vector4, 4);
|
||||
mat_display_impl!(Matrix4, 4);
|
||||
|
||||
/// Square matrix of dimension 5.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Mat5<N> {
|
||||
pub struct Matrix5<N> {
|
||||
pub m11: N, pub m21: N, pub m31: N, pub m41: N, pub m51: N,
|
||||
pub m12: N, pub m22: N, pub m32: N, pub m42: N, pub m52: N,
|
||||
pub m13: N, pub m23: N, pub m33: N, pub m43: N, pub m53: N,
|
||||
|
@ -370,137 +370,137 @@ pub struct Mat5<N> {
|
|||
pub m15: N, pub m25: N, pub m35: N, pub m45: N, pub m55: N
|
||||
}
|
||||
|
||||
eye_impl!(Mat5, 5, m11, m22, m33, m44, m55);
|
||||
eye_impl!(Matrix5, 5, m11, m22, m33, m44, m55);
|
||||
|
||||
mat_impl!(Mat5,
|
||||
mat_impl!(Matrix5,
|
||||
m11, m12, m13, m14, m15,
|
||||
m21, m22, m23, m24, m25,
|
||||
m31, m32, m33, m34, m35,
|
||||
m41, m42, m43, m44, m45,
|
||||
m51, m52, m53, m54, m55
|
||||
);
|
||||
repeat_impl!(Mat5,
|
||||
repeat_impl!(Matrix5,
|
||||
m11, m12, m13, m14, m15,
|
||||
m21, m22, m23, m24, m25,
|
||||
m31, m32, m33, m34, m35,
|
||||
m41, m42, m43, m44, m45,
|
||||
m51, m52, m53, m54, m55
|
||||
);
|
||||
conversion_impl!(Mat5, 5);
|
||||
mat_cast_impl!(Mat5,
|
||||
conversion_impl!(Matrix5, 5);
|
||||
mat_cast_impl!(Matrix5,
|
||||
m11, m12, m13, m14, m15,
|
||||
m21, m22, m23, m24, m25,
|
||||
m31, m32, m33, m34, m35,
|
||||
m41, m42, m43, m44, m45,
|
||||
m51, m52, m53, m54, m55
|
||||
);
|
||||
absolute_impl!(Mat5,
|
||||
absolute_impl!(Matrix5,
|
||||
m11, m12, m13, m14, m15,
|
||||
m21, m22, m23, m24, m25,
|
||||
m31, m32, m33, m34, m35,
|
||||
m41, m42, m43, m44, m45,
|
||||
m51, m52, m53, m54, m55
|
||||
);
|
||||
zero_impl!(Mat5,
|
||||
zero_impl!(Matrix5,
|
||||
m11, m12, m13, m14, m15,
|
||||
m21, m22, m23, m24, m25,
|
||||
m31, m32, m33, m34, m35,
|
||||
m41, m42, m43, m44, m45,
|
||||
m51, m52, m53, m54, m55
|
||||
);
|
||||
one_impl!(Mat5,
|
||||
one_impl!(Matrix5,
|
||||
::one , ::zero, ::zero, ::zero, ::zero,
|
||||
::zero, ::one , ::zero, ::zero, ::zero,
|
||||
::zero, ::zero, ::one , ::zero, ::zero,
|
||||
::zero, ::zero, ::zero, ::one , ::zero,
|
||||
::zero, ::zero, ::zero, ::zero, ::one
|
||||
);
|
||||
add_impl!(Mat5,
|
||||
add_impl!(Matrix5,
|
||||
m11, m12, m13, m14, m15,
|
||||
m21, m22, m23, m24, m25,
|
||||
m31, m32, m33, m34, m35,
|
||||
m41, m42, m43, m44, m45,
|
||||
m51, m52, m53, m54, m55
|
||||
);
|
||||
sub_impl!(Mat5,
|
||||
sub_impl!(Matrix5,
|
||||
m11, m12, m13, m14, m15,
|
||||
m21, m22, m23, m24, m25,
|
||||
m31, m32, m33, m34, m35,
|
||||
m41, m42, m43, m44, m45,
|
||||
m51, m52, m53, m54, m55
|
||||
);
|
||||
scalar_add_impl!(Mat5,
|
||||
scalar_add_impl!(Matrix5,
|
||||
m11, m12, m13, m14, m15,
|
||||
m21, m22, m23, m24, m25,
|
||||
m31, m32, m33, m34, m35,
|
||||
m41, m42, m43, m44, m45,
|
||||
m51, m52, m53, m54, m55
|
||||
);
|
||||
scalar_sub_impl!(Mat5,
|
||||
scalar_sub_impl!(Matrix5,
|
||||
m11, m12, m13, m14, m15,
|
||||
m21, m22, m23, m24, m25,
|
||||
m31, m32, m33, m34, m35,
|
||||
m41, m42, m43, m44, m45,
|
||||
m51, m52, m53, m54, m55
|
||||
);
|
||||
scalar_mul_impl!(Mat5,
|
||||
scalar_mul_impl!(Matrix5,
|
||||
m11, m12, m13, m14, m15,
|
||||
m21, m22, m23, m24, m25,
|
||||
m31, m32, m33, m34, m35,
|
||||
m41, m42, m43, m44, m45,
|
||||
m51, m52, m53, m54, m55
|
||||
);
|
||||
scalar_div_impl!(Mat5,
|
||||
scalar_div_impl!(Matrix5,
|
||||
m11, m12, m13, m14, m15,
|
||||
m21, m22, m23, m24, m25,
|
||||
m31, m32, m33, m34, m35,
|
||||
m41, m42, m43, m44, m45,
|
||||
m51, m52, m53, m54, m55
|
||||
);
|
||||
iterable_impl!(Mat5, 5);
|
||||
iterable_mut_impl!(Mat5, 5);
|
||||
dim_impl!(Mat5, 5);
|
||||
indexable_impl!(Mat5, 5);
|
||||
index_impl!(Mat5, 5);
|
||||
at_fast_impl!(Mat5, 5);
|
||||
mat_mul_mat_impl!(Mat5, 5);
|
||||
mat_mul_vec_impl!(Mat5, Vec5, 5, ::zero);
|
||||
vec_mul_mat_impl!(Mat5, Vec5, 5, ::zero);
|
||||
mat_mul_pnt_impl!(Mat5, Pnt5, 5, Orig::orig);
|
||||
pnt_mul_mat_impl!(Mat5, Pnt5, 5, Orig::orig);
|
||||
inv_impl!(Mat5, 5);
|
||||
transpose_impl!(Mat5, 5);
|
||||
approx_eq_impl!(Mat5);
|
||||
row_impl!(Mat5, Vec5, 5);
|
||||
col_impl!(Mat5, Vec5, 5);
|
||||
col_slice_impl!(Mat5, Vec5, DVec5, 5);
|
||||
row_slice_impl!(Mat5, Vec5, DVec5, 5);
|
||||
diag_impl!(Mat5, Vec5, 5);
|
||||
to_homogeneous_impl!(Mat5, Mat6, 5, 6);
|
||||
from_homogeneous_impl!(Mat5, Mat6, 5, 6);
|
||||
outer_impl!(Vec5, Mat5);
|
||||
eigen_qr_impl!(Mat5, Vec5);
|
||||
arbitrary_impl!(Mat5,
|
||||
iterable_impl!(Matrix5, 5);
|
||||
iterable_mut_impl!(Matrix5, 5);
|
||||
dim_impl!(Matrix5, 5);
|
||||
indexable_impl!(Matrix5, 5);
|
||||
index_impl!(Matrix5, 5);
|
||||
at_fast_impl!(Matrix5, 5);
|
||||
mat_mul_mat_impl!(Matrix5, 5);
|
||||
mat_mul_vec_impl!(Matrix5, Vector5, 5, ::zero);
|
||||
vec_mul_mat_impl!(Matrix5, Vector5, 5, ::zero);
|
||||
mat_mul_point_impl!(Matrix5, Point5, 5, Origin::origin);
|
||||
point_mul_mat_impl!(Matrix5, Point5, 5, Origin::origin);
|
||||
inverse_impl!(Matrix5, 5);
|
||||
transpose_impl!(Matrix5, 5);
|
||||
approx_eq_impl!(Matrix5);
|
||||
row_impl!(Matrix5, Vector5, 5);
|
||||
col_impl!(Matrix5, Vector5, 5);
|
||||
col_slice_impl!(Matrix5, Vector5, DVector5, 5);
|
||||
row_slice_impl!(Matrix5, Vector5, DVector5, 5);
|
||||
diag_impl!(Matrix5, Vector5, 5);
|
||||
to_homogeneous_impl!(Matrix5, Matrix6, 5, 6);
|
||||
from_homogeneous_impl!(Matrix5, Matrix6, 5, 6);
|
||||
outer_impl!(Vector5, Matrix5);
|
||||
eigen_qr_impl!(Matrix5, Vector5);
|
||||
arbitrary_impl!(Matrix5,
|
||||
m11, m12, m13, m14, m15,
|
||||
m21, m22, m23, m24, m25,
|
||||
m31, m32, m33, m34, m35,
|
||||
m41, m42, m43, m44, m45,
|
||||
m51, m52, m53, m54, m55
|
||||
);
|
||||
rand_impl!(Mat5,
|
||||
rand_impl!(Matrix5,
|
||||
m11, m12, m13, m14, m15,
|
||||
m21, m22, m23, m24, m25,
|
||||
m31, m32, m33, m34, m35,
|
||||
m41, m42, m43, m44, m45,
|
||||
m51, m52, m53, m54, m55
|
||||
);
|
||||
mean_impl!(Mat5, Vec5, 5);
|
||||
mat_display_impl!(Mat5, 5);
|
||||
mean_impl!(Matrix5, Vector5, 5);
|
||||
mat_display_impl!(Matrix5, 5);
|
||||
|
||||
/// Square matrix of dimension 6.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Mat6<N> {
|
||||
pub struct Matrix6<N> {
|
||||
pub m11: N, pub m21: N, pub m31: N, pub m41: N, pub m51: N, pub m61: N,
|
||||
pub m12: N, pub m22: N, pub m32: N, pub m42: N, pub m52: N, pub m62: N,
|
||||
pub m13: N, pub m23: N, pub m33: N, pub m43: N, pub m53: N, pub m63: N,
|
||||
|
@ -509,9 +509,9 @@ pub struct Mat6<N> {
|
|||
pub m16: N, pub m26: N, pub m36: N, pub m46: N, pub m56: N, pub m66: N
|
||||
}
|
||||
|
||||
eye_impl!(Mat6, 6, m11, m22, m33, m44, m55, m66);
|
||||
eye_impl!(Matrix6, 6, m11, m22, m33, m44, m55, m66);
|
||||
|
||||
mat_impl!(Mat6,
|
||||
mat_impl!(Matrix6,
|
||||
m11, m12, m13, m14, m15, m16,
|
||||
m21, m22, m23, m24, m25, m26,
|
||||
m31, m32, m33, m34, m35, m36,
|
||||
|
@ -519,7 +519,7 @@ mat_impl!(Mat6,
|
|||
m51, m52, m53, m54, m55, m56,
|
||||
m61, m62, m63, m64, m65, m66
|
||||
);
|
||||
repeat_impl!(Mat6,
|
||||
repeat_impl!(Matrix6,
|
||||
m11, m12, m13, m14, m15, m16,
|
||||
m21, m22, m23, m24, m25, m26,
|
||||
m31, m32, m33, m34, m35, m36,
|
||||
|
@ -527,8 +527,8 @@ repeat_impl!(Mat6,
|
|||
m51, m52, m53, m54, m55, m56,
|
||||
m61, m62, m63, m64, m65, m66
|
||||
);
|
||||
conversion_impl!(Mat6, 6);
|
||||
mat_cast_impl!(Mat6,
|
||||
conversion_impl!(Matrix6, 6);
|
||||
mat_cast_impl!(Matrix6,
|
||||
m11, m12, m13, m14, m15, m16,
|
||||
m21, m22, m23, m24, m25, m26,
|
||||
m31, m32, m33, m34, m35, m36,
|
||||
|
@ -536,7 +536,7 @@ mat_cast_impl!(Mat6,
|
|||
m51, m52, m53, m54, m55, m56,
|
||||
m61, m62, m63, m64, m65, m66
|
||||
);
|
||||
add_impl!(Mat6,
|
||||
add_impl!(Matrix6,
|
||||
m11, m12, m13, m14, m15, m16,
|
||||
m21, m22, m23, m24, m25, m26,
|
||||
m31, m32, m33, m34, m35, m36,
|
||||
|
@ -544,7 +544,7 @@ add_impl!(Mat6,
|
|||
m51, m52, m53, m54, m55, m56,
|
||||
m61, m62, m63, m64, m65, m66
|
||||
);
|
||||
sub_impl!(Mat6,
|
||||
sub_impl!(Matrix6,
|
||||
m11, m12, m13, m14, m15, m16,
|
||||
m21, m22, m23, m24, m25, m26,
|
||||
m31, m32, m33, m34, m35, m36,
|
||||
|
@ -552,7 +552,7 @@ sub_impl!(Mat6,
|
|||
m51, m52, m53, m54, m55, m56,
|
||||
m61, m62, m63, m64, m65, m66
|
||||
);
|
||||
scalar_add_impl!(Mat6,
|
||||
scalar_add_impl!(Matrix6,
|
||||
m11, m12, m13, m14, m15, m16,
|
||||
m21, m22, m23, m24, m25, m26,
|
||||
m31, m32, m33, m34, m35, m36,
|
||||
|
@ -560,7 +560,7 @@ scalar_add_impl!(Mat6,
|
|||
m51, m52, m53, m54, m55, m56,
|
||||
m61, m62, m63, m64, m65, m66
|
||||
);
|
||||
scalar_sub_impl!(Mat6,
|
||||
scalar_sub_impl!(Matrix6,
|
||||
m11, m12, m13, m14, m15, m16,
|
||||
m21, m22, m23, m24, m25, m26,
|
||||
m31, m32, m33, m34, m35, m36,
|
||||
|
@ -568,7 +568,7 @@ scalar_sub_impl!(Mat6,
|
|||
m51, m52, m53, m54, m55, m56,
|
||||
m61, m62, m63, m64, m65, m66
|
||||
);
|
||||
scalar_mul_impl!(Mat6,
|
||||
scalar_mul_impl!(Matrix6,
|
||||
m11, m12, m13, m14, m15, m16,
|
||||
m21, m22, m23, m24, m25, m26,
|
||||
m31, m32, m33, m34, m35, m36,
|
||||
|
@ -576,7 +576,7 @@ scalar_mul_impl!(Mat6,
|
|||
m51, m52, m53, m54, m55, m56,
|
||||
m61, m62, m63, m64, m65, m66
|
||||
);
|
||||
scalar_div_impl!(Mat6,
|
||||
scalar_div_impl!(Matrix6,
|
||||
m11, m12, m13, m14, m15, m16,
|
||||
m21, m22, m23, m24, m25, m26,
|
||||
m31, m32, m33, m34, m35, m36,
|
||||
|
@ -584,15 +584,15 @@ scalar_div_impl!(Mat6,
|
|||
m51, m52, m53, m54, m55, m56,
|
||||
m61, m62, m63, m64, m65, m66
|
||||
);
|
||||
absolute_impl!(Mat6, m11, m12, m13, m14, m15, m16, m21, m22, m23, m24, m25, m26,
|
||||
absolute_impl!(Matrix6, m11, m12, m13, m14, m15, m16, m21, m22, m23, m24, m25, m26,
|
||||
m31, m32, m33, m34, m35, m36, m41, m42, m43, m44, m45, m46, m51, m52, m53, m54, m55, m56,
|
||||
m61, m62, m63, m64, m65, m66);
|
||||
|
||||
zero_impl!(Mat6, m11, m12, m13, m14, m15, m16, m21, m22, m23, m24, m25, m26,
|
||||
zero_impl!(Matrix6, m11, m12, m13, m14, m15, m16, m21, m22, m23, m24, m25, m26,
|
||||
m31, m32, m33, m34, m35, m36, m41, m42, m43, m44, m45, m46, m51, m52, m53, m54, m55, m56,
|
||||
m61, m62, m63, m64, m65, m66);
|
||||
|
||||
one_impl!(Mat6,
|
||||
one_impl!(Matrix6,
|
||||
::one , ::zero, ::zero, ::zero, ::zero, ::zero,
|
||||
::zero, ::one , ::zero, ::zero, ::zero, ::zero,
|
||||
::zero, ::zero, ::one , ::zero, ::zero, ::zero,
|
||||
|
@ -600,28 +600,28 @@ one_impl!(Mat6,
|
|||
::zero, ::zero, ::zero, ::zero, ::one , ::zero,
|
||||
::zero, ::zero, ::zero, ::zero, ::zero, ::one
|
||||
);
|
||||
iterable_impl!(Mat6, 6);
|
||||
iterable_mut_impl!(Mat6, 6);
|
||||
dim_impl!(Mat6, 6);
|
||||
indexable_impl!(Mat6, 6);
|
||||
index_impl!(Mat6, 6);
|
||||
at_fast_impl!(Mat6, 6);
|
||||
mat_mul_mat_impl!(Mat6, 6);
|
||||
mat_mul_vec_impl!(Mat6, Vec6, 6, ::zero);
|
||||
vec_mul_mat_impl!(Mat6, Vec6, 6, ::zero);
|
||||
mat_mul_pnt_impl!(Mat6, Pnt6, 6, Orig::orig);
|
||||
pnt_mul_mat_impl!(Mat6, Pnt6, 6, Orig::orig);
|
||||
inv_impl!(Mat6, 6);
|
||||
transpose_impl!(Mat6, 6);
|
||||
approx_eq_impl!(Mat6);
|
||||
row_impl!(Mat6, Vec6, 6);
|
||||
col_impl!(Mat6, Vec6, 6);
|
||||
col_slice_impl!(Mat6, Vec6, DVec6, 6);
|
||||
row_slice_impl!(Mat6, Vec6, DVec6, 6);
|
||||
diag_impl!(Mat6, Vec6, 6);
|
||||
outer_impl!(Vec6, Mat6);
|
||||
eigen_qr_impl!(Mat6, Vec6);
|
||||
arbitrary_impl!(Mat6,
|
||||
iterable_impl!(Matrix6, 6);
|
||||
iterable_mut_impl!(Matrix6, 6);
|
||||
dim_impl!(Matrix6, 6);
|
||||
indexable_impl!(Matrix6, 6);
|
||||
index_impl!(Matrix6, 6);
|
||||
at_fast_impl!(Matrix6, 6);
|
||||
mat_mul_mat_impl!(Matrix6, 6);
|
||||
mat_mul_vec_impl!(Matrix6, Vector6, 6, ::zero);
|
||||
vec_mul_mat_impl!(Matrix6, Vector6, 6, ::zero);
|
||||
mat_mul_point_impl!(Matrix6, Point6, 6, Origin::origin);
|
||||
point_mul_mat_impl!(Matrix6, Point6, 6, Origin::origin);
|
||||
inverse_impl!(Matrix6, 6);
|
||||
transpose_impl!(Matrix6, 6);
|
||||
approx_eq_impl!(Matrix6);
|
||||
row_impl!(Matrix6, Vector6, 6);
|
||||
col_impl!(Matrix6, Vector6, 6);
|
||||
col_slice_impl!(Matrix6, Vector6, DVector6, 6);
|
||||
row_slice_impl!(Matrix6, Vector6, DVector6, 6);
|
||||
diag_impl!(Matrix6, Vector6, 6);
|
||||
outer_impl!(Vector6, Matrix6);
|
||||
eigen_qr_impl!(Matrix6, Vector6);
|
||||
arbitrary_impl!(Matrix6,
|
||||
m11, m12, m13, m14, m15, m16,
|
||||
m21, m22, m23, m24, m25, m26,
|
||||
m31, m32, m33, m34, m35, m36,
|
||||
|
@ -629,7 +629,7 @@ arbitrary_impl!(Mat6,
|
|||
m51, m52, m53, m54, m55, m56,
|
||||
m61, m62, m63, m64, m65, m66
|
||||
);
|
||||
rand_impl!(Mat6,
|
||||
rand_impl!(Matrix6,
|
||||
m11, m12, m13, m14, m15, m16,
|
||||
m21, m22, m23, m24, m25, m26,
|
||||
m31, m32, m33, m34, m35, m36,
|
||||
|
@ -637,5 +637,5 @@ rand_impl!(Mat6,
|
|||
m51, m52, m53, m54, m55, m56,
|
||||
m61, m62, m63, m64, m65, m66
|
||||
);
|
||||
mean_impl!(Mat6, Vec6, 6);
|
||||
mat_display_impl!(Mat6, 6);
|
||||
mean_impl!(Matrix6, Vector6, 6);
|
||||
mat_display_impl!(Matrix6, 6);
|
|
@ -14,37 +14,37 @@ macro_rules! mat_impl(
|
|||
);
|
||||
|
||||
macro_rules! conversion_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N> AsRef<[[N; $dim]; $dim]> for $t<N> {
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N> AsRef<[[N; $dimension]; $dimension]> for $t<N> {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &[[N; $dim]; $dim] {
|
||||
fn as_ref(&self) -> &[[N; $dimension]; $dimension] {
|
||||
unsafe {
|
||||
mem::transmute(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> AsMut<[[N; $dim]; $dim]> for $t<N> {
|
||||
impl<N> AsMut<[[N; $dimension]; $dimension]> for $t<N> {
|
||||
#[inline]
|
||||
fn as_mut(&mut self) -> &mut [[N; $dim]; $dim] {
|
||||
fn as_mut(&mut self) -> &mut [[N; $dimension]; $dimension] {
|
||||
unsafe {
|
||||
mem::transmute(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, N> From<&'a [[N; $dim]; $dim]> for &'a $t<N> {
|
||||
impl<'a, N> From<&'a [[N; $dimension]; $dimension]> for &'a $t<N> {
|
||||
#[inline]
|
||||
fn from(arr: &'a [[N; $dim]; $dim]) -> &'a $t<N> {
|
||||
fn from(arr: &'a [[N; $dimension]; $dimension]) -> &'a $t<N> {
|
||||
unsafe {
|
||||
mem::transmute(arr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, N> From<&'a mut [[N; $dim]; $dim]> for &'a mut $t<N> {
|
||||
impl<'a, N> From<&'a mut [[N; $dimension]; $dimension]> for &'a mut $t<N> {
|
||||
#[inline]
|
||||
fn from(arr: &'a mut [[N; $dim]; $dim]) -> &'a mut $t<N> {
|
||||
fn from(arr: &'a mut [[N; $dimension]; $dimension]) -> &'a mut $t<N> {
|
||||
unsafe {
|
||||
mem::transmute(arr)
|
||||
}
|
||||
|
@ -54,18 +54,18 @@ macro_rules! conversion_impl(
|
|||
);
|
||||
|
||||
macro_rules! at_fast_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N: Copy> $t<N> {
|
||||
#[inline]
|
||||
pub unsafe fn at_fast(&self, (i, j): (usize, usize)) -> N {
|
||||
(*mem::transmute::<&$t<N>, &[N; $dim * $dim]>(self)
|
||||
.get_unchecked(i + j * $dim))
|
||||
(*mem::transmute::<&$t<N>, &[N; $dimension * $dimension]>(self)
|
||||
.get_unchecked(i + j * $dimension))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn set_fast(&mut self, (i, j): (usize, usize), val: N) {
|
||||
(*mem::transmute::<&mut $t<N>, &mut [N; $dim * $dim]>(self)
|
||||
.get_unchecked_mut(i + j * $dim)) = val
|
||||
(*mem::transmute::<&mut $t<N>, &mut [N; $dimension * $dimension]>(self)
|
||||
.get_unchecked_mut(i + j * $dimension)) = val
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -259,10 +259,10 @@ macro_rules! mat_sub_scalar_impl(
|
|||
|
||||
|
||||
macro_rules! eye_impl(
|
||||
($t: ident, $dim: expr, $($comp_diagN: ident),+) => (
|
||||
($t: ident, $dimension: expr, $($comp_diagN: ident),+) => (
|
||||
impl<N: Zero + One> Eye for $t<N> {
|
||||
fn new_identity(dim: usize) -> $t<N> {
|
||||
assert!(dim == $dim);
|
||||
fn new_identity(dimension: usize) -> $t<N> {
|
||||
assert!(dimension == $dimension);
|
||||
let mut eye: $t<N> = ::zero();
|
||||
$(eye.$comp_diagN = ::one();)+
|
||||
eye
|
||||
|
@ -295,12 +295,12 @@ macro_rules! absolute_impl(
|
|||
);
|
||||
|
||||
macro_rules! iterable_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N> Iterable<N> for $t<N> {
|
||||
#[inline]
|
||||
fn iter<'l>(&'l self) -> Iter<'l, N> {
|
||||
unsafe {
|
||||
mem::transmute::<&'l $t<N>, &'l [N; $dim * $dim]>(self).iter()
|
||||
mem::transmute::<&'l $t<N>, &'l [N; $dimension * $dimension]>(self).iter()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -308,12 +308,12 @@ macro_rules! iterable_impl(
|
|||
);
|
||||
|
||||
macro_rules! iterable_mut_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N> IterableMut<N> for $t<N> {
|
||||
#[inline]
|
||||
fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> {
|
||||
unsafe {
|
||||
mem::transmute::<&'l mut $t<N>, &'l mut [N; $dim * $dim]>(self).iter_mut()
|
||||
mem::transmute::<&'l mut $t<N>, &'l mut [N; $dimension * $dimension]>(self).iter_mut()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -350,22 +350,22 @@ macro_rules! zero_impl(
|
|||
);
|
||||
|
||||
macro_rules! dim_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N> Dim for $t<N> {
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N> Dimension for $t<N> {
|
||||
#[inline]
|
||||
fn dim(_: Option<$t<N>>) -> usize {
|
||||
$dim
|
||||
fn dimension(_: Option<$t<N>>) -> usize {
|
||||
$dimension
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! indexable_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N> Shape<(usize, usize)> for $t<N> {
|
||||
#[inline]
|
||||
fn shape(&self) -> (usize, usize) {
|
||||
($dim, $dim)
|
||||
($dimension, $dimension)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -373,32 +373,32 @@ macro_rules! indexable_impl(
|
|||
#[inline]
|
||||
fn swap(&mut self, (i1, j1): (usize, usize), (i2, j2): (usize, usize)) {
|
||||
unsafe {
|
||||
mem::transmute::<&mut $t<N>, &mut [N; $dim * $dim]>(self)
|
||||
.swap(i1 + j1 * $dim, i2 + j2 * $dim)
|
||||
mem::transmute::<&mut $t<N>, &mut [N; $dimension * $dimension]>(self)
|
||||
.swap(i1 + j1 * $dimension, i2 + j2 * $dimension)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn unsafe_at(&self, (i, j): (usize, usize)) -> N {
|
||||
(*mem::transmute::<&$t<N>, &[N; $dim * $dim]>(self).get_unchecked(i + j * $dim))
|
||||
(*mem::transmute::<&$t<N>, &[N; $dimension * $dimension]>(self).get_unchecked(i + j * $dimension))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn unsafe_set(&mut self, (i, j): (usize, usize), val: N) {
|
||||
(*mem::transmute::<&mut $t<N>, &mut [N; $dim * $dim]>(self).get_unchecked_mut(i + j * $dim)) = val
|
||||
(*mem::transmute::<&mut $t<N>, &mut [N; $dimension * $dimension]>(self).get_unchecked_mut(i + j * $dimension)) = val
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! index_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N> Index<(usize, usize)> for $t<N> {
|
||||
type Output = N;
|
||||
|
||||
fn index(&self, (i, j): (usize, usize)) -> &N {
|
||||
unsafe {
|
||||
&mem::transmute::<&$t<N>, & [N; $dim * $dim]>(self)[i + j * $dim]
|
||||
&mem::transmute::<&$t<N>, & [N; $dimension * $dimension]>(self)[i + j * $dimension]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -406,7 +406,7 @@ macro_rules! index_impl(
|
|||
impl<N> IndexMut<(usize, usize)> for $t<N> {
|
||||
fn index_mut(&mut self, (i, j): (usize, usize)) -> &mut N {
|
||||
unsafe {
|
||||
&mut mem::transmute::<&mut $t<N>, &mut [N; $dim * $dim]>(self)[i + j * $dim]
|
||||
&mut mem::transmute::<&mut $t<N>, &mut [N; $dimension * $dimension]>(self)[i + j * $dimension]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -414,23 +414,23 @@ macro_rules! index_impl(
|
|||
);
|
||||
|
||||
macro_rules! col_slice_impl(
|
||||
($t: ident, $tv: ident, $slice: ident, $dim: expr) => (
|
||||
impl<N: Clone + Copy + Zero> ColSlice<$slice<N>> for $t<N> {
|
||||
($t: ident, $tv: ident, $slice: ident, $dimension: expr) => (
|
||||
impl<N: Clone + Copy + Zero> ColumnSlice<$slice<N>> for $t<N> {
|
||||
fn col_slice(&self, cid: usize, rstart: usize, rend: usize) -> $slice<N> {
|
||||
let col = self.col(cid);
|
||||
let column = self.column(cid);
|
||||
|
||||
$slice::from_slice(rend - rstart, &col.as_ref()[rstart .. rend])
|
||||
$slice::from_slice(rend - rstart, &column.as_ref()[rstart .. rend])
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! row_impl(
|
||||
($t: ident, $tv: ident, $dim: expr) => (
|
||||
($t: ident, $tv: ident, $dimension: expr) => (
|
||||
impl<N: Copy + Zero> Row<$tv<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn nrows(&self) -> usize {
|
||||
Dim::dim(None::<$t<N>>)
|
||||
Dimension::dimension(None::<$t<N>>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -455,7 +455,7 @@ macro_rules! row_impl(
|
|||
);
|
||||
|
||||
macro_rules! row_slice_impl(
|
||||
($t: ident, $tv: ident, $slice: ident, $dim: expr) => (
|
||||
($t: ident, $tv: ident, $slice: ident, $dimension: expr) => (
|
||||
impl<N: Clone + Copy + Zero> RowSlice<$slice<N>> for $t<N> {
|
||||
fn row_slice(&self, rid: usize, cstart: usize, cend: usize) -> $slice<N> {
|
||||
let row = self.row(rid);
|
||||
|
@ -467,26 +467,26 @@ macro_rules! row_slice_impl(
|
|||
);
|
||||
|
||||
macro_rules! col_impl(
|
||||
($t: ident, $tv: ident, $dim: expr) => (
|
||||
impl<N: Copy + Zero> Col<$tv<N>> for $t<N> {
|
||||
($t: ident, $tv: ident, $dimension: expr) => (
|
||||
impl<N: Copy + Zero> Column<$tv<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn ncols(&self) -> usize {
|
||||
Dim::dim(None::<$t<N>>)
|
||||
Dimension::dimension(None::<$t<N>>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_col(&mut self, col: usize, v: $tv<N>) {
|
||||
fn set_col(&mut self, column: usize, v: $tv<N>) {
|
||||
for (i, e) in v.iter().enumerate() {
|
||||
self[(i, col)] = *e;
|
||||
self[(i, column)] = *e;
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn col(&self, col: usize) -> $tv<N> {
|
||||
fn column(&self, column: usize) -> $tv<N> {
|
||||
let mut res: $tv<N> = ::zero();
|
||||
|
||||
for (i, e) in res.iter_mut().enumerate() {
|
||||
*e = self[(i, col)];
|
||||
*e = self[(i, column)];
|
||||
}
|
||||
|
||||
res
|
||||
|
@ -496,34 +496,34 @@ macro_rules! col_impl(
|
|||
);
|
||||
|
||||
macro_rules! diag_impl(
|
||||
($t: ident, $tv: ident, $dim: expr) => (
|
||||
impl<N: Copy + Zero> Diag<$tv<N>> for $t<N> {
|
||||
($t: ident, $tv: ident, $dimension: expr) => (
|
||||
impl<N: Copy + Zero> Diagonal<$tv<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn from_diag(diag: &$tv<N>) -> $t<N> {
|
||||
fn from_diag(diagonal: &$tv<N>) -> $t<N> {
|
||||
let mut res: $t<N> = ::zero();
|
||||
|
||||
res.set_diag(diag);
|
||||
res.set_diag(diagonal);
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn diag(&self) -> $tv<N> {
|
||||
let mut diag: $tv<N> = ::zero();
|
||||
fn diagonal(&self) -> $tv<N> {
|
||||
let mut diagonal: $tv<N> = ::zero();
|
||||
|
||||
for i in 0 .. $dim {
|
||||
unsafe { diag.unsafe_set(i, self.unsafe_at((i, i))) }
|
||||
for i in 0 .. $dimension {
|
||||
unsafe { diagonal.unsafe_set(i, self.unsafe_at((i, i))) }
|
||||
}
|
||||
|
||||
diag
|
||||
diagonal
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Zero> DiagMut<$tv<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn set_diag(&mut self, diag: &$tv<N>) {
|
||||
for i in 0 .. $dim {
|
||||
unsafe { self.unsafe_set((i, i), diag.unsafe_at(i)) }
|
||||
fn set_diag(&mut self, diagonal: &$tv<N>) {
|
||||
for i in 0 .. $dimension {
|
||||
unsafe { self.unsafe_set((i, i), diagonal.unsafe_at(i)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -531,19 +531,19 @@ macro_rules! diag_impl(
|
|||
);
|
||||
|
||||
macro_rules! mat_mul_mat_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N: Copy + BaseNum> Mul<$t<N>> for $t<N> {
|
||||
type Output = $t<N>;
|
||||
#[inline]
|
||||
fn mul(self, right: $t<N>) -> $t<N> {
|
||||
let mut res: $t<N> = ::zero();
|
||||
|
||||
for i in 0 .. $dim {
|
||||
for j in 0 .. $dim {
|
||||
for i in 0 .. $dimension {
|
||||
for j in 0 .. $dimension {
|
||||
let mut acc: N = ::zero();
|
||||
|
||||
unsafe {
|
||||
for k in 0 .. $dim {
|
||||
for k in 0 .. $dimension {
|
||||
acc = acc + self.at_fast((i, k)) * right.at_fast((k, j));
|
||||
}
|
||||
|
||||
|
@ -568,7 +568,7 @@ macro_rules! mat_mul_mat_impl(
|
|||
);
|
||||
|
||||
macro_rules! vec_mul_mat_impl(
|
||||
($t: ident, $v: ident, $dim: expr, $zero: expr) => (
|
||||
($t: ident, $v: ident, $dimension: expr, $zero: expr) => (
|
||||
impl<N: Copy + BaseNum> Mul<$t<N>> for $v<N> {
|
||||
type Output = $v<N>;
|
||||
|
||||
|
@ -576,8 +576,8 @@ macro_rules! vec_mul_mat_impl(
|
|||
fn mul(self, right: $t<N>) -> $v<N> {
|
||||
let mut res : $v<N> = $zero();
|
||||
|
||||
for i in 0..$dim {
|
||||
for j in 0..$dim {
|
||||
for i in 0..$dimension {
|
||||
for j in 0..$dimension {
|
||||
unsafe {
|
||||
let val = res.at_fast(i) + self.at_fast(j) * right.at_fast((j, i));
|
||||
res.set_fast(i, val)
|
||||
|
@ -601,7 +601,7 @@ macro_rules! vec_mul_mat_impl(
|
|||
);
|
||||
|
||||
macro_rules! mat_mul_vec_impl(
|
||||
($t: ident, $v: ident, $dim: expr, $zero: expr) => (
|
||||
($t: ident, $v: ident, $dimension: expr, $zero: expr) => (
|
||||
impl<N: Copy + BaseNum> Mul<$v<N>> for $t<N> {
|
||||
type Output = $v<N>;
|
||||
|
||||
|
@ -609,8 +609,8 @@ macro_rules! mat_mul_vec_impl(
|
|||
fn mul(self, right: $v<N>) -> $v<N> {
|
||||
let mut res : $v<N> = $zero();
|
||||
|
||||
for i in 0 .. $dim {
|
||||
for j in 0 .. $dim {
|
||||
for i in 0 .. $dimension {
|
||||
for j in 0 .. $dimension {
|
||||
unsafe {
|
||||
let val = res.at_fast(i) + self.at_fast((i, j)) * right.at_fast(j);
|
||||
res.set_fast(i, val)
|
||||
|
@ -624,26 +624,26 @@ macro_rules! mat_mul_vec_impl(
|
|||
)
|
||||
);
|
||||
|
||||
macro_rules! pnt_mul_mat_impl(
|
||||
($t: ident, $v: ident, $dim: expr, $zero: expr) => (
|
||||
vec_mul_mat_impl!($t, $v, $dim, $zero);
|
||||
macro_rules! point_mul_mat_impl(
|
||||
($t: ident, $v: ident, $dimension: expr, $zero: expr) => (
|
||||
vec_mul_mat_impl!($t, $v, $dimension, $zero);
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! mat_mul_pnt_impl(
|
||||
($t: ident, $v: ident, $dim: expr, $zero: expr) => (
|
||||
mat_mul_vec_impl!($t, $v, $dim, $zero);
|
||||
macro_rules! mat_mul_point_impl(
|
||||
($t: ident, $v: ident, $dimension: expr, $zero: expr) => (
|
||||
mat_mul_vec_impl!($t, $v, $dimension, $zero);
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! inv_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
macro_rules! inverse_impl(
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N: Copy + BaseNum>
|
||||
Inv for $t<N> {
|
||||
Inverse for $t<N> {
|
||||
#[inline]
|
||||
fn inv(&self) -> Option<$t<N>> {
|
||||
fn inverse(&self) -> Option<$t<N>> {
|
||||
let mut res : $t<N> = *self;
|
||||
if res.inv_mut() {
|
||||
if res.inverse_mut() {
|
||||
Some(res)
|
||||
}
|
||||
else {
|
||||
|
@ -651,18 +651,18 @@ macro_rules! inv_impl(
|
|||
}
|
||||
}
|
||||
|
||||
fn inv_mut(&mut self) -> bool {
|
||||
fn inverse_mut(&mut self) -> bool {
|
||||
let mut res: $t<N> = ::one();
|
||||
|
||||
// inversion using Gauss-Jordan elimination
|
||||
for k in 0..$dim {
|
||||
for k in 0..$dimension {
|
||||
// search a non-zero value on the k-th column
|
||||
// FIXME: would it be worth it to spend some more time searching for the
|
||||
// max instead?
|
||||
|
||||
let mut n0 = k; // index of a non-zero entry
|
||||
|
||||
while n0 != $dim {
|
||||
while n0 != $dimension {
|
||||
if self[(n0, k)] != ::zero() {
|
||||
break;
|
||||
}
|
||||
|
@ -670,13 +670,13 @@ macro_rules! inv_impl(
|
|||
n0 = n0 + 1;
|
||||
}
|
||||
|
||||
if n0 == $dim {
|
||||
if n0 == $dimension {
|
||||
return false
|
||||
}
|
||||
|
||||
// swap pivot line
|
||||
if n0 != k {
|
||||
for j in 0..$dim {
|
||||
for j in 0..$dimension {
|
||||
self.swap((n0, j), (k, j));
|
||||
res.swap((n0, j), (k, j));
|
||||
}
|
||||
|
@ -684,26 +684,26 @@ macro_rules! inv_impl(
|
|||
|
||||
let pivot = self[(k, k)];
|
||||
|
||||
for j in k..$dim {
|
||||
for j in k..$dimension {
|
||||
let selfval = self[(k, j)] / pivot;
|
||||
self[(k, j)] = selfval;
|
||||
}
|
||||
|
||||
for j in 0..$dim {
|
||||
for j in 0..$dimension {
|
||||
let resval = res[(k, j)] / pivot;
|
||||
res[(k, j)] = resval;
|
||||
}
|
||||
|
||||
for l in 0..$dim {
|
||||
for l in 0..$dimension {
|
||||
if l != k {
|
||||
let normalizer = self[(l, k)];
|
||||
|
||||
for j in k..$dim {
|
||||
for j in k..$dimension {
|
||||
let selfval = self[(l, j)] - self[(k, j)] * normalizer;
|
||||
self[(l, j)] = selfval;
|
||||
}
|
||||
|
||||
for j in 0..$dim {
|
||||
for j in 0..$dimension {
|
||||
let resval = res[(l, j)] - res[(k, j)] * normalizer;
|
||||
res[(l, j)] = resval;
|
||||
}
|
||||
|
@ -720,7 +720,7 @@ macro_rules! inv_impl(
|
|||
);
|
||||
|
||||
macro_rules! transpose_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N: Copy> Transpose for $t<N> {
|
||||
#[inline]
|
||||
fn transpose(&self) -> $t<N> {
|
||||
|
@ -732,7 +732,7 @@ macro_rules! transpose_impl(
|
|||
|
||||
#[inline]
|
||||
fn transpose_mut(&mut self) {
|
||||
for i in 1..$dim {
|
||||
for i in 1..$dimension {
|
||||
for j in 0..i {
|
||||
self.swap((i, j), (j, i))
|
||||
}
|
||||
|
@ -771,14 +771,14 @@ macro_rules! approx_eq_impl(
|
|||
);
|
||||
|
||||
macro_rules! to_homogeneous_impl(
|
||||
($t: ident, $t2: ident, $dim: expr, $dim2: expr) => (
|
||||
($t: ident, $t2: ident, $dimension: expr, $dim2: expr) => (
|
||||
impl<N: BaseNum + Copy> ToHomogeneous<$t2<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn to_homogeneous(&self) -> $t2<N> {
|
||||
let mut res: $t2<N> = ::one();
|
||||
|
||||
for i in 0..$dim {
|
||||
for j in 0..$dim {
|
||||
for i in 0..$dimension {
|
||||
for j in 0..$dimension {
|
||||
res[(i, j)] = self[(i, j)]
|
||||
}
|
||||
}
|
||||
|
@ -790,14 +790,14 @@ macro_rules! to_homogeneous_impl(
|
|||
);
|
||||
|
||||
macro_rules! from_homogeneous_impl(
|
||||
($t: ident, $t2: ident, $dim: expr, $dim2: expr) => (
|
||||
($t: ident, $t2: ident, $dimension: expr, $dim2: expr) => (
|
||||
impl<N: BaseNum + Copy> FromHomogeneous<$t2<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn from(m: &$t2<N>) -> $t<N> {
|
||||
let mut res: $t<N> = ::one();
|
||||
|
||||
for i in 0..$dim {
|
||||
for j in 0..$dim {
|
||||
for i in 0..$dimension {
|
||||
for j in 0..$dimension {
|
||||
res[(i, j)] = m[(i, j)]
|
||||
}
|
||||
}
|
||||
|
@ -819,8 +819,8 @@ macro_rules! outer_impl(
|
|||
#[inline]
|
||||
fn outer(&self, other: &$t<N>) -> $m<N> {
|
||||
let mut res: $m<N> = ::zero();
|
||||
for i in 0..Dim::dim(None::<$t<N>>) {
|
||||
for j in 0..Dim::dim(None::<$t<N>>) {
|
||||
for i in 0..Dimension::dimension(None::<$t<N>>) {
|
||||
for j in 0..Dimension::dimension(None::<$t<N>>) {
|
||||
res[(i, j)] = self[i] * other[j]
|
||||
}
|
||||
}
|
||||
|
@ -843,14 +843,14 @@ macro_rules! eigen_qr_impl(
|
|||
|
||||
|
||||
macro_rules! mean_impl(
|
||||
($t: ident, $v: ident, $dim: expr) => (
|
||||
($t: ident, $v: ident, $dimension: expr) => (
|
||||
impl<N: BaseNum + Cast<f64> + Clone> Mean<$v<N>> for $t<N> {
|
||||
fn mean(&self) -> $v<N> {
|
||||
let mut res: $v<N> = ::zero();
|
||||
let normalizer: N = Cast::from(1.0f64 / $dim as f64);
|
||||
let normalizer: N = Cast::from(1.0f64 / $dimension as f64);
|
||||
|
||||
for i in 0 .. $dim {
|
||||
for j in 0 .. $dim {
|
||||
for i in 0 .. $dimension {
|
||||
for j in 0 .. $dimension {
|
||||
unsafe {
|
||||
let acc = res.unsafe_at(j) + self.unsafe_at((i, j)) * normalizer;
|
||||
res.unsafe_set(j, acc);
|
||||
|
@ -865,7 +865,7 @@ macro_rules! mean_impl(
|
|||
);
|
||||
|
||||
macro_rules! mat_display_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
|
||||
// XXX: will will not always work correctly due to rounding errors.
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
@ -888,8 +888,8 @@ macro_rules! mat_display_impl(
|
|||
|
||||
let mut max_decimal_length = 0;
|
||||
let mut decimal_lengths: $t<usize> = ::zero();
|
||||
for i in 0 .. $dim {
|
||||
for j in 0 .. $dim {
|
||||
for i in 0 .. $dimension {
|
||||
for j in 0 .. $dimension {
|
||||
decimal_lengths[(i, j)] = integral_length(&self[(i, j)].clone());
|
||||
max_decimal_length = ::max(max_decimal_length, decimal_lengths[(i, j)]);
|
||||
}
|
||||
|
@ -898,11 +898,11 @@ macro_rules! mat_display_impl(
|
|||
let precision = f.precision().unwrap_or(3);
|
||||
let max_number_length = max_decimal_length + precision + 1;
|
||||
|
||||
try!(writeln!(f, " ┌ {:>width$} ┐", "", width = max_number_length * $dim + $dim - 1));
|
||||
try!(writeln!(f, " ┌ {:>width$} ┐", "", width = max_number_length * $dimension + $dimension - 1));
|
||||
|
||||
for i in 0 .. $dim {
|
||||
for i in 0 .. $dimension {
|
||||
try!(write!(f, " │"));
|
||||
for j in 0 .. $dim {
|
||||
for j in 0 .. $dimension {
|
||||
let number_length = decimal_lengths[(i, j)] + precision + 1;
|
||||
let pad = max_number_length - number_length;
|
||||
try!(write!(f, " {:>thepad$}", "", thepad = pad));
|
||||
|
@ -911,7 +911,7 @@ macro_rules! mat_display_impl(
|
|||
try!(writeln!(f, " │"));
|
||||
}
|
||||
|
||||
writeln!(f, " └ {:>width$} ┘", "", width = max_number_length * $dim + $dim - 1)
|
||||
writeln!(f, " └ {:>width$} ┘", "", width = max_number_length * $dimension + $dimension - 1)
|
||||
}
|
||||
}
|
||||
)
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use traits::structure::{BaseFloat, Cast};
|
||||
use structs::{Pnt3, Vec3, Mat4};
|
||||
use structs::{Point3, Vector3, Matrix4};
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
@ -11,7 +11,7 @@ use quickcheck::{Arbitrary, Gen};
|
|||
/// `(-1, -1, -1)` to `(1, 1, 1)`. Reading or modifying its individual properties is cheap but
|
||||
/// applying the transformation is costly.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
|
||||
pub struct Ortho3<N> {
|
||||
pub struct Orthographic3<N> {
|
||||
left: N,
|
||||
right: N,
|
||||
bottom: N,
|
||||
|
@ -26,18 +26,18 @@ pub struct Ortho3<N> {
|
|||
/// `(-1, -1, -1)` to `(1, 1, 1)`. Reading or modifying its individual properties is costly but
|
||||
/// applying the transformation is cheap.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
|
||||
pub struct OrthoMat3<N> {
|
||||
mat: Mat4<N>
|
||||
pub struct OrthographicMatrix3<N> {
|
||||
matrix: Matrix4<N>
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> Ortho3<N> {
|
||||
impl<N: BaseFloat> Orthographic3<N> {
|
||||
/// Creates a new 3D orthographic projection.
|
||||
pub fn new(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Ortho3<N> {
|
||||
pub fn new(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Orthographic3<N> {
|
||||
assert!(!::is_zero(&(zfar - znear)));
|
||||
assert!(!::is_zero(&(left - right)));
|
||||
assert!(!::is_zero(&(top - bottom)));
|
||||
|
||||
Ortho3 {
|
||||
Orthographic3 {
|
||||
left: left,
|
||||
right: right,
|
||||
bottom: bottom,
|
||||
|
@ -48,30 +48,30 @@ impl<N: BaseFloat> Ortho3<N> {
|
|||
}
|
||||
|
||||
/// Builds a 4D projection matrix (using homogeneous coordinates) for this projection.
|
||||
pub fn to_mat(&self) -> Mat4<N> {
|
||||
self.to_persp_mat().mat
|
||||
pub fn to_matrix(&self) -> Matrix4<N> {
|
||||
self.to_orthographic_matrix().matrix
|
||||
}
|
||||
|
||||
/// Build a `OrthoMat3` representing this projection.
|
||||
pub fn to_persp_mat(&self) -> OrthoMat3<N> {
|
||||
OrthoMat3::new(self.left, self.right, self.bottom, self.top, self.znear, self.zfar)
|
||||
/// Build a `OrthographicMatrix3` representing this projection.
|
||||
pub fn to_orthographic_matrix(&self) -> OrthographicMatrix3<N> {
|
||||
OrthographicMatrix3::new(self.left, self.right, self.bottom, self.top, self.znear, self.zfar)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for Ortho3<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> Ortho3<N> {
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for Orthographic3<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> Orthographic3<N> {
|
||||
let left = Arbitrary::arbitrary(g);
|
||||
let right = reject(g, |x: &N| *x > left);
|
||||
let bottom = Arbitrary::arbitrary(g);
|
||||
let top = reject(g, |x: &N| *x > bottom);
|
||||
let znear = Arbitrary::arbitrary(g);
|
||||
let zfar = reject(g, |x: &N| *x > znear);
|
||||
Ortho3::new(left, right, bottom, top, znear, zfar)
|
||||
Orthographic3::new(left, right, bottom, top, znear, zfar)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + Clone> Ortho3<N> {
|
||||
impl<N: BaseFloat + Clone> Orthographic3<N> {
|
||||
/// The smallest x-coordinate of the view cuboid.
|
||||
#[inline]
|
||||
pub fn left(&self) -> N {
|
||||
|
@ -152,29 +152,29 @@ impl<N: BaseFloat + Clone> Ortho3<N> {
|
|||
|
||||
/// Projects a point.
|
||||
#[inline]
|
||||
pub fn project_pnt(&self, p: &Pnt3<N>) -> Pnt3<N> {
|
||||
pub fn project_point(&self, p: &Point3<N>) -> Point3<N> {
|
||||
// FIXME: optimize that
|
||||
self.to_persp_mat().project_pnt(p)
|
||||
self.to_orthographic_matrix().project_point(p)
|
||||
}
|
||||
|
||||
/// Projects a vector.
|
||||
#[inline]
|
||||
pub fn project_vec(&self, p: &Vec3<N>) -> Vec3<N> {
|
||||
pub fn project_vector(&self, p: &Vector3<N>) -> Vector3<N> {
|
||||
// FIXME: optimize that
|
||||
self.to_persp_mat().project_vec(p)
|
||||
self.to_orthographic_matrix().project_vector(p)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> OrthoMat3<N> {
|
||||
impl<N: BaseFloat> OrthographicMatrix3<N> {
|
||||
/// Creates a new orthographic projection matrix.
|
||||
pub fn new(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> OrthoMat3<N> {
|
||||
pub fn new(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> OrthographicMatrix3<N> {
|
||||
assert!(left < right, "The left corner must be farther than the right corner.");
|
||||
assert!(bottom < top, "The top corner must be higher than the bottom corner.");
|
||||
assert!(znear < zfar, "The far plane must be farther than the near plane.");
|
||||
|
||||
let mat: Mat4<N> = ::one();
|
||||
let matrix: Matrix4<N> = ::one();
|
||||
|
||||
let mut res = OrthoMat3 { mat: mat };
|
||||
let mut res = OrthographicMatrix3 { matrix: matrix };
|
||||
res.set_left_and_right(left, right);
|
||||
res.set_bottom_and_top(bottom, top);
|
||||
res.set_znear_and_zfar(znear, zfar);
|
||||
|
@ -183,7 +183,7 @@ impl<N: BaseFloat> OrthoMat3<N> {
|
|||
}
|
||||
|
||||
/// Creates a new orthographic projection matrix from an aspect ratio and the vertical field of view.
|
||||
pub fn new_with_fov(aspect: N, vfov: N, znear: N, zfar: N) -> OrthoMat3<N> {
|
||||
pub fn new_with_fov(aspect: N, vfov: N, znear: N, zfar: N) -> OrthographicMatrix3<N> {
|
||||
assert!(znear < zfar, "The far plane must be farther than the near plane.");
|
||||
assert!(!::is_zero(&aspect));
|
||||
|
||||
|
@ -192,59 +192,59 @@ impl<N: BaseFloat> OrthoMat3<N> {
|
|||
let width = zfar * (vfov / _2).tan();
|
||||
let height = width / aspect;
|
||||
|
||||
OrthoMat3::new(-width / _2, width / _2, -height / _2, height / _2, znear, zfar)
|
||||
OrthographicMatrix3::new(-width / _2, width / _2, -height / _2, height / _2, znear, zfar)
|
||||
}
|
||||
|
||||
/// Creates a new orthographic matrix from a 4D matrix.
|
||||
///
|
||||
/// This is unsafe because the input matrix is not checked to be a orthographic projection.
|
||||
#[inline]
|
||||
pub unsafe fn new_with_mat(mat: Mat4<N>) -> OrthoMat3<N> {
|
||||
OrthoMat3 {
|
||||
mat: mat
|
||||
pub unsafe fn new_with_matrix(matrix: Matrix4<N>) -> OrthographicMatrix3<N> {
|
||||
OrthographicMatrix3 {
|
||||
matrix: matrix
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a reference to the 4D matrix (using homogeneous coordinates) of this projection.
|
||||
#[inline]
|
||||
pub fn as_mat<'a>(&'a self) -> &'a Mat4<N> {
|
||||
&self.mat
|
||||
pub fn as_matrix<'a>(&'a self) -> &'a Matrix4<N> {
|
||||
&self.matrix
|
||||
}
|
||||
|
||||
/// The smallest x-coordinate of the view cuboid.
|
||||
#[inline]
|
||||
pub fn left(&self) -> N {
|
||||
(-::one::<N>() - self.mat.m14) / self.mat.m11
|
||||
(-::one::<N>() - self.matrix.m14) / self.matrix.m11
|
||||
}
|
||||
|
||||
/// The largest x-coordinate of the view cuboid.
|
||||
#[inline]
|
||||
pub fn right(&self) -> N {
|
||||
(::one::<N>() - self.mat.m14) / self.mat.m11
|
||||
(::one::<N>() - self.matrix.m14) / self.matrix.m11
|
||||
}
|
||||
|
||||
/// The smallest y-coordinate of the view cuboid.
|
||||
#[inline]
|
||||
pub fn bottom(&self) -> N {
|
||||
(-::one::<N>() - self.mat.m24) / self.mat.m22
|
||||
(-::one::<N>() - self.matrix.m24) / self.matrix.m22
|
||||
}
|
||||
|
||||
/// The largest y-coordinate of the view cuboid.
|
||||
#[inline]
|
||||
pub fn top(&self) -> N {
|
||||
(::one::<N>() - self.mat.m24) / self.mat.m22
|
||||
(::one::<N>() - self.matrix.m24) / self.matrix.m22
|
||||
}
|
||||
|
||||
/// The near plane offset of the view cuboid.
|
||||
#[inline]
|
||||
pub fn znear(&self) -> N {
|
||||
(::one::<N>() + self.mat.m34) / self.mat.m33
|
||||
(::one::<N>() + self.matrix.m34) / self.matrix.m33
|
||||
}
|
||||
|
||||
/// The far plane offset of the view cuboid.
|
||||
#[inline]
|
||||
pub fn zfar(&self) -> N {
|
||||
(-::one::<N>() + self.mat.m34) / self.mat.m33
|
||||
(-::one::<N>() + self.matrix.m34) / self.matrix.m33
|
||||
}
|
||||
|
||||
/// Sets the smallest x-coordinate of the view cuboid.
|
||||
|
@ -293,65 +293,65 @@ impl<N: BaseFloat> OrthoMat3<N> {
|
|||
#[inline]
|
||||
pub fn set_left_and_right(&mut self, left: N, right: N) {
|
||||
assert!(left < right, "The left corner must be farther than the right corner.");
|
||||
self.mat.m11 = <N as Cast<f64>>::from(2.0) / (right - left);
|
||||
self.mat.m14 = -(right + left) / (right - left);
|
||||
self.matrix.m11 = <N as Cast<f64>>::from(2.0) / (right - left);
|
||||
self.matrix.m14 = -(right + left) / (right - left);
|
||||
}
|
||||
|
||||
/// Sets the view cuboid coordinates along the `y` axis.
|
||||
#[inline]
|
||||
pub fn set_bottom_and_top(&mut self, bottom: N, top: N) {
|
||||
assert!(bottom < top, "The top corner must be higher than the bottom corner.");
|
||||
self.mat.m22 = <N as Cast<f64>>::from(2.0) / (top - bottom);
|
||||
self.mat.m24 = -(top + bottom) / (top - bottom);
|
||||
self.matrix.m22 = <N as Cast<f64>>::from(2.0) / (top - bottom);
|
||||
self.matrix.m24 = -(top + bottom) / (top - bottom);
|
||||
}
|
||||
|
||||
/// Sets the near and far plane offsets of the view cuboid.
|
||||
#[inline]
|
||||
pub fn set_znear_and_zfar(&mut self, znear: N, zfar: N) {
|
||||
assert!(!::is_zero(&(zfar - znear)));
|
||||
self.mat.m33 = -<N as Cast<f64>>::from(2.0) / (zfar - znear);
|
||||
self.mat.m34 = -(zfar + znear) / (zfar - znear);
|
||||
self.matrix.m33 = -<N as Cast<f64>>::from(2.0) / (zfar - znear);
|
||||
self.matrix.m34 = -(zfar + znear) / (zfar - znear);
|
||||
}
|
||||
|
||||
/// Projects a point.
|
||||
#[inline]
|
||||
pub fn project_pnt(&self, p: &Pnt3<N>) -> Pnt3<N> {
|
||||
Pnt3::new(
|
||||
self.mat.m11 * p.x + self.mat.m14,
|
||||
self.mat.m22 * p.y + self.mat.m24,
|
||||
self.mat.m33 * p.z + self.mat.m34
|
||||
pub fn project_point(&self, p: &Point3<N>) -> Point3<N> {
|
||||
Point3::new(
|
||||
self.matrix.m11 * p.x + self.matrix.m14,
|
||||
self.matrix.m22 * p.y + self.matrix.m24,
|
||||
self.matrix.m33 * p.z + self.matrix.m34
|
||||
)
|
||||
}
|
||||
|
||||
/// Projects a vector.
|
||||
#[inline]
|
||||
pub fn project_vec(&self, p: &Vec3<N>) -> Vec3<N> {
|
||||
Vec3::new(
|
||||
self.mat.m11 * p.x,
|
||||
self.mat.m22 * p.y,
|
||||
self.mat.m33 * p.z
|
||||
pub fn project_vector(&self, p: &Vector3<N>) -> Vector3<N> {
|
||||
Vector3::new(
|
||||
self.matrix.m11 * p.x,
|
||||
self.matrix.m22 * p.y,
|
||||
self.matrix.m33 * p.z
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + Clone> OrthoMat3<N> {
|
||||
impl<N: BaseFloat + Clone> OrthographicMatrix3<N> {
|
||||
/// Returns the 4D matrix (using homogeneous coordinates) of this projection.
|
||||
#[inline]
|
||||
pub fn to_mat<'a>(&'a self) -> Mat4<N> {
|
||||
self.mat.clone()
|
||||
pub fn to_matrix<'a>(&'a self) -> Matrix4<N> {
|
||||
self.matrix.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for OrthoMat3<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> OrthoMat3<N> {
|
||||
let x: Ortho3<N> = Arbitrary::arbitrary(g);
|
||||
x.to_persp_mat()
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for OrthographicMatrix3<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> OrthographicMatrix3<N> {
|
||||
let x: Orthographic3<N> = Arbitrary::arbitrary(g);
|
||||
x.to_orthographic_matrix()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Simple helper function for rejection sampling
|
||||
/// Similarityple helper function for rejection sampling
|
||||
#[cfg(feature="arbitrary")]
|
||||
#[inline]
|
||||
pub fn reject<G: Gen, F: FnMut(&T) -> bool, T: Arbitrary>(g: &mut G, f: F) -> T {
|
|
@ -1,5 +1,5 @@
|
|||
use traits::structure::BaseFloat;
|
||||
use structs::{Pnt3, Vec3, Mat4};
|
||||
use structs::{Point3, Vector3, Matrix4};
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
@ -11,9 +11,9 @@ use quickcheck::{Arbitrary, Gen};
|
|||
/// `(1, 1, 1)`. Reading or modifying its individual properties is cheap but applying the
|
||||
/// transformation is costly.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
|
||||
pub struct Persp3<N> {
|
||||
pub struct Perspective3<N> {
|
||||
aspect: N,
|
||||
fovy: N,
|
||||
fovy: N,
|
||||
znear: N,
|
||||
zfar: N
|
||||
}
|
||||
|
@ -24,46 +24,46 @@ pub struct Persp3<N> {
|
|||
/// `(1, 1, 1)`. Reading or modifying its individual properties is costly but applying the
|
||||
/// transformation is cheap.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
|
||||
pub struct PerspMat3<N> {
|
||||
mat: Mat4<N>
|
||||
pub struct PerspectiveMatrix3<N> {
|
||||
matrix: Matrix4<N>
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> Persp3<N> {
|
||||
impl<N: BaseFloat> Perspective3<N> {
|
||||
/// Creates a new 3D perspective projection.
|
||||
pub fn new(aspect: N, fovy: N, znear: N, zfar: N) -> Persp3<N> {
|
||||
pub fn new(aspect: N, fovy: N, znear: N, zfar: N) -> Perspective3<N> {
|
||||
assert!(!::is_zero(&(zfar - znear)));
|
||||
assert!(!::is_zero(&aspect));
|
||||
|
||||
Persp3 {
|
||||
Perspective3 {
|
||||
aspect: aspect,
|
||||
fovy: fovy,
|
||||
fovy: fovy,
|
||||
znear: znear,
|
||||
zfar: zfar
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a 4D projection matrix (using homogeneous coordinates) for this projection.
|
||||
pub fn to_mat(&self) -> Mat4<N> {
|
||||
self.to_persp_mat().mat
|
||||
pub fn to_matrix(&self) -> Matrix4<N> {
|
||||
self.to_perspective_matrix().matrix
|
||||
}
|
||||
|
||||
/// Build a `PerspMat3` representing this projection.
|
||||
pub fn to_persp_mat(&self) -> PerspMat3<N> {
|
||||
PerspMat3::new(self.aspect, self.fovy, self.znear, self.zfar)
|
||||
/// Build a `PerspectiveMatrix3` representing this projection.
|
||||
pub fn to_perspective_matrix(&self) -> PerspectiveMatrix3<N> {
|
||||
PerspectiveMatrix3::new(self.aspect, self.fovy, self.znear, self.zfar)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for Persp3<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> Persp3<N> {
|
||||
use structs::ortho::reject;
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for Perspective3<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> Perspective3<N> {
|
||||
use structs::orthographic::reject;
|
||||
let znear = Arbitrary::arbitrary(g);
|
||||
let zfar = reject(g, |&x: &N| !::is_zero(&(x - znear)));
|
||||
Persp3::new(Arbitrary::arbitrary(g), Arbitrary::arbitrary(g), znear, zfar)
|
||||
Perspective3::new(Arbitrary::arbitrary(g), Arbitrary::arbitrary(g), znear, zfar)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + Clone> Persp3<N> {
|
||||
impl<N: BaseFloat + Clone> Perspective3<N> {
|
||||
/// Gets the `width / height` aspect ratio.
|
||||
#[inline]
|
||||
pub fn aspect(&self) -> N {
|
||||
|
@ -122,33 +122,33 @@ impl<N: BaseFloat + Clone> Persp3<N> {
|
|||
|
||||
/// Projects a point.
|
||||
#[inline]
|
||||
pub fn project_pnt(&self, p: &Pnt3<N>) -> Pnt3<N> {
|
||||
pub fn project_point(&self, p: &Point3<N>) -> Point3<N> {
|
||||
// FIXME: optimize that
|
||||
self.to_persp_mat().project_pnt(p)
|
||||
self.to_perspective_matrix().project_point(p)
|
||||
}
|
||||
|
||||
/// Projects a vector.
|
||||
#[inline]
|
||||
pub fn project_vec(&self, p: &Vec3<N>) -> Vec3<N> {
|
||||
pub fn project_vector(&self, p: &Vector3<N>) -> Vector3<N> {
|
||||
// FIXME: optimize that
|
||||
self.to_persp_mat().project_vec(p)
|
||||
self.to_perspective_matrix().project_vector(p)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> PerspMat3<N> {
|
||||
impl<N: BaseFloat> PerspectiveMatrix3<N> {
|
||||
/// Creates a new perspective matrix from the aspect ratio, y field of view, and near/far planes.
|
||||
pub fn new(aspect: N, fovy: N, znear: N, zfar: N) -> PerspMat3<N> {
|
||||
pub fn new(aspect: N, fovy: N, znear: N, zfar: N) -> PerspectiveMatrix3<N> {
|
||||
assert!(!::is_zero(&(znear - zfar)));
|
||||
assert!(!::is_zero(&aspect));
|
||||
|
||||
let mat: Mat4<N> = ::one();
|
||||
let matrix: Matrix4<N> = ::one();
|
||||
|
||||
let mut res = PerspMat3 { mat: mat };
|
||||
let mut res = PerspectiveMatrix3 { matrix: matrix };
|
||||
res.set_fovy(fovy);
|
||||
res.set_aspect(aspect);
|
||||
res.set_znear_and_zfar(znear, zfar);
|
||||
res.mat.m44 = ::zero();
|
||||
res.mat.m43 = -::one::<N>();
|
||||
res.matrix.m44 = ::zero();
|
||||
res.matrix.m43 = -::one::<N>();
|
||||
|
||||
res
|
||||
}
|
||||
|
@ -157,22 +157,22 @@ impl<N: BaseFloat> PerspMat3<N> {
|
|||
///
|
||||
/// This is unsafe because the input matrix is not checked to be a perspective projection.
|
||||
#[inline]
|
||||
pub unsafe fn new_with_mat(mat: Mat4<N>) -> PerspMat3<N> {
|
||||
PerspMat3 {
|
||||
mat: mat
|
||||
pub unsafe fn new_with_matrix(matrix: Matrix4<N>) -> PerspectiveMatrix3<N> {
|
||||
PerspectiveMatrix3 {
|
||||
matrix: matrix
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a reference to the 4D matrix (using homogeneous coordinates) of this projection.
|
||||
#[inline]
|
||||
pub fn as_mat<'a>(&'a self) -> &'a Mat4<N> {
|
||||
&self.mat
|
||||
pub fn as_matrix<'a>(&'a self) -> &'a Matrix4<N> {
|
||||
&self.matrix
|
||||
}
|
||||
|
||||
/// Gets the `width / height` aspect ratio of the view frustrum.
|
||||
#[inline]
|
||||
pub fn aspect(&self) -> N {
|
||||
self.mat.m22 / self.mat.m11
|
||||
self.matrix.m22 / self.matrix.m11
|
||||
}
|
||||
|
||||
/// Gets the y field of view of the view frustrum.
|
||||
|
@ -181,7 +181,7 @@ impl<N: BaseFloat> PerspMat3<N> {
|
|||
let _1: N = ::one();
|
||||
let _2 = _1 + _1;
|
||||
|
||||
(_1 / self.mat.m22).atan() * _2
|
||||
(_1 / self.matrix.m22).atan() * _2
|
||||
}
|
||||
|
||||
/// Gets the near plane offset of the view frustrum.
|
||||
|
@ -189,9 +189,9 @@ impl<N: BaseFloat> PerspMat3<N> {
|
|||
pub fn znear(&self) -> N {
|
||||
let _1: N = ::one();
|
||||
let _2 = _1 + _1;
|
||||
let ratio = (-self.mat.m33 + _1) / (-self.mat.m33 - _1);
|
||||
let ratio = (-self.matrix.m33 + _1) / (-self.matrix.m33 - _1);
|
||||
|
||||
self.mat.m34 / (_2 * ratio) - self.mat.m34 / _2
|
||||
self.matrix.m34 / (_2 * ratio) - self.matrix.m34 / _2
|
||||
}
|
||||
|
||||
/// Gets the far plane offset of the view frustrum.
|
||||
|
@ -199,9 +199,9 @@ impl<N: BaseFloat> PerspMat3<N> {
|
|||
pub fn zfar(&self) -> N {
|
||||
let _1: N = ::one();
|
||||
let _2 = _1 + _1;
|
||||
let ratio = (-self.mat.m33 + _1) / (-self.mat.m33 - _1);
|
||||
let ratio = (-self.matrix.m33 + _1) / (-self.matrix.m33 - _1);
|
||||
|
||||
(self.mat.m34 - ratio * self.mat.m34) / _2
|
||||
(self.matrix.m34 - ratio * self.matrix.m34) / _2
|
||||
}
|
||||
|
||||
// FIXME: add a method to retrieve znear and zfar simultaneously?
|
||||
|
@ -211,7 +211,7 @@ impl<N: BaseFloat> PerspMat3<N> {
|
|||
#[inline]
|
||||
pub fn set_aspect(&mut self, aspect: N) {
|
||||
assert!(!::is_zero(&aspect));
|
||||
self.mat.m11 = self.mat.m22 / aspect;
|
||||
self.matrix.m11 = self.matrix.m22 / aspect;
|
||||
}
|
||||
|
||||
/// Updates this projection with a new y field of view of the view frustrum.
|
||||
|
@ -220,9 +220,9 @@ impl<N: BaseFloat> PerspMat3<N> {
|
|||
let _1: N = ::one();
|
||||
let _2 = _1 + _1;
|
||||
|
||||
let old_m22 = self.mat.m22.clone();
|
||||
self.mat.m22 = _1 / (fovy / _2).tan();
|
||||
self.mat.m11 = self.mat.m11 * (self.mat.m22 / old_m22);
|
||||
let old_m22 = self.matrix.m22.clone();
|
||||
self.matrix.m22 = _1 / (fovy / _2).tan();
|
||||
self.matrix.m11 = self.matrix.m11 * (self.matrix.m22 / old_m22);
|
||||
}
|
||||
|
||||
/// Updates this projection matrix with a new near plane offset of the view frustrum.
|
||||
|
@ -245,47 +245,47 @@ impl<N: BaseFloat> PerspMat3<N> {
|
|||
let _1: N = ::one();
|
||||
let _2 = _1 + _1;
|
||||
|
||||
self.mat.m33 = (zfar + znear) / (znear - zfar);
|
||||
self.mat.m34 = zfar * znear * _2 / (znear - zfar);
|
||||
self.matrix.m33 = (zfar + znear) / (znear - zfar);
|
||||
self.matrix.m34 = zfar * znear * _2 / (znear - zfar);
|
||||
}
|
||||
|
||||
/// Projects a point.
|
||||
#[inline]
|
||||
pub fn project_pnt(&self, p: &Pnt3<N>) -> Pnt3<N> {
|
||||
pub fn project_point(&self, p: &Point3<N>) -> Point3<N> {
|
||||
let _1: N = ::one();
|
||||
let inv_denom = -_1 / p.z;
|
||||
Pnt3::new(
|
||||
self.mat.m11 * p.x * inv_denom,
|
||||
self.mat.m22 * p.y * inv_denom,
|
||||
(self.mat.m33 * p.z + self.mat.m34) * inv_denom
|
||||
let inverse_denom = -_1 / p.z;
|
||||
Point3::new(
|
||||
self.matrix.m11 * p.x * inverse_denom,
|
||||
self.matrix.m22 * p.y * inverse_denom,
|
||||
(self.matrix.m33 * p.z + self.matrix.m34) * inverse_denom
|
||||
)
|
||||
}
|
||||
|
||||
/// Projects a vector.
|
||||
#[inline]
|
||||
pub fn project_vec(&self, p: &Vec3<N>) -> Vec3<N> {
|
||||
pub fn project_vector(&self, p: &Vector3<N>) -> Vector3<N> {
|
||||
let _1: N = ::one();
|
||||
let inv_denom = -_1 / p.z;
|
||||
Vec3::new(
|
||||
self.mat.m11 * p.x * inv_denom,
|
||||
self.mat.m22 * p.y * inv_denom,
|
||||
self.mat.m33
|
||||
let inverse_denom = -_1 / p.z;
|
||||
Vector3::new(
|
||||
self.matrix.m11 * p.x * inverse_denom,
|
||||
self.matrix.m22 * p.y * inverse_denom,
|
||||
self.matrix.m33
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + Clone> PerspMat3<N> {
|
||||
impl<N: BaseFloat + Clone> PerspectiveMatrix3<N> {
|
||||
/// Returns the 4D matrix (using homogeneous coordinates) of this projection.
|
||||
#[inline]
|
||||
pub fn to_mat<'a>(&'a self) -> Mat4<N> {
|
||||
self.mat.clone()
|
||||
pub fn to_matrix<'a>(&'a self) -> Matrix4<N> {
|
||||
self.matrix.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for PerspMat3<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> PerspMat3<N> {
|
||||
let x: Persp3<N> = Arbitrary::arbitrary(g);
|
||||
x.to_persp_mat()
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for PerspectiveMatrix3<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> PerspectiveMatrix3<N> {
|
||||
let x: Perspective3<N> = Arbitrary::arbitrary(g);
|
||||
x.to_perspective_matrix()
|
||||
}
|
||||
}
|
|
@ -1,309 +0,0 @@
|
|||
//! Points with dimension known at compile-time.
|
||||
|
||||
use std::mem;
|
||||
use std::fmt;
|
||||
use std::slice::{Iter, IterMut};
|
||||
use std::iter::{Iterator, FromIterator, IntoIterator};
|
||||
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
|
||||
use rand::{Rand, Rng};
|
||||
use num::{Zero, One};
|
||||
use traits::operations::{ApproxEq, POrd, POrdering, Axpy};
|
||||
use traits::structure::{Cast, Dim, Indexable, Iterable, IterableMut, PntAsVec, Shape,
|
||||
NumPnt, FloatPnt, BaseFloat, BaseNum, Bounded, Repeat};
|
||||
use traits::geometry::{Orig, FromHomogeneous, ToHomogeneous};
|
||||
use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6};
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// Point of dimension 1.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Pnt1<N> {
|
||||
/// First component of the point.
|
||||
pub x: N
|
||||
}
|
||||
|
||||
new_impl!(Pnt1, x);
|
||||
orig_impl!(Pnt1, x);
|
||||
pord_impl!(Pnt1, x,);
|
||||
scalar_mul_impl!(Pnt1, x);
|
||||
scalar_div_impl!(Pnt1, x);
|
||||
scalar_add_impl!(Pnt1, x);
|
||||
scalar_sub_impl!(Pnt1, x);
|
||||
vec_cast_impl!(Pnt1, x);
|
||||
conversion_impl!(Pnt1, 1);
|
||||
index_impl!(Pnt1);
|
||||
indexable_impl!(Pnt1, 1);
|
||||
at_fast_impl!(Pnt1, 1);
|
||||
repeat_impl!(Pnt1, val, x);
|
||||
dim_impl!(Pnt1, 1);
|
||||
container_impl!(Pnt1);
|
||||
pnt_as_vec_impl!(Pnt1, Vec1, x);
|
||||
pnt_sub_impl!(Pnt1, Vec1);
|
||||
neg_impl!(Pnt1, x);
|
||||
pnt_add_vec_impl!(Pnt1, Vec1, x);
|
||||
pnt_sub_vec_impl!(Pnt1, Vec1, x);
|
||||
approx_eq_impl!(Pnt1, x);
|
||||
from_iterator_impl!(Pnt1, iterator);
|
||||
bounded_impl!(Pnt1, x);
|
||||
axpy_impl!(Pnt1, x);
|
||||
iterable_impl!(Pnt1, 1);
|
||||
iterable_mut_impl!(Pnt1, 1);
|
||||
pnt_to_homogeneous_impl!(Pnt1, Pnt2, y, x);
|
||||
pnt_from_homogeneous_impl!(Pnt1, Pnt2, y, x);
|
||||
num_float_pnt_impl!(Pnt1, Vec1);
|
||||
arbitrary_pnt_impl!(Pnt1, x);
|
||||
rand_impl!(Pnt1, x);
|
||||
pnt_display_impl!(Pnt1);
|
||||
|
||||
/// Point of dimension 2.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Pnt2<N> {
|
||||
/// First component of the point.
|
||||
pub x: N,
|
||||
/// Second component of the point.
|
||||
pub y: N
|
||||
}
|
||||
|
||||
new_impl!(Pnt2, x, y);
|
||||
orig_impl!(Pnt2, x, y);
|
||||
pord_impl!(Pnt2, x, y);
|
||||
scalar_mul_impl!(Pnt2, x, y);
|
||||
scalar_div_impl!(Pnt2, x, y);
|
||||
scalar_add_impl!(Pnt2, x, y);
|
||||
scalar_sub_impl!(Pnt2, x, y);
|
||||
vec_cast_impl!(Pnt2, x, y);
|
||||
conversion_impl!(Pnt2, 2);
|
||||
index_impl!(Pnt2);
|
||||
indexable_impl!(Pnt2, 2);
|
||||
at_fast_impl!(Pnt2, 2);
|
||||
repeat_impl!(Pnt2, val, x, y);
|
||||
dim_impl!(Pnt2, 2);
|
||||
container_impl!(Pnt2);
|
||||
pnt_as_vec_impl!(Pnt2, Vec2, x, y);
|
||||
pnt_sub_impl!(Pnt2, Vec2);
|
||||
neg_impl!(Pnt2, x, y);
|
||||
pnt_add_vec_impl!(Pnt2, Vec2, x, y);
|
||||
pnt_sub_vec_impl!(Pnt2, Vec2, x, y);
|
||||
approx_eq_impl!(Pnt2, x, y);
|
||||
from_iterator_impl!(Pnt2, iterator, iterator);
|
||||
bounded_impl!(Pnt2, x, y);
|
||||
axpy_impl!(Pnt2, x, y);
|
||||
iterable_impl!(Pnt2, 2);
|
||||
iterable_mut_impl!(Pnt2, 2);
|
||||
pnt_to_homogeneous_impl!(Pnt2, Pnt3, z, x, y);
|
||||
pnt_from_homogeneous_impl!(Pnt2, Pnt3, z, x, y);
|
||||
num_float_pnt_impl!(Pnt2, Vec2);
|
||||
arbitrary_pnt_impl!(Pnt2, x, y);
|
||||
rand_impl!(Pnt2, x, y);
|
||||
pnt_display_impl!(Pnt2);
|
||||
|
||||
/// Point of dimension 3.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Pnt3<N> {
|
||||
/// First component of the point.
|
||||
pub x: N,
|
||||
/// Second component of the point.
|
||||
pub y: N,
|
||||
/// Third component of the point.
|
||||
pub z: N
|
||||
}
|
||||
|
||||
new_impl!(Pnt3, x, y, z);
|
||||
orig_impl!(Pnt3, x, y, z);
|
||||
pord_impl!(Pnt3, x, y, z);
|
||||
scalar_mul_impl!(Pnt3, x, y, z);
|
||||
scalar_div_impl!(Pnt3, x, y, z);
|
||||
scalar_add_impl!(Pnt3, x, y, z);
|
||||
scalar_sub_impl!(Pnt3, x, y, z);
|
||||
vec_cast_impl!(Pnt3, x, y, z);
|
||||
conversion_impl!(Pnt3, 3);
|
||||
index_impl!(Pnt3);
|
||||
indexable_impl!(Pnt3, 3);
|
||||
at_fast_impl!(Pnt3, 3);
|
||||
repeat_impl!(Pnt3, val, x, y, z);
|
||||
dim_impl!(Pnt3, 3);
|
||||
container_impl!(Pnt3);
|
||||
pnt_as_vec_impl!(Pnt3, Vec3, x, y, z);
|
||||
pnt_sub_impl!(Pnt3, Vec3);
|
||||
neg_impl!(Pnt3, x, y, z);
|
||||
pnt_add_vec_impl!(Pnt3, Vec3, x, y, z);
|
||||
pnt_sub_vec_impl!(Pnt3, Vec3, x, y, z);
|
||||
approx_eq_impl!(Pnt3, x, y, z);
|
||||
from_iterator_impl!(Pnt3, iterator, iterator, iterator);
|
||||
bounded_impl!(Pnt3, x, y, z);
|
||||
axpy_impl!(Pnt3, x, y, z);
|
||||
iterable_impl!(Pnt3, 3);
|
||||
iterable_mut_impl!(Pnt3, 3);
|
||||
pnt_to_homogeneous_impl!(Pnt3, Pnt4, w, x, y, z);
|
||||
pnt_from_homogeneous_impl!(Pnt3, Pnt4, w, x, y, z);
|
||||
num_float_pnt_impl!(Pnt3, Vec3);
|
||||
arbitrary_pnt_impl!(Pnt3, x, y, z);
|
||||
rand_impl!(Pnt3, x, y, z);
|
||||
pnt_display_impl!(Pnt3);
|
||||
|
||||
/// Point of dimension 4.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Pnt4<N> {
|
||||
/// First component of the point.
|
||||
pub x: N,
|
||||
/// Second component of the point.
|
||||
pub y: N,
|
||||
/// Third component of the point.
|
||||
pub z: N,
|
||||
/// Fourth component of the point.
|
||||
pub w: N
|
||||
}
|
||||
|
||||
new_impl!(Pnt4, x, y, z, w);
|
||||
orig_impl!(Pnt4, x, y, z, w);
|
||||
pord_impl!(Pnt4, x, y, z, w);
|
||||
scalar_mul_impl!(Pnt4, x, y, z, w);
|
||||
scalar_div_impl!(Pnt4, x, y, z, w);
|
||||
scalar_add_impl!(Pnt4, x, y, z, w);
|
||||
scalar_sub_impl!(Pnt4, x, y, z, w);
|
||||
vec_cast_impl!(Pnt4, x, y, z, w);
|
||||
conversion_impl!(Pnt4, 4);
|
||||
index_impl!(Pnt4);
|
||||
indexable_impl!(Pnt4, 4);
|
||||
at_fast_impl!(Pnt4, 4);
|
||||
repeat_impl!(Pnt4, val, x, y, z, w);
|
||||
dim_impl!(Pnt4, 4);
|
||||
container_impl!(Pnt4);
|
||||
pnt_as_vec_impl!(Pnt4, Vec4, x, y, z, w);
|
||||
pnt_sub_impl!(Pnt4, Vec4);
|
||||
neg_impl!(Pnt4, x, y, z, w);
|
||||
pnt_add_vec_impl!(Pnt4, Vec4, x, y, z, w);
|
||||
pnt_sub_vec_impl!(Pnt4, Vec4, x, y, z, w);
|
||||
approx_eq_impl!(Pnt4, x, y, z, w);
|
||||
from_iterator_impl!(Pnt4, iterator, iterator, iterator, iterator);
|
||||
bounded_impl!(Pnt4, x, y, z, w);
|
||||
axpy_impl!(Pnt4, x, y, z, w);
|
||||
iterable_impl!(Pnt4, 4);
|
||||
iterable_mut_impl!(Pnt4, 4);
|
||||
pnt_to_homogeneous_impl!(Pnt4, Pnt5, a, x, y, z, w);
|
||||
pnt_from_homogeneous_impl!(Pnt4, Pnt5, a, x, y, z, w);
|
||||
num_float_pnt_impl!(Pnt4, Vec4);
|
||||
arbitrary_pnt_impl!(Pnt4, x, y, z, w);
|
||||
rand_impl!(Pnt4, x, y, z, w);
|
||||
pnt_display_impl!(Pnt4);
|
||||
|
||||
/// Point of dimension 5.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Pnt5<N> {
|
||||
/// First component of the point.
|
||||
pub x: N,
|
||||
/// Second component of the point.
|
||||
pub y: N,
|
||||
/// Third component of the point.
|
||||
pub z: N,
|
||||
/// Fourth component of the point.
|
||||
pub w: N,
|
||||
/// Fifth of the point.
|
||||
pub a: N
|
||||
}
|
||||
|
||||
new_impl!(Pnt5, x, y, z, w, a);
|
||||
orig_impl!(Pnt5, x, y, z, w, a);
|
||||
pord_impl!(Pnt5, x, y, z, w, a);
|
||||
scalar_mul_impl!(Pnt5, x, y, z, w, a);
|
||||
scalar_div_impl!(Pnt5, x, y, z, w, a);
|
||||
scalar_add_impl!(Pnt5, x, y, z, w, a);
|
||||
scalar_sub_impl!(Pnt5, x, y, z, w, a);
|
||||
vec_cast_impl!(Pnt5, x, y, z, w, a);
|
||||
conversion_impl!(Pnt5, 5);
|
||||
index_impl!(Pnt5);
|
||||
indexable_impl!(Pnt5, 5);
|
||||
at_fast_impl!(Pnt5, 5);
|
||||
repeat_impl!(Pnt5, val, x, y, z, w, a);
|
||||
dim_impl!(Pnt5, 5);
|
||||
container_impl!(Pnt5);
|
||||
pnt_as_vec_impl!(Pnt5, Vec5, x, y, z, w, a);
|
||||
pnt_sub_impl!(Pnt5, Vec5);
|
||||
neg_impl!(Pnt5, x, y, z, w, a);
|
||||
pnt_add_vec_impl!(Pnt5, Vec5, x, y, z, w, a);
|
||||
pnt_sub_vec_impl!(Pnt5, Vec5, x, y, z, w, a);
|
||||
approx_eq_impl!(Pnt5, x, y, z, w, a);
|
||||
from_iterator_impl!(Pnt5, iterator, iterator, iterator, iterator, iterator);
|
||||
bounded_impl!(Pnt5, x, y, z, w, a);
|
||||
axpy_impl!(Pnt5, x, y, z, w, a);
|
||||
iterable_impl!(Pnt5, 5);
|
||||
iterable_mut_impl!(Pnt5, 5);
|
||||
pnt_to_homogeneous_impl!(Pnt5, Pnt6, b, x, y, z, w, a);
|
||||
pnt_from_homogeneous_impl!(Pnt5, Pnt6, b, x, y, z, w, a);
|
||||
num_float_pnt_impl!(Pnt5, Vec5);
|
||||
arbitrary_pnt_impl!(Pnt5, x, y, z, w, a);
|
||||
rand_impl!(Pnt5, x, y, z, w, a);
|
||||
pnt_display_impl!(Pnt5);
|
||||
|
||||
/// Point of dimension 6.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Pnt6<N> {
|
||||
/// First component of the point.
|
||||
pub x: N,
|
||||
/// Second component of the point.
|
||||
pub y: N,
|
||||
/// Third component of the point.
|
||||
pub z: N,
|
||||
/// Fourth component of the point.
|
||||
pub w: N,
|
||||
/// Fifth of the point.
|
||||
pub a: N,
|
||||
/// Sixth component of the point.
|
||||
pub b: N
|
||||
}
|
||||
|
||||
new_impl!(Pnt6, x, y, z, w, a, b);
|
||||
orig_impl!(Pnt6, x, y, z, w, a, b);
|
||||
pord_impl!(Pnt6, x, y, z, w, a, b);
|
||||
scalar_mul_impl!(Pnt6, x, y, z, w, a, b);
|
||||
scalar_div_impl!(Pnt6, x, y, z, w, a, b);
|
||||
scalar_add_impl!(Pnt6, x, y, z, w, a, b);
|
||||
scalar_sub_impl!(Pnt6, x, y, z, w, a, b);
|
||||
vec_cast_impl!(Pnt6, x, y, z, w, a, b);
|
||||
conversion_impl!(Pnt6, 6);
|
||||
index_impl!(Pnt6);
|
||||
indexable_impl!(Pnt6, 6);
|
||||
at_fast_impl!(Pnt6, 6);
|
||||
repeat_impl!(Pnt6, val, x, y, z, w, a, b);
|
||||
dim_impl!(Pnt6, 6);
|
||||
container_impl!(Pnt6);
|
||||
pnt_as_vec_impl!(Pnt6, Vec6, x, y, z, w, a, b);
|
||||
pnt_sub_impl!(Pnt6, Vec6);
|
||||
neg_impl!(Pnt6, x, y, z, w, a, b);
|
||||
pnt_add_vec_impl!(Pnt6, Vec6, x, y, z, w, a, b);
|
||||
pnt_sub_vec_impl!(Pnt6, Vec6, x, y, z, w, a, b);
|
||||
approx_eq_impl!(Pnt6, x, y, z, w, a, b);
|
||||
from_iterator_impl!(Pnt6, iterator, iterator, iterator, iterator, iterator, iterator);
|
||||
bounded_impl!(Pnt6, x, y, z, w, a, b);
|
||||
axpy_impl!(Pnt6, x, y, z, w, a, b);
|
||||
iterable_impl!(Pnt6, 6);
|
||||
iterable_mut_impl!(Pnt6, 6);
|
||||
num_float_pnt_impl!(Pnt6, Vec6);
|
||||
arbitrary_pnt_impl!(Pnt6, x, y, z, w, a, b);
|
||||
rand_impl!(Pnt6, x, y, z, w, a, b);
|
||||
pnt_display_impl!(Pnt6);
|
|
@ -0,0 +1,309 @@
|
|||
//! Points with dimension known at compile-time.
|
||||
|
||||
use std::mem;
|
||||
use std::fmt;
|
||||
use std::slice::{Iter, IterMut};
|
||||
use std::iter::{Iterator, FromIterator, IntoIterator};
|
||||
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
|
||||
use rand::{Rand, Rng};
|
||||
use num::{Zero, One};
|
||||
use traits::operations::{ApproxEq, PartialOrder, PartialOrdering, Axpy};
|
||||
use traits::structure::{Cast, Dimension, Indexable, Iterable, IterableMut, PointAsVector, Shape,
|
||||
NumPoint, FloatPoint, BaseFloat, BaseNum, Bounded, Repeat};
|
||||
use traits::geometry::{Origin, FromHomogeneous, ToHomogeneous};
|
||||
use structs::vector::{Vector1, Vector2, Vector3, Vector4, Vector5, Vector6};
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// Point of dimension 1.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Point1<N> {
|
||||
/// First component of the point.
|
||||
pub x: N
|
||||
}
|
||||
|
||||
new_impl!(Point1, x);
|
||||
origin_impl!(Point1, x);
|
||||
pord_impl!(Point1, x,);
|
||||
scalar_mul_impl!(Point1, x);
|
||||
scalar_div_impl!(Point1, x);
|
||||
scalar_add_impl!(Point1, x);
|
||||
scalar_sub_impl!(Point1, x);
|
||||
vec_cast_impl!(Point1, x);
|
||||
conversion_impl!(Point1, 1);
|
||||
index_impl!(Point1);
|
||||
indexable_impl!(Point1, 1);
|
||||
at_fast_impl!(Point1, 1);
|
||||
repeat_impl!(Point1, val, x);
|
||||
dim_impl!(Point1, 1);
|
||||
container_impl!(Point1);
|
||||
point_as_vec_impl!(Point1, Vector1, x);
|
||||
point_sub_impl!(Point1, Vector1);
|
||||
neg_impl!(Point1, x);
|
||||
point_add_vec_impl!(Point1, Vector1, x);
|
||||
point_sub_vec_impl!(Point1, Vector1, x);
|
||||
approx_eq_impl!(Point1, x);
|
||||
from_iterator_impl!(Point1, iterator);
|
||||
bounded_impl!(Point1, x);
|
||||
axpy_impl!(Point1, x);
|
||||
iterable_impl!(Point1, 1);
|
||||
iterable_mut_impl!(Point1, 1);
|
||||
point_to_homogeneous_impl!(Point1, Point2, y, x);
|
||||
point_from_homogeneous_impl!(Point1, Point2, y, x);
|
||||
num_float_point_impl!(Point1, Vector1);
|
||||
arbitrary_point_impl!(Point1, x);
|
||||
rand_impl!(Point1, x);
|
||||
point_display_impl!(Point1);
|
||||
|
||||
/// Point of dimension 2.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Point2<N> {
|
||||
/// First component of the point.
|
||||
pub x: N,
|
||||
/// Second component of the point.
|
||||
pub y: N
|
||||
}
|
||||
|
||||
new_impl!(Point2, x, y);
|
||||
origin_impl!(Point2, x, y);
|
||||
pord_impl!(Point2, x, y);
|
||||
scalar_mul_impl!(Point2, x, y);
|
||||
scalar_div_impl!(Point2, x, y);
|
||||
scalar_add_impl!(Point2, x, y);
|
||||
scalar_sub_impl!(Point2, x, y);
|
||||
vec_cast_impl!(Point2, x, y);
|
||||
conversion_impl!(Point2, 2);
|
||||
index_impl!(Point2);
|
||||
indexable_impl!(Point2, 2);
|
||||
at_fast_impl!(Point2, 2);
|
||||
repeat_impl!(Point2, val, x, y);
|
||||
dim_impl!(Point2, 2);
|
||||
container_impl!(Point2);
|
||||
point_as_vec_impl!(Point2, Vector2, x, y);
|
||||
point_sub_impl!(Point2, Vector2);
|
||||
neg_impl!(Point2, x, y);
|
||||
point_add_vec_impl!(Point2, Vector2, x, y);
|
||||
point_sub_vec_impl!(Point2, Vector2, x, y);
|
||||
approx_eq_impl!(Point2, x, y);
|
||||
from_iterator_impl!(Point2, iterator, iterator);
|
||||
bounded_impl!(Point2, x, y);
|
||||
axpy_impl!(Point2, x, y);
|
||||
iterable_impl!(Point2, 2);
|
||||
iterable_mut_impl!(Point2, 2);
|
||||
point_to_homogeneous_impl!(Point2, Point3, z, x, y);
|
||||
point_from_homogeneous_impl!(Point2, Point3, z, x, y);
|
||||
num_float_point_impl!(Point2, Vector2);
|
||||
arbitrary_point_impl!(Point2, x, y);
|
||||
rand_impl!(Point2, x, y);
|
||||
point_display_impl!(Point2);
|
||||
|
||||
/// Point of dimension 3.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Point3<N> {
|
||||
/// First component of the point.
|
||||
pub x: N,
|
||||
/// Second component of the point.
|
||||
pub y: N,
|
||||
/// Third component of the point.
|
||||
pub z: N
|
||||
}
|
||||
|
||||
new_impl!(Point3, x, y, z);
|
||||
origin_impl!(Point3, x, y, z);
|
||||
pord_impl!(Point3, x, y, z);
|
||||
scalar_mul_impl!(Point3, x, y, z);
|
||||
scalar_div_impl!(Point3, x, y, z);
|
||||
scalar_add_impl!(Point3, x, y, z);
|
||||
scalar_sub_impl!(Point3, x, y, z);
|
||||
vec_cast_impl!(Point3, x, y, z);
|
||||
conversion_impl!(Point3, 3);
|
||||
index_impl!(Point3);
|
||||
indexable_impl!(Point3, 3);
|
||||
at_fast_impl!(Point3, 3);
|
||||
repeat_impl!(Point3, val, x, y, z);
|
||||
dim_impl!(Point3, 3);
|
||||
container_impl!(Point3);
|
||||
point_as_vec_impl!(Point3, Vector3, x, y, z);
|
||||
point_sub_impl!(Point3, Vector3);
|
||||
neg_impl!(Point3, x, y, z);
|
||||
point_add_vec_impl!(Point3, Vector3, x, y, z);
|
||||
point_sub_vec_impl!(Point3, Vector3, x, y, z);
|
||||
approx_eq_impl!(Point3, x, y, z);
|
||||
from_iterator_impl!(Point3, iterator, iterator, iterator);
|
||||
bounded_impl!(Point3, x, y, z);
|
||||
axpy_impl!(Point3, x, y, z);
|
||||
iterable_impl!(Point3, 3);
|
||||
iterable_mut_impl!(Point3, 3);
|
||||
point_to_homogeneous_impl!(Point3, Point4, w, x, y, z);
|
||||
point_from_homogeneous_impl!(Point3, Point4, w, x, y, z);
|
||||
num_float_point_impl!(Point3, Vector3);
|
||||
arbitrary_point_impl!(Point3, x, y, z);
|
||||
rand_impl!(Point3, x, y, z);
|
||||
point_display_impl!(Point3);
|
||||
|
||||
/// Point of dimension 4.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Point4<N> {
|
||||
/// First component of the point.
|
||||
pub x: N,
|
||||
/// Second component of the point.
|
||||
pub y: N,
|
||||
/// Third component of the point.
|
||||
pub z: N,
|
||||
/// Fourth component of the point.
|
||||
pub w: N
|
||||
}
|
||||
|
||||
new_impl!(Point4, x, y, z, w);
|
||||
origin_impl!(Point4, x, y, z, w);
|
||||
pord_impl!(Point4, x, y, z, w);
|
||||
scalar_mul_impl!(Point4, x, y, z, w);
|
||||
scalar_div_impl!(Point4, x, y, z, w);
|
||||
scalar_add_impl!(Point4, x, y, z, w);
|
||||
scalar_sub_impl!(Point4, x, y, z, w);
|
||||
vec_cast_impl!(Point4, x, y, z, w);
|
||||
conversion_impl!(Point4, 4);
|
||||
index_impl!(Point4);
|
||||
indexable_impl!(Point4, 4);
|
||||
at_fast_impl!(Point4, 4);
|
||||
repeat_impl!(Point4, val, x, y, z, w);
|
||||
dim_impl!(Point4, 4);
|
||||
container_impl!(Point4);
|
||||
point_as_vec_impl!(Point4, Vector4, x, y, z, w);
|
||||
point_sub_impl!(Point4, Vector4);
|
||||
neg_impl!(Point4, x, y, z, w);
|
||||
point_add_vec_impl!(Point4, Vector4, x, y, z, w);
|
||||
point_sub_vec_impl!(Point4, Vector4, x, y, z, w);
|
||||
approx_eq_impl!(Point4, x, y, z, w);
|
||||
from_iterator_impl!(Point4, iterator, iterator, iterator, iterator);
|
||||
bounded_impl!(Point4, x, y, z, w);
|
||||
axpy_impl!(Point4, x, y, z, w);
|
||||
iterable_impl!(Point4, 4);
|
||||
iterable_mut_impl!(Point4, 4);
|
||||
point_to_homogeneous_impl!(Point4, Point5, a, x, y, z, w);
|
||||
point_from_homogeneous_impl!(Point4, Point5, a, x, y, z, w);
|
||||
num_float_point_impl!(Point4, Vector4);
|
||||
arbitrary_point_impl!(Point4, x, y, z, w);
|
||||
rand_impl!(Point4, x, y, z, w);
|
||||
point_display_impl!(Point4);
|
||||
|
||||
/// Point of dimension 5.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Point5<N> {
|
||||
/// First component of the point.
|
||||
pub x: N,
|
||||
/// Second component of the point.
|
||||
pub y: N,
|
||||
/// Third component of the point.
|
||||
pub z: N,
|
||||
/// Fourth component of the point.
|
||||
pub w: N,
|
||||
/// Fifth of the point.
|
||||
pub a: N
|
||||
}
|
||||
|
||||
new_impl!(Point5, x, y, z, w, a);
|
||||
origin_impl!(Point5, x, y, z, w, a);
|
||||
pord_impl!(Point5, x, y, z, w, a);
|
||||
scalar_mul_impl!(Point5, x, y, z, w, a);
|
||||
scalar_div_impl!(Point5, x, y, z, w, a);
|
||||
scalar_add_impl!(Point5, x, y, z, w, a);
|
||||
scalar_sub_impl!(Point5, x, y, z, w, a);
|
||||
vec_cast_impl!(Point5, x, y, z, w, a);
|
||||
conversion_impl!(Point5, 5);
|
||||
index_impl!(Point5);
|
||||
indexable_impl!(Point5, 5);
|
||||
at_fast_impl!(Point5, 5);
|
||||
repeat_impl!(Point5, val, x, y, z, w, a);
|
||||
dim_impl!(Point5, 5);
|
||||
container_impl!(Point5);
|
||||
point_as_vec_impl!(Point5, Vector5, x, y, z, w, a);
|
||||
point_sub_impl!(Point5, Vector5);
|
||||
neg_impl!(Point5, x, y, z, w, a);
|
||||
point_add_vec_impl!(Point5, Vector5, x, y, z, w, a);
|
||||
point_sub_vec_impl!(Point5, Vector5, x, y, z, w, a);
|
||||
approx_eq_impl!(Point5, x, y, z, w, a);
|
||||
from_iterator_impl!(Point5, iterator, iterator, iterator, iterator, iterator);
|
||||
bounded_impl!(Point5, x, y, z, w, a);
|
||||
axpy_impl!(Point5, x, y, z, w, a);
|
||||
iterable_impl!(Point5, 5);
|
||||
iterable_mut_impl!(Point5, 5);
|
||||
point_to_homogeneous_impl!(Point5, Point6, b, x, y, z, w, a);
|
||||
point_from_homogeneous_impl!(Point5, Point6, b, x, y, z, w, a);
|
||||
num_float_point_impl!(Point5, Vector5);
|
||||
arbitrary_point_impl!(Point5, x, y, z, w, a);
|
||||
rand_impl!(Point5, x, y, z, w, a);
|
||||
point_display_impl!(Point5);
|
||||
|
||||
/// Point of dimension 6.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Point6<N> {
|
||||
/// First component of the point.
|
||||
pub x: N,
|
||||
/// Second component of the point.
|
||||
pub y: N,
|
||||
/// Third component of the point.
|
||||
pub z: N,
|
||||
/// Fourth component of the point.
|
||||
pub w: N,
|
||||
/// Fifth of the point.
|
||||
pub a: N,
|
||||
/// Sixth component of the point.
|
||||
pub b: N
|
||||
}
|
||||
|
||||
new_impl!(Point6, x, y, z, w, a, b);
|
||||
origin_impl!(Point6, x, y, z, w, a, b);
|
||||
pord_impl!(Point6, x, y, z, w, a, b);
|
||||
scalar_mul_impl!(Point6, x, y, z, w, a, b);
|
||||
scalar_div_impl!(Point6, x, y, z, w, a, b);
|
||||
scalar_add_impl!(Point6, x, y, z, w, a, b);
|
||||
scalar_sub_impl!(Point6, x, y, z, w, a, b);
|
||||
vec_cast_impl!(Point6, x, y, z, w, a, b);
|
||||
conversion_impl!(Point6, 6);
|
||||
index_impl!(Point6);
|
||||
indexable_impl!(Point6, 6);
|
||||
at_fast_impl!(Point6, 6);
|
||||
repeat_impl!(Point6, val, x, y, z, w, a, b);
|
||||
dim_impl!(Point6, 6);
|
||||
container_impl!(Point6);
|
||||
point_as_vec_impl!(Point6, Vector6, x, y, z, w, a, b);
|
||||
point_sub_impl!(Point6, Vector6);
|
||||
neg_impl!(Point6, x, y, z, w, a, b);
|
||||
point_add_vec_impl!(Point6, Vector6, x, y, z, w, a, b);
|
||||
point_sub_vec_impl!(Point6, Vector6, x, y, z, w, a, b);
|
||||
approx_eq_impl!(Point6, x, y, z, w, a, b);
|
||||
from_iterator_impl!(Point6, iterator, iterator, iterator, iterator, iterator, iterator);
|
||||
bounded_impl!(Point6, x, y, z, w, a, b);
|
||||
axpy_impl!(Point6, x, y, z, w, a, b);
|
||||
iterable_impl!(Point6, 6);
|
||||
iterable_mut_impl!(Point6, 6);
|
||||
num_float_point_impl!(Point6, Vector6);
|
||||
arbitrary_point_impl!(Point6, x, y, z, w, a, b);
|
||||
rand_impl!(Point6, x, y, z, w, a, b);
|
||||
point_display_impl!(Point6);
|
|
@ -1,37 +1,37 @@
|
|||
#![macro_use]
|
||||
|
||||
macro_rules! orig_impl(
|
||||
macro_rules! origin_impl(
|
||||
($t: ident, $($compN: ident),+) => (
|
||||
impl<N: Zero> Orig for $t<N> {
|
||||
impl<N: Zero> Origin for $t<N> {
|
||||
#[inline]
|
||||
fn orig() -> $t<N> {
|
||||
fn origin() -> $t<N> {
|
||||
$t {
|
||||
$($compN: ::zero() ),+
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_orig(&self) -> bool {
|
||||
fn is_origin(&self) -> bool {
|
||||
$(self.$compN.is_zero() )&&+
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! pnt_sub_impl(
|
||||
macro_rules! point_sub_impl(
|
||||
($t: ident, $tv: ident) => (
|
||||
impl<N: Copy + Sub<N, Output = N>> Sub<$t<N>> for $t<N> {
|
||||
type Output = $tv<N>;
|
||||
|
||||
#[inline]
|
||||
fn sub(self, right: $t<N>) -> $tv<N> {
|
||||
*self.as_vec() - *right.as_vec()
|
||||
*self.as_vector() - *right.as_vector()
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! pnt_add_vec_impl(
|
||||
macro_rules! point_add_vec_impl(
|
||||
($t: ident, $tv: ident, $($compN: ident),+) => (
|
||||
impl<N: Copy + Add<N, Output = N>> Add<$tv<N>> for $t<N> {
|
||||
type Output = $t<N>;
|
||||
|
@ -51,7 +51,7 @@ macro_rules! pnt_add_vec_impl(
|
|||
)
|
||||
);
|
||||
|
||||
macro_rules! pnt_sub_vec_impl(
|
||||
macro_rules! point_sub_vec_impl(
|
||||
($t: ident, $tv: ident, $($compN: ident),+) => (
|
||||
impl<N: Copy + Sub<N, Output = N>> Sub<$tv<N>> for $t<N> {
|
||||
type Output = $t<N>;
|
||||
|
@ -71,12 +71,12 @@ macro_rules! pnt_sub_vec_impl(
|
|||
)
|
||||
);
|
||||
|
||||
macro_rules! pnt_as_vec_impl(
|
||||
macro_rules! point_as_vec_impl(
|
||||
($t: ident, $tv: ident, $($compN: ident),+) => (
|
||||
impl<N> $t<N> {
|
||||
/// Converts this point to its associated vector.
|
||||
#[inline]
|
||||
pub fn to_vec(self) -> $tv<N> {
|
||||
pub fn to_vector(self) -> $tv<N> {
|
||||
$tv::new(
|
||||
$(self.$compN),+
|
||||
)
|
||||
|
@ -84,7 +84,7 @@ macro_rules! pnt_as_vec_impl(
|
|||
|
||||
/// Converts a reference to this point to a reference to its associated vector.
|
||||
#[inline]
|
||||
pub fn as_vec<'a>(&'a self) -> &'a $tv<N> {
|
||||
pub fn as_vector<'a>(&'a self) -> &'a $tv<N> {
|
||||
unsafe {
|
||||
mem::transmute(self)
|
||||
}
|
||||
|
@ -96,17 +96,17 @@ macro_rules! pnt_as_vec_impl(
|
|||
}
|
||||
}
|
||||
|
||||
impl<N> PntAsVec for $t<N> {
|
||||
type Vec = $tv<N>;
|
||||
impl<N> PointAsVector for $t<N> {
|
||||
type Vector = $tv<N>;
|
||||
|
||||
#[inline]
|
||||
fn to_vec(self) -> $tv<N> {
|
||||
self.to_vec()
|
||||
fn to_vector(self) -> $tv<N> {
|
||||
self.to_vector()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn as_vec<'a>(&'a self) -> &'a $tv<N> {
|
||||
self.as_vec()
|
||||
fn as_vector<'a>(&'a self) -> &'a $tv<N> {
|
||||
self.as_vector()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -117,11 +117,11 @@ macro_rules! pnt_as_vec_impl(
|
|||
)
|
||||
);
|
||||
|
||||
macro_rules! pnt_to_homogeneous_impl(
|
||||
macro_rules! point_to_homogeneous_impl(
|
||||
($t: ident, $t2: ident, $extra: ident, $($compN: ident),+) => (
|
||||
impl<N: Copy + One + Zero> ToHomogeneous<$t2<N>> for $t<N> {
|
||||
fn to_homogeneous(&self) -> $t2<N> {
|
||||
let mut res: $t2<N> = Orig::orig();
|
||||
let mut res: $t2<N> = Origin::origin();
|
||||
|
||||
$( res.$compN = self.$compN; )+
|
||||
res.$extra = ::one();
|
||||
|
@ -132,11 +132,11 @@ macro_rules! pnt_to_homogeneous_impl(
|
|||
)
|
||||
);
|
||||
|
||||
macro_rules! pnt_from_homogeneous_impl(
|
||||
macro_rules! point_from_homogeneous_impl(
|
||||
($t: ident, $t2: ident, $extra: ident, $($compN: ident),+) => (
|
||||
impl<N: Copy + Div<N, Output = N> + One + Zero> FromHomogeneous<$t2<N>> for $t<N> {
|
||||
fn from(v: &$t2<N>) -> $t<N> {
|
||||
let mut res: $t<N> = Orig::orig();
|
||||
let mut res: $t<N> = Origin::origin();
|
||||
|
||||
$( res.$compN = v.$compN / v.$extra; )+
|
||||
|
||||
|
@ -146,19 +146,19 @@ macro_rules! pnt_from_homogeneous_impl(
|
|||
)
|
||||
);
|
||||
|
||||
macro_rules! num_float_pnt_impl(
|
||||
macro_rules! num_float_point_impl(
|
||||
($t: ident, $tv: ident) => (
|
||||
impl<N> NumPnt<N> for $t<N>
|
||||
impl<N> NumPoint<N> for $t<N>
|
||||
where N: BaseNum {
|
||||
}
|
||||
|
||||
impl<N> FloatPnt<N> for $t<N>
|
||||
impl<N> FloatPoint<N> for $t<N>
|
||||
where N: BaseFloat + ApproxEq<N> {
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! arbitrary_pnt_impl(
|
||||
macro_rules! arbitrary_point_impl(
|
||||
($t: ident, $($compN: ident),*) => (
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary> Arbitrary for $t<N> {
|
||||
|
@ -172,7 +172,7 @@ macro_rules! arbitrary_pnt_impl(
|
|||
)
|
||||
);
|
||||
|
||||
macro_rules! pnt_display_impl(
|
||||
macro_rules! point_display_impl(
|
||||
($t: ident) => (
|
||||
impl<N: fmt::Display> fmt::Display for $t<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
@ -1,598 +0,0 @@
|
|||
//! Quaternion definition.
|
||||
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
use std::slice::{Iter, IterMut};
|
||||
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
|
||||
use std::iter::{FromIterator, IntoIterator};
|
||||
use rand::{Rand, Rng};
|
||||
use num::{Zero, One};
|
||||
use structs::{Vec3, Pnt3, Rot3, Mat3};
|
||||
use traits::operations::{ApproxEq, Inv, POrd, POrdering, Axpy};
|
||||
use traits::structure::{Cast, Indexable, Iterable, IterableMut, Dim, Shape, BaseFloat, BaseNum,
|
||||
Bounded, Repeat};
|
||||
use traits::geometry::{Norm, Rotation, RotationMatrix, Rotate, RotationTo, Transform};
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// A quaternion.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Quat<N> {
|
||||
/// The scalar component of the quaternion.
|
||||
pub w: N,
|
||||
/// The first vector component of the quaternion.
|
||||
pub i: N,
|
||||
/// The second vector component of the quaternion.
|
||||
pub j: N,
|
||||
/// The third vector component of the quaternion.
|
||||
pub k: N
|
||||
}
|
||||
|
||||
impl<N> Quat<N> {
|
||||
/// Creates a new quaternion from its components.
|
||||
#[inline]
|
||||
pub fn new(w: N, i: N, j: N, k: N) -> Quat<N> {
|
||||
Quat {
|
||||
w: w,
|
||||
i: i,
|
||||
j: j,
|
||||
k: k
|
||||
}
|
||||
}
|
||||
|
||||
/// The vector part `(i, j, k)` of this quaternion.
|
||||
#[inline]
|
||||
pub fn vector<'a>(&'a self) -> &'a Vec3<N> {
|
||||
// FIXME: do this require a `repr(C)` ?
|
||||
unsafe {
|
||||
mem::transmute(&self.i)
|
||||
}
|
||||
}
|
||||
|
||||
/// The scalar part `w` of this quaternion.
|
||||
#[inline]
|
||||
pub fn scalar<'a>(&'a self) -> &'a N {
|
||||
&self.w
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Neg<Output = N> + Copy> Quat<N> {
|
||||
/// Compute the conjugate of this quaternion.
|
||||
#[inline]
|
||||
pub fn conjugate(&self) -> Quat<N> {
|
||||
Quat { w: self.w, i: -self.i, j: -self.j, k: -self.k }
|
||||
}
|
||||
|
||||
/// Replaces this quaternion by its conjugate.
|
||||
#[inline]
|
||||
pub fn conjugate_mut(&mut self) {
|
||||
self.i = -self.i;
|
||||
self.j = -self.j;
|
||||
self.k = -self.k;
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + ApproxEq<N>> Inv for Quat<N> {
|
||||
#[inline]
|
||||
fn inv(&self) -> Option<Quat<N>> {
|
||||
let mut res = *self;
|
||||
|
||||
if res.inv_mut() {
|
||||
Some(res)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_mut(&mut self) -> bool {
|
||||
let sqnorm = Norm::sqnorm(self);
|
||||
|
||||
if ApproxEq::approx_eq(&sqnorm, &::zero()) {
|
||||
false
|
||||
}
|
||||
else {
|
||||
self.conjugate_mut();
|
||||
self.w = self.w / sqnorm;
|
||||
self.i = self.i / sqnorm;
|
||||
self.j = self.j / sqnorm;
|
||||
self.k = self.k / sqnorm;
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> Norm<N> for Quat<N> {
|
||||
#[inline]
|
||||
fn sqnorm(&self) -> N {
|
||||
self.w * self.w + self.i * self.i + self.j * self.j + self.k * self.k
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn normalize(&self) -> Quat<N> {
|
||||
let n = self.norm();
|
||||
Quat::new(self.w / n, self.i / n, self.j / n, self.k / n)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn normalize_mut(&mut self) -> N {
|
||||
let n = Norm::norm(self);
|
||||
|
||||
self.w = self.w / n;
|
||||
self.i = self.i / n;
|
||||
self.j = self.j / n;
|
||||
self.k = self.k / n;
|
||||
|
||||
n
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> Mul<Quat<N>> for Quat<N>
|
||||
where N: Copy + Mul<N, Output = N> + Sub<N, Output = N> + Add<N, Output = N> {
|
||||
type Output = Quat<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: Quat<N>) -> Quat<N> {
|
||||
Quat::new(
|
||||
self.w * right.w - self.i * right.i - self.j * right.j - self.k * right.k,
|
||||
self.w * right.i + self.i * right.w + self.j * right.k - self.k * right.j,
|
||||
self.w * right.j - self.i * right.k + self.j * right.w + self.k * right.i,
|
||||
self.w * right.k + self.i * right.j - self.j * right.i + self.k * right.w)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> MulAssign<Quat<N>> for Quat<N>
|
||||
where N: Copy + Mul<N, Output = N> + Sub<N, Output = N> + Add<N, Output = N> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, right: Quat<N>) {
|
||||
*self = *self * right;
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ApproxEq<N> + BaseFloat> Div<Quat<N>> for Quat<N> {
|
||||
type Output = Quat<N>;
|
||||
|
||||
#[inline]
|
||||
fn div(self, right: Quat<N>) -> Quat<N> {
|
||||
self * right.inv().expect("Unable to invert the denominator.")
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ApproxEq<N> + BaseFloat> DivAssign<Quat<N>> for Quat<N> {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, right: Quat<N>) {
|
||||
*self *= right.inv().expect("Unable to invert the denominator.")
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: fmt::Display> fmt::Display for Quat<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Quaternion {} − ({}, {}, {})", self.w, self.i, self.j, self.k)
|
||||
}
|
||||
}
|
||||
|
||||
rand_impl!(Quat, w, i, j, k);
|
||||
|
||||
|
||||
/// A unit quaternion that can represent a 3D rotation.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct UnitQuat<N> {
|
||||
q: Quat<N>
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> UnitQuat<N> {
|
||||
/// Creates a new unit quaternion from the axis-angle representation of a rotation.
|
||||
#[inline]
|
||||
pub fn new(axisangle: Vec3<N>) -> UnitQuat<N> {
|
||||
let sqang = Norm::sqnorm(&axisangle);
|
||||
|
||||
if ::is_zero(&sqang) {
|
||||
::one()
|
||||
}
|
||||
else {
|
||||
let ang = sqang.sqrt();
|
||||
let (s, c) = (ang / Cast::from(2.0)).sin_cos();
|
||||
|
||||
let s_ang = s / ang;
|
||||
|
||||
unsafe {
|
||||
UnitQuat::new_with_unit_quat(
|
||||
Quat::new(
|
||||
c,
|
||||
axisangle.x * s_ang,
|
||||
axisangle.y * s_ang,
|
||||
axisangle.z * s_ang)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new unit quaternion from a quaternion.
|
||||
///
|
||||
/// The input quaternion will be normalized.
|
||||
#[inline]
|
||||
pub fn new_with_quat(q: Quat<N>) -> UnitQuat<N> {
|
||||
UnitQuat { q: q.normalize() }
|
||||
}
|
||||
|
||||
/// Creates a new unit quaternion from Euler angles.
|
||||
///
|
||||
/// The primitive rotations are applied in order: 1 roll − 2 pitch − 3 yaw.
|
||||
#[inline]
|
||||
pub fn new_with_euler_angles(roll: N, pitch: N, yaw: N) -> UnitQuat<N> {
|
||||
let _0_5: N = Cast::from(0.5);
|
||||
let (sr, cr) = (roll * _0_5).sin_cos();
|
||||
let (sp, cp) = (pitch * _0_5).sin_cos();
|
||||
let (sy, cy) = (yaw * _0_5).sin_cos();
|
||||
|
||||
unsafe {
|
||||
UnitQuat::new_with_unit_quat(
|
||||
Quat::new(
|
||||
cr * cp * cy + sr * sp * sy,
|
||||
sr * cp * cy - cr * sp * sy,
|
||||
cr * sp * cy + sr * cp * sy,
|
||||
cr * cp * sy - sr * sp * cy)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a rotation matrix from this quaternion.
|
||||
pub fn to_rot(&self) -> Rot3<N> {
|
||||
let _2: N = Cast::from(2.0);
|
||||
let ww = self.q.w * self.q.w;
|
||||
let ii = self.q.i * self.q.i;
|
||||
let jj = self.q.j * self.q.j;
|
||||
let kk = self.q.k * self.q.k;
|
||||
let ij = _2 * self.q.i * self.q.j;
|
||||
let wk = _2 * self.q.w * self.q.k;
|
||||
let wj = _2 * self.q.w * self.q.j;
|
||||
let ik = _2 * self.q.i * self.q.k;
|
||||
let jk = _2 * self.q.j * self.q.k;
|
||||
let wi = _2 * self.q.w * self.q.i;
|
||||
|
||||
unsafe {
|
||||
Rot3::new_with_mat(
|
||||
Mat3::new(
|
||||
ww + ii - jj - kk, ij - wk, wj + ik,
|
||||
wk + ij, ww - ii + jj - kk, jk - wi,
|
||||
ik - wj, wi + jk, ww - ii - jj + kk
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<N> UnitQuat<N> {
|
||||
/// Creates a new unit quaternion from a quaternion.
|
||||
///
|
||||
/// This is unsafe because the input quaternion will not be normalized.
|
||||
#[inline]
|
||||
pub unsafe fn new_with_unit_quat(q: Quat<N>) -> UnitQuat<N> {
|
||||
UnitQuat {
|
||||
q: q
|
||||
}
|
||||
}
|
||||
|
||||
/// The `Quat` representation of this unit quaternion.
|
||||
#[inline]
|
||||
pub fn quat<'a>(&'a self) -> &'a Quat<N> {
|
||||
&self.q
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum> One for UnitQuat<N> {
|
||||
#[inline]
|
||||
fn one() -> UnitQuat<N> {
|
||||
unsafe {
|
||||
UnitQuat::new_with_unit_quat(Quat::new(::one(), ::zero(), ::zero(), ::zero()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Neg<Output = N>> Inv for UnitQuat<N> {
|
||||
#[inline]
|
||||
fn inv(&self) -> Option<UnitQuat<N>> {
|
||||
let mut cpy = *self;
|
||||
|
||||
cpy.inv_mut();
|
||||
Some(cpy)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_mut(&mut self) -> bool {
|
||||
self.q.conjugate_mut();
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Rand + BaseFloat> Rand for UnitQuat<N> {
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> UnitQuat<N> {
|
||||
UnitQuat::new(rng.gen())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ApproxEq<N>> ApproxEq<N> for UnitQuat<N> {
|
||||
#[inline]
|
||||
fn approx_epsilon(_: Option<UnitQuat<N>>) -> N {
|
||||
ApproxEq::approx_epsilon(None::<N>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_ulps(_: Option<UnitQuat<N>>) -> u32 {
|
||||
ApproxEq::approx_ulps(None::<N>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &UnitQuat<N>, eps: &N) -> bool {
|
||||
ApproxEq::approx_eq_eps(&self.q, &other.q, eps)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_ulps(&self, other: &UnitQuat<N>, ulps: u32) -> bool {
|
||||
ApproxEq::approx_eq_ulps(&self.q, &other.q, ulps)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + ApproxEq<N>> Div<UnitQuat<N>> for UnitQuat<N> {
|
||||
type Output = UnitQuat<N>;
|
||||
|
||||
#[inline]
|
||||
fn div(self, other: UnitQuat<N>) -> UnitQuat<N> {
|
||||
UnitQuat { q: self.q / other.q }
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + ApproxEq<N>> DivAssign<UnitQuat<N>> for UnitQuat<N> {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, other: UnitQuat<N>) {
|
||||
self.q /= other.q
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum> Mul<UnitQuat<N>> for UnitQuat<N> {
|
||||
type Output = UnitQuat<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: UnitQuat<N>) -> UnitQuat<N> {
|
||||
UnitQuat { q: self.q * right.q }
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum> MulAssign<UnitQuat<N>> for UnitQuat<N> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, right: UnitQuat<N>) {
|
||||
self.q *= right.q
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum> Mul<Vec3<N>> for UnitQuat<N> {
|
||||
type Output = Vec3<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: Vec3<N>) -> Vec3<N> {
|
||||
let _2: N = ::one::<N>() + ::one();
|
||||
let mut t = ::cross(self.q.vector(), &right);
|
||||
t.x = t.x * _2;
|
||||
t.y = t.y * _2;
|
||||
t.z = t.z * _2;
|
||||
|
||||
Vec3::new(t.x * self.q.w, t.y * self.q.w, t.z * self.q.w) + ::cross(self.q.vector(), &t) + right
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum> Mul<Pnt3<N>> for UnitQuat<N> {
|
||||
type Output = Pnt3<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: Pnt3<N>) -> Pnt3<N> {
|
||||
::orig::<Pnt3<N>>() + self * *right.as_vec()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N>> Mul<UnitQuat<N>> for Vec3<N> {
|
||||
type Output = Vec3<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: UnitQuat<N>) -> Vec3<N> {
|
||||
let mut inv_quat = right;
|
||||
|
||||
inv_quat.inv_mut();
|
||||
|
||||
inv_quat * self
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N>> Mul<UnitQuat<N>> for Pnt3<N> {
|
||||
type Output = Pnt3<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: UnitQuat<N>) -> Pnt3<N> {
|
||||
::orig::<Pnt3<N>>() + *self.as_vec() * right
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N>> MulAssign<UnitQuat<N>> for Vec3<N> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, right: UnitQuat<N>) {
|
||||
*self = *self * right
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N>> MulAssign<UnitQuat<N>> for Pnt3<N> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, right: UnitQuat<N>) {
|
||||
*self = *self * right
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> Rotation<Vec3<N>> for UnitQuat<N> {
|
||||
#[inline]
|
||||
fn rotation(&self) -> Vec3<N> {
|
||||
let _2 = ::one::<N>() + ::one();
|
||||
let mut v = *self.q.vector();
|
||||
let ang = _2 * v.normalize_mut().atan2(self.q.w);
|
||||
|
||||
if ::is_zero(&ang) {
|
||||
::zero()
|
||||
}
|
||||
else {
|
||||
Vec3::new(v.x * ang, v.y * ang, v.z * ang)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_rotation(&self) -> Vec3<N> {
|
||||
-self.rotation()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn append_rotation_mut(&mut self, amount: &Vec3<N>) {
|
||||
*self = Rotation::append_rotation(self, amount)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn append_rotation(&self, amount: &Vec3<N>) -> UnitQuat<N> {
|
||||
*self * UnitQuat::new(*amount)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prepend_rotation_mut(&mut self, amount: &Vec3<N>) {
|
||||
*self = Rotation::prepend_rotation(self, amount)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prepend_rotation(&self, amount: &Vec3<N>) -> UnitQuat<N> {
|
||||
UnitQuat::new(*amount) * *self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_rotation(&mut self, v: Vec3<N>) {
|
||||
*self = UnitQuat::new(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> RotationMatrix<N, Vec3<N>, Vec3<N>> for UnitQuat<N> {
|
||||
type Output = Rot3<N>;
|
||||
|
||||
#[inline]
|
||||
fn to_rot_mat(&self) -> Rot3<N> {
|
||||
self.to_rot()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N>> Rotate<Vec3<N>> for UnitQuat<N> {
|
||||
#[inline]
|
||||
fn rotate(&self, v: &Vec3<N>) -> Vec3<N> {
|
||||
*self * *v
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_rotate(&self, v: &Vec3<N>) -> Vec3<N> {
|
||||
*v * *self
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N>> Rotate<Pnt3<N>> for UnitQuat<N> {
|
||||
#[inline]
|
||||
fn rotate(&self, p: &Pnt3<N>) -> Pnt3<N> {
|
||||
*self * *p
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_rotate(&self, p: &Pnt3<N>) -> Pnt3<N> {
|
||||
*p * *self
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + ApproxEq<N>> RotationTo for UnitQuat<N> {
|
||||
type AngleType = N;
|
||||
type DeltaRotationType = UnitQuat<N>;
|
||||
|
||||
#[inline]
|
||||
fn angle_to(&self, other: &Self) -> N {
|
||||
let delta = self.rotation_to(other);
|
||||
let _2 = ::one::<N>() + ::one();
|
||||
|
||||
_2 * delta.q.vector().norm().atan2(delta.q.w)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rotation_to(&self, other: &Self) -> UnitQuat<N> {
|
||||
*other / *self
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N>> Transform<Vec3<N>> for UnitQuat<N> {
|
||||
#[inline]
|
||||
fn transform(&self, v: &Vec3<N>) -> Vec3<N> {
|
||||
*self * *v
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_transform(&self, v: &Vec3<N>) -> Vec3<N> {
|
||||
*v * *self
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N>> Transform<Pnt3<N>> for UnitQuat<N> {
|
||||
#[inline]
|
||||
fn transform(&self, p: &Pnt3<N>) -> Pnt3<N> {
|
||||
*self * *p
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_transform(&self, p: &Pnt3<N>) -> Pnt3<N> {
|
||||
*p * *self
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: fmt::Display> fmt::Display for UnitQuat<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Unit quaternion {} − ({}, {}, {})", self.q.w, self.q.i, self.q.j, self.q.k)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for UnitQuat<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> UnitQuat<N> {
|
||||
UnitQuat::new(Arbitrary::arbitrary(g))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pord_impl!(Quat, w, i, j, k);
|
||||
vec_axis_impl!(Quat, w, i, j, k);
|
||||
vec_cast_impl!(Quat, w, i, j, k);
|
||||
conversion_impl!(Quat, 4);
|
||||
index_impl!(Quat);
|
||||
indexable_impl!(Quat, 4);
|
||||
at_fast_impl!(Quat, 4);
|
||||
repeat_impl!(Quat, val, w, i, j, k);
|
||||
dim_impl!(Quat, 3);
|
||||
container_impl!(Quat);
|
||||
add_impl!(Quat, w, i, j, k);
|
||||
sub_impl!(Quat, w, i, j, k);
|
||||
scalar_add_impl!(Quat, w, i, j, k);
|
||||
scalar_sub_impl!(Quat, w, i, j, k);
|
||||
scalar_mul_impl!(Quat, w, i, j, k);
|
||||
scalar_div_impl!(Quat, w, i, j, k);
|
||||
neg_impl!(Quat, w, i, j, k);
|
||||
zero_one_impl!(Quat, w, i, j, k);
|
||||
approx_eq_impl!(Quat, w, i, j, k);
|
||||
from_iterator_impl!(Quat, iterator, iterator, iterator, iterator);
|
||||
bounded_impl!(Quat, w, i, j, k);
|
||||
axpy_impl!(Quat, w, i, j, k);
|
||||
iterable_impl!(Quat, 4);
|
||||
iterable_mut_impl!(Quat, 4);
|
||||
arbitrary_impl!(Quat, w, i, j, k);
|
||||
|
||||
dim_impl!(UnitQuat, 3);
|
|
@ -0,0 +1,598 @@
|
|||
//! Quaternion definition.
|
||||
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
use std::slice::{Iter, IterMut};
|
||||
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
|
||||
use std::iter::{FromIterator, IntoIterator};
|
||||
use rand::{Rand, Rng};
|
||||
use num::{Zero, One};
|
||||
use structs::{Vector3, Point3, Rotation3, Matrix3};
|
||||
use traits::operations::{ApproxEq, Inverse, PartialOrder, PartialOrdering, Axpy};
|
||||
use traits::structure::{Cast, Indexable, Iterable, IterableMut, Dimension, Shape, BaseFloat, BaseNum,
|
||||
Bounded, Repeat};
|
||||
use traits::geometry::{Norm, Rotation, RotationMatrix, Rotate, RotationTo, Transform};
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// A quaternion. See `UnitQuaternion` for a quaternion that can be used as a rotation.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Quaternion<N> {
|
||||
/// The scalar component of the quaternion.
|
||||
pub w: N,
|
||||
/// The first vector component of the quaternion.
|
||||
pub i: N,
|
||||
/// The second vector component of the quaternion.
|
||||
pub j: N,
|
||||
/// The third vector component of the quaternion.
|
||||
pub k: N
|
||||
}
|
||||
|
||||
impl<N> Quaternion<N> {
|
||||
/// Creates a new quaternion from its components.
|
||||
#[inline]
|
||||
pub fn new(w: N, i: N, j: N, k: N) -> Quaternion<N> {
|
||||
Quaternion {
|
||||
w: w,
|
||||
i: i,
|
||||
j: j,
|
||||
k: k
|
||||
}
|
||||
}
|
||||
|
||||
/// The vector part `(i, j, k)` of this quaternion.
|
||||
#[inline]
|
||||
pub fn vector<'a>(&'a self) -> &'a Vector3<N> {
|
||||
// FIXME: do this require a `repr(C)` ?
|
||||
unsafe {
|
||||
mem::transmute(&self.i)
|
||||
}
|
||||
}
|
||||
|
||||
/// The scalar part `w` of this quaternion.
|
||||
#[inline]
|
||||
pub fn scalar<'a>(&'a self) -> &'a N {
|
||||
&self.w
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Neg<Output = N> + Copy> Quaternion<N> {
|
||||
/// Compute the conjugate of this quaternion.
|
||||
#[inline]
|
||||
pub fn conjugate(&self) -> Quaternion<N> {
|
||||
Quaternion { w: self.w, i: -self.i, j: -self.j, k: -self.k }
|
||||
}
|
||||
|
||||
/// Replaces this quaternion by its conjugate.
|
||||
#[inline]
|
||||
pub fn conjugate_mut(&mut self) {
|
||||
self.i = -self.i;
|
||||
self.j = -self.j;
|
||||
self.k = -self.k;
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + ApproxEq<N>> Inverse for Quaternion<N> {
|
||||
#[inline]
|
||||
fn inverse(&self) -> Option<Quaternion<N>> {
|
||||
let mut res = *self;
|
||||
|
||||
if res.inverse_mut() {
|
||||
Some(res)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inverse_mut(&mut self) -> bool {
|
||||
let norm_squared = Norm::norm_squared(self);
|
||||
|
||||
if ApproxEq::approx_eq(&norm_squared, &::zero()) {
|
||||
false
|
||||
}
|
||||
else {
|
||||
self.conjugate_mut();
|
||||
self.w = self.w / norm_squared;
|
||||
self.i = self.i / norm_squared;
|
||||
self.j = self.j / norm_squared;
|
||||
self.k = self.k / norm_squared;
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> Norm<N> for Quaternion<N> {
|
||||
#[inline]
|
||||
fn norm_squared(&self) -> N {
|
||||
self.w * self.w + self.i * self.i + self.j * self.j + self.k * self.k
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn normalize(&self) -> Quaternion<N> {
|
||||
let n = self.norm();
|
||||
Quaternion::new(self.w / n, self.i / n, self.j / n, self.k / n)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn normalize_mut(&mut self) -> N {
|
||||
let n = Norm::norm(self);
|
||||
|
||||
self.w = self.w / n;
|
||||
self.i = self.i / n;
|
||||
self.j = self.j / n;
|
||||
self.k = self.k / n;
|
||||
|
||||
n
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> Mul<Quaternion<N>> for Quaternion<N>
|
||||
where N: Copy + Mul<N, Output = N> + Sub<N, Output = N> + Add<N, Output = N> {
|
||||
type Output = Quaternion<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: Quaternion<N>) -> Quaternion<N> {
|
||||
Quaternion::new(
|
||||
self.w * right.w - self.i * right.i - self.j * right.j - self.k * right.k,
|
||||
self.w * right.i + self.i * right.w + self.j * right.k - self.k * right.j,
|
||||
self.w * right.j - self.i * right.k + self.j * right.w + self.k * right.i,
|
||||
self.w * right.k + self.i * right.j - self.j * right.i + self.k * right.w)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> MulAssign<Quaternion<N>> for Quaternion<N>
|
||||
where N: Copy + Mul<N, Output = N> + Sub<N, Output = N> + Add<N, Output = N> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, right: Quaternion<N>) {
|
||||
*self = *self * right;
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ApproxEq<N> + BaseFloat> Div<Quaternion<N>> for Quaternion<N> {
|
||||
type Output = Quaternion<N>;
|
||||
|
||||
#[inline]
|
||||
fn div(self, right: Quaternion<N>) -> Quaternion<N> {
|
||||
self * right.inverse().expect("Unable to invert the denominator.")
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ApproxEq<N> + BaseFloat> DivAssign<Quaternion<N>> for Quaternion<N> {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, right: Quaternion<N>) {
|
||||
*self *= right.inverse().expect("Unable to invert the denominator.")
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: fmt::Display> fmt::Display for Quaternion<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Quaternion {} − ({}, {}, {})", self.w, self.i, self.j, self.k)
|
||||
}
|
||||
}
|
||||
|
||||
rand_impl!(Quaternion, w, i, j, k);
|
||||
|
||||
|
||||
/// A unit quaternion that can represent a 3D rotation.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct UnitQuaternion<N> {
|
||||
q: Quaternion<N>
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> UnitQuaternion<N> {
|
||||
/// Creates a new unit quaternion from the axis-angle representation of a rotation.
|
||||
#[inline]
|
||||
pub fn new(axisangle: Vector3<N>) -> UnitQuaternion<N> {
|
||||
let sqang = Norm::norm_squared(&axisangle);
|
||||
|
||||
if ::is_zero(&sqang) {
|
||||
::one()
|
||||
}
|
||||
else {
|
||||
let ang = sqang.sqrt();
|
||||
let (s, c) = (ang / Cast::from(2.0)).sin_cos();
|
||||
|
||||
let s_ang = s / ang;
|
||||
|
||||
unsafe {
|
||||
UnitQuaternion::new_with_unit_quaternion(
|
||||
Quaternion::new(
|
||||
c,
|
||||
axisangle.x * s_ang,
|
||||
axisangle.y * s_ang,
|
||||
axisangle.z * s_ang)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new unit quaternion from a quaternion.
|
||||
///
|
||||
/// The input quaternion will be normalized.
|
||||
#[inline]
|
||||
pub fn new_with_quaternion(q: Quaternion<N>) -> UnitQuaternion<N> {
|
||||
UnitQuaternion { q: q.normalize() }
|
||||
}
|
||||
|
||||
/// Creates a new unit quaternion from Euler angles.
|
||||
///
|
||||
/// The primitive rotations are applied in order: 1 roll − 2 pitch − 3 yaw.
|
||||
#[inline]
|
||||
pub fn new_with_euler_angles(roll: N, pitch: N, yaw: N) -> UnitQuaternion<N> {
|
||||
let _0_5: N = Cast::from(0.5);
|
||||
let (sr, cr) = (roll * _0_5).sin_cos();
|
||||
let (sp, cp) = (pitch * _0_5).sin_cos();
|
||||
let (sy, cy) = (yaw * _0_5).sin_cos();
|
||||
|
||||
unsafe {
|
||||
UnitQuaternion::new_with_unit_quaternion(
|
||||
Quaternion::new(
|
||||
cr * cp * cy + sr * sp * sy,
|
||||
sr * cp * cy - cr * sp * sy,
|
||||
cr * sp * cy + sr * cp * sy,
|
||||
cr * cp * sy - sr * sp * cy)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a rotation matrix from this quaternion.
|
||||
pub fn to_rotation_matrix(&self) -> Rotation3<N> {
|
||||
let _2: N = Cast::from(2.0);
|
||||
let ww = self.q.w * self.q.w;
|
||||
let ii = self.q.i * self.q.i;
|
||||
let jj = self.q.j * self.q.j;
|
||||
let kk = self.q.k * self.q.k;
|
||||
let ij = _2 * self.q.i * self.q.j;
|
||||
let wk = _2 * self.q.w * self.q.k;
|
||||
let wj = _2 * self.q.w * self.q.j;
|
||||
let ik = _2 * self.q.i * self.q.k;
|
||||
let jk = _2 * self.q.j * self.q.k;
|
||||
let wi = _2 * self.q.w * self.q.i;
|
||||
|
||||
unsafe {
|
||||
Rotation3::new_with_matrix(
|
||||
Matrix3::new(
|
||||
ww + ii - jj - kk, ij - wk, wj + ik,
|
||||
wk + ij, ww - ii + jj - kk, jk - wi,
|
||||
ik - wj, wi + jk, ww - ii - jj + kk
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<N> UnitQuaternion<N> {
|
||||
/// Creates a new unit quaternion from a quaternion.
|
||||
///
|
||||
/// This is unsafe because the input quaternion will not be normalized.
|
||||
#[inline]
|
||||
pub unsafe fn new_with_unit_quaternion(q: Quaternion<N>) -> UnitQuaternion<N> {
|
||||
UnitQuaternion {
|
||||
q: q
|
||||
}
|
||||
}
|
||||
|
||||
/// The `Quaternion` representation of this unit quaternion.
|
||||
#[inline]
|
||||
pub fn quaternion<'a>(&'a self) -> &'a Quaternion<N> {
|
||||
&self.q
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum> One for UnitQuaternion<N> {
|
||||
#[inline]
|
||||
fn one() -> UnitQuaternion<N> {
|
||||
unsafe {
|
||||
UnitQuaternion::new_with_unit_quaternion(Quaternion::new(::one(), ::zero(), ::zero(), ::zero()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Neg<Output = N>> Inverse for UnitQuaternion<N> {
|
||||
#[inline]
|
||||
fn inverse(&self) -> Option<UnitQuaternion<N>> {
|
||||
let mut cpy = *self;
|
||||
|
||||
cpy.inverse_mut();
|
||||
Some(cpy)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inverse_mut(&mut self) -> bool {
|
||||
self.q.conjugate_mut();
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Rand + BaseFloat> Rand for UnitQuaternion<N> {
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> UnitQuaternion<N> {
|
||||
UnitQuaternion::new(rng.gen())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ApproxEq<N>> ApproxEq<N> for UnitQuaternion<N> {
|
||||
#[inline]
|
||||
fn approx_epsilon(_: Option<UnitQuaternion<N>>) -> N {
|
||||
ApproxEq::approx_epsilon(None::<N>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_ulps(_: Option<UnitQuaternion<N>>) -> u32 {
|
||||
ApproxEq::approx_ulps(None::<N>)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &UnitQuaternion<N>, eps: &N) -> bool {
|
||||
ApproxEq::approx_eq_eps(&self.q, &other.q, eps)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_ulps(&self, other: &UnitQuaternion<N>, ulps: u32) -> bool {
|
||||
ApproxEq::approx_eq_ulps(&self.q, &other.q, ulps)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + ApproxEq<N>> Div<UnitQuaternion<N>> for UnitQuaternion<N> {
|
||||
type Output = UnitQuaternion<N>;
|
||||
|
||||
#[inline]
|
||||
fn div(self, other: UnitQuaternion<N>) -> UnitQuaternion<N> {
|
||||
UnitQuaternion { q: self.q / other.q }
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + ApproxEq<N>> DivAssign<UnitQuaternion<N>> for UnitQuaternion<N> {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, other: UnitQuaternion<N>) {
|
||||
self.q /= other.q
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum> Mul<UnitQuaternion<N>> for UnitQuaternion<N> {
|
||||
type Output = UnitQuaternion<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: UnitQuaternion<N>) -> UnitQuaternion<N> {
|
||||
UnitQuaternion { q: self.q * right.q }
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum> MulAssign<UnitQuaternion<N>> for UnitQuaternion<N> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, right: UnitQuaternion<N>) {
|
||||
self.q *= right.q
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum> Mul<Vector3<N>> for UnitQuaternion<N> {
|
||||
type Output = Vector3<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: Vector3<N>) -> Vector3<N> {
|
||||
let _2: N = ::one::<N>() + ::one();
|
||||
let mut t = ::cross(self.q.vector(), &right);
|
||||
t.x = t.x * _2;
|
||||
t.y = t.y * _2;
|
||||
t.z = t.z * _2;
|
||||
|
||||
Vector3::new(t.x * self.q.w, t.y * self.q.w, t.z * self.q.w) + ::cross(self.q.vector(), &t) + right
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum> Mul<Point3<N>> for UnitQuaternion<N> {
|
||||
type Output = Point3<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: Point3<N>) -> Point3<N> {
|
||||
::origin::<Point3<N>>() + self * *right.as_vector()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N>> Mul<UnitQuaternion<N>> for Vector3<N> {
|
||||
type Output = Vector3<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: UnitQuaternion<N>) -> Vector3<N> {
|
||||
let mut inverse_quaternion = right;
|
||||
|
||||
inverse_quaternion.inverse_mut();
|
||||
|
||||
inverse_quaternion * self
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N>> Mul<UnitQuaternion<N>> for Point3<N> {
|
||||
type Output = Point3<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: UnitQuaternion<N>) -> Point3<N> {
|
||||
::origin::<Point3<N>>() + *self.as_vector() * right
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N>> MulAssign<UnitQuaternion<N>> for Vector3<N> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, right: UnitQuaternion<N>) {
|
||||
*self = *self * right
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N>> MulAssign<UnitQuaternion<N>> for Point3<N> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, right: UnitQuaternion<N>) {
|
||||
*self = *self * right
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> Rotation<Vector3<N>> for UnitQuaternion<N> {
|
||||
#[inline]
|
||||
fn rotation(&self) -> Vector3<N> {
|
||||
let _2 = ::one::<N>() + ::one();
|
||||
let mut v = *self.q.vector();
|
||||
let ang = _2 * v.normalize_mut().atan2(self.q.w);
|
||||
|
||||
if ::is_zero(&ang) {
|
||||
::zero()
|
||||
}
|
||||
else {
|
||||
Vector3::new(v.x * ang, v.y * ang, v.z * ang)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inverse_rotation(&self) -> Vector3<N> {
|
||||
-self.rotation()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn append_rotation_mut(&mut self, amount: &Vector3<N>) {
|
||||
*self = Rotation::append_rotation(self, amount)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn append_rotation(&self, amount: &Vector3<N>) -> UnitQuaternion<N> {
|
||||
*self * UnitQuaternion::new(*amount)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prepend_rotation_mut(&mut self, amount: &Vector3<N>) {
|
||||
*self = Rotation::prepend_rotation(self, amount)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prepend_rotation(&self, amount: &Vector3<N>) -> UnitQuaternion<N> {
|
||||
UnitQuaternion::new(*amount) * *self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_rotation(&mut self, v: Vector3<N>) {
|
||||
*self = UnitQuaternion::new(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> RotationMatrix<N, Vector3<N>, Vector3<N>> for UnitQuaternion<N> {
|
||||
type Output = Rotation3<N>;
|
||||
|
||||
#[inline]
|
||||
fn to_rotation_matrix(&self) -> Rotation3<N> {
|
||||
self.to_rotation_matrix()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N>> Rotate<Vector3<N>> for UnitQuaternion<N> {
|
||||
#[inline]
|
||||
fn rotate(&self, v: &Vector3<N>) -> Vector3<N> {
|
||||
*self * *v
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inverse_rotate(&self, v: &Vector3<N>) -> Vector3<N> {
|
||||
*v * *self
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N>> Rotate<Point3<N>> for UnitQuaternion<N> {
|
||||
#[inline]
|
||||
fn rotate(&self, p: &Point3<N>) -> Point3<N> {
|
||||
*self * *p
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inverse_rotate(&self, p: &Point3<N>) -> Point3<N> {
|
||||
*p * *self
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + ApproxEq<N>> RotationTo for UnitQuaternion<N> {
|
||||
type AngleType = N;
|
||||
type DeltaRotationType = UnitQuaternion<N>;
|
||||
|
||||
#[inline]
|
||||
fn angle_to(&self, other: &Self) -> N {
|
||||
let delta = self.rotation_to(other);
|
||||
let _2 = ::one::<N>() + ::one();
|
||||
|
||||
_2 * delta.q.vector().norm().atan2(delta.q.w)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rotation_to(&self, other: &Self) -> UnitQuaternion<N> {
|
||||
*other / *self
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N>> Transform<Vector3<N>> for UnitQuaternion<N> {
|
||||
#[inline]
|
||||
fn transform(&self, v: &Vector3<N>) -> Vector3<N> {
|
||||
*self * *v
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inverse_transform(&self, v: &Vector3<N>) -> Vector3<N> {
|
||||
*v * *self
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N>> Transform<Point3<N>> for UnitQuaternion<N> {
|
||||
#[inline]
|
||||
fn transform(&self, p: &Point3<N>) -> Point3<N> {
|
||||
*self * *p
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inverse_transform(&self, p: &Point3<N>) -> Point3<N> {
|
||||
*p * *self
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: fmt::Display> fmt::Display for UnitQuaternion<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Unit quaternion {} − ({}, {}, {})", self.q.w, self.q.i, self.q.j, self.q.k)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for UnitQuaternion<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> UnitQuaternion<N> {
|
||||
UnitQuaternion::new(Arbitrary::arbitrary(g))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pord_impl!(Quaternion, w, i, j, k);
|
||||
vec_axis_impl!(Quaternion, w, i, j, k);
|
||||
vec_cast_impl!(Quaternion, w, i, j, k);
|
||||
conversion_impl!(Quaternion, 4);
|
||||
index_impl!(Quaternion);
|
||||
indexable_impl!(Quaternion, 4);
|
||||
at_fast_impl!(Quaternion, 4);
|
||||
repeat_impl!(Quaternion, val, w, i, j, k);
|
||||
dim_impl!(Quaternion, 3);
|
||||
container_impl!(Quaternion);
|
||||
add_impl!(Quaternion, w, i, j, k);
|
||||
sub_impl!(Quaternion, w, i, j, k);
|
||||
scalar_add_impl!(Quaternion, w, i, j, k);
|
||||
scalar_sub_impl!(Quaternion, w, i, j, k);
|
||||
scalar_mul_impl!(Quaternion, w, i, j, k);
|
||||
scalar_div_impl!(Quaternion, w, i, j, k);
|
||||
neg_impl!(Quaternion, w, i, j, k);
|
||||
zero_one_impl!(Quaternion, w, i, j, k);
|
||||
approx_eq_impl!(Quaternion, w, i, j, k);
|
||||
from_iterator_impl!(Quaternion, iterator, iterator, iterator, iterator);
|
||||
bounded_impl!(Quaternion, w, i, j, k);
|
||||
axpy_impl!(Quaternion, w, i, j, k);
|
||||
iterable_impl!(Quaternion, 4);
|
||||
iterable_mut_impl!(Quaternion, 4);
|
||||
arbitrary_impl!(Quaternion, w, i, j, k);
|
||||
|
||||
dim_impl!(UnitQuaternion, 3);
|
|
@ -1,407 +0,0 @@
|
|||
//! Rotations matrices.
|
||||
|
||||
use std::fmt;
|
||||
use std::ops::{Mul, Neg, MulAssign, Index};
|
||||
use rand::{Rand, Rng};
|
||||
use num::{Zero, One};
|
||||
use traits::geometry::{Rotate, Rotation, AbsoluteRotate, RotationMatrix, RotationTo, Transform,
|
||||
ToHomogeneous, Norm, Cross};
|
||||
use traits::structure::{Cast, Dim, Row, Col, BaseFloat, BaseNum, Eye, Diag};
|
||||
use traits::operations::{Absolute, Inv, Transpose, ApproxEq};
|
||||
use structs::vec::{Vec1, Vec2, Vec3};
|
||||
use structs::pnt::{Pnt2, Pnt3};
|
||||
use structs::mat::{Mat2, Mat3, Mat4};
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// Two dimensional rotation matrix.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Hash, Copy)]
|
||||
pub struct Rot2<N> {
|
||||
submat: Mat2<N>
|
||||
}
|
||||
|
||||
impl<N: Clone + BaseFloat + Neg<Output = N>> Rot2<N> {
|
||||
/// Builds a 2 dimensional rotation matrix from an angle in radian.
|
||||
pub fn new(angle: Vec1<N>) -> Rot2<N> {
|
||||
let (sia, coa) = angle.x.sin_cos();
|
||||
|
||||
Rot2 {
|
||||
submat: Mat2::new(coa.clone(), -sia, sia, coa)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + Clone> Rotation<Vec1<N>> for Rot2<N> {
|
||||
#[inline]
|
||||
fn rotation(&self) -> Vec1<N> {
|
||||
Vec1::new((-self.submat.m12).atan2(self.submat.m11.clone()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_rotation(&self) -> Vec1<N> {
|
||||
-self.rotation()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn append_rotation_mut(&mut self, rot: &Vec1<N>) {
|
||||
*self = Rotation::append_rotation(self, rot)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn append_rotation(&self, rot: &Vec1<N>) -> Rot2<N> {
|
||||
Rot2::new(rot.clone()) * *self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prepend_rotation_mut(&mut self, rot: &Vec1<N>) {
|
||||
*self = Rotation::prepend_rotation(self, rot)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prepend_rotation(&self, rot: &Vec1<N>) -> Rot2<N> {
|
||||
*self * Rot2::new(rot.clone())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_rotation(&mut self, rot: Vec1<N>) {
|
||||
*self = Rot2::new(rot)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> RotationTo for Rot2<N> {
|
||||
type AngleType = N;
|
||||
type DeltaRotationType = Rot2<N>;
|
||||
|
||||
#[inline]
|
||||
fn angle_to(&self, other: &Self) -> N {
|
||||
self.rotation_to(other).rotation().norm()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rotation_to(&self, other: &Self) -> Rot2<N> {
|
||||
*other * ::inv(self).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Rand + BaseFloat> Rand for Rot2<N> {
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> Rot2<N> {
|
||||
Rot2::new(rng.gen())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> AbsoluteRotate<Vec2<N>> for Rot2<N> {
|
||||
#[inline]
|
||||
fn absolute_rotate(&self, v: &Vec2<N>) -> Vec2<N> {
|
||||
// the matrix is skew-symetric, so we dont need to compute the absolute value of every
|
||||
// component.
|
||||
let m11 = ::abs(&self.submat.m11);
|
||||
let m12 = ::abs(&self.submat.m12);
|
||||
let m22 = ::abs(&self.submat.m22);
|
||||
|
||||
Vec2::new(m11 * v.x + m12 * v.y, m12 * v.x + m22 * v.y)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + Clone + BaseFloat + Neg<Output = N>> Arbitrary for Rot2<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> Rot2<N> {
|
||||
Rot2::new(Arbitrary::arbitrary(g))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 3d rotation
|
||||
*/
|
||||
/// Three dimensional rotation matrix.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Hash, Copy)]
|
||||
pub struct Rot3<N> {
|
||||
submat: Mat3<N>
|
||||
}
|
||||
|
||||
|
||||
impl<N: Clone + BaseFloat> Rot3<N> {
|
||||
/// Builds a 3 dimensional rotation matrix from an axis and an angle.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `axisangle` - A vector representing the rotation. Its magnitude is the amount of rotation
|
||||
/// in radian. Its direction is the axis of rotation.
|
||||
pub fn new(axisangle: Vec3<N>) -> Rot3<N> {
|
||||
if ::is_zero(&Norm::sqnorm(&axisangle)) {
|
||||
::one()
|
||||
}
|
||||
else {
|
||||
let mut axis = axisangle;
|
||||
let angle = axis.normalize_mut();
|
||||
let _1: N = ::one();
|
||||
let ux = axis.x.clone();
|
||||
let uy = axis.y.clone();
|
||||
let uz = axis.z.clone();
|
||||
let sqx = ux * ux;
|
||||
let sqy = uy * uy;
|
||||
let sqz = uz * uz;
|
||||
let (sin, cos) = angle.sin_cos();
|
||||
let one_m_cos = _1 - cos;
|
||||
|
||||
Rot3 {
|
||||
submat: Mat3::new(
|
||||
(sqx + (_1 - sqx) * cos),
|
||||
(ux * uy * one_m_cos - uz * sin),
|
||||
(ux * uz * one_m_cos + uy * sin),
|
||||
|
||||
(ux * uy * one_m_cos + uz * sin),
|
||||
(sqy + (_1 - sqy) * cos),
|
||||
(uy * uz * one_m_cos - ux * sin),
|
||||
|
||||
(ux * uz * one_m_cos - uy * sin),
|
||||
(uy * uz * one_m_cos + ux * sin),
|
||||
(sqz + (_1 - sqz) * cos))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a rotation matrix from an orthogonal matrix.
|
||||
///
|
||||
/// This is unsafe because the orthogonality of `mat` is not checked.
|
||||
pub unsafe fn new_with_mat(mat: Mat3<N>) -> Rot3<N> {
|
||||
Rot3 {
|
||||
submat: mat
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new rotation from Euler angles.
|
||||
///
|
||||
/// The primitive rotations are applied in order: 1 roll − 2 pitch − 3 yaw.
|
||||
pub fn new_with_euler_angles(roll: N, pitch: N, yaw: N) -> Rot3<N> {
|
||||
let (sr, cr) = roll.sin_cos();
|
||||
let (sp, cp) = pitch.sin_cos();
|
||||
let (sy, cy) = yaw.sin_cos();
|
||||
|
||||
unsafe {
|
||||
Rot3::new_with_mat(
|
||||
Mat3::new(
|
||||
cy * cp, cy * sp * sr - sy * cr, cy * sp * cr + sy * sr,
|
||||
sy * cp, sy * sp * sr + cy * cr, sy * sp * cr - cy * sr,
|
||||
-sp, cp * sr, cp * cr
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + BaseFloat> Rot3<N> {
|
||||
/// Creates a rotation that corresponds to the local frame of an observer standing at the
|
||||
/// origin and looking toward `dir`.
|
||||
///
|
||||
/// It maps the view direction `dir` to the positive `z` axis.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * dir - The look direction, that is, direction the matrix `z` axis will be aligned with.
|
||||
/// * up - The vertical direction. The only requirement of this parameter is to not be
|
||||
/// collinear
|
||||
/// to `dir`. Non-collinearity is not checked.
|
||||
#[inline]
|
||||
pub fn new_observer_frame(dir: &Vec3<N>, up: &Vec3<N>) -> Rot3<N> {
|
||||
let zaxis = Norm::normalize(dir);
|
||||
let xaxis = Norm::normalize(&Cross::cross(up, &zaxis));
|
||||
let yaxis = Norm::normalize(&Cross::cross(&zaxis, &xaxis));
|
||||
|
||||
unsafe {
|
||||
Rot3::new_with_mat(Mat3::new(
|
||||
xaxis.x.clone(), yaxis.x.clone(), zaxis.x.clone(),
|
||||
xaxis.y.clone(), yaxis.y.clone(), zaxis.y.clone(),
|
||||
xaxis.z , yaxis.z , zaxis.z))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Builds a right-handed look-at view matrix without translation.
|
||||
///
|
||||
/// This conforms to the common notion of right handed look-at matrix from the computer
|
||||
/// graphics community.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * eye - The eye position.
|
||||
/// * target - The target position.
|
||||
/// * up - A vector approximately aligned with required the vertical axis. The only
|
||||
/// requirement of this parameter is to not be collinear to `target - eye`.
|
||||
#[inline]
|
||||
pub fn look_at_rh(dir: &Vec3<N>, up: &Vec3<N>) -> Rot3<N> {
|
||||
Rot3::new_observer_frame(&(-*dir), up).inv().unwrap()
|
||||
}
|
||||
|
||||
/// Builds a left-handed look-at view matrix without translation.
|
||||
///
|
||||
/// This conforms to the common notion of left handed look-at matrix from the computer
|
||||
/// graphics community.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * eye - The eye position.
|
||||
/// * target - The target position.
|
||||
/// * up - A vector approximately aligned with required the vertical axis. The only
|
||||
/// requirement of this parameter is to not be collinear to `target - eye`.
|
||||
#[inline]
|
||||
pub fn look_at_lh(dir: &Vec3<N>, up: &Vec3<N>) -> Rot3<N> {
|
||||
Rot3::new_observer_frame(&(*dir), up).inv().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + BaseFloat + Cast<f64>>
|
||||
Rotation<Vec3<N>> for Rot3<N> {
|
||||
#[inline]
|
||||
fn rotation(&self) -> Vec3<N> {
|
||||
let angle = ((self.submat.m11 + self.submat.m22 + self.submat.m33 - ::one()) / Cast::from(2.0)).acos();
|
||||
|
||||
if angle != angle {
|
||||
// FIXME: handle that correctly
|
||||
::zero()
|
||||
}
|
||||
else if ::is_zero(&angle) {
|
||||
::zero()
|
||||
}
|
||||
else {
|
||||
let m32_m23 = self.submat.m32 - self.submat.m23;
|
||||
let m13_m31 = self.submat.m13 - self.submat.m31;
|
||||
let m21_m12 = self.submat.m21 - self.submat.m12;
|
||||
|
||||
let denom = (m32_m23 * m32_m23 + m13_m31 * m13_m31 + m21_m12 * m21_m12).sqrt();
|
||||
|
||||
if ::is_zero(&denom) {
|
||||
// XXX: handle that properly
|
||||
// panic!("Internal error: singularity.")
|
||||
::zero()
|
||||
}
|
||||
else {
|
||||
let a_d = angle / denom;
|
||||
|
||||
Vec3::new(m32_m23 * a_d, m13_m31 * a_d, m21_m12 * a_d)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_rotation(&self) -> Vec3<N> {
|
||||
-self.rotation()
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
fn append_rotation_mut(&mut self, rot: &Vec3<N>) {
|
||||
*self = Rotation::append_rotation(self, rot)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn append_rotation(&self, axisangle: &Vec3<N>) -> Rot3<N> {
|
||||
Rot3::new(axisangle.clone()) * *self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prepend_rotation_mut(&mut self, rot: &Vec3<N>) {
|
||||
*self = Rotation::prepend_rotation(self, rot)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prepend_rotation(&self, axisangle: &Vec3<N>) -> Rot3<N> {
|
||||
*self * Rot3::new(axisangle.clone())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_rotation(&mut self, axisangle: Vec3<N>) {
|
||||
*self = Rot3::new(axisangle)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> RotationTo for Rot3<N> {
|
||||
type AngleType = N;
|
||||
type DeltaRotationType = Rot3<N>;
|
||||
|
||||
#[inline]
|
||||
fn angle_to(&self, other: &Self) -> N {
|
||||
// FIXME: refactor to avoid the normalization of the rotation axisangle vector.
|
||||
self.rotation_to(other).rotation().norm()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rotation_to(&self, other: &Self) -> Rot3<N> {
|
||||
*other * ::inv(self).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Rand + BaseFloat> Rand for Rot3<N> {
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> Rot3<N> {
|
||||
Rot3::new(rng.gen())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> AbsoluteRotate<Vec3<N>> for Rot3<N> {
|
||||
#[inline]
|
||||
fn absolute_rotate(&self, v: &Vec3<N>) -> Vec3<N> {
|
||||
Vec3::new(
|
||||
::abs(&self.submat.m11) * v.x + ::abs(&self.submat.m12) * v.y + ::abs(&self.submat.m13) * v.z,
|
||||
::abs(&self.submat.m21) * v.x + ::abs(&self.submat.m22) * v.y + ::abs(&self.submat.m23) * v.z,
|
||||
::abs(&self.submat.m31) * v.x + ::abs(&self.submat.m32) * v.y + ::abs(&self.submat.m33) * v.z)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + Clone + BaseFloat> Arbitrary for Rot3<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> Rot3<N> {
|
||||
Rot3::new(Arbitrary::arbitrary(g))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Common implementations.
|
||||
*/
|
||||
|
||||
submat_impl!(Rot2, Mat2);
|
||||
rotate_impl!(Rot2, Vec2, Pnt2);
|
||||
transform_impl!(Rot2, Vec2, Pnt2);
|
||||
dim_impl!(Rot2, 2);
|
||||
rot_mul_rot_impl!(Rot2);
|
||||
rot_mul_vec_impl!(Rot2, Vec2);
|
||||
vec_mul_rot_impl!(Rot2, Vec2);
|
||||
rot_mul_pnt_impl!(Rot2, Pnt2);
|
||||
pnt_mul_rot_impl!(Rot2, Pnt2);
|
||||
one_impl!(Rot2);
|
||||
eye_impl!(Rot2);
|
||||
rotation_matrix_impl!(Rot2, Vec2, Vec1);
|
||||
col_impl!(Rot2, Vec2);
|
||||
row_impl!(Rot2, Vec2);
|
||||
index_impl!(Rot2);
|
||||
absolute_impl!(Rot2, Mat2);
|
||||
to_homogeneous_impl!(Rot2, Mat3);
|
||||
inv_impl!(Rot2);
|
||||
transpose_impl!(Rot2);
|
||||
approx_eq_impl!(Rot2);
|
||||
diag_impl!(Rot2, Vec2);
|
||||
rot_display_impl!(Rot2);
|
||||
|
||||
submat_impl!(Rot3, Mat3);
|
||||
rotate_impl!(Rot3, Vec3, Pnt3);
|
||||
transform_impl!(Rot3, Vec3, Pnt3);
|
||||
dim_impl!(Rot3, 3);
|
||||
rot_mul_rot_impl!(Rot3);
|
||||
rot_mul_vec_impl!(Rot3, Vec3);
|
||||
vec_mul_rot_impl!(Rot3, Vec3);
|
||||
rot_mul_pnt_impl!(Rot3, Pnt3);
|
||||
pnt_mul_rot_impl!(Rot3, Pnt3);
|
||||
one_impl!(Rot3);
|
||||
eye_impl!(Rot3);
|
||||
rotation_matrix_impl!(Rot3, Vec3, Vec3);
|
||||
col_impl!(Rot3, Vec3);
|
||||
row_impl!(Rot3, Vec3);
|
||||
index_impl!(Rot3);
|
||||
absolute_impl!(Rot3, Mat3);
|
||||
to_homogeneous_impl!(Rot3, Mat4);
|
||||
inv_impl!(Rot3);
|
||||
transpose_impl!(Rot3);
|
||||
approx_eq_impl!(Rot3);
|
||||
diag_impl!(Rot3, Vec3);
|
||||
rot_display_impl!(Rot3);
|
|
@ -0,0 +1,407 @@
|
|||
//! Rotations matrices.
|
||||
|
||||
use std::fmt;
|
||||
use std::ops::{Mul, Neg, MulAssign, Index};
|
||||
use rand::{Rand, Rng};
|
||||
use num::{Zero, One};
|
||||
use traits::geometry::{Rotate, Rotation, AbsoluteRotate, RotationMatrix, RotationTo, Transform,
|
||||
ToHomogeneous, Norm, Cross};
|
||||
use traits::structure::{Cast, Dimension, Row, Column, BaseFloat, BaseNum, Eye, Diagonal};
|
||||
use traits::operations::{Absolute, Inverse, Transpose, ApproxEq};
|
||||
use structs::vector::{Vector1, Vector2, Vector3};
|
||||
use structs::point::{Point2, Point3};
|
||||
use structs::matrix::{Matrix2, Matrix3, Matrix4};
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// Two dimensional rotation matrix.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Hash, Copy)]
|
||||
pub struct Rotation2<N> {
|
||||
submatrix: Matrix2<N>
|
||||
}
|
||||
|
||||
impl<N: Clone + BaseFloat + Neg<Output = N>> Rotation2<N> {
|
||||
/// Builds a 2 dimensional rotation matrix from an angle in radian.
|
||||
pub fn new(angle: Vector1<N>) -> Rotation2<N> {
|
||||
let (sia, coa) = angle.x.sin_cos();
|
||||
|
||||
Rotation2 {
|
||||
submatrix: Matrix2::new(coa.clone(), -sia, sia, coa)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat + Clone> Rotation<Vector1<N>> for Rotation2<N> {
|
||||
#[inline]
|
||||
fn rotation(&self) -> Vector1<N> {
|
||||
Vector1::new((-self.submatrix.m12).atan2(self.submatrix.m11.clone()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inverse_rotation(&self) -> Vector1<N> {
|
||||
-self.rotation()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn append_rotation_mut(&mut self, rotation: &Vector1<N>) {
|
||||
*self = Rotation::append_rotation(self, rotation)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn append_rotation(&self, rotation: &Vector1<N>) -> Rotation2<N> {
|
||||
Rotation2::new(rotation.clone()) * *self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prepend_rotation_mut(&mut self, rotation: &Vector1<N>) {
|
||||
*self = Rotation::prepend_rotation(self, rotation)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prepend_rotation(&self, rotation: &Vector1<N>) -> Rotation2<N> {
|
||||
*self * Rotation2::new(rotation.clone())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_rotation(&mut self, rotation: Vector1<N>) {
|
||||
*self = Rotation2::new(rotation)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> RotationTo for Rotation2<N> {
|
||||
type AngleType = N;
|
||||
type DeltaRotationType = Rotation2<N>;
|
||||
|
||||
#[inline]
|
||||
fn angle_to(&self, other: &Self) -> N {
|
||||
self.rotation_to(other).rotation().norm()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rotation_to(&self, other: &Self) -> Rotation2<N> {
|
||||
*other * ::inverse(self).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Rand + BaseFloat> Rand for Rotation2<N> {
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> Rotation2<N> {
|
||||
Rotation2::new(rng.gen())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> AbsoluteRotate<Vector2<N>> for Rotation2<N> {
|
||||
#[inline]
|
||||
fn absolute_rotate(&self, v: &Vector2<N>) -> Vector2<N> {
|
||||
// the matrix is skew-symetric, so we dont need to compute the absolute value of every
|
||||
// component.
|
||||
let m11 = ::abs(&self.submatrix.m11);
|
||||
let m12 = ::abs(&self.submatrix.m12);
|
||||
let m22 = ::abs(&self.submatrix.m22);
|
||||
|
||||
Vector2::new(m11 * v.x + m12 * v.y, m12 * v.x + m22 * v.y)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + Clone + BaseFloat + Neg<Output = N>> Arbitrary for Rotation2<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> Rotation2<N> {
|
||||
Rotation2::new(Arbitrary::arbitrary(g))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 3d rotation
|
||||
*/
|
||||
/// Three dimensional rotation matrix.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Hash, Copy)]
|
||||
pub struct Rotation3<N> {
|
||||
submatrix: Matrix3<N>
|
||||
}
|
||||
|
||||
|
||||
impl<N: Clone + BaseFloat> Rotation3<N> {
|
||||
/// Builds a 3 dimensional rotation matrix from an axis and an angle.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `axisangle` - A vector representing the rotation. Its magnitude is the amount of rotation
|
||||
/// in radian. Its direction is the axis of rotation.
|
||||
pub fn new(axisangle: Vector3<N>) -> Rotation3<N> {
|
||||
if ::is_zero(&Norm::norm_squared(&axisangle)) {
|
||||
::one()
|
||||
}
|
||||
else {
|
||||
let mut axis = axisangle;
|
||||
let angle = axis.normalize_mut();
|
||||
let _1: N = ::one();
|
||||
let ux = axis.x.clone();
|
||||
let uy = axis.y.clone();
|
||||
let uz = axis.z.clone();
|
||||
let sqx = ux * ux;
|
||||
let sqy = uy * uy;
|
||||
let sqz = uz * uz;
|
||||
let (sin, cos) = angle.sin_cos();
|
||||
let one_m_cos = _1 - cos;
|
||||
|
||||
Rotation3 {
|
||||
submatrix: Matrix3::new(
|
||||
(sqx + (_1 - sqx) * cos),
|
||||
(ux * uy * one_m_cos - uz * sin),
|
||||
(ux * uz * one_m_cos + uy * sin),
|
||||
|
||||
(ux * uy * one_m_cos + uz * sin),
|
||||
(sqy + (_1 - sqy) * cos),
|
||||
(uy * uz * one_m_cos - ux * sin),
|
||||
|
||||
(ux * uz * one_m_cos - uy * sin),
|
||||
(uy * uz * one_m_cos + ux * sin),
|
||||
(sqz + (_1 - sqz) * cos))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a rotation matrix from an orthogonal matrix.
|
||||
///
|
||||
/// This is unsafe because the orthogonality of `matrix` is not checked.
|
||||
pub unsafe fn new_with_matrix(matrix: Matrix3<N>) -> Rotation3<N> {
|
||||
Rotation3 {
|
||||
submatrix: matrix
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new rotation from Euler angles.
|
||||
///
|
||||
/// The primitive rotations are applied in order: 1 roll − 2 pitch − 3 yaw.
|
||||
pub fn new_with_euler_angles(roll: N, pitch: N, yaw: N) -> Rotation3<N> {
|
||||
let (sr, cr) = roll.sin_cos();
|
||||
let (sp, cp) = pitch.sin_cos();
|
||||
let (sy, cy) = yaw.sin_cos();
|
||||
|
||||
unsafe {
|
||||
Rotation3::new_with_matrix(
|
||||
Matrix3::new(
|
||||
cy * cp, cy * sp * sr - sy * cr, cy * sp * cr + sy * sr,
|
||||
sy * cp, sy * sp * sr + cy * cr, sy * sp * cr - cy * sr,
|
||||
-sp, cp * sr, cp * cr
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + BaseFloat> Rotation3<N> {
|
||||
/// Creates a rotation that corresponds to the local frame of an observer standing at the
|
||||
/// origin and looking toward `dir`.
|
||||
///
|
||||
/// It maps the view direction `dir` to the positive `z` axis.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * dir - The look direction, that is, direction the matrix `z` axis will be aligned with.
|
||||
/// * up - The vertical direction. The only requirement of this parameter is to not be
|
||||
/// collinear
|
||||
/// to `dir`. Non-collinearity is not checked.
|
||||
#[inline]
|
||||
pub fn new_observer_frame(dir: &Vector3<N>, up: &Vector3<N>) -> Rotation3<N> {
|
||||
let zaxis = Norm::normalize(dir);
|
||||
let xaxis = Norm::normalize(&Cross::cross(up, &zaxis));
|
||||
let yaxis = Norm::normalize(&Cross::cross(&zaxis, &xaxis));
|
||||
|
||||
unsafe {
|
||||
Rotation3::new_with_matrix(Matrix3::new(
|
||||
xaxis.x.clone(), yaxis.x.clone(), zaxis.x.clone(),
|
||||
xaxis.y.clone(), yaxis.y.clone(), zaxis.y.clone(),
|
||||
xaxis.z , yaxis.z , zaxis.z))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Builds a right-handed look-at view matrix without translation.
|
||||
///
|
||||
/// This conforms to the common notion of right handed look-at matrix from the computer
|
||||
/// graphics community.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * eye - The eye position.
|
||||
/// * target - The target position.
|
||||
/// * up - A vector approximately aligned with required the vertical axis. The only
|
||||
/// requirement of this parameter is to not be collinear to `target - eye`.
|
||||
#[inline]
|
||||
pub fn look_at_rh(dir: &Vector3<N>, up: &Vector3<N>) -> Rotation3<N> {
|
||||
Rotation3::new_observer_frame(&(-*dir), up).inverse().unwrap()
|
||||
}
|
||||
|
||||
/// Builds a left-handed look-at view matrix without translation.
|
||||
///
|
||||
/// This conforms to the common notion of left handed look-at matrix from the computer
|
||||
/// graphics community.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * eye - The eye position.
|
||||
/// * target - The target position.
|
||||
/// * up - A vector approximately aligned with required the vertical axis. The only
|
||||
/// requirement of this parameter is to not be collinear to `target - eye`.
|
||||
#[inline]
|
||||
pub fn look_at_lh(dir: &Vector3<N>, up: &Vector3<N>) -> Rotation3<N> {
|
||||
Rotation3::new_observer_frame(&(*dir), up).inverse().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + BaseFloat + Cast<f64>>
|
||||
Rotation<Vector3<N>> for Rotation3<N> {
|
||||
#[inline]
|
||||
fn rotation(&self) -> Vector3<N> {
|
||||
let angle = ((self.submatrix.m11 + self.submatrix.m22 + self.submatrix.m33 - ::one()) / Cast::from(2.0)).acos();
|
||||
|
||||
if angle != angle {
|
||||
// FIXME: handle that correctly
|
||||
::zero()
|
||||
}
|
||||
else if ::is_zero(&angle) {
|
||||
::zero()
|
||||
}
|
||||
else {
|
||||
let m32_m23 = self.submatrix.m32 - self.submatrix.m23;
|
||||
let m13_m31 = self.submatrix.m13 - self.submatrix.m31;
|
||||
let m21_m12 = self.submatrix.m21 - self.submatrix.m12;
|
||||
|
||||
let denom = (m32_m23 * m32_m23 + m13_m31 * m13_m31 + m21_m12 * m21_m12).sqrt();
|
||||
|
||||
if ::is_zero(&denom) {
|
||||
// XXX: handle that properly
|
||||
// panic!("Internal error: singularity.")
|
||||
::zero()
|
||||
}
|
||||
else {
|
||||
let a_d = angle / denom;
|
||||
|
||||
Vector3::new(m32_m23 * a_d, m13_m31 * a_d, m21_m12 * a_d)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inverse_rotation(&self) -> Vector3<N> {
|
||||
-self.rotation()
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
fn append_rotation_mut(&mut self, rotation: &Vector3<N>) {
|
||||
*self = Rotation::append_rotation(self, rotation)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn append_rotation(&self, axisangle: &Vector3<N>) -> Rotation3<N> {
|
||||
Rotation3::new(axisangle.clone()) * *self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prepend_rotation_mut(&mut self, rotation: &Vector3<N>) {
|
||||
*self = Rotation::prepend_rotation(self, rotation)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prepend_rotation(&self, axisangle: &Vector3<N>) -> Rotation3<N> {
|
||||
*self * Rotation3::new(axisangle.clone())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_rotation(&mut self, axisangle: Vector3<N>) {
|
||||
*self = Rotation3::new(axisangle)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> RotationTo for Rotation3<N> {
|
||||
type AngleType = N;
|
||||
type DeltaRotationType = Rotation3<N>;
|
||||
|
||||
#[inline]
|
||||
fn angle_to(&self, other: &Self) -> N {
|
||||
// FIXME: refactor to avoid the normalization of the rotation axisangle vector.
|
||||
self.rotation_to(other).rotation().norm()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rotation_to(&self, other: &Self) -> Rotation3<N> {
|
||||
*other * ::inverse(self).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Rand + BaseFloat> Rand for Rotation3<N> {
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> Rotation3<N> {
|
||||
Rotation3::new(rng.gen())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> AbsoluteRotate<Vector3<N>> for Rotation3<N> {
|
||||
#[inline]
|
||||
fn absolute_rotate(&self, v: &Vector3<N>) -> Vector3<N> {
|
||||
Vector3::new(
|
||||
::abs(&self.submatrix.m11) * v.x + ::abs(&self.submatrix.m12) * v.y + ::abs(&self.submatrix.m13) * v.z,
|
||||
::abs(&self.submatrix.m21) * v.x + ::abs(&self.submatrix.m22) * v.y + ::abs(&self.submatrix.m23) * v.z,
|
||||
::abs(&self.submatrix.m31) * v.x + ::abs(&self.submatrix.m32) * v.y + ::abs(&self.submatrix.m33) * v.z)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + Clone + BaseFloat> Arbitrary for Rotation3<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> Rotation3<N> {
|
||||
Rotation3::new(Arbitrary::arbitrary(g))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Common implementations.
|
||||
*/
|
||||
|
||||
submat_impl!(Rotation2, Matrix2);
|
||||
rotate_impl!(Rotation2, Vector2, Point2);
|
||||
transform_impl!(Rotation2, Vector2, Point2);
|
||||
dim_impl!(Rotation2, 2);
|
||||
rotation_mul_rotation_impl!(Rotation2);
|
||||
rotation_mul_vec_impl!(Rotation2, Vector2);
|
||||
vec_mul_rotation_impl!(Rotation2, Vector2);
|
||||
rotation_mul_point_impl!(Rotation2, Point2);
|
||||
point_mul_rotation_impl!(Rotation2, Point2);
|
||||
one_impl!(Rotation2);
|
||||
eye_impl!(Rotation2);
|
||||
rotation_matrix_impl!(Rotation2, Vector2, Vector1);
|
||||
col_impl!(Rotation2, Vector2);
|
||||
row_impl!(Rotation2, Vector2);
|
||||
index_impl!(Rotation2);
|
||||
absolute_impl!(Rotation2, Matrix2);
|
||||
to_homogeneous_impl!(Rotation2, Matrix3);
|
||||
inverse_impl!(Rotation2);
|
||||
transpose_impl!(Rotation2);
|
||||
approx_eq_impl!(Rotation2);
|
||||
diag_impl!(Rotation2, Vector2);
|
||||
rotation_display_impl!(Rotation2);
|
||||
|
||||
submat_impl!(Rotation3, Matrix3);
|
||||
rotate_impl!(Rotation3, Vector3, Point3);
|
||||
transform_impl!(Rotation3, Vector3, Point3);
|
||||
dim_impl!(Rotation3, 3);
|
||||
rotation_mul_rotation_impl!(Rotation3);
|
||||
rotation_mul_vec_impl!(Rotation3, Vector3);
|
||||
vec_mul_rotation_impl!(Rotation3, Vector3);
|
||||
rotation_mul_point_impl!(Rotation3, Point3);
|
||||
point_mul_rotation_impl!(Rotation3, Point3);
|
||||
one_impl!(Rotation3);
|
||||
eye_impl!(Rotation3);
|
||||
rotation_matrix_impl!(Rotation3, Vector3, Vector3);
|
||||
col_impl!(Rotation3, Vector3);
|
||||
row_impl!(Rotation3, Vector3);
|
||||
index_impl!(Rotation3);
|
||||
absolute_impl!(Rotation3, Matrix3);
|
||||
to_homogeneous_impl!(Rotation3, Matrix4);
|
||||
inverse_impl!(Rotation3);
|
||||
transpose_impl!(Rotation3);
|
||||
approx_eq_impl!(Rotation3);
|
||||
diag_impl!(Rotation3, Vector3);
|
||||
rotation_display_impl!(Rotation3);
|
|
@ -1,12 +1,12 @@
|
|||
#![macro_use]
|
||||
|
||||
macro_rules! submat_impl(
|
||||
($t: ident, $submat: ident) => (
|
||||
($t: ident, $submatrix: ident) => (
|
||||
impl<N> $t<N> {
|
||||
/// This rotation's underlying matrix.
|
||||
#[inline]
|
||||
pub fn submat<'r>(&'r self) -> &'r $submat<N> {
|
||||
&self.submat
|
||||
pub fn submatrix<'r>(&'r self) -> &'r $submatrix<N> {
|
||||
&self.submatrix
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -21,7 +21,7 @@ macro_rules! rotate_impl(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_rotate(&self, v: &$tv<N>) -> $tv<N> {
|
||||
fn inverse_rotate(&self, v: &$tv<N>) -> $tv<N> {
|
||||
*v * *self
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ macro_rules! rotate_impl(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_rotate(&self, p: &$tp<N>) -> $tp<N> {
|
||||
fn inverse_rotate(&self, p: &$tp<N>) -> $tp<N> {
|
||||
*p * *self
|
||||
}
|
||||
}
|
||||
|
@ -49,8 +49,8 @@ macro_rules! transform_impl(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_transform(&self, v: &$tv<N>) -> $tv<N> {
|
||||
self.inv_rotate(v)
|
||||
fn inverse_transform(&self, v: &$tv<N>) -> $tv<N> {
|
||||
self.inverse_rotate(v)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,19 +61,19 @@ macro_rules! transform_impl(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_transform(&self, p: &$tp<N>) -> $tp<N> {
|
||||
self.inv_rotate(p)
|
||||
fn inverse_transform(&self, p: &$tp<N>) -> $tp<N> {
|
||||
self.inverse_rotate(p)
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! dim_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N> Dim for $t<N> {
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N> Dimension for $t<N> {
|
||||
#[inline]
|
||||
fn dim(_: Option<$t<N>>) -> usize {
|
||||
$dim
|
||||
fn dimension(_: Option<$t<N>>) -> usize {
|
||||
$dimension
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -85,7 +85,7 @@ macro_rules! rotation_matrix_impl(
|
|||
type Output = $t<N>;
|
||||
|
||||
#[inline]
|
||||
fn to_rot_mat(&self) -> $t<N> {
|
||||
fn to_rotation_matrix(&self) -> $t<N> {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ macro_rules! one_impl(
|
|||
impl<N: BaseNum> One for $t<N> {
|
||||
#[inline]
|
||||
fn one() -> $t<N> {
|
||||
$t { submat: ::one() }
|
||||
$t { submatrix: ::one() }
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -107,9 +107,9 @@ macro_rules! eye_impl(
|
|||
($t: ident) => (
|
||||
impl<N: BaseNum> Eye for $t<N> {
|
||||
#[inline]
|
||||
fn new_identity(dim: usize) -> $t<N> {
|
||||
if dim != ::dim::<$t<N>>() {
|
||||
panic!("Dimension mismatch: should be {}, got {}.", ::dim::<$t<N>>(), dim);
|
||||
fn new_identity(dimension: usize) -> $t<N> {
|
||||
if dimension != ::dimension::<$t<N>>() {
|
||||
panic!("Dimension mismatch: should be {}, got {}.", ::dimension::<$t<N>>(), dimension);
|
||||
}
|
||||
else {
|
||||
::one()
|
||||
|
@ -121,90 +121,90 @@ macro_rules! eye_impl(
|
|||
|
||||
macro_rules! diag_impl(
|
||||
($t: ident, $tv: ident) => (
|
||||
impl<N: Copy + Zero> Diag<$tv<N>> for $t<N> {
|
||||
impl<N: Copy + Zero> Diagonal<$tv<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn from_diag(diag: &$tv<N>) -> $t<N> {
|
||||
$t { submat: Diag::from_diag(diag) }
|
||||
fn from_diag(diagonal: &$tv<N>) -> $t<N> {
|
||||
$t { submatrix: Diagonal::from_diag(diagonal) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn diag(&self) -> $tv<N> {
|
||||
self.submat.diag()
|
||||
fn diagonal(&self) -> $tv<N> {
|
||||
self.submatrix.diagonal()
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! rot_mul_rot_impl(
|
||||
macro_rules! rotation_mul_rotation_impl(
|
||||
($t: ident) => (
|
||||
impl<N: BaseNum> Mul<$t<N>> for $t<N> {
|
||||
type Output = $t<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: $t<N>) -> $t<N> {
|
||||
$t { submat: self.submat * right.submat }
|
||||
$t { submatrix: self.submatrix * right.submatrix }
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + BaseNum> MulAssign<$t<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, right: $t<N>) {
|
||||
self.submat *= right.submat
|
||||
self.submatrix *= right.submatrix
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! rot_mul_vec_impl(
|
||||
macro_rules! rotation_mul_vec_impl(
|
||||
($t: ident, $tv: ident) => (
|
||||
impl<N: BaseNum> Mul<$tv<N>> for $t<N> {
|
||||
type Output = $tv<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: $tv<N>) -> $tv<N> {
|
||||
self.submat * right
|
||||
self.submatrix * right
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! rot_mul_pnt_impl(
|
||||
macro_rules! rotation_mul_point_impl(
|
||||
($t: ident, $tv: ident) => (
|
||||
rot_mul_vec_impl!($t, $tv);
|
||||
rotation_mul_vec_impl!($t, $tv);
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! vec_mul_rot_impl(
|
||||
macro_rules! vec_mul_rotation_impl(
|
||||
($t: ident, $tv: ident) => (
|
||||
impl<N: BaseNum> Mul<$t<N>> for $tv<N> {
|
||||
type Output = $tv<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: $t<N>) -> $tv<N> {
|
||||
self * right.submat
|
||||
self * right.submatrix
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + BaseNum> MulAssign<$t<N>> for $tv<N> {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, right: $t<N>) {
|
||||
*self *= right.submat
|
||||
*self *= right.submatrix
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! pnt_mul_rot_impl(
|
||||
macro_rules! point_mul_rotation_impl(
|
||||
($t: ident, $tv: ident) => (
|
||||
vec_mul_rot_impl!($t, $tv);
|
||||
vec_mul_rotation_impl!($t, $tv);
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! inv_impl(
|
||||
macro_rules! inverse_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Copy> Inv for $t<N> {
|
||||
impl<N: Copy> Inverse for $t<N> {
|
||||
#[inline]
|
||||
fn inv_mut(&mut self) -> bool {
|
||||
fn inverse_mut(&mut self) -> bool {
|
||||
self.transpose_mut();
|
||||
|
||||
// always succeed
|
||||
|
@ -212,7 +212,7 @@ macro_rules! inv_impl(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn inv(&self) -> Option<$t<N>> {
|
||||
fn inverse(&self) -> Option<$t<N>> {
|
||||
// always succeed
|
||||
Some(self.transpose())
|
||||
}
|
||||
|
@ -225,12 +225,12 @@ macro_rules! transpose_impl(
|
|||
impl<N: Copy> Transpose for $t<N> {
|
||||
#[inline]
|
||||
fn transpose(&self) -> $t<N> {
|
||||
$t { submat: Transpose::transpose(&self.submat) }
|
||||
$t { submatrix: Transpose::transpose(&self.submatrix) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn transpose_mut(&mut self) {
|
||||
self.submat.transpose_mut()
|
||||
self.submatrix.transpose_mut()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -241,16 +241,16 @@ macro_rules! row_impl(
|
|||
impl<N: Copy + Zero> Row<$tv<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn nrows(&self) -> usize {
|
||||
self.submat.nrows()
|
||||
self.submatrix.nrows()
|
||||
}
|
||||
#[inline]
|
||||
fn row(&self, i: usize) -> $tv<N> {
|
||||
self.submat.row(i)
|
||||
self.submatrix.row(i)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_row(&mut self, i: usize, row: $tv<N>) {
|
||||
self.submat.set_row(i, row);
|
||||
self.submatrix.set_row(i, row);
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -258,19 +258,19 @@ macro_rules! row_impl(
|
|||
|
||||
macro_rules! col_impl(
|
||||
($t: ident, $tv: ident) => (
|
||||
impl<N: Copy + Zero> Col<$tv<N>> for $t<N> {
|
||||
impl<N: Copy + Zero> Column<$tv<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn ncols(&self) -> usize {
|
||||
self.submat.ncols()
|
||||
self.submatrix.ncols()
|
||||
}
|
||||
#[inline]
|
||||
fn col(&self, i: usize) -> $tv<N> {
|
||||
self.submat.col(i)
|
||||
fn column(&self, i: usize) -> $tv<N> {
|
||||
self.submatrix.column(i)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_col(&mut self, i: usize, col: $tv<N>) {
|
||||
self.submat.set_col(i, col);
|
||||
fn set_col(&mut self, i: usize, column: $tv<N>) {
|
||||
self.submatrix.set_col(i, column);
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -282,7 +282,7 @@ macro_rules! index_impl(
|
|||
type Output = N;
|
||||
|
||||
fn index(&self, i: (usize, usize)) -> &N {
|
||||
&self.submat[i]
|
||||
&self.submatrix[i]
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -293,7 +293,7 @@ macro_rules! to_homogeneous_impl(
|
|||
impl<N: BaseNum> ToHomogeneous<$tm<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn to_homogeneous(&self) -> $tm<N> {
|
||||
self.submat.to_homogeneous()
|
||||
self.submatrix.to_homogeneous()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -314,17 +314,17 @@ macro_rules! approx_eq_impl(
|
|||
|
||||
#[inline]
|
||||
fn approx_eq(&self, other: &$t<N>) -> bool {
|
||||
ApproxEq::approx_eq(&self.submat, &other.submat)
|
||||
ApproxEq::approx_eq(&self.submatrix, &other.submatrix)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N) -> bool {
|
||||
ApproxEq::approx_eq_eps(&self.submat, &other.submat, epsilon)
|
||||
ApproxEq::approx_eq_eps(&self.submatrix, &other.submatrix, epsilon)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn approx_eq_ulps(&self, other: &$t<N>, ulps: u32) -> bool {
|
||||
ApproxEq::approx_eq_ulps(&self.submat, &other.submat, ulps)
|
||||
ApproxEq::approx_eq_ulps(&self.submatrix, &other.submatrix, ulps)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -335,20 +335,20 @@ macro_rules! absolute_impl(
|
|||
impl<N: Absolute<N>> Absolute<$tm<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn abs(m: &$t<N>) -> $tm<N> {
|
||||
Absolute::abs(&m.submat)
|
||||
Absolute::abs(&m.submatrix)
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! rot_display_impl(
|
||||
macro_rules! rotation_display_impl(
|
||||
($t: ident) => (
|
||||
impl<N: fmt::Display + BaseFloat> fmt::Display for $t<N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let precision = f.precision().unwrap_or(3);
|
||||
|
||||
try!(writeln!(f, "Rotation matrix {{"));
|
||||
try!(write!(f, "{:.*}", precision, self.submat));
|
||||
try!(write!(f, "{:.*}", precision, self.submatrix));
|
||||
writeln!(f, "}}")
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
use std::fmt;
|
||||
use std::ops::{Mul, Neg, MulAssign};
|
||||
|
||||
use rand::{Rand, Rng};
|
||||
use num::One;
|
||||
use structs::mat::{Mat3, Mat4};
|
||||
use traits::structure::{Dim, Col, BaseFloat, BaseNum};
|
||||
use traits::operations::{Inv, ApproxEq};
|
||||
use traits::geometry::{Rotation, Transform, Transformation, Translation, ToHomogeneous};
|
||||
|
||||
use structs::vec::{Vec1, Vec2, Vec3};
|
||||
use structs::pnt::{Pnt2, Pnt3};
|
||||
use structs::rot::{Rot2, Rot3};
|
||||
use structs::iso::{Iso2, Iso3};
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
// FIXME: the name is not explicit at all but coherent with the other tree-letters names…
|
||||
/// A two-dimensional similarity transformation.
|
||||
///
|
||||
/// This is a composition of a uniform scale, followed by a rotation, followed by a translation.
|
||||
/// Vectors `Vec2` are not affected by the translational component of this transformation while
|
||||
/// points `Pnt2` are.
|
||||
/// Similarity transformations conserve angles. Distances are multiplied by some constant (the
|
||||
/// scale factor). The scale factor cannot be zero.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
|
||||
pub struct Sim2<N> {
|
||||
/// The uniform scale applicable by this similarity transformation.
|
||||
scale: N,
|
||||
/// The isometry applicable by this similarity transformation.
|
||||
pub isometry: Iso2<N>
|
||||
}
|
||||
|
||||
/// A three-dimensional similarity transformation.
|
||||
///
|
||||
/// This is a composition of a scale, followed by a rotation, followed by a translation.
|
||||
/// Vectors `Vec3` are not affected by the translational component of this transformation while
|
||||
/// points `Pnt3` are.
|
||||
/// Similarity transformations conserve angles. Distances are multiplied by some constant (the
|
||||
/// scale factor). The scale factor cannot be zero.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
|
||||
pub struct Sim3<N> {
|
||||
/// The uniform scale applicable by this similarity transformation.
|
||||
scale: N,
|
||||
/// The isometry applicable by this similarity transformation.
|
||||
pub isometry: Iso3<N>
|
||||
}
|
||||
|
||||
sim_impl!(Sim2, Iso2, Rot2, Vec2, Vec1);
|
||||
dim_impl!(Sim2, 2);
|
||||
sim_scale_impl!(Sim2);
|
||||
sim_one_impl!(Sim2);
|
||||
sim_mul_sim_impl!(Sim2);
|
||||
sim_mul_iso_impl!(Sim2, Iso2);
|
||||
sim_mul_rot_impl!(Sim2, Rot2);
|
||||
sim_mul_pnt_vec_impl!(Sim2, Pnt2);
|
||||
sim_mul_pnt_vec_impl!(Sim2, Vec2);
|
||||
transformation_impl!(Sim2);
|
||||
sim_transform_impl!(Sim2, Pnt2);
|
||||
sim_inv_impl!(Sim2);
|
||||
sim_to_homogeneous_impl!(Sim2, Mat3);
|
||||
sim_approx_eq_impl!(Sim2);
|
||||
sim_rand_impl!(Sim2);
|
||||
sim_arbitrary_impl!(Sim2);
|
||||
sim_display_impl!(Sim2);
|
||||
|
||||
sim_impl!(Sim3, Iso3, Rot3, Vec3, Vec3);
|
||||
dim_impl!(Sim3, 3);
|
||||
sim_scale_impl!(Sim3);
|
||||
sim_one_impl!(Sim3);
|
||||
sim_mul_sim_impl!(Sim3);
|
||||
sim_mul_iso_impl!(Sim3, Iso3);
|
||||
sim_mul_rot_impl!(Sim3, Rot3);
|
||||
sim_mul_pnt_vec_impl!(Sim3, Pnt3);
|
||||
sim_mul_pnt_vec_impl!(Sim3, Vec3);
|
||||
transformation_impl!(Sim3);
|
||||
sim_transform_impl!(Sim3, Pnt3);
|
||||
sim_inv_impl!(Sim3);
|
||||
sim_to_homogeneous_impl!(Sim3, Mat4);
|
||||
sim_approx_eq_impl!(Sim3);
|
||||
sim_rand_impl!(Sim3);
|
||||
sim_arbitrary_impl!(Sim3);
|
||||
sim_display_impl!(Sim3);
|
|
@ -0,0 +1,86 @@
|
|||
use std::fmt;
|
||||
use std::ops::{Mul, Neg, MulAssign};
|
||||
|
||||
use rand::{Rand, Rng};
|
||||
use num::One;
|
||||
use structs::matrix::{Matrix3, Matrix4};
|
||||
use traits::structure::{Dimension, Column, BaseFloat, BaseNum};
|
||||
use traits::operations::{Inverse, ApproxEq};
|
||||
use traits::geometry::{Rotation, Transform, Transformation, Translation, ToHomogeneous};
|
||||
|
||||
use structs::vector::{Vector1, Vector2, Vector3};
|
||||
use structs::point::{Point2, Point3};
|
||||
use structs::rotation::{Rotation2, Rotation3};
|
||||
use structs::isometry::{Isometry2, Isometry3};
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
// FIXME: the name is not explicit at all but coherent with the other tree-letters names…
|
||||
/// A two-dimensional similarity transformation.
|
||||
///
|
||||
/// This is a composition of a uniform scale, followed by a rotation, followed by a translation.
|
||||
/// Vectors `Vector2` are not affected by the translational component of this transformation while
|
||||
/// points `Point2` are.
|
||||
/// Similarity transformations conserve angles. Distances are multiplied by some constant (the
|
||||
/// scale factor). The scale factor cannot be zero.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
|
||||
pub struct Similarity2<N> {
|
||||
/// The uniform scale applicable by this similarity transformation.
|
||||
scale: N,
|
||||
/// The isometry applicable by this similarity transformation.
|
||||
pub isometry: Isometry2<N>
|
||||
}
|
||||
|
||||
/// A three-dimensional similarity transformation.
|
||||
///
|
||||
/// This is a composition of a scale, followed by a rotation, followed by a translation.
|
||||
/// Vectors `Vector3` are not affected by the translational component of this transformation while
|
||||
/// points `Point3` are.
|
||||
/// Similarity transformations conserve angles. Distances are multiplied by some constant (the
|
||||
/// scale factor). The scale factor cannot be zero.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
|
||||
pub struct Similarity3<N> {
|
||||
/// The uniform scale applicable by this similarity transformation.
|
||||
scale: N,
|
||||
/// The isometry applicable by this similarity transformation.
|
||||
pub isometry: Isometry3<N>
|
||||
}
|
||||
|
||||
sim_impl!(Similarity2, Isometry2, Rotation2, Vector2, Vector1);
|
||||
dim_impl!(Similarity2, 2);
|
||||
sim_scale_impl!(Similarity2);
|
||||
sim_one_impl!(Similarity2);
|
||||
sim_mul_sim_impl!(Similarity2);
|
||||
sim_mul_isometry_impl!(Similarity2, Isometry2);
|
||||
sim_mul_rotation_impl!(Similarity2, Rotation2);
|
||||
sim_mul_point_vec_impl!(Similarity2, Point2);
|
||||
sim_mul_point_vec_impl!(Similarity2, Vector2);
|
||||
transformation_impl!(Similarity2);
|
||||
sim_transform_impl!(Similarity2, Point2);
|
||||
sim_inverse_impl!(Similarity2);
|
||||
sim_to_homogeneous_impl!(Similarity2, Matrix3);
|
||||
sim_approx_eq_impl!(Similarity2);
|
||||
sim_rand_impl!(Similarity2);
|
||||
sim_arbitrary_impl!(Similarity2);
|
||||
sim_display_impl!(Similarity2);
|
||||
|
||||
sim_impl!(Similarity3, Isometry3, Rotation3, Vector3, Vector3);
|
||||
dim_impl!(Similarity3, 3);
|
||||
sim_scale_impl!(Similarity3);
|
||||
sim_one_impl!(Similarity3);
|
||||
sim_mul_sim_impl!(Similarity3);
|
||||
sim_mul_isometry_impl!(Similarity3, Isometry3);
|
||||
sim_mul_rotation_impl!(Similarity3, Rotation3);
|
||||
sim_mul_point_vec_impl!(Similarity3, Point3);
|
||||
sim_mul_point_vec_impl!(Similarity3, Vector3);
|
||||
transformation_impl!(Similarity3);
|
||||
sim_transform_impl!(Similarity3, Point3);
|
||||
sim_inverse_impl!(Similarity3);
|
||||
sim_to_homogeneous_impl!(Similarity3, Matrix4);
|
||||
sim_approx_eq_impl!(Similarity3);
|
||||
sim_rand_impl!(Similarity3);
|
||||
sim_arbitrary_impl!(Similarity3);
|
||||
sim_display_impl!(Similarity3);
|
|
@ -1,18 +1,18 @@
|
|||
#![macro_use]
|
||||
|
||||
macro_rules! sim_impl(
|
||||
($t: ident, $iso: ident, $rotmat: ident, $subvec: ident, $subrotvec: ident) => (
|
||||
($t: ident, $isometry: ident, $rotation_matrix: ident, $subvector: ident, $subrotvector: ident) => (
|
||||
impl<N: BaseFloat> $t<N> {
|
||||
/// Creates a new similarity transformation from a vector, an axis-angle rotation, and a scale factor.
|
||||
///
|
||||
/// The scale factor may be negative but not zero.
|
||||
#[inline]
|
||||
pub fn new(translation: $subvec<N>, rotation: $subrotvec<N>, scale: N) -> $t<N> {
|
||||
pub fn new(translation: $subvector<N>, rotation: $subrotvector<N>, scale: N) -> $t<N> {
|
||||
assert!(!scale.is_zero(), "A similarity transformation scale factor cannot be zero.");
|
||||
|
||||
$t {
|
||||
scale: scale,
|
||||
isometry: $iso::new(translation, rotation)
|
||||
isometry: $isometry::new(translation, rotation)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,12 +20,12 @@ macro_rules! sim_impl(
|
|||
///
|
||||
/// The scale factor may be negative but not zero.
|
||||
#[inline]
|
||||
pub fn new_with_rotmat(translation: $subvec<N>, rotation: $rotmat<N>, scale: N) -> $t<N> {
|
||||
pub fn new_with_rotation_matrix(translation: $subvector<N>, rotation: $rotation_matrix<N>, scale: N) -> $t<N> {
|
||||
assert!(!scale.is_zero(), "A similarity transformation scale factor cannot be zero.");
|
||||
|
||||
$t {
|
||||
scale: scale,
|
||||
isometry: $iso::new_with_rotmat(translation, rotation)
|
||||
isometry: $isometry::new_with_rotation_matrix(translation, rotation)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ macro_rules! sim_impl(
|
|||
///
|
||||
/// The scale factor may be negative but not zero.
|
||||
#[inline]
|
||||
pub fn new_with_iso(isometry: $iso<N>, scale: N) -> $t<N> {
|
||||
pub fn new_with_isometry(isometry: $isometry<N>, scale: N) -> $t<N> {
|
||||
assert!(!scale.is_zero(), "A similarity transformation scale factor cannot be zero.");
|
||||
|
||||
$t {
|
||||
|
@ -56,7 +56,7 @@ macro_rules! sim_scale_impl(
|
|||
|
||||
/// The inverse scale factor of this similarity transformation.
|
||||
#[inline]
|
||||
pub fn inv_scale(&self) -> N {
|
||||
pub fn inverse_scale(&self) -> N {
|
||||
::one::<N>() / self.scale
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ macro_rules! sim_scale_impl(
|
|||
#[inline]
|
||||
pub fn append_scale(&self, s: &N) -> $t<N> {
|
||||
assert!(!s.is_zero(), "Cannot append a zero scale to a similarity transformation.");
|
||||
$t::new_with_rotmat(self.isometry.translation * *s, self.isometry.rotation, self.scale * *s)
|
||||
$t::new_with_rotation_matrix(self.isometry.translation * *s, self.isometry.rotation, self.scale * *s)
|
||||
}
|
||||
|
||||
/// Prepends in-place a scale to this similarity transformation.
|
||||
|
@ -86,7 +86,7 @@ macro_rules! sim_scale_impl(
|
|||
#[inline]
|
||||
pub fn prepend_scale(&self, s: &N) -> $t<N> {
|
||||
assert!(!s.is_zero(), "A similarity transformation scale must not be zero.");
|
||||
$t::new_with_iso(self.isometry, self.scale * *s)
|
||||
$t::new_with_isometry(self.isometry, self.scale * *s)
|
||||
}
|
||||
|
||||
/// Sets the scale of this similarity transformation.
|
||||
|
@ -104,7 +104,7 @@ macro_rules! sim_one_impl(
|
|||
impl<N: BaseFloat> One for $t<N> {
|
||||
#[inline]
|
||||
fn one() -> $t<N> {
|
||||
$t::new_with_iso(::one(), ::one())
|
||||
$t::new_with_isometry(::one(), ::one())
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -117,7 +117,7 @@ macro_rules! sim_mul_sim_impl(
|
|||
|
||||
#[inline]
|
||||
fn mul(self, right: $t<N>) -> $t<N> {
|
||||
$t::new_with_rotmat(
|
||||
$t::new_with_rotation_matrix(
|
||||
self.isometry.translation + self.isometry.rotation * (right.isometry.translation * self.scale),
|
||||
self.isometry.rotation * right.isometry.rotation,
|
||||
self.scale * right.scale)
|
||||
|
@ -135,14 +135,14 @@ macro_rules! sim_mul_sim_impl(
|
|||
)
|
||||
);
|
||||
|
||||
macro_rules! sim_mul_iso_impl(
|
||||
macro_rules! sim_mul_isometry_impl(
|
||||
($t: ident, $ti: ident) => (
|
||||
impl<N: BaseFloat> Mul<$ti<N>> for $t<N> {
|
||||
type Output = $t<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: $ti<N>) -> $t<N> {
|
||||
$t::new_with_rotmat(
|
||||
$t::new_with_rotation_matrix(
|
||||
self.isometry.translation + self.isometry.rotation * (right.translation * self.scale),
|
||||
self.isometry.rotation * right.rotation,
|
||||
self.scale)
|
||||
|
@ -162,7 +162,7 @@ macro_rules! sim_mul_iso_impl(
|
|||
|
||||
#[inline]
|
||||
fn mul(self, right: $t<N>) -> $t<N> {
|
||||
$t::new_with_rotmat(
|
||||
$t::new_with_rotation_matrix(
|
||||
self.translation + self.rotation * right.isometry.translation,
|
||||
self.rotation * right.isometry.rotation,
|
||||
right.scale)
|
||||
|
@ -171,14 +171,14 @@ macro_rules! sim_mul_iso_impl(
|
|||
)
|
||||
);
|
||||
|
||||
macro_rules! sim_mul_rot_impl(
|
||||
macro_rules! sim_mul_rotation_impl(
|
||||
($t: ident, $tr: ident) => (
|
||||
impl<N: BaseFloat> Mul<$tr<N>> for $t<N> {
|
||||
type Output = $t<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: $tr<N>) -> $t<N> {
|
||||
$t::new_with_rotmat(
|
||||
$t::new_with_rotation_matrix(
|
||||
self.isometry.translation,
|
||||
self.isometry.rotation * right,
|
||||
self.scale)
|
||||
|
@ -197,7 +197,7 @@ macro_rules! sim_mul_rot_impl(
|
|||
|
||||
#[inline]
|
||||
fn mul(self, right: $t<N>) -> $t<N> {
|
||||
$t::new_with_rotmat(
|
||||
$t::new_with_rotation_matrix(
|
||||
self * right.isometry.translation,
|
||||
self * right.isometry.rotation,
|
||||
right.scale)
|
||||
|
@ -206,7 +206,7 @@ macro_rules! sim_mul_rot_impl(
|
|||
)
|
||||
);
|
||||
|
||||
macro_rules! sim_mul_pnt_vec_impl(
|
||||
macro_rules! sim_mul_point_vec_impl(
|
||||
($t: ident, $tv: ident) => (
|
||||
impl<N: BaseNum> Mul<$tv<N>> for $t<N> {
|
||||
type Output = $tv<N>;
|
||||
|
@ -232,20 +232,20 @@ macro_rules! sim_transform_impl(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_transform(&self, p: &$tp<N>) -> $tp<N> {
|
||||
self.isometry.inv_transform(p) / self.scale
|
||||
fn inverse_transform(&self, p: &$tp<N>) -> $tp<N> {
|
||||
self.isometry.inverse_transform(p) / self.scale
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! sim_inv_impl(
|
||||
macro_rules! sim_inverse_impl(
|
||||
($t: ident) => (
|
||||
impl<N: BaseNum + Neg<Output = N>> Inv for $t<N> {
|
||||
impl<N: BaseNum + Neg<Output = N>> Inverse for $t<N> {
|
||||
#[inline]
|
||||
fn inv_mut(&mut self) -> bool {
|
||||
fn inverse_mut(&mut self) -> bool {
|
||||
self.scale = ::one::<N>() / self.scale;
|
||||
self.isometry.inv_mut();
|
||||
self.isometry.inverse_mut();
|
||||
// We multiply (instead of dividing) by self.scale because it has already been
|
||||
// inverted.
|
||||
self.isometry.translation = self.isometry.translation * self.scale;
|
||||
|
@ -255,9 +255,9 @@ macro_rules! sim_inv_impl(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn inv(&self) -> Option<$t<N>> {
|
||||
fn inverse(&self) -> Option<$t<N>> {
|
||||
let mut res = *self;
|
||||
res.inv_mut();
|
||||
res.inverse_mut();
|
||||
|
||||
// Always succeed.
|
||||
Some(res)
|
||||
|
@ -270,12 +270,12 @@ macro_rules! sim_to_homogeneous_impl(
|
|||
($t: ident, $th: ident) => (
|
||||
impl<N: BaseNum> ToHomogeneous<$th<N>> for $t<N> {
|
||||
fn to_homogeneous(&self) -> $th<N> {
|
||||
let mut res = (*self.isometry.rotation.submat() * self.scale).to_homogeneous();
|
||||
let mut res = (*self.isometry.rotation.submatrix() * self.scale).to_homogeneous();
|
||||
|
||||
// copy the translation
|
||||
let dim = Dim::dim(None::<$th<N>>);
|
||||
let dimension = Dimension::dimension(None::<$th<N>>);
|
||||
|
||||
res.set_col(dim - 1, self.isometry.translation.as_pnt().to_homogeneous().to_vec());
|
||||
res.set_col(dimension - 1, self.isometry.translation.as_point().to_homogeneous().to_vector());
|
||||
|
||||
res
|
||||
}
|
||||
|
@ -321,7 +321,7 @@ macro_rules! sim_rand_impl(
|
|||
scale = rng.gen();
|
||||
}
|
||||
|
||||
$t::new_with_iso(rng.gen(), scale)
|
||||
$t::new_with_isometry(rng.gen(), scale)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -332,7 +332,7 @@ macro_rules! sim_arbitrary_impl(
|
|||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + BaseFloat> Arbitrary for $t<N> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> $t<N> {
|
||||
$t::new_with_iso(
|
||||
$t::new_with_isometry(
|
||||
Arbitrary::arbitrary(g),
|
||||
Arbitrary::arbitrary(g)
|
||||
)
|
||||
|
@ -351,13 +351,13 @@ macro_rules! sim_display_impl(
|
|||
try!(writeln!(f, "... scale factor: {:.*}", precision, self.scale));
|
||||
try!(writeln!(f, "... translation: {:.*}", precision, self.isometry.translation));
|
||||
try!(writeln!(f, "... rotation matrix:"));
|
||||
try!(write!(f, "{:.*}", precision, *self.isometry.rotation.submat()));
|
||||
try!(write!(f, "{:.*}", precision, *self.isometry.rotation.submatrix()));
|
||||
}
|
||||
else {
|
||||
try!(writeln!(f, "... scale factor: {}", self.scale));
|
||||
try!(writeln!(f, "... translation: {}", self.isometry.translation));
|
||||
try!(writeln!(f, "... rotation matrix:"));
|
||||
try!(write!(f, "{}", *self.isometry.rotation.submat()));
|
||||
try!(write!(f, "{}", *self.isometry.rotation.submatrix()));
|
||||
}
|
||||
|
||||
writeln!(f, "}}")
|
|
@ -1,307 +0,0 @@
|
|||
use std::ops::{Sub, Mul, Neg};
|
||||
use num::{Zero, One};
|
||||
use traits::structure::{Cast, Row, Basis, BaseFloat};
|
||||
use traits::geometry::{Norm, Cross, CrossMatrix, RotationTo, UniformSphereSample};
|
||||
use structs::vec::{Vec1, Vec2, Vec3, Vec4};
|
||||
use structs::mat::Mat3;
|
||||
use structs::rot::{Rot2, Rot3};
|
||||
|
||||
impl<N: BaseFloat> RotationTo for Vec2<N> {
|
||||
type AngleType = N;
|
||||
type DeltaRotationType = Rot2<N>;
|
||||
|
||||
#[inline]
|
||||
fn angle_to(&self, other: &Self) -> N {
|
||||
::cross(self, other).x.atan2(::dot(self, other))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rotation_to(&self, other: &Self) -> Rot2<N> {
|
||||
Rot2::new(Vec1::new(self.angle_to(other)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> RotationTo for Vec3<N> {
|
||||
type AngleType = N;
|
||||
type DeltaRotationType = Rot3<N>;
|
||||
|
||||
#[inline]
|
||||
fn angle_to(&self, other: &Self) -> N {
|
||||
::cross(self, other).norm().atan2(::dot(self, other))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rotation_to(&self, other: &Self) -> Rot3<N> {
|
||||
let mut axis = ::cross(self, other);
|
||||
let norm = axis.normalize_mut();
|
||||
|
||||
if ::is_zero(&norm) {
|
||||
::one()
|
||||
}
|
||||
else {
|
||||
let axis_angle = axis * norm.atan2(::dot(self, other));
|
||||
|
||||
Rot3::new(axis_angle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Mul<N, Output = N> + Sub<N, Output = N>> Cross for Vec2<N> {
|
||||
type CrossProductType = Vec1<N>;
|
||||
|
||||
#[inline]
|
||||
fn cross(&self, other: &Vec2<N>) -> Vec1<N> {
|
||||
Vec1::new(self.x * other.y - self.y * other.x)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: instead of returning a Vec2, define a Mat2x1 matrix?
|
||||
impl<N: Neg<Output = N> + Copy> CrossMatrix<Vec2<N>> for Vec2<N> {
|
||||
#[inline]
|
||||
fn cross_matrix(&self) -> Vec2<N> {
|
||||
Vec2::new(-self.y, self.x)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Mul<N, Output = N> + Sub<N, Output = N>> Cross for Vec3<N> {
|
||||
type CrossProductType = Vec3<N>;
|
||||
|
||||
#[inline]
|
||||
fn cross(&self, other: &Vec3<N>) -> Vec3<N> {
|
||||
Vec3::new(
|
||||
self.y * other.z - self.z * other.y,
|
||||
self.z * other.x - self.x * other.z,
|
||||
self.x * other.y - self.y * other.x
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Neg<Output = N> + Zero + Copy> CrossMatrix<Mat3<N>> for Vec3<N> {
|
||||
#[inline]
|
||||
fn cross_matrix(&self) -> Mat3<N> {
|
||||
Mat3::new(
|
||||
::zero(), -self.z, self.y,
|
||||
self.z, ::zero(), -self.x,
|
||||
-self.y, self.x, ::zero()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: implement this for all other vectors
|
||||
impl<N: Copy> Row<Vec1<N>> for Vec2<N> {
|
||||
#[inline]
|
||||
fn nrows(&self) -> usize {
|
||||
2
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn row(&self, i: usize) -> Vec1<N> {
|
||||
match i {
|
||||
0 => Vec1::new(self.x),
|
||||
1 => Vec1::new(self.y),
|
||||
_ => panic!(format!("Index out of range: 2d vectors do not have {} rows. ", i))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_row(&mut self, i: usize, r: Vec1<N>) {
|
||||
match i {
|
||||
0 => self.x = r.x,
|
||||
1 => self.y = r.x,
|
||||
_ => panic!(format!("Index out of range: 2d vectors do not have {} rows.", i))
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: One> Basis for Vec1<N> {
|
||||
#[inline(always)]
|
||||
fn canonical_basis<F: FnMut(Vec1<N>) -> bool>(mut f: F) {
|
||||
f(Vec1::new(::one()));
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn orthonormal_subspace_basis<F: FnMut(Vec1<N>) -> bool>(_: &Vec1<N>, _: F) { }
|
||||
|
||||
#[inline]
|
||||
fn canonical_basis_element(i: usize) -> Option<Vec1<N>> {
|
||||
if i == 0 {
|
||||
Some(Vec1::new(::one()))
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + One + Zero + Neg<Output = N>> Basis for Vec2<N> {
|
||||
#[inline(always)]
|
||||
fn canonical_basis<F: FnMut(Vec2<N>) -> bool>(mut f: F) {
|
||||
if !f(Vec2::new(::one(), ::zero())) { return };
|
||||
f(Vec2::new(::zero(), ::one()));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn orthonormal_subspace_basis<F: FnMut(Vec2<N>) -> bool>(n: &Vec2<N>, mut f: F) {
|
||||
f(Vec2::new(-n.y, n.x));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn canonical_basis_element(i: usize) -> Option<Vec2<N>> {
|
||||
if i == 0 {
|
||||
Some(Vec2::new(::one(), ::zero()))
|
||||
}
|
||||
else if i == 1 {
|
||||
Some(Vec2::new(::zero(), ::one()))
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> Basis for Vec3<N> {
|
||||
#[inline(always)]
|
||||
fn canonical_basis<F: FnMut(Vec3<N>) -> bool>(mut f: F) {
|
||||
if !f(Vec3::new(::one(), ::zero(), ::zero())) { return };
|
||||
if !f(Vec3::new(::zero(), ::one(), ::zero())) { return };
|
||||
f(Vec3::new(::zero(), ::zero(), ::one()));
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn orthonormal_subspace_basis<F: FnMut(Vec3<N>) -> bool>(n: &Vec3<N>, mut f: F) {
|
||||
let a =
|
||||
if n.x.abs() > n.y.abs() {
|
||||
Norm::normalize(&Vec3::new(n.z, ::zero(), -n.x))
|
||||
}
|
||||
else {
|
||||
Norm::normalize(&Vec3::new(::zero(), -n.z, n.y))
|
||||
};
|
||||
|
||||
if !f(Cross::cross(&a, n)) { return };
|
||||
f(a);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn canonical_basis_element(i: usize) -> Option<Vec3<N>> {
|
||||
if i == 0 {
|
||||
Some(Vec3::new(::one(), ::zero(), ::zero()))
|
||||
}
|
||||
else if i == 1 {
|
||||
Some(Vec3::new(::zero(), ::one(), ::zero()))
|
||||
}
|
||||
else if i == 2 {
|
||||
Some(Vec3::new(::zero(), ::zero(), ::one()))
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: this bad: this fixes definitly the number of samples…
|
||||
static SAMPLES_2_F64: [Vec2<f64>; 21] = [
|
||||
Vec2 { x: 1.0, y: 0.0 },
|
||||
Vec2 { x: 0.95557281, y: 0.29475517 },
|
||||
Vec2 { x: 0.82623877, y: 0.56332006 },
|
||||
Vec2 { x: 0.6234898, y: 0.78183148 },
|
||||
Vec2 { x: 0.36534102, y: 0.93087375 },
|
||||
Vec2 { x: 0.07473009, y: 0.9972038 },
|
||||
Vec2 { x: -0.22252093, y: 0.97492791 },
|
||||
Vec2 { x: -0.5, y: 0.8660254 },
|
||||
Vec2 { x: -0.73305187, y: 0.68017274 },
|
||||
Vec2 { x: -0.90096887, y: 0.43388374 },
|
||||
Vec2 { x: -0.98883083, y: 0.14904227 },
|
||||
Vec2 { x: -0.98883083, y: -0.14904227 },
|
||||
Vec2 { x: -0.90096887, y: -0.43388374 },
|
||||
Vec2 { x: -0.73305187, y: -0.68017274 },
|
||||
Vec2 { x: -0.5, y: -0.8660254 },
|
||||
Vec2 { x: -0.22252093, y: -0.97492791 },
|
||||
Vec2 { x: 0.07473009, y: -0.9972038 },
|
||||
Vec2 { x: 0.36534102, y: -0.93087375 },
|
||||
Vec2 { x: 0.6234898, y: -0.78183148 },
|
||||
Vec2 { x: 0.82623877, y: -0.56332006 },
|
||||
Vec2 { x: 0.95557281, y: -0.29475517 },
|
||||
];
|
||||
|
||||
// Those vectors come from bullet 3d
|
||||
static SAMPLES_3_F64: [Vec3<f64>; 42] = [
|
||||
Vec3 { x: 0.000000 , y: -0.000000, z: -1.000000 },
|
||||
Vec3 { x: 0.723608 , y: -0.525725, z: -0.447219 },
|
||||
Vec3 { x: -0.276388, y: -0.850649, z: -0.447219 },
|
||||
Vec3 { x: -0.894426, y: -0.000000, z: -0.447216 },
|
||||
Vec3 { x: -0.276388, y: 0.850649 , z: -0.447220 },
|
||||
Vec3 { x: 0.723608 , y: 0.525725 , z: -0.447219 },
|
||||
Vec3 { x: 0.276388 , y: -0.850649, z: 0.447220 },
|
||||
Vec3 { x: -0.723608, y: -0.525725, z: 0.447219 },
|
||||
Vec3 { x: -0.723608, y: 0.525725 , z: 0.447219 },
|
||||
Vec3 { x: 0.276388 , y: 0.850649 , z: 0.447219 },
|
||||
Vec3 { x: 0.894426 , y: 0.000000 , z: 0.447216 },
|
||||
Vec3 { x: -0.000000, y: 0.000000 , z: 1.000000 },
|
||||
Vec3 { x: 0.425323 , y: -0.309011, z: -0.850654 },
|
||||
Vec3 { x: -0.162456, y: -0.499995, z: -0.850654 },
|
||||
Vec3 { x: 0.262869 , y: -0.809012, z: -0.525738 },
|
||||
Vec3 { x: 0.425323 , y: 0.309011 , z: -0.850654 },
|
||||
Vec3 { x: 0.850648 , y: -0.000000, z: -0.525736 },
|
||||
Vec3 { x: -0.525730, y: -0.000000, z: -0.850652 },
|
||||
Vec3 { x: -0.688190, y: -0.499997, z: -0.525736 },
|
||||
Vec3 { x: -0.162456, y: 0.499995 , z: -0.850654 },
|
||||
Vec3 { x: -0.688190, y: 0.499997 , z: -0.525736 },
|
||||
Vec3 { x: 0.262869 , y: 0.809012 , z: -0.525738 },
|
||||
Vec3 { x: 0.951058 , y: 0.309013 , z: 0.000000 },
|
||||
Vec3 { x: 0.951058 , y: -0.309013, z: 0.000000 },
|
||||
Vec3 { x: 0.587786 , y: -0.809017, z: 0.000000 },
|
||||
Vec3 { x: 0.000000 , y: -1.000000, z: 0.000000 },
|
||||
Vec3 { x: -0.587786, y: -0.809017, z: 0.000000 },
|
||||
Vec3 { x: -0.951058, y: -0.309013, z: -0.000000 },
|
||||
Vec3 { x: -0.951058, y: 0.309013 , z: -0.000000 },
|
||||
Vec3 { x: -0.587786, y: 0.809017 , z: -0.000000 },
|
||||
Vec3 { x: -0.000000, y: 1.000000 , z: -0.000000 },
|
||||
Vec3 { x: 0.587786 , y: 0.809017 , z: -0.000000 },
|
||||
Vec3 { x: 0.688190 , y: -0.499997, z: 0.525736 },
|
||||
Vec3 { x: -0.262869, y: -0.809012, z: 0.525738 },
|
||||
Vec3 { x: -0.850648, y: 0.000000 , z: 0.525736 },
|
||||
Vec3 { x: -0.262869, y: 0.809012 , z: 0.525738 },
|
||||
Vec3 { x: 0.688190 , y: 0.499997 , z: 0.525736 },
|
||||
Vec3 { x: 0.525730 , y: 0.000000 , z: 0.850652 },
|
||||
Vec3 { x: 0.162456 , y: -0.499995, z: 0.850654 },
|
||||
Vec3 { x: -0.425323, y: -0.309011, z: 0.850654 },
|
||||
Vec3 { x: -0.425323, y: 0.309011 , z: 0.850654 },
|
||||
Vec3 { x: 0.162456 , y: 0.499995 , z: 0.850654 }
|
||||
];
|
||||
|
||||
impl<N> UniformSphereSample for Vec1<N>
|
||||
where Vec1<N>: One {
|
||||
#[inline(always)]
|
||||
fn sample<F: FnMut(Vec1<N>)>(mut f: F) {
|
||||
f(::one())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Cast<f64> + Copy> UniformSphereSample for Vec2<N> {
|
||||
#[inline(always)]
|
||||
fn sample<F: FnMut(Vec2<N>)>(mut f: F) {
|
||||
for sample in SAMPLES_2_F64.iter() {
|
||||
f(Cast::from(*sample))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Cast<f64> + Copy> UniformSphereSample for Vec3<N> {
|
||||
#[inline(always)]
|
||||
fn sample<F: FnMut(Vec3<N>)>(mut f: F) {
|
||||
for sample in SAMPLES_3_F64.iter() {
|
||||
f(Cast::from(*sample))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Cast<f64> + Copy> UniformSphereSample for Vec4<N> {
|
||||
#[inline(always)]
|
||||
fn sample<F: FnMut(Vec4<N>)>(_: F) {
|
||||
panic!("UniformSphereSample::<Vec4<N>>::sample : Not yet implemented.")
|
||||
// for sample in SAMPLES_3_F32.iter() {
|
||||
// f(Cast::from(*sample))
|
||||
// }
|
||||
}
|
||||
}
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
use std::num::Zero;
|
||||
use extra::complex::Cmplx;
|
||||
use traits::operations::{Absolute, Inv};
|
||||
use traits::structure::{Dim};
|
||||
use traits::operations::{Absolute, Inverse};
|
||||
use traits::structure::{Dimension};
|
||||
|
||||
impl<N: Clone + BaseNum> Absolute<Cmplx<N>> for Cmplx<N> {
|
||||
#[inline]
|
||||
|
@ -12,7 +12,7 @@ impl<N: Clone + BaseNum> Absolute<Cmplx<N>> for Cmplx<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + BaseNum + BaseNumCast + Zero> Inv for Cmplx<N> {
|
||||
impl<N: Clone + BaseNum + BaseNumCast + Zero> Inverse for Cmplx<N> {
|
||||
#[inline]
|
||||
fn inverse(&self) -> Option<Cmplx<N>> {
|
||||
if self.is_zero() {
|
||||
|
@ -43,55 +43,55 @@ impl<N: Clone + BaseNum + BaseNumCast + Zero> Inv for Cmplx<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N> Dim for Cmplx<N> {
|
||||
impl<N> Dimension for Cmplx<N> {
|
||||
#[inline]
|
||||
fn dim(unsused_mut: Option<Cmplx<N>>) -> usize {
|
||||
fn dimension(unsused_mut: Option<Cmplx<N>>) -> usize {
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> Rotation<Vec2<N>> for Cmplx<N> {
|
||||
impl<N> Rotation<Vector2<N>> for Cmplx<N> {
|
||||
#[inline]
|
||||
fn rotation(&self) -> Vec2<N> {
|
||||
fn rotation(&self) -> Vector2<N> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_rotation(&self) -> Vec2<N> {
|
||||
fn inverse_rotation(&self) -> Vector2<N> {
|
||||
-self.rotation();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rotate_by(&mut self, rotation: &Vec2<N>) {
|
||||
fn rotate_by(&mut self, rotation: &Vector2<N>) {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rotated(&self, rotation: &Vec2<N>) -> Cmplx<N> {
|
||||
fn rotated(&self, rotation: &Vector2<N>) -> Cmplx<N> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_rotation(&mut self, rotation: Vec2<N>) {
|
||||
fn set_rotation(&mut self, rotation: Vector2<N>) {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> Rotate<Vec2<N>> for Cmplx<N> {
|
||||
impl<N> Rotate<Vector2<N>> for Cmplx<N> {
|
||||
#[inline]
|
||||
fn rotate(&self, rotation: &V) -> V {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_rotate(&self, rotation: &V) -> V {
|
||||
fn inverse_rotate(&self, rotation: &V) -> V {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> RotationMatrix<Vec2<N>, Vec2<N>, Rotmat<Mat2<N>>> for Cmplx<N> {
|
||||
impl<N> RotationMatrix<Vector2<N>, Vector2<N>, Rotationmatrix<Matrix2<N>>> for Cmplx<N> {
|
||||
#[inline]
|
||||
fn to_rot_mat(&self) -> Rotmat<Mat2<N>> {
|
||||
fn to_rotation_matrix(&self) -> Rotationmatrix<Matrix2<N>> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> Norm<N> for Cmplx<N> {
|
||||
#[inline]
|
||||
fn sqnorm(&self) -> N {
|
||||
fn norm_squared(&self) -> N {
|
||||
}
|
||||
|
||||
#[inline]
|
|
@ -1,27 +1,27 @@
|
|||
use std::ops::Mul;
|
||||
use num::One;
|
||||
use structs::mat;
|
||||
use traits::operations::{Inv, Transpose};
|
||||
use structs::matrix::Identity;
|
||||
use traits::operations::{Inverse, Transpose};
|
||||
use traits::geometry::{Translate, Rotate, Transform, AbsoluteRotate};
|
||||
|
||||
impl One for mat::Identity {
|
||||
impl One for Identity {
|
||||
#[inline]
|
||||
fn one() -> mat::Identity {
|
||||
mat::Identity::new()
|
||||
fn one() -> Identity {
|
||||
Identity::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Inv for mat::Identity {
|
||||
fn inv(&self) -> Option<mat::Identity> {
|
||||
Some(mat::Identity::new())
|
||||
impl Inverse for Identity {
|
||||
fn inverse(&self) -> Option<Identity> {
|
||||
Some(Identity::new())
|
||||
}
|
||||
|
||||
fn inv_mut(&mut self) -> bool {
|
||||
fn inverse_mut(&mut self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> Mul<T> for mat::Identity {
|
||||
impl<T: Clone> Mul<T> for Identity {
|
||||
type Output = T;
|
||||
|
||||
#[inline]
|
||||
|
@ -30,10 +30,10 @@ impl<T: Clone> Mul<T> for mat::Identity {
|
|||
}
|
||||
}
|
||||
|
||||
impl Transpose for mat::Identity {
|
||||
impl Transpose for Identity {
|
||||
#[inline]
|
||||
fn transpose(&self) -> mat::Identity {
|
||||
mat::Identity::new()
|
||||
fn transpose(&self) -> Identity {
|
||||
Identity::new()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -41,45 +41,45 @@ impl Transpose for mat::Identity {
|
|||
}
|
||||
}
|
||||
|
||||
impl<V: Clone> Translate<V> for mat::Identity {
|
||||
impl<V: Clone> Translate<V> for Identity {
|
||||
#[inline]
|
||||
fn translate(&self, v: &V) -> V {
|
||||
v.clone()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_translate(&self, v: &V) -> V {
|
||||
fn inverse_translate(&self, v: &V) -> V {
|
||||
v.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Clone> Rotate<V> for mat::Identity {
|
||||
impl<V: Clone> Rotate<V> for Identity {
|
||||
#[inline]
|
||||
fn rotate(&self, v: &V) -> V {
|
||||
v.clone()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_rotate(&self, v: &V) -> V {
|
||||
fn inverse_rotate(&self, v: &V) -> V {
|
||||
v.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Clone> AbsoluteRotate<V> for mat::Identity {
|
||||
impl<V: Clone> AbsoluteRotate<V> for Identity {
|
||||
#[inline]
|
||||
fn absolute_rotate(&self, v: &V) -> V {
|
||||
v.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Clone> Transform<V> for mat::Identity {
|
||||
impl<V: Clone> Transform<V> for Identity {
|
||||
#[inline]
|
||||
fn transform(&self, v: &V) -> V {
|
||||
v.clone()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_transform(&self, v: &V) -> V {
|
||||
fn inverse_transform(&self, v: &V) -> V {
|
||||
v.clone()
|
||||
}
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
use std::ops::{Add, Mul, Neg, MulAssign};
|
||||
use structs::vec::{Vec2, Vec3};
|
||||
use structs::pnt::{Pnt2, Pnt3};
|
||||
use structs::mat::{Mat1, Mat2, Mat3};
|
||||
use traits::operations::{Inv, Det, ApproxEq};
|
||||
use traits::structure::{Row, Col, BaseNum};
|
||||
use structs::vector::{Vector2, Vector3};
|
||||
use structs::point::{Point2, Point3};
|
||||
use structs::matrix::{Matrix1, Matrix2, Matrix3};
|
||||
use traits::operations::{Inverse, Determinant, ApproxEq};
|
||||
use traits::structure::{Row, Column, BaseNum};
|
||||
|
||||
// some specializations:
|
||||
impl<N: BaseNum + ApproxEq<N>> Inv for Mat1<N> {
|
||||
impl<N: BaseNum + ApproxEq<N>> Inverse for Matrix1<N> {
|
||||
#[inline]
|
||||
fn inv(&self) -> Option<Mat1<N>> {
|
||||
fn inverse(&self) -> Option<Matrix1<N>> {
|
||||
let mut res = *self;
|
||||
if res.inv_mut() {
|
||||
if res.inverse_mut() {
|
||||
Some(res)
|
||||
}
|
||||
else {
|
||||
|
@ -19,24 +19,24 @@ impl<N: BaseNum + ApproxEq<N>> Inv for Mat1<N> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_mut(&mut self) -> bool {
|
||||
fn inverse_mut(&mut self) -> bool {
|
||||
if ApproxEq::approx_eq(&self.m11, &::zero()) {
|
||||
false
|
||||
}
|
||||
else {
|
||||
let _1: N = ::one();
|
||||
|
||||
self.m11 = _1 / Det::det(self);
|
||||
self.m11 = _1 / Determinant::determinant(self);
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N> + ApproxEq<N>> Inv for Mat2<N> {
|
||||
impl<N: BaseNum + Neg<Output = N> + ApproxEq<N>> Inverse for Matrix2<N> {
|
||||
#[inline]
|
||||
fn inv(&self) -> Option<Mat2<N>> {
|
||||
fn inverse(&self) -> Option<Matrix2<N>> {
|
||||
let mut res = *self;
|
||||
if res.inv_mut() {
|
||||
if res.inverse_mut() {
|
||||
Some(res)
|
||||
}
|
||||
else {
|
||||
|
@ -45,28 +45,28 @@ impl<N: BaseNum + Neg<Output = N> + ApproxEq<N>> Inv for Mat2<N> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_mut(&mut self) -> bool {
|
||||
let det = Det::det(self);
|
||||
fn inverse_mut(&mut self) -> bool {
|
||||
let determinant = Determinant::determinant(self);
|
||||
|
||||
if ApproxEq::approx_eq(&det, &::zero()) {
|
||||
if ApproxEq::approx_eq(&determinant, &::zero()) {
|
||||
false
|
||||
}
|
||||
else {
|
||||
*self = Mat2::new(
|
||||
self.m22 / det , -self.m12 / det,
|
||||
-self.m21 / det, self.m11 / det);
|
||||
*self = Matrix2::new(
|
||||
self.m22 / determinant , -self.m12 / determinant,
|
||||
-self.m21 / determinant, self.m11 / determinant);
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum + Neg<Output = N> + ApproxEq<N>> Inv for Mat3<N> {
|
||||
impl<N: BaseNum + Neg<Output = N> + ApproxEq<N>> Inverse for Matrix3<N> {
|
||||
#[inline]
|
||||
fn inv(&self) -> Option<Mat3<N>> {
|
||||
fn inverse(&self) -> Option<Matrix3<N>> {
|
||||
let mut res = *self;
|
||||
|
||||
if res.inv_mut() {
|
||||
if res.inverse_mut() {
|
||||
Some(res)
|
||||
}
|
||||
else {
|
||||
|
@ -75,29 +75,29 @@ impl<N: BaseNum + Neg<Output = N> + ApproxEq<N>> Inv for Mat3<N> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_mut(&mut self) -> bool {
|
||||
fn inverse_mut(&mut self) -> bool {
|
||||
let minor_m12_m23 = self.m22 * self.m33 - self.m32 * self.m23;
|
||||
let minor_m11_m23 = self.m21 * self.m33 - self.m31 * self.m23;
|
||||
let minor_m11_m22 = self.m21 * self.m32 - self.m31 * self.m22;
|
||||
|
||||
let det = self.m11 * minor_m12_m23 - self.m12 * minor_m11_m23 + self.m13 * minor_m11_m22;
|
||||
let determinant = self.m11 * minor_m12_m23 - self.m12 * minor_m11_m23 + self.m13 * minor_m11_m22;
|
||||
|
||||
if ApproxEq::approx_eq(&det, &::zero()) {
|
||||
if ApproxEq::approx_eq(&determinant, &::zero()) {
|
||||
false
|
||||
}
|
||||
else {
|
||||
*self = Mat3::new(
|
||||
(minor_m12_m23 / det),
|
||||
((self.m13 * self.m32 - self.m33 * self.m12) / det),
|
||||
((self.m12 * self.m23 - self.m22 * self.m13) / det),
|
||||
*self = Matrix3::new(
|
||||
(minor_m12_m23 / determinant),
|
||||
((self.m13 * self.m32 - self.m33 * self.m12) / determinant),
|
||||
((self.m12 * self.m23 - self.m22 * self.m13) / determinant),
|
||||
|
||||
(-minor_m11_m23 / det),
|
||||
((self.m11 * self.m33 - self.m31 * self.m13) / det),
|
||||
((self.m13 * self.m21 - self.m23 * self.m11) / det),
|
||||
(-minor_m11_m23 / determinant),
|
||||
((self.m11 * self.m33 - self.m31 * self.m13) / determinant),
|
||||
((self.m13 * self.m21 - self.m23 * self.m11) / determinant),
|
||||
|
||||
(minor_m11_m22 / det),
|
||||
((self.m12 * self.m31 - self.m32 * self.m11) / det),
|
||||
((self.m11 * self.m22 - self.m21 * self.m12) / det)
|
||||
(minor_m11_m22 / determinant),
|
||||
((self.m12 * self.m31 - self.m32 * self.m11) / determinant),
|
||||
((self.m11 * self.m22 - self.m21 * self.m12) / determinant)
|
||||
);
|
||||
|
||||
true
|
||||
|
@ -105,23 +105,23 @@ impl<N: BaseNum + Neg<Output = N> + ApproxEq<N>> Inv for Mat3<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum> Det<N> for Mat1<N> {
|
||||
impl<N: BaseNum> Determinant<N> for Matrix1<N> {
|
||||
#[inline]
|
||||
fn det(&self) -> N {
|
||||
fn determinant(&self) -> N {
|
||||
self.m11
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum> Det<N> for Mat2<N> {
|
||||
impl<N: BaseNum> Determinant<N> for Matrix2<N> {
|
||||
#[inline]
|
||||
fn det(&self) -> N {
|
||||
fn determinant(&self) -> N {
|
||||
self.m11 * self.m22 - self.m21 * self.m12
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseNum> Det<N> for Mat3<N> {
|
||||
impl<N: BaseNum> Determinant<N> for Matrix3<N> {
|
||||
#[inline]
|
||||
fn det(&self) -> N {
|
||||
fn determinant(&self) -> N {
|
||||
let minor_m12_m23 = self.m22 * self.m33 - self.m32 * self.m23;
|
||||
let minor_m11_m23 = self.m21 * self.m33 - self.m31 * self.m23;
|
||||
let minor_m11_m22 = self.m21 * self.m32 - self.m31 * self.m22;
|
||||
|
@ -130,24 +130,24 @@ impl<N: BaseNum> Det<N> for Mat3<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Copy> Row<Vec3<N>> for Mat3<N> {
|
||||
impl<N: Copy> Row<Vector3<N>> for Matrix3<N> {
|
||||
#[inline]
|
||||
fn nrows(&self) -> usize {
|
||||
3
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn row(&self, i: usize) -> Vec3<N> {
|
||||
fn row(&self, i: usize) -> Vector3<N> {
|
||||
match i {
|
||||
0 => Vec3::new(self.m11, self.m12, self.m13),
|
||||
1 => Vec3::new(self.m21, self.m22, self.m23),
|
||||
2 => Vec3::new(self.m31, self.m32, self.m33),
|
||||
0 => Vector3::new(self.m11, self.m12, self.m13),
|
||||
1 => Vector3::new(self.m21, self.m22, self.m23),
|
||||
2 => Vector3::new(self.m31, self.m32, self.m33),
|
||||
_ => panic!(format!("Index out of range: 3d matrices do not have {} rows.", i))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_row(&mut self, i: usize, r: Vec3<N>) {
|
||||
fn set_row(&mut self, i: usize, r: Vector3<N>) {
|
||||
match i {
|
||||
0 => {
|
||||
self.m11 = r.x;
|
||||
|
@ -170,24 +170,24 @@ impl<N: Copy> Row<Vec3<N>> for Mat3<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Copy> Col<Vec3<N>> for Mat3<N> {
|
||||
impl<N: Copy> Column<Vector3<N>> for Matrix3<N> {
|
||||
#[inline]
|
||||
fn ncols(&self) -> usize {
|
||||
3
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn col(&self, i: usize) -> Vec3<N> {
|
||||
fn column(&self, i: usize) -> Vector3<N> {
|
||||
match i {
|
||||
0 => Vec3::new(self.m11, self.m21, self.m31),
|
||||
1 => Vec3::new(self.m12, self.m22, self.m32),
|
||||
2 => Vec3::new(self.m13, self.m23, self.m33),
|
||||
0 => Vector3::new(self.m11, self.m21, self.m31),
|
||||
1 => Vector3::new(self.m12, self.m22, self.m32),
|
||||
2 => Vector3::new(self.m13, self.m23, self.m33),
|
||||
_ => panic!(format!("Index out of range: 3d matrices do not have {} cols.", i))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_col(&mut self, i: usize, r: Vec3<N>) {
|
||||
fn set_col(&mut self, i: usize, r: Vector3<N>) {
|
||||
match i {
|
||||
0 => {
|
||||
self.m11 = r.x;
|
||||
|
@ -210,12 +210,12 @@ impl<N: Copy> Col<Vec3<N>> for Mat3<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat3<N>> for Mat3<N> {
|
||||
type Output = Mat3<N>;
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Matrix3<N> {
|
||||
type Output = Matrix3<N>;
|
||||
|
||||
#[inline]
|
||||
fn mul(self, right: Mat3<N>) -> Mat3<N> {
|
||||
Mat3::new(
|
||||
fn mul(self, right: Matrix3<N>) -> Matrix3<N> {
|
||||
Matrix3::new(
|
||||
self.m11 * right.m11 + self.m12 * right.m21 + self.m13 * right.m31,
|
||||
self.m11 * right.m12 + self.m12 * right.m22 + self.m13 * right.m32,
|
||||
self.m11 * right.m13 + self.m12 * right.m23 + self.m13 * right.m33,
|
||||
|
@ -231,12 +231,12 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat3<N>> for Mat3<N>
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat2<N>> for Mat2<N> {
|
||||
type Output = Mat2<N>;
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Matrix2<N> {
|
||||
type Output = Matrix2<N>;
|
||||
|
||||
#[inline(always)]
|
||||
fn mul(self, right: Mat2<N>) -> Mat2<N> {
|
||||
Mat2::new(
|
||||
fn mul(self, right: Matrix2<N>) -> Matrix2<N> {
|
||||
Matrix2::new(
|
||||
self.m11 * right.m11 + self.m12 * right.m21,
|
||||
self.m11 * right.m12 + self.m12 * right.m22,
|
||||
|
||||
|
@ -246,12 +246,12 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat2<N>> for Mat2<N>
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vec3<N>> for Mat3<N> {
|
||||
type Output = Vec3<N>;
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vector3<N>> for Matrix3<N> {
|
||||
type Output = Vector3<N>;
|
||||
|
||||
#[inline(always)]
|
||||
fn mul(self, right: Vec3<N>) -> Vec3<N> {
|
||||
Vec3::new(
|
||||
fn mul(self, right: Vector3<N>) -> Vector3<N> {
|
||||
Vector3::new(
|
||||
self.m11 * right.x + self.m12 * right.y + self.m13 * right.z,
|
||||
self.m21 * right.x + self.m22 * right.y + self.m23 * right.z,
|
||||
self.m31 * right.x + self.m32 * right.y + self.m33 * right.z
|
||||
|
@ -259,12 +259,12 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vec3<N>> for Mat3<N>
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat3<N>> for Vec3<N> {
|
||||
type Output = Vec3<N>;
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Vector3<N> {
|
||||
type Output = Vector3<N>;
|
||||
|
||||
#[inline(always)]
|
||||
fn mul(self, right: Mat3<N>) -> Vec3<N> {
|
||||
Vec3::new(
|
||||
fn mul(self, right: Matrix3<N>) -> Vector3<N> {
|
||||
Vector3::new(
|
||||
self.x * right.m11 + self.y * right.m21 + self.z * right.m31,
|
||||
self.x * right.m12 + self.y * right.m22 + self.z * right.m32,
|
||||
self.x * right.m13 + self.y * right.m23 + self.z * right.m33
|
||||
|
@ -272,36 +272,36 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat3<N>> for Vec3<N>
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat2<N>> for Vec2<N> {
|
||||
type Output = Vec2<N>;
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Vector2<N> {
|
||||
type Output = Vector2<N>;
|
||||
|
||||
#[inline(always)]
|
||||
fn mul(self, right: Mat2<N>) -> Vec2<N> {
|
||||
Vec2::new(
|
||||
fn mul(self, right: Matrix2<N>) -> Vector2<N> {
|
||||
Vector2::new(
|
||||
self.x * right.m11 + self.y * right.m21,
|
||||
self.x * right.m12 + self.y * right.m22
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vec2<N>> for Mat2<N> {
|
||||
type Output = Vec2<N>;
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vector2<N>> for Matrix2<N> {
|
||||
type Output = Vector2<N>;
|
||||
|
||||
#[inline(always)]
|
||||
fn mul(self, right: Vec2<N>) -> Vec2<N> {
|
||||
Vec2::new(
|
||||
fn mul(self, right: Vector2<N>) -> Vector2<N> {
|
||||
Vector2::new(
|
||||
self.m11 * right.x + self.m12 * right.y,
|
||||
self.m21 * right.x + self.m22 * right.y
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Pnt3<N>> for Mat3<N> {
|
||||
type Output = Pnt3<N>;
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Point3<N>> for Matrix3<N> {
|
||||
type Output = Point3<N>;
|
||||
|
||||
#[inline(always)]
|
||||
fn mul(self, right: Pnt3<N>) -> Pnt3<N> {
|
||||
Pnt3::new(
|
||||
fn mul(self, right: Point3<N>) -> Point3<N> {
|
||||
Point3::new(
|
||||
self.m11 * right.x + self.m12 * right.y + self.m13 * right.z,
|
||||
self.m21 * right.x + self.m22 * right.y + self.m23 * right.z,
|
||||
self.m31 * right.x + self.m32 * right.y + self.m33 * right.z
|
||||
|
@ -309,12 +309,12 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Pnt3<N>> for Mat3<N>
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat3<N>> for Pnt3<N> {
|
||||
type Output = Pnt3<N>;
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Point3<N> {
|
||||
type Output = Point3<N>;
|
||||
|
||||
#[inline(always)]
|
||||
fn mul(self, right: Mat3<N>) -> Pnt3<N> {
|
||||
Pnt3::new(
|
||||
fn mul(self, right: Matrix3<N>) -> Point3<N> {
|
||||
Point3::new(
|
||||
self.x * right.m11 + self.y * right.m21 + self.z * right.m31,
|
||||
self.x * right.m12 + self.y * right.m22 + self.z * right.m32,
|
||||
self.x * right.m13 + self.y * right.m23 + self.z * right.m33
|
||||
|
@ -322,24 +322,24 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat3<N>> for Pnt3<N>
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Mat2<N>> for Pnt2<N> {
|
||||
type Output = Pnt2<N>;
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Point2<N> {
|
||||
type Output = Point2<N>;
|
||||
|
||||
#[inline(always)]
|
||||
fn mul(self, right: Mat2<N>) -> Pnt2<N> {
|
||||
Pnt2::new(
|
||||
fn mul(self, right: Matrix2<N>) -> Point2<N> {
|
||||
Point2::new(
|
||||
self.x * right.m11 + self.y * right.m21,
|
||||
self.x * right.m12 + self.y * right.m22
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Pnt2<N>> for Mat2<N> {
|
||||
type Output = Pnt2<N>;
|
||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Point2<N>> for Matrix2<N> {
|
||||
type Output = Point2<N>;
|
||||
|
||||
#[inline(always)]
|
||||
fn mul(self, right: Pnt2<N>) -> Pnt2<N> {
|
||||
Pnt2::new(
|
||||
fn mul(self, right: Point2<N>) -> Point2<N> {
|
||||
Point2::new(
|
||||
self.m11 * right.x + self.m12 * right.y,
|
||||
self.m21 * right.x + self.m22 * right.y
|
||||
)
|
||||
|
@ -360,10 +360,10 @@ macro_rules! impl_mul_assign_from_mul(
|
|||
)
|
||||
);
|
||||
|
||||
impl_mul_assign_from_mul!(Mat3, Mat3);
|
||||
impl_mul_assign_from_mul!(Mat2, Mat2);
|
||||
impl_mul_assign_from_mul!(Matrix3, Matrix3);
|
||||
impl_mul_assign_from_mul!(Matrix2, Matrix2);
|
||||
|
||||
impl_mul_assign_from_mul!(Vec3, Mat3);
|
||||
impl_mul_assign_from_mul!(Vec2, Mat2);
|
||||
impl_mul_assign_from_mul!(Pnt3, Mat3);
|
||||
impl_mul_assign_from_mul!(Pnt2, Mat2);
|
||||
impl_mul_assign_from_mul!(Vector3, Matrix3);
|
||||
impl_mul_assign_from_mul!(Vector2, Matrix2);
|
||||
impl_mul_assign_from_mul!(Point3, Matrix3);
|
||||
impl_mul_assign_from_mul!(Point2, Matrix2);
|
|
@ -0,0 +1,307 @@
|
|||
use std::ops::{Sub, Mul, Neg};
|
||||
use num::{Zero, One};
|
||||
use traits::structure::{Cast, Row, Basis, BaseFloat};
|
||||
use traits::geometry::{Norm, Cross, CrossMatrix, RotationTo, UniformSphereSample};
|
||||
use structs::vector::{Vector1, Vector2, Vector3, Vector4};
|
||||
use structs::matrix::Matrix3;
|
||||
use structs::rotation::{Rotation2, Rotation3};
|
||||
|
||||
impl<N: BaseFloat> RotationTo for Vector2<N> {
|
||||
type AngleType = N;
|
||||
type DeltaRotationType = Rotation2<N>;
|
||||
|
||||
#[inline]
|
||||
fn angle_to(&self, other: &Self) -> N {
|
||||
::cross(self, other).x.atan2(::dot(self, other))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rotation_to(&self, other: &Self) -> Rotation2<N> {
|
||||
Rotation2::new(Vector1::new(self.angle_to(other)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> RotationTo for Vector3<N> {
|
||||
type AngleType = N;
|
||||
type DeltaRotationType = Rotation3<N>;
|
||||
|
||||
#[inline]
|
||||
fn angle_to(&self, other: &Self) -> N {
|
||||
::cross(self, other).norm().atan2(::dot(self, other))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rotation_to(&self, other: &Self) -> Rotation3<N> {
|
||||
let mut axis = ::cross(self, other);
|
||||
let norm = axis.normalize_mut();
|
||||
|
||||
if ::is_zero(&norm) {
|
||||
::one()
|
||||
}
|
||||
else {
|
||||
let axis_angle = axis * norm.atan2(::dot(self, other));
|
||||
|
||||
Rotation3::new(axis_angle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Mul<N, Output = N> + Sub<N, Output = N>> Cross for Vector2<N> {
|
||||
type CrossProductType = Vector1<N>;
|
||||
|
||||
#[inline]
|
||||
fn cross(&self, other: &Vector2<N>) -> Vector1<N> {
|
||||
Vector1::new(self.x * other.y - self.y * other.x)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: instead of returning a Vector2, define a Matrix2x1 matrix?
|
||||
impl<N: Neg<Output = N> + Copy> CrossMatrix<Vector2<N>> for Vector2<N> {
|
||||
#[inline]
|
||||
fn cross_matrix(&self) -> Vector2<N> {
|
||||
Vector2::new(-self.y, self.x)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Mul<N, Output = N> + Sub<N, Output = N>> Cross for Vector3<N> {
|
||||
type CrossProductType = Vector3<N>;
|
||||
|
||||
#[inline]
|
||||
fn cross(&self, other: &Vector3<N>) -> Vector3<N> {
|
||||
Vector3::new(
|
||||
self.y * other.z - self.z * other.y,
|
||||
self.z * other.x - self.x * other.z,
|
||||
self.x * other.y - self.y * other.x
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Neg<Output = N> + Zero + Copy> CrossMatrix<Matrix3<N>> for Vector3<N> {
|
||||
#[inline]
|
||||
fn cross_matrix(&self) -> Matrix3<N> {
|
||||
Matrix3::new(
|
||||
::zero(), -self.z, self.y,
|
||||
self.z, ::zero(), -self.x,
|
||||
-self.y, self.x, ::zero()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: implement this for all other vectors
|
||||
impl<N: Copy> Row<Vector1<N>> for Vector2<N> {
|
||||
#[inline]
|
||||
fn nrows(&self) -> usize {
|
||||
2
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn row(&self, i: usize) -> Vector1<N> {
|
||||
match i {
|
||||
0 => Vector1::new(self.x),
|
||||
1 => Vector1::new(self.y),
|
||||
_ => panic!(format!("Index out of range: 2d vectors do not have {} rows. ", i))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_row(&mut self, i: usize, r: Vector1<N>) {
|
||||
match i {
|
||||
0 => self.x = r.x,
|
||||
1 => self.y = r.x,
|
||||
_ => panic!(format!("Index out of range: 2d vectors do not have {} rows.", i))
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: One> Basis for Vector1<N> {
|
||||
#[inline(always)]
|
||||
fn canonical_basis<F: FnMut(Vector1<N>) -> bool>(mut f: F) {
|
||||
f(Vector1::new(::one()));
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn orthonormal_subspace_basis<F: FnMut(Vector1<N>) -> bool>(_: &Vector1<N>, _: F) { }
|
||||
|
||||
#[inline]
|
||||
fn canonical_basis_element(i: usize) -> Option<Vector1<N>> {
|
||||
if i == 0 {
|
||||
Some(Vector1::new(::one()))
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + One + Zero + Neg<Output = N>> Basis for Vector2<N> {
|
||||
#[inline(always)]
|
||||
fn canonical_basis<F: FnMut(Vector2<N>) -> bool>(mut f: F) {
|
||||
if !f(Vector2::new(::one(), ::zero())) { return };
|
||||
f(Vector2::new(::zero(), ::one()));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn orthonormal_subspace_basis<F: FnMut(Vector2<N>) -> bool>(n: &Vector2<N>, mut f: F) {
|
||||
f(Vector2::new(-n.y, n.x));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn canonical_basis_element(i: usize) -> Option<Vector2<N>> {
|
||||
if i == 0 {
|
||||
Some(Vector2::new(::one(), ::zero()))
|
||||
}
|
||||
else if i == 1 {
|
||||
Some(Vector2::new(::zero(), ::one()))
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: BaseFloat> Basis for Vector3<N> {
|
||||
#[inline(always)]
|
||||
fn canonical_basis<F: FnMut(Vector3<N>) -> bool>(mut f: F) {
|
||||
if !f(Vector3::new(::one(), ::zero(), ::zero())) { return };
|
||||
if !f(Vector3::new(::zero(), ::one(), ::zero())) { return };
|
||||
f(Vector3::new(::zero(), ::zero(), ::one()));
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn orthonormal_subspace_basis<F: FnMut(Vector3<N>) -> bool>(n: &Vector3<N>, mut f: F) {
|
||||
let a =
|
||||
if n.x.abs() > n.y.abs() {
|
||||
Norm::normalize(&Vector3::new(n.z, ::zero(), -n.x))
|
||||
}
|
||||
else {
|
||||
Norm::normalize(&Vector3::new(::zero(), -n.z, n.y))
|
||||
};
|
||||
|
||||
if !f(Cross::cross(&a, n)) { return };
|
||||
f(a);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn canonical_basis_element(i: usize) -> Option<Vector3<N>> {
|
||||
if i == 0 {
|
||||
Some(Vector3::new(::one(), ::zero(), ::zero()))
|
||||
}
|
||||
else if i == 1 {
|
||||
Some(Vector3::new(::zero(), ::one(), ::zero()))
|
||||
}
|
||||
else if i == 2 {
|
||||
Some(Vector3::new(::zero(), ::zero(), ::one()))
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: this bad: this fixes definitly the number of samples…
|
||||
static SAMPLES_2_F64: [Vector2<f64>; 21] = [
|
||||
Vector2 { x: 1.0, y: 0.0 },
|
||||
Vector2 { x: 0.95557281, y: 0.29475517 },
|
||||
Vector2 { x: 0.82623877, y: 0.56332006 },
|
||||
Vector2 { x: 0.6234898, y: 0.78183148 },
|
||||
Vector2 { x: 0.36534102, y: 0.93087375 },
|
||||
Vector2 { x: 0.07473009, y: 0.9972038 },
|
||||
Vector2 { x: -0.22252093, y: 0.97492791 },
|
||||
Vector2 { x: -0.5, y: 0.8660254 },
|
||||
Vector2 { x: -0.73305187, y: 0.68017274 },
|
||||
Vector2 { x: -0.90096887, y: 0.43388374 },
|
||||
Vector2 { x: -0.98883083, y: 0.14904227 },
|
||||
Vector2 { x: -0.98883083, y: -0.14904227 },
|
||||
Vector2 { x: -0.90096887, y: -0.43388374 },
|
||||
Vector2 { x: -0.73305187, y: -0.68017274 },
|
||||
Vector2 { x: -0.5, y: -0.8660254 },
|
||||
Vector2 { x: -0.22252093, y: -0.97492791 },
|
||||
Vector2 { x: 0.07473009, y: -0.9972038 },
|
||||
Vector2 { x: 0.36534102, y: -0.93087375 },
|
||||
Vector2 { x: 0.6234898, y: -0.78183148 },
|
||||
Vector2 { x: 0.82623877, y: -0.56332006 },
|
||||
Vector2 { x: 0.95557281, y: -0.29475517 },
|
||||
];
|
||||
|
||||
// Those vectors come from bullet 3d
|
||||
static SAMPLES_3_F64: [Vector3<f64>; 42] = [
|
||||
Vector3 { x: 0.000000 , y: -0.000000, z: -1.000000 },
|
||||
Vector3 { x: 0.723608 , y: -0.525725, z: -0.447219 },
|
||||
Vector3 { x: -0.276388, y: -0.850649, z: -0.447219 },
|
||||
Vector3 { x: -0.894426, y: -0.000000, z: -0.447216 },
|
||||
Vector3 { x: -0.276388, y: 0.850649 , z: -0.447220 },
|
||||
Vector3 { x: 0.723608 , y: 0.525725 , z: -0.447219 },
|
||||
Vector3 { x: 0.276388 , y: -0.850649, z: 0.447220 },
|
||||
Vector3 { x: -0.723608, y: -0.525725, z: 0.447219 },
|
||||
Vector3 { x: -0.723608, y: 0.525725 , z: 0.447219 },
|
||||
Vector3 { x: 0.276388 , y: 0.850649 , z: 0.447219 },
|
||||
Vector3 { x: 0.894426 , y: 0.000000 , z: 0.447216 },
|
||||
Vector3 { x: -0.000000, y: 0.000000 , z: 1.000000 },
|
||||
Vector3 { x: 0.425323 , y: -0.309011, z: -0.850654 },
|
||||
Vector3 { x: -0.162456, y: -0.499995, z: -0.850654 },
|
||||
Vector3 { x: 0.262869 , y: -0.809012, z: -0.525738 },
|
||||
Vector3 { x: 0.425323 , y: 0.309011 , z: -0.850654 },
|
||||
Vector3 { x: 0.850648 , y: -0.000000, z: -0.525736 },
|
||||
Vector3 { x: -0.525730, y: -0.000000, z: -0.850652 },
|
||||
Vector3 { x: -0.688190, y: -0.499997, z: -0.525736 },
|
||||
Vector3 { x: -0.162456, y: 0.499995 , z: -0.850654 },
|
||||
Vector3 { x: -0.688190, y: 0.499997 , z: -0.525736 },
|
||||
Vector3 { x: 0.262869 , y: 0.809012 , z: -0.525738 },
|
||||
Vector3 { x: 0.951058 , y: 0.309013 , z: 0.000000 },
|
||||
Vector3 { x: 0.951058 , y: -0.309013, z: 0.000000 },
|
||||
Vector3 { x: 0.587786 , y: -0.809017, z: 0.000000 },
|
||||
Vector3 { x: 0.000000 , y: -1.000000, z: 0.000000 },
|
||||
Vector3 { x: -0.587786, y: -0.809017, z: 0.000000 },
|
||||
Vector3 { x: -0.951058, y: -0.309013, z: -0.000000 },
|
||||
Vector3 { x: -0.951058, y: 0.309013 , z: -0.000000 },
|
||||
Vector3 { x: -0.587786, y: 0.809017 , z: -0.000000 },
|
||||
Vector3 { x: -0.000000, y: 1.000000 , z: -0.000000 },
|
||||
Vector3 { x: 0.587786 , y: 0.809017 , z: -0.000000 },
|
||||
Vector3 { x: 0.688190 , y: -0.499997, z: 0.525736 },
|
||||
Vector3 { x: -0.262869, y: -0.809012, z: 0.525738 },
|
||||
Vector3 { x: -0.850648, y: 0.000000 , z: 0.525736 },
|
||||
Vector3 { x: -0.262869, y: 0.809012 , z: 0.525738 },
|
||||
Vector3 { x: 0.688190 , y: 0.499997 , z: 0.525736 },
|
||||
Vector3 { x: 0.525730 , y: 0.000000 , z: 0.850652 },
|
||||
Vector3 { x: 0.162456 , y: -0.499995, z: 0.850654 },
|
||||
Vector3 { x: -0.425323, y: -0.309011, z: 0.850654 },
|
||||
Vector3 { x: -0.425323, y: 0.309011 , z: 0.850654 },
|
||||
Vector3 { x: 0.162456 , y: 0.499995 , z: 0.850654 }
|
||||
];
|
||||
|
||||
impl<N> UniformSphereSample for Vector1<N>
|
||||
where Vector1<N>: One {
|
||||
#[inline(always)]
|
||||
fn sample<F: FnMut(Vector1<N>)>(mut f: F) {
|
||||
f(::one())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Cast<f64> + Copy> UniformSphereSample for Vector2<N> {
|
||||
#[inline(always)]
|
||||
fn sample<F: FnMut(Vector2<N>)>(mut f: F) {
|
||||
for sample in SAMPLES_2_F64.iter() {
|
||||
f(Cast::from(*sample))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Cast<f64> + Copy> UniformSphereSample for Vector3<N> {
|
||||
#[inline(always)]
|
||||
fn sample<F: FnMut(Vector3<N>)>(mut f: F) {
|
||||
for sample in SAMPLES_3_F64.iter() {
|
||||
f(Cast::from(*sample))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Cast<f64> + Copy> UniformSphereSample for Vector4<N> {
|
||||
#[inline(always)]
|
||||
fn sample<F: FnMut(Vector4<N>)>(_: F) {
|
||||
panic!("UniformSphereSample::<Vector4<N>>::sample : Not yet implemented.")
|
||||
// for sample in SAMPLES_3_F32.iter() {
|
||||
// f(Cast::from(*sample))
|
||||
// }
|
||||
}
|
||||
}
|
|
@ -1,384 +0,0 @@
|
|||
//! Vectors with dimension known at compile-time.
|
||||
|
||||
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
|
||||
use std::mem;
|
||||
use std::slice::{Iter, IterMut};
|
||||
use std::iter::{Iterator, FromIterator, IntoIterator};
|
||||
use std::fmt;
|
||||
use rand::{Rand, Rng};
|
||||
use num::{Zero, One};
|
||||
use traits::operations::{ApproxEq, POrd, POrdering, Axpy, Absolute, Mean};
|
||||
use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm,
|
||||
Translation, Translate};
|
||||
use traits::structure::{Basis, Cast, Dim, Indexable, Iterable, IterableMut, Shape, NumVec,
|
||||
FloatVec, BaseFloat, BaseNum, Bounded, Repeat};
|
||||
use structs::pnt::{Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6};
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// Vector of dimension 1.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Vec1<N> {
|
||||
/// First component of the vector.
|
||||
pub x: N
|
||||
}
|
||||
|
||||
new_impl!(Vec1, x);
|
||||
pord_impl!(Vec1, x,);
|
||||
vec_axis_impl!(Vec1, x);
|
||||
vec_cast_impl!(Vec1, x);
|
||||
conversion_impl!(Vec1, 1);
|
||||
index_impl!(Vec1);
|
||||
indexable_impl!(Vec1, 1);
|
||||
at_fast_impl!(Vec1, 1);
|
||||
repeat_impl!(Vec1, val, x);
|
||||
dim_impl!(Vec1, 1);
|
||||
container_impl!(Vec1);
|
||||
// (specialized); basis_impl!(Vec1, 1);
|
||||
add_impl!(Vec1, x);
|
||||
sub_impl!(Vec1, x);
|
||||
mul_impl!(Vec1, x);
|
||||
div_impl!(Vec1, x);
|
||||
scalar_add_impl!(Vec1, x);
|
||||
scalar_sub_impl!(Vec1, x);
|
||||
scalar_mul_impl!(Vec1, x);
|
||||
scalar_div_impl!(Vec1, x);
|
||||
neg_impl!(Vec1, x);
|
||||
dot_impl!(Vec1, x);
|
||||
translation_impl!(Vec1);
|
||||
norm_impl!(Vec1, x);
|
||||
approx_eq_impl!(Vec1, x);
|
||||
zero_one_impl!(Vec1, x);
|
||||
from_iterator_impl!(Vec1, iterator);
|
||||
bounded_impl!(Vec1, x);
|
||||
axpy_impl!(Vec1, x);
|
||||
iterable_impl!(Vec1, 1);
|
||||
iterable_mut_impl!(Vec1, 1);
|
||||
vec_to_homogeneous_impl!(Vec1, Vec2, y, x);
|
||||
vec_from_homogeneous_impl!(Vec1, Vec2, y, x);
|
||||
translate_impl!(Vec1, Pnt1);
|
||||
rotate_impl!(Vec1);
|
||||
rotate_impl!(Pnt1);
|
||||
transform_impl!(Vec1, Pnt1);
|
||||
vec_as_pnt_impl!(Vec1, Pnt1, x);
|
||||
num_float_vec_impl!(Vec1);
|
||||
absolute_vec_impl!(Vec1, x);
|
||||
arbitrary_impl!(Vec1, x);
|
||||
rand_impl!(Vec1, x);
|
||||
mean_impl!(Vec1);
|
||||
vec_display_impl!(Vec1);
|
||||
|
||||
/// Vector of dimension 2.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Vec2<N> {
|
||||
/// First component of the vector.
|
||||
pub x: N,
|
||||
/// Second component of the vector.
|
||||
pub y: N
|
||||
}
|
||||
|
||||
new_impl!(Vec2, x, y);
|
||||
pord_impl!(Vec2, x, y);
|
||||
vec_axis_impl!(Vec2, x, y);
|
||||
vec_cast_impl!(Vec2, x, y);
|
||||
conversion_impl!(Vec2, 2);
|
||||
index_impl!(Vec2);
|
||||
indexable_impl!(Vec2, 2);
|
||||
at_fast_impl!(Vec2, 2);
|
||||
repeat_impl!(Vec2, val, x, y);
|
||||
dim_impl!(Vec2, 2);
|
||||
container_impl!(Vec2);
|
||||
// (specialized); basis_impl!(Vec2, 1);
|
||||
add_impl!(Vec2, x, y);
|
||||
sub_impl!(Vec2, x, y);
|
||||
mul_impl!(Vec2, x, y);
|
||||
div_impl!(Vec2, x, y);
|
||||
scalar_add_impl!(Vec2, x, y);
|
||||
scalar_sub_impl!(Vec2, x, y);
|
||||
scalar_mul_impl!(Vec2, x, y);
|
||||
scalar_div_impl!(Vec2, x, y);
|
||||
neg_impl!(Vec2, x, y);
|
||||
dot_impl!(Vec2, x, y);
|
||||
translation_impl!(Vec2);
|
||||
norm_impl!(Vec2, x, y);
|
||||
approx_eq_impl!(Vec2, x, y);
|
||||
zero_one_impl!(Vec2, x, y);
|
||||
from_iterator_impl!(Vec2, iterator, iterator);
|
||||
bounded_impl!(Vec2, x, y);
|
||||
axpy_impl!(Vec2, x, y);
|
||||
iterable_impl!(Vec2, 2);
|
||||
iterable_mut_impl!(Vec2, 2);
|
||||
vec_to_homogeneous_impl!(Vec2, Vec3, z, x, y);
|
||||
vec_from_homogeneous_impl!(Vec2, Vec3, z, x, y);
|
||||
translate_impl!(Vec2, Pnt2);
|
||||
rotate_impl!(Vec2);
|
||||
rotate_impl!(Pnt2);
|
||||
transform_impl!(Vec2, Pnt2);
|
||||
vec_as_pnt_impl!(Vec2, Pnt2, x, y);
|
||||
num_float_vec_impl!(Vec2);
|
||||
absolute_vec_impl!(Vec2, x, y);
|
||||
arbitrary_impl!(Vec2, x, y);
|
||||
rand_impl!(Vec2, x, y);
|
||||
mean_impl!(Vec2);
|
||||
vec_display_impl!(Vec2);
|
||||
|
||||
/// Vector of dimension 3.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Vec3<N> {
|
||||
/// First component of the vector.
|
||||
pub x: N,
|
||||
/// Second component of the vector.
|
||||
pub y: N,
|
||||
/// Third component of the vector.
|
||||
pub z: N
|
||||
}
|
||||
|
||||
new_impl!(Vec3, x, y, z);
|
||||
pord_impl!(Vec3, x, y, z);
|
||||
vec_axis_impl!(Vec3, x, y, z);
|
||||
vec_cast_impl!(Vec3, x, y, z);
|
||||
conversion_impl!(Vec3, 3);
|
||||
index_impl!(Vec3);
|
||||
indexable_impl!(Vec3, 3);
|
||||
at_fast_impl!(Vec3, 3);
|
||||
repeat_impl!(Vec3, val, x, y, z);
|
||||
dim_impl!(Vec3, 3);
|
||||
container_impl!(Vec3);
|
||||
// (specialized); basis_impl!(Vec3, 1);
|
||||
add_impl!(Vec3, x, y, z);
|
||||
sub_impl!(Vec3, x, y, z);
|
||||
mul_impl!(Vec3, x, y, z);
|
||||
div_impl!(Vec3, x, y, z);
|
||||
scalar_add_impl!(Vec3, x, y, z);
|
||||
scalar_sub_impl!(Vec3, x, y, z);
|
||||
scalar_mul_impl!(Vec3, x, y, z);
|
||||
scalar_div_impl!(Vec3, x, y, z);
|
||||
neg_impl!(Vec3, x, y, z);
|
||||
dot_impl!(Vec3, x, y, z);
|
||||
translation_impl!(Vec3);
|
||||
norm_impl!(Vec3, x, y ,z);
|
||||
approx_eq_impl!(Vec3, x, y, z);
|
||||
zero_one_impl!(Vec3, x, y, z);
|
||||
from_iterator_impl!(Vec3, iterator, iterator, iterator);
|
||||
bounded_impl!(Vec3, x, y, z);
|
||||
axpy_impl!(Vec3, x, y, z);
|
||||
iterable_impl!(Vec3, 3);
|
||||
iterable_mut_impl!(Vec3, 3);
|
||||
vec_to_homogeneous_impl!(Vec3, Vec4, w, x, y, z);
|
||||
vec_from_homogeneous_impl!(Vec3, Vec4, w, x, y, z);
|
||||
translate_impl!(Vec3, Pnt3);
|
||||
rotate_impl!(Vec3);
|
||||
rotate_impl!(Pnt3);
|
||||
transform_impl!(Vec3, Pnt3);
|
||||
vec_as_pnt_impl!(Vec3, Pnt3, x, y, z);
|
||||
num_float_vec_impl!(Vec3);
|
||||
absolute_vec_impl!(Vec3, x, y, z);
|
||||
arbitrary_impl!(Vec3, x, y, z);
|
||||
rand_impl!(Vec3, x, y, z);
|
||||
mean_impl!(Vec3);
|
||||
vec_display_impl!(Vec3);
|
||||
|
||||
|
||||
/// Vector of dimension 4.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Vec4<N> {
|
||||
/// First component of the vector.
|
||||
pub x: N,
|
||||
/// Second component of the vector.
|
||||
pub y: N,
|
||||
/// Third component of the vector.
|
||||
pub z: N,
|
||||
/// Fourth component of the vector.
|
||||
pub w: N
|
||||
}
|
||||
|
||||
new_impl!(Vec4, x, y, z, w);
|
||||
pord_impl!(Vec4, x, y, z, w);
|
||||
vec_axis_impl!(Vec4, x, y, z, w);
|
||||
vec_cast_impl!(Vec4, x, y, z, w);
|
||||
conversion_impl!(Vec4, 4);
|
||||
index_impl!(Vec4);
|
||||
indexable_impl!(Vec4, 4);
|
||||
at_fast_impl!(Vec4, 4);
|
||||
repeat_impl!(Vec4, val, x, y, z, w);
|
||||
dim_impl!(Vec4, 4);
|
||||
container_impl!(Vec4);
|
||||
basis_impl!(Vec4, 4);
|
||||
add_impl!(Vec4, x, y, z, w);
|
||||
sub_impl!(Vec4, x, y, z, w);
|
||||
mul_impl!(Vec4, x, y, z, w);
|
||||
div_impl!(Vec4, x, y, z, w);
|
||||
scalar_add_impl!(Vec4, x, y, z, w);
|
||||
scalar_sub_impl!(Vec4, x, y, z, w);
|
||||
scalar_mul_impl!(Vec4, x, y, z, w);
|
||||
scalar_div_impl!(Vec4, x, y, z, w);
|
||||
neg_impl!(Vec4, x, y, z, w);
|
||||
dot_impl!(Vec4, x, y, z, w);
|
||||
translation_impl!(Vec4);
|
||||
norm_impl!(Vec4, x, y, z, w);
|
||||
approx_eq_impl!(Vec4, x, y, z, w);
|
||||
zero_one_impl!(Vec4, x, y, z, w);
|
||||
from_iterator_impl!(Vec4, iterator, iterator, iterator, iterator);
|
||||
bounded_impl!(Vec4, x, y, z, w);
|
||||
axpy_impl!(Vec4, x, y, z, w);
|
||||
iterable_impl!(Vec4, 4);
|
||||
iterable_mut_impl!(Vec4, 4);
|
||||
vec_to_homogeneous_impl!(Vec4, Vec5, a, x, y, z, w);
|
||||
vec_from_homogeneous_impl!(Vec4, Vec5, a, x, y, z, w);
|
||||
translate_impl!(Vec4, Pnt4);
|
||||
rotate_impl!(Vec4);
|
||||
rotate_impl!(Pnt4);
|
||||
transform_impl!(Vec4, Pnt4);
|
||||
vec_as_pnt_impl!(Vec4, Pnt4, x, y, z, w);
|
||||
num_float_vec_impl!(Vec4);
|
||||
absolute_vec_impl!(Vec4, x, y, z, w);
|
||||
arbitrary_impl!(Vec4, x, y, z, w);
|
||||
rand_impl!(Vec4, x, y, z, w);
|
||||
mean_impl!(Vec4);
|
||||
vec_display_impl!(Vec4);
|
||||
|
||||
/// Vector of dimension 5.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Vec5<N> {
|
||||
/// First component of the vector.
|
||||
pub x: N,
|
||||
/// Second component of the vector.
|
||||
pub y: N,
|
||||
/// Third component of the vector.
|
||||
pub z: N,
|
||||
/// Fourth component of the vector.
|
||||
pub w: N,
|
||||
/// Fifth of the vector.
|
||||
pub a: N
|
||||
}
|
||||
|
||||
new_impl!(Vec5, x, y, z, w, a);
|
||||
pord_impl!(Vec5, x, y, z, w, a);
|
||||
vec_axis_impl!(Vec5, x, y, z, w, a);
|
||||
vec_cast_impl!(Vec5, x, y, z, w, a);
|
||||
conversion_impl!(Vec5, 5);
|
||||
index_impl!(Vec5);
|
||||
indexable_impl!(Vec5, 5);
|
||||
at_fast_impl!(Vec5, 5);
|
||||
repeat_impl!(Vec5, val, x, y, z, w, a);
|
||||
dim_impl!(Vec5, 5);
|
||||
container_impl!(Vec5);
|
||||
basis_impl!(Vec5, 5);
|
||||
add_impl!(Vec5, x, y, z, w, a);
|
||||
sub_impl!(Vec5, x, y, z, w, a);
|
||||
mul_impl!(Vec5, x, y, z, w, a);
|
||||
div_impl!(Vec5, x, y, z, w, a);
|
||||
scalar_add_impl!(Vec5, x, y, z, w, a);
|
||||
scalar_sub_impl!(Vec5, x, y, z, w, a);
|
||||
scalar_mul_impl!(Vec5, x, y, z, w, a);
|
||||
scalar_div_impl!(Vec5, x, y, z, w, a);
|
||||
neg_impl!(Vec5, x, y, z, w, a);
|
||||
dot_impl!(Vec5, x, y, z, w, a);
|
||||
translation_impl!(Vec5);
|
||||
norm_impl!(Vec5, x, y, z, w, a);
|
||||
approx_eq_impl!(Vec5, x, y, z, w, a);
|
||||
zero_one_impl!(Vec5, x, y, z, w, a);
|
||||
from_iterator_impl!(Vec5, iterator, iterator, iterator, iterator, iterator);
|
||||
bounded_impl!(Vec5, x, y, z, w, a);
|
||||
axpy_impl!(Vec5, x, y, z, w, a);
|
||||
iterable_impl!(Vec5, 5);
|
||||
iterable_mut_impl!(Vec5, 5);
|
||||
vec_to_homogeneous_impl!(Vec5, Vec6, b, x, y, z, w, a);
|
||||
vec_from_homogeneous_impl!(Vec5, Vec6, b, x, y, z, w, a);
|
||||
translate_impl!(Vec5, Pnt5);
|
||||
rotate_impl!(Vec5);
|
||||
rotate_impl!(Pnt5);
|
||||
transform_impl!(Vec5, Pnt5);
|
||||
vec_as_pnt_impl!(Vec5, Pnt5, x, y, z, w, a);
|
||||
num_float_vec_impl!(Vec5);
|
||||
absolute_vec_impl!(Vec5, x, y, z, w, a);
|
||||
arbitrary_impl!(Vec5, x, y, z, w, a);
|
||||
rand_impl!(Vec5, x, y, z, w, a);
|
||||
mean_impl!(Vec5);
|
||||
vec_display_impl!(Vec5);
|
||||
|
||||
/// Vector of dimension 6.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Vec6<N> {
|
||||
/// First component of the vector.
|
||||
pub x: N,
|
||||
/// Second component of the vector.
|
||||
pub y: N,
|
||||
/// Third component of the vector.
|
||||
pub z: N,
|
||||
/// Fourth component of the vector.
|
||||
pub w: N,
|
||||
/// Fifth of the vector.
|
||||
pub a: N,
|
||||
/// Sixth component of the vector.
|
||||
pub b: N
|
||||
}
|
||||
|
||||
new_impl!(Vec6, x, y, z, w, a, b);
|
||||
pord_impl!(Vec6, x, y, z, w, a, b);
|
||||
vec_axis_impl!(Vec6, x, y, z, w, a, b);
|
||||
vec_cast_impl!(Vec6, x, y, z, w, a, b);
|
||||
conversion_impl!(Vec6, 6);
|
||||
index_impl!(Vec6);
|
||||
indexable_impl!(Vec6, 6);
|
||||
at_fast_impl!(Vec6, 6);
|
||||
repeat_impl!(Vec6, val, x, y, z, w, a, b);
|
||||
dim_impl!(Vec6, 6);
|
||||
container_impl!(Vec6);
|
||||
basis_impl!(Vec6, 6);
|
||||
add_impl!(Vec6, x, y, z, w, a, b);
|
||||
sub_impl!(Vec6, x, y, z, w, a, b);
|
||||
mul_impl!(Vec6, x, y, z, w, a, b);
|
||||
div_impl!(Vec6, x, y, z, w, a, b);
|
||||
scalar_add_impl!(Vec6, x, y, z, w, a, b);
|
||||
scalar_sub_impl!(Vec6, x, y, z, w, a, b);
|
||||
scalar_mul_impl!(Vec6, x, y, z, w, a, b);
|
||||
scalar_div_impl!(Vec6, x, y, z, w, a, b);
|
||||
neg_impl!(Vec6, x, y, z, w, a, b);
|
||||
dot_impl!(Vec6, x, y, z, w, a, b);
|
||||
translation_impl!(Vec6);
|
||||
norm_impl!(Vec6, x, y, z, w, a, b);
|
||||
approx_eq_impl!(Vec6, x, y, z, w, a, b);
|
||||
zero_one_impl!(Vec6, x, y, z, w, a, b);
|
||||
from_iterator_impl!(Vec6, iterator, iterator, iterator, iterator, iterator, iterator);
|
||||
bounded_impl!(Vec6, x, y, z, w, a, b);
|
||||
axpy_impl!(Vec6, x, y, z, w, a, b);
|
||||
iterable_impl!(Vec6, 6);
|
||||
iterable_mut_impl!(Vec6, 6);
|
||||
translate_impl!(Vec6, Pnt6);
|
||||
rotate_impl!(Vec6);
|
||||
rotate_impl!(Pnt6);
|
||||
transform_impl!(Vec6, Pnt6);
|
||||
vec_as_pnt_impl!(Vec6, Pnt6, x, y, z, w, a, b);
|
||||
num_float_vec_impl!(Vec6);
|
||||
absolute_vec_impl!(Vec6, x, y, z, w, a, b);
|
||||
arbitrary_impl!(Vec6, x, y, z, w, a, b);
|
||||
rand_impl!(Vec6, x, y, z, w, a, b);
|
||||
mean_impl!(Vec6);
|
||||
vec_display_impl!(Vec6);
|
|
@ -0,0 +1,384 @@
|
|||
//! Vectors with dimension known at compile-time.
|
||||
|
||||
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
|
||||
use std::mem;
|
||||
use std::slice::{Iter, IterMut};
|
||||
use std::iter::{Iterator, FromIterator, IntoIterator};
|
||||
use std::fmt;
|
||||
use rand::{Rand, Rng};
|
||||
use num::{Zero, One};
|
||||
use traits::operations::{ApproxEq, PartialOrder, PartialOrdering, Axpy, Absolute, Mean};
|
||||
use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm,
|
||||
Translation, Translate};
|
||||
use traits::structure::{Basis, Cast, Dimension, Indexable, Iterable, IterableMut, Shape, NumVector,
|
||||
FloatVector, BaseFloat, BaseNum, Bounded, Repeat};
|
||||
use structs::point::{Point1, Point2, Point3, Point4, Point5, Point6};
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
||||
/// Vector of dimension 1.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Vector1<N> {
|
||||
/// First component of the vector.
|
||||
pub x: N
|
||||
}
|
||||
|
||||
new_impl!(Vector1, x);
|
||||
pord_impl!(Vector1, x,);
|
||||
vec_axis_impl!(Vector1, x);
|
||||
vec_cast_impl!(Vector1, x);
|
||||
conversion_impl!(Vector1, 1);
|
||||
index_impl!(Vector1);
|
||||
indexable_impl!(Vector1, 1);
|
||||
at_fast_impl!(Vector1, 1);
|
||||
repeat_impl!(Vector1, val, x);
|
||||
dim_impl!(Vector1, 1);
|
||||
container_impl!(Vector1);
|
||||
// (specialized); basis_impl!(Vector1, 1);
|
||||
add_impl!(Vector1, x);
|
||||
sub_impl!(Vector1, x);
|
||||
mul_impl!(Vector1, x);
|
||||
div_impl!(Vector1, x);
|
||||
scalar_add_impl!(Vector1, x);
|
||||
scalar_sub_impl!(Vector1, x);
|
||||
scalar_mul_impl!(Vector1, x);
|
||||
scalar_div_impl!(Vector1, x);
|
||||
neg_impl!(Vector1, x);
|
||||
dot_impl!(Vector1, x);
|
||||
translation_impl!(Vector1);
|
||||
norm_impl!(Vector1, x);
|
||||
approx_eq_impl!(Vector1, x);
|
||||
zero_one_impl!(Vector1, x);
|
||||
from_iterator_impl!(Vector1, iterator);
|
||||
bounded_impl!(Vector1, x);
|
||||
axpy_impl!(Vector1, x);
|
||||
iterable_impl!(Vector1, 1);
|
||||
iterable_mut_impl!(Vector1, 1);
|
||||
vec_to_homogeneous_impl!(Vector1, Vector2, y, x);
|
||||
vec_from_homogeneous_impl!(Vector1, Vector2, y, x);
|
||||
translate_impl!(Vector1, Point1);
|
||||
rotate_impl!(Vector1);
|
||||
rotate_impl!(Point1);
|
||||
transform_impl!(Vector1, Point1);
|
||||
vec_as_point_impl!(Vector1, Point1, x);
|
||||
num_float_vec_impl!(Vector1);
|
||||
absolute_vec_impl!(Vector1, x);
|
||||
arbitrary_impl!(Vector1, x);
|
||||
rand_impl!(Vector1, x);
|
||||
mean_impl!(Vector1);
|
||||
vec_display_impl!(Vector1);
|
||||
|
||||
/// Vector of dimension 2.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Vector2<N> {
|
||||
/// First component of the vector.
|
||||
pub x: N,
|
||||
/// Second component of the vector.
|
||||
pub y: N
|
||||
}
|
||||
|
||||
new_impl!(Vector2, x, y);
|
||||
pord_impl!(Vector2, x, y);
|
||||
vec_axis_impl!(Vector2, x, y);
|
||||
vec_cast_impl!(Vector2, x, y);
|
||||
conversion_impl!(Vector2, 2);
|
||||
index_impl!(Vector2);
|
||||
indexable_impl!(Vector2, 2);
|
||||
at_fast_impl!(Vector2, 2);
|
||||
repeat_impl!(Vector2, val, x, y);
|
||||
dim_impl!(Vector2, 2);
|
||||
container_impl!(Vector2);
|
||||
// (specialized); basis_impl!(Vector2, 1);
|
||||
add_impl!(Vector2, x, y);
|
||||
sub_impl!(Vector2, x, y);
|
||||
mul_impl!(Vector2, x, y);
|
||||
div_impl!(Vector2, x, y);
|
||||
scalar_add_impl!(Vector2, x, y);
|
||||
scalar_sub_impl!(Vector2, x, y);
|
||||
scalar_mul_impl!(Vector2, x, y);
|
||||
scalar_div_impl!(Vector2, x, y);
|
||||
neg_impl!(Vector2, x, y);
|
||||
dot_impl!(Vector2, x, y);
|
||||
translation_impl!(Vector2);
|
||||
norm_impl!(Vector2, x, y);
|
||||
approx_eq_impl!(Vector2, x, y);
|
||||
zero_one_impl!(Vector2, x, y);
|
||||
from_iterator_impl!(Vector2, iterator, iterator);
|
||||
bounded_impl!(Vector2, x, y);
|
||||
axpy_impl!(Vector2, x, y);
|
||||
iterable_impl!(Vector2, 2);
|
||||
iterable_mut_impl!(Vector2, 2);
|
||||
vec_to_homogeneous_impl!(Vector2, Vector3, z, x, y);
|
||||
vec_from_homogeneous_impl!(Vector2, Vector3, z, x, y);
|
||||
translate_impl!(Vector2, Point2);
|
||||
rotate_impl!(Vector2);
|
||||
rotate_impl!(Point2);
|
||||
transform_impl!(Vector2, Point2);
|
||||
vec_as_point_impl!(Vector2, Point2, x, y);
|
||||
num_float_vec_impl!(Vector2);
|
||||
absolute_vec_impl!(Vector2, x, y);
|
||||
arbitrary_impl!(Vector2, x, y);
|
||||
rand_impl!(Vector2, x, y);
|
||||
mean_impl!(Vector2);
|
||||
vec_display_impl!(Vector2);
|
||||
|
||||
/// Vector of dimension 3.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Vector3<N> {
|
||||
/// First component of the vector.
|
||||
pub x: N,
|
||||
/// Second component of the vector.
|
||||
pub y: N,
|
||||
/// Third component of the vector.
|
||||
pub z: N
|
||||
}
|
||||
|
||||
new_impl!(Vector3, x, y, z);
|
||||
pord_impl!(Vector3, x, y, z);
|
||||
vec_axis_impl!(Vector3, x, y, z);
|
||||
vec_cast_impl!(Vector3, x, y, z);
|
||||
conversion_impl!(Vector3, 3);
|
||||
index_impl!(Vector3);
|
||||
indexable_impl!(Vector3, 3);
|
||||
at_fast_impl!(Vector3, 3);
|
||||
repeat_impl!(Vector3, val, x, y, z);
|
||||
dim_impl!(Vector3, 3);
|
||||
container_impl!(Vector3);
|
||||
// (specialized); basis_impl!(Vector3, 1);
|
||||
add_impl!(Vector3, x, y, z);
|
||||
sub_impl!(Vector3, x, y, z);
|
||||
mul_impl!(Vector3, x, y, z);
|
||||
div_impl!(Vector3, x, y, z);
|
||||
scalar_add_impl!(Vector3, x, y, z);
|
||||
scalar_sub_impl!(Vector3, x, y, z);
|
||||
scalar_mul_impl!(Vector3, x, y, z);
|
||||
scalar_div_impl!(Vector3, x, y, z);
|
||||
neg_impl!(Vector3, x, y, z);
|
||||
dot_impl!(Vector3, x, y, z);
|
||||
translation_impl!(Vector3);
|
||||
norm_impl!(Vector3, x, y ,z);
|
||||
approx_eq_impl!(Vector3, x, y, z);
|
||||
zero_one_impl!(Vector3, x, y, z);
|
||||
from_iterator_impl!(Vector3, iterator, iterator, iterator);
|
||||
bounded_impl!(Vector3, x, y, z);
|
||||
axpy_impl!(Vector3, x, y, z);
|
||||
iterable_impl!(Vector3, 3);
|
||||
iterable_mut_impl!(Vector3, 3);
|
||||
vec_to_homogeneous_impl!(Vector3, Vector4, w, x, y, z);
|
||||
vec_from_homogeneous_impl!(Vector3, Vector4, w, x, y, z);
|
||||
translate_impl!(Vector3, Point3);
|
||||
rotate_impl!(Vector3);
|
||||
rotate_impl!(Point3);
|
||||
transform_impl!(Vector3, Point3);
|
||||
vec_as_point_impl!(Vector3, Point3, x, y, z);
|
||||
num_float_vec_impl!(Vector3);
|
||||
absolute_vec_impl!(Vector3, x, y, z);
|
||||
arbitrary_impl!(Vector3, x, y, z);
|
||||
rand_impl!(Vector3, x, y, z);
|
||||
mean_impl!(Vector3);
|
||||
vec_display_impl!(Vector3);
|
||||
|
||||
|
||||
/// Vector of dimension 4.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Vector4<N> {
|
||||
/// First component of the vector.
|
||||
pub x: N,
|
||||
/// Second component of the vector.
|
||||
pub y: N,
|
||||
/// Third component of the vector.
|
||||
pub z: N,
|
||||
/// Fourth component of the vector.
|
||||
pub w: N
|
||||
}
|
||||
|
||||
new_impl!(Vector4, x, y, z, w);
|
||||
pord_impl!(Vector4, x, y, z, w);
|
||||
vec_axis_impl!(Vector4, x, y, z, w);
|
||||
vec_cast_impl!(Vector4, x, y, z, w);
|
||||
conversion_impl!(Vector4, 4);
|
||||
index_impl!(Vector4);
|
||||
indexable_impl!(Vector4, 4);
|
||||
at_fast_impl!(Vector4, 4);
|
||||
repeat_impl!(Vector4, val, x, y, z, w);
|
||||
dim_impl!(Vector4, 4);
|
||||
container_impl!(Vector4);
|
||||
basis_impl!(Vector4, 4);
|
||||
add_impl!(Vector4, x, y, z, w);
|
||||
sub_impl!(Vector4, x, y, z, w);
|
||||
mul_impl!(Vector4, x, y, z, w);
|
||||
div_impl!(Vector4, x, y, z, w);
|
||||
scalar_add_impl!(Vector4, x, y, z, w);
|
||||
scalar_sub_impl!(Vector4, x, y, z, w);
|
||||
scalar_mul_impl!(Vector4, x, y, z, w);
|
||||
scalar_div_impl!(Vector4, x, y, z, w);
|
||||
neg_impl!(Vector4, x, y, z, w);
|
||||
dot_impl!(Vector4, x, y, z, w);
|
||||
translation_impl!(Vector4);
|
||||
norm_impl!(Vector4, x, y, z, w);
|
||||
approx_eq_impl!(Vector4, x, y, z, w);
|
||||
zero_one_impl!(Vector4, x, y, z, w);
|
||||
from_iterator_impl!(Vector4, iterator, iterator, iterator, iterator);
|
||||
bounded_impl!(Vector4, x, y, z, w);
|
||||
axpy_impl!(Vector4, x, y, z, w);
|
||||
iterable_impl!(Vector4, 4);
|
||||
iterable_mut_impl!(Vector4, 4);
|
||||
vec_to_homogeneous_impl!(Vector4, Vector5, a, x, y, z, w);
|
||||
vec_from_homogeneous_impl!(Vector4, Vector5, a, x, y, z, w);
|
||||
translate_impl!(Vector4, Point4);
|
||||
rotate_impl!(Vector4);
|
||||
rotate_impl!(Point4);
|
||||
transform_impl!(Vector4, Point4);
|
||||
vec_as_point_impl!(Vector4, Point4, x, y, z, w);
|
||||
num_float_vec_impl!(Vector4);
|
||||
absolute_vec_impl!(Vector4, x, y, z, w);
|
||||
arbitrary_impl!(Vector4, x, y, z, w);
|
||||
rand_impl!(Vector4, x, y, z, w);
|
||||
mean_impl!(Vector4);
|
||||
vec_display_impl!(Vector4);
|
||||
|
||||
/// Vector of dimension 5.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Vector5<N> {
|
||||
/// First component of the vector.
|
||||
pub x: N,
|
||||
/// Second component of the vector.
|
||||
pub y: N,
|
||||
/// Third component of the vector.
|
||||
pub z: N,
|
||||
/// Fourth component of the vector.
|
||||
pub w: N,
|
||||
/// Fifth of the vector.
|
||||
pub a: N
|
||||
}
|
||||
|
||||
new_impl!(Vector5, x, y, z, w, a);
|
||||
pord_impl!(Vector5, x, y, z, w, a);
|
||||
vec_axis_impl!(Vector5, x, y, z, w, a);
|
||||
vec_cast_impl!(Vector5, x, y, z, w, a);
|
||||
conversion_impl!(Vector5, 5);
|
||||
index_impl!(Vector5);
|
||||
indexable_impl!(Vector5, 5);
|
||||
at_fast_impl!(Vector5, 5);
|
||||
repeat_impl!(Vector5, val, x, y, z, w, a);
|
||||
dim_impl!(Vector5, 5);
|
||||
container_impl!(Vector5);
|
||||
basis_impl!(Vector5, 5);
|
||||
add_impl!(Vector5, x, y, z, w, a);
|
||||
sub_impl!(Vector5, x, y, z, w, a);
|
||||
mul_impl!(Vector5, x, y, z, w, a);
|
||||
div_impl!(Vector5, x, y, z, w, a);
|
||||
scalar_add_impl!(Vector5, x, y, z, w, a);
|
||||
scalar_sub_impl!(Vector5, x, y, z, w, a);
|
||||
scalar_mul_impl!(Vector5, x, y, z, w, a);
|
||||
scalar_div_impl!(Vector5, x, y, z, w, a);
|
||||
neg_impl!(Vector5, x, y, z, w, a);
|
||||
dot_impl!(Vector5, x, y, z, w, a);
|
||||
translation_impl!(Vector5);
|
||||
norm_impl!(Vector5, x, y, z, w, a);
|
||||
approx_eq_impl!(Vector5, x, y, z, w, a);
|
||||
zero_one_impl!(Vector5, x, y, z, w, a);
|
||||
from_iterator_impl!(Vector5, iterator, iterator, iterator, iterator, iterator);
|
||||
bounded_impl!(Vector5, x, y, z, w, a);
|
||||
axpy_impl!(Vector5, x, y, z, w, a);
|
||||
iterable_impl!(Vector5, 5);
|
||||
iterable_mut_impl!(Vector5, 5);
|
||||
vec_to_homogeneous_impl!(Vector5, Vector6, b, x, y, z, w, a);
|
||||
vec_from_homogeneous_impl!(Vector5, Vector6, b, x, y, z, w, a);
|
||||
translate_impl!(Vector5, Point5);
|
||||
rotate_impl!(Vector5);
|
||||
rotate_impl!(Point5);
|
||||
transform_impl!(Vector5, Point5);
|
||||
vec_as_point_impl!(Vector5, Point5, x, y, z, w, a);
|
||||
num_float_vec_impl!(Vector5);
|
||||
absolute_vec_impl!(Vector5, x, y, z, w, a);
|
||||
arbitrary_impl!(Vector5, x, y, z, w, a);
|
||||
rand_impl!(Vector5, x, y, z, w, a);
|
||||
mean_impl!(Vector5);
|
||||
vec_display_impl!(Vector5);
|
||||
|
||||
/// Vector of dimension 6.
|
||||
///
|
||||
/// The main differance between a point and a vector is that a vector is not affected by
|
||||
/// translations.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Vector6<N> {
|
||||
/// First component of the vector.
|
||||
pub x: N,
|
||||
/// Second component of the vector.
|
||||
pub y: N,
|
||||
/// Third component of the vector.
|
||||
pub z: N,
|
||||
/// Fourth component of the vector.
|
||||
pub w: N,
|
||||
/// Fifth of the vector.
|
||||
pub a: N,
|
||||
/// Sixth component of the vector.
|
||||
pub b: N
|
||||
}
|
||||
|
||||
new_impl!(Vector6, x, y, z, w, a, b);
|
||||
pord_impl!(Vector6, x, y, z, w, a, b);
|
||||
vec_axis_impl!(Vector6, x, y, z, w, a, b);
|
||||
vec_cast_impl!(Vector6, x, y, z, w, a, b);
|
||||
conversion_impl!(Vector6, 6);
|
||||
index_impl!(Vector6);
|
||||
indexable_impl!(Vector6, 6);
|
||||
at_fast_impl!(Vector6, 6);
|
||||
repeat_impl!(Vector6, val, x, y, z, w, a, b);
|
||||
dim_impl!(Vector6, 6);
|
||||
container_impl!(Vector6);
|
||||
basis_impl!(Vector6, 6);
|
||||
add_impl!(Vector6, x, y, z, w, a, b);
|
||||
sub_impl!(Vector6, x, y, z, w, a, b);
|
||||
mul_impl!(Vector6, x, y, z, w, a, b);
|
||||
div_impl!(Vector6, x, y, z, w, a, b);
|
||||
scalar_add_impl!(Vector6, x, y, z, w, a, b);
|
||||
scalar_sub_impl!(Vector6, x, y, z, w, a, b);
|
||||
scalar_mul_impl!(Vector6, x, y, z, w, a, b);
|
||||
scalar_div_impl!(Vector6, x, y, z, w, a, b);
|
||||
neg_impl!(Vector6, x, y, z, w, a, b);
|
||||
dot_impl!(Vector6, x, y, z, w, a, b);
|
||||
translation_impl!(Vector6);
|
||||
norm_impl!(Vector6, x, y, z, w, a, b);
|
||||
approx_eq_impl!(Vector6, x, y, z, w, a, b);
|
||||
zero_one_impl!(Vector6, x, y, z, w, a, b);
|
||||
from_iterator_impl!(Vector6, iterator, iterator, iterator, iterator, iterator, iterator);
|
||||
bounded_impl!(Vector6, x, y, z, w, a, b);
|
||||
axpy_impl!(Vector6, x, y, z, w, a, b);
|
||||
iterable_impl!(Vector6, 6);
|
||||
iterable_mut_impl!(Vector6, 6);
|
||||
translate_impl!(Vector6, Point6);
|
||||
rotate_impl!(Vector6);
|
||||
rotate_impl!(Point6);
|
||||
transform_impl!(Vector6, Point6);
|
||||
vec_as_point_impl!(Vector6, Point6, x, y, z, w, a, b);
|
||||
num_float_vec_impl!(Vector6);
|
||||
absolute_vec_impl!(Vector6, x, y, z, w, a, b);
|
||||
arbitrary_impl!(Vector6, x, y, z, w, a, b);
|
||||
rand_impl!(Vector6, x, y, z, w, a, b);
|
||||
mean_impl!(Vector6);
|
||||
vec_display_impl!(Vector6);
|
|
@ -15,37 +15,37 @@ macro_rules! new_impl(
|
|||
);
|
||||
|
||||
macro_rules! conversion_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N> AsRef<[N; $dim]> for $t<N> {
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N> AsRef<[N; $dimension]> for $t<N> {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &[N; $dim] {
|
||||
fn as_ref(&self) -> &[N; $dimension] {
|
||||
unsafe {
|
||||
mem::transmute(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> AsMut<[N; $dim]> for $t<N> {
|
||||
impl<N> AsMut<[N; $dimension]> for $t<N> {
|
||||
#[inline]
|
||||
fn as_mut(&mut self) -> &mut [N; $dim] {
|
||||
fn as_mut(&mut self) -> &mut [N; $dimension] {
|
||||
unsafe {
|
||||
mem::transmute(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, N> From<&'a [N; $dim]> for &'a $t<N> {
|
||||
impl<'a, N> From<&'a [N; $dimension]> for &'a $t<N> {
|
||||
#[inline]
|
||||
fn from(arr: &'a [N; $dim]) -> &'a $t<N> {
|
||||
fn from(arr: &'a [N; $dimension]) -> &'a $t<N> {
|
||||
unsafe {
|
||||
mem::transmute(arr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, N> From<&'a mut [N; $dim]> for &'a mut $t<N> {
|
||||
impl<'a, N> From<&'a mut [N; $dimension]> for &'a mut $t<N> {
|
||||
#[inline]
|
||||
fn from(arr: &'a mut [N; $dim]) -> &'a mut $t<N> {
|
||||
fn from(arr: &'a mut [N; $dimension]) -> &'a mut $t<N> {
|
||||
unsafe {
|
||||
mem::transmute(arr)
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ macro_rules! conversion_impl(
|
|||
);
|
||||
|
||||
macro_rules! at_fast_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N: Copy> $t<N> {
|
||||
/// Unsafe read access to a vector element by index.
|
||||
#[inline]
|
||||
|
@ -76,7 +76,7 @@ macro_rules! at_fast_impl(
|
|||
// However, f32/f64 does not implement Ord…
|
||||
macro_rules! pord_impl(
|
||||
($t: ident, $comp0: ident, $($compN: ident),*) => (
|
||||
impl<N: BaseFloat> POrd for $t<N> {
|
||||
impl<N: BaseFloat> PartialOrder for $t<N> {
|
||||
#[inline]
|
||||
fn inf(&self, other: &$t<N>) -> $t<N> {
|
||||
$t::new(self.$comp0.min(other.$comp0)
|
||||
|
@ -90,24 +90,24 @@ macro_rules! pord_impl(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(unused_mut)] // otherwise there will be a warning for is_eq or Vec1.
|
||||
fn partial_cmp(&self, other: &$t<N>) -> POrdering {
|
||||
#[allow(unused_mut)] // otherwise there will be a warning for is_eq or Vector1.
|
||||
fn partial_cmp(&self, other: &$t<N>) -> PartialOrdering {
|
||||
let is_lt = self.$comp0 < other.$comp0;
|
||||
let mut is_eq = self.$comp0 == other.$comp0;
|
||||
|
||||
if is_lt { // <
|
||||
$(
|
||||
if self.$compN > other.$compN {
|
||||
return POrdering::NotComparable
|
||||
return PartialOrdering::NotComparable
|
||||
}
|
||||
)*
|
||||
|
||||
POrdering::PartialLess
|
||||
PartialOrdering::PartialLess
|
||||
}
|
||||
else { // >=
|
||||
$(
|
||||
if self.$compN < other.$compN {
|
||||
return POrdering::NotComparable
|
||||
return PartialOrdering::NotComparable
|
||||
}
|
||||
else if self.$compN > other.$compN {
|
||||
is_eq = false;
|
||||
|
@ -116,10 +116,10 @@ macro_rules! pord_impl(
|
|||
)*
|
||||
|
||||
if is_eq {
|
||||
POrdering::PartialEqual
|
||||
PartialOrdering::PartialEqual
|
||||
}
|
||||
else {
|
||||
POrdering::PartialGreater
|
||||
PartialOrdering::PartialGreater
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -177,11 +177,11 @@ macro_rules! vec_cast_impl(
|
|||
);
|
||||
|
||||
macro_rules! indexable_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N> Shape<usize> for $t<N> {
|
||||
#[inline]
|
||||
fn shape(&self) -> usize {
|
||||
$dim
|
||||
$dimension
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,18 +189,18 @@ macro_rules! indexable_impl(
|
|||
#[inline]
|
||||
fn swap(&mut self, i1: usize, i2: usize) {
|
||||
unsafe {
|
||||
mem::transmute::<&mut $t<N>, &mut [N; $dim]>(self).swap(i1, i2)
|
||||
mem::transmute::<&mut $t<N>, &mut [N; $dimension]>(self).swap(i1, i2)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn unsafe_at(&self, i: usize) -> N {
|
||||
(*mem::transmute::<&$t<N>, &[N; $dim]>(self).get_unchecked(i))
|
||||
(*mem::transmute::<&$t<N>, &[N; $dimension]>(self).get_unchecked(i))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn unsafe_set(&mut self, i: usize, val: N) {
|
||||
(*mem::transmute::<&mut $t<N>, &mut [N; $dim]>(self).get_unchecked_mut(i)) = val
|
||||
(*mem::transmute::<&mut $t<N>, &mut [N; $dimension]>(self).get_unchecked_mut(i)) = val
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -239,12 +239,12 @@ macro_rules! repeat_impl(
|
|||
);
|
||||
|
||||
macro_rules! iterable_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N> Iterable<N> for $t<N> {
|
||||
#[inline]
|
||||
fn iter<'l>(&'l self) -> Iter<'l, N> {
|
||||
unsafe {
|
||||
mem::transmute::<&'l $t<N>, &'l [N; $dim]>(self).iter()
|
||||
mem::transmute::<&'l $t<N>, &'l [N; $dimension]>(self).iter()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -252,12 +252,12 @@ macro_rules! iterable_impl(
|
|||
);
|
||||
|
||||
macro_rules! iterable_mut_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N> IterableMut<N> for $t<N> {
|
||||
#[inline]
|
||||
fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> {
|
||||
unsafe {
|
||||
mem::transmute::<&'l mut $t<N>, &'l mut [N; $dim]>(self).iter_mut()
|
||||
mem::transmute::<&'l mut $t<N>, &'l mut [N; $dimension]>(self).iter_mut()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -265,11 +265,11 @@ macro_rules! iterable_mut_impl(
|
|||
);
|
||||
|
||||
macro_rules! dim_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N> Dim for $t<N> {
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N> Dimension for $t<N> {
|
||||
#[inline]
|
||||
fn dim(_: Option<$t<N>>) -> usize {
|
||||
$dim
|
||||
fn dimension(_: Option<$t<N>>) -> usize {
|
||||
$dimension
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -281,18 +281,18 @@ macro_rules! container_impl(
|
|||
/// The dimension of this entity.
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
Dim::dim(None::<$t<N>>)
|
||||
Dimension::dimension(None::<$t<N>>)
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! basis_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
($t: ident, $dimension: expr) => (
|
||||
impl<N: BaseFloat + ApproxEq<N>> Basis for $t<N> {
|
||||
#[inline]
|
||||
fn canonical_basis<F: FnMut($t<N>) -> bool>(mut f: F) {
|
||||
for i in 0 .. $dim {
|
||||
for i in 0 .. $dimension {
|
||||
if !f(Basis::canonical_basis_element(i).unwrap()) { return }
|
||||
}
|
||||
}
|
||||
|
@ -303,14 +303,14 @@ macro_rules! basis_impl(
|
|||
// orthogonalization algorithm.
|
||||
let mut basis: Vec<$t<N>> = Vec::new();
|
||||
|
||||
for i in 0 .. $dim {
|
||||
for i in 0 .. $dimension {
|
||||
let mut basis_element : $t<N> = ::zero();
|
||||
|
||||
unsafe {
|
||||
basis_element.set_fast(i, ::one());
|
||||
}
|
||||
|
||||
if basis.len() == $dim - 1 {
|
||||
if basis.len() == $dimension - 1 {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -322,7 +322,7 @@ macro_rules! basis_impl(
|
|||
elt = elt - *v * Dot::dot(&elt, v)
|
||||
};
|
||||
|
||||
if !ApproxEq::approx_eq(&Norm::sqnorm(&elt), &::zero()) {
|
||||
if !ApproxEq::approx_eq(&Norm::norm_squared(&elt), &::zero()) {
|
||||
let new_element = Norm::normalize(&elt);
|
||||
|
||||
if !f(new_element) { return };
|
||||
|
@ -334,7 +334,7 @@ macro_rules! basis_impl(
|
|||
|
||||
#[inline]
|
||||
fn canonical_basis_element(i: usize) -> Option<$t<N>> {
|
||||
if i < $dim {
|
||||
if i < $dimension {
|
||||
let mut basis_element : $t<N> = ::zero();
|
||||
|
||||
unsafe {
|
||||
|
@ -621,7 +621,7 @@ macro_rules! translation_impl(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn inv_translation(&self) -> $t<N> {
|
||||
fn inverse_translation(&self) -> $t<N> {
|
||||
-*self
|
||||
}
|
||||
|
||||
|
@ -657,7 +657,7 @@ macro_rules! norm_impl(
|
|||
($t: ident, $($compN: ident),+) => (
|
||||
impl<N: BaseFloat> Norm<N> for $t<N> {
|
||||
#[inline]
|
||||
fn sqnorm(&self) -> N {
|
||||
fn norm_squared(&self) -> N {
|
||||
Dot::dot(self, self)
|
||||
}
|
||||
|
||||
|
@ -816,7 +816,7 @@ macro_rules! translate_impl(
|
|||
*other + *self
|
||||
}
|
||||
|
||||
fn inv_translate(&self, other: &$t<N>) -> $t<N> {
|
||||
fn inverse_translate(&self, other: &$t<N>) -> $t<N> {
|
||||
*other - *self
|
||||
}
|
||||
}
|
||||
|
@ -830,7 +830,7 @@ macro_rules! rotate_impl(
|
|||
*other
|
||||
}
|
||||
|
||||
fn inv_rotate(&self, other: &O) -> O {
|
||||
fn inverse_rotate(&self, other: &O) -> O {
|
||||
*other
|
||||
}
|
||||
}
|
||||
|
@ -844,19 +844,19 @@ macro_rules! transform_impl(
|
|||
self.translate(other)
|
||||
}
|
||||
|
||||
fn inv_transform(&self, other: &$t<N>) -> $t<N> {
|
||||
self.inv_translate(other)
|
||||
fn inverse_transform(&self, other: &$t<N>) -> $t<N> {
|
||||
self.inverse_translate(other)
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
macro_rules! vec_as_pnt_impl(
|
||||
macro_rules! vec_as_point_impl(
|
||||
($tv: ident, $t: ident, $($compN: ident),+) => (
|
||||
impl<N> $tv<N> {
|
||||
/// Converts this vector to a point.
|
||||
#[inline]
|
||||
pub fn to_pnt(self) -> $t<N> {
|
||||
pub fn to_point(self) -> $t<N> {
|
||||
$t::new(
|
||||
$(self.$compN),+
|
||||
)
|
||||
|
@ -864,7 +864,7 @@ macro_rules! vec_as_pnt_impl(
|
|||
|
||||
/// Reinterprets this vector as a point.
|
||||
#[inline]
|
||||
pub fn as_pnt(&self) -> &$t<N> {
|
||||
pub fn as_point(&self) -> &$t<N> {
|
||||
unsafe {
|
||||
mem::transmute(self)
|
||||
}
|
||||
|
@ -875,11 +875,11 @@ macro_rules! vec_as_pnt_impl(
|
|||
|
||||
macro_rules! num_float_vec_impl(
|
||||
($t: ident) => (
|
||||
impl<N> NumVec<N> for $t<N>
|
||||
impl<N> NumVector<N> for $t<N>
|
||||
where N: BaseNum {
|
||||
}
|
||||
|
||||
impl<N> FloatVec<N> for $t<N>
|
||||
impl<N> FloatVector<N> for $t<N>
|
||||
where N: BaseFloat + ApproxEq<N> {
|
||||
}
|
||||
)
|
|
@ -7,35 +7,35 @@ use num::{Zero, One};
|
|||
use generic_array::{GenericArray, ArrayLength};
|
||||
use traits::operations::{ApproxEq, Axpy, Mean};
|
||||
use traits::geometry::{Dot, Norm};
|
||||
use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat, BaseNum, Cast, Dim};
|
||||
use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat, BaseNum, Cast, Dimension};
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
/// A static array of arbitrary dimension.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, Debug)] // FIXME: Hash, RustcEncodable, RustcDecodable
|
||||
pub struct VecN<N, D: ArrayLength<N>> {
|
||||
pub struct VectorN<N, D: ArrayLength<N>> {
|
||||
/// The underlying data of the vector.
|
||||
pub at: GenericArray<N, D>
|
||||
}
|
||||
|
||||
unsafe impl<N: Send, D: ArrayLength<N>> Send for VecN<N, D> {
|
||||
unsafe impl<N: Send, D: ArrayLength<N>> Send for VectorN<N, D> {
|
||||
}
|
||||
|
||||
impl<N: Clone, D: ArrayLength<N>> Clone for VecN<N, D> {
|
||||
fn clone(&self) -> VecN<N, D> {
|
||||
VecN::new(self.at.clone())
|
||||
impl<N: Clone, D: ArrayLength<N>> Clone for VectorN<N, D> {
|
||||
fn clone(&self) -> VectorN<N, D> {
|
||||
VectorN::new(self.at.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy, D: ArrayLength<N>> Copy for VecN<N, D>
|
||||
impl<N: Copy, D: ArrayLength<N>> Copy for VectorN<N, D>
|
||||
where D::ArrayType: Copy { }
|
||||
|
||||
impl<N, D: ArrayLength<N>> VecN<N, D> {
|
||||
impl<N, D: ArrayLength<N>> VectorN<N, D> {
|
||||
/// Creates a new vector from a given arbirtarily-sized array.
|
||||
#[inline]
|
||||
pub fn new(components: GenericArray<N, D>) -> VecN<N, D> {
|
||||
VecN {
|
||||
pub fn new(components: GenericArray<N, D>) -> VectorN<N, D> {
|
||||
VectorN {
|
||||
at: components
|
||||
}
|
||||
}
|
||||
|
@ -47,31 +47,31 @@ impl<N, D: ArrayLength<N>> VecN<N, D> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N, D: ArrayLength<N>> Dim for VecN<N, D> {
|
||||
fn dim(_unused: Option<Self>) -> usize {
|
||||
impl<N, D: ArrayLength<N>> Dimension for VectorN<N, D> {
|
||||
fn dimension(_unused: Option<Self>) -> usize {
|
||||
D::to_usize()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy, D: ArrayLength<N>> FromIterator<N> for VecN<N, D> {
|
||||
impl<N: Copy, D: ArrayLength<N>> FromIterator<N> for VectorN<N, D> {
|
||||
#[inline]
|
||||
fn from_iter<I: IntoIterator<Item = N>>(param: I) -> VecN<N, D> {
|
||||
let mut res: VecN<N, D> = unsafe { mem::uninitialized() };
|
||||
fn from_iter<I: IntoIterator<Item = N>>(param: I) -> VectorN<N, D> {
|
||||
let mut res: VectorN<N, D> = unsafe { mem::uninitialized() };
|
||||
|
||||
let mut it = param.into_iter();
|
||||
|
||||
for e in res.iter_mut() {
|
||||
*e = it.next().expect("Not enough data into the provided iterator to initialize this `VecN`.");
|
||||
*e = it.next().expect("Not enough data into the provided iterator to initialize this `VectorN`.");
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Rand + Zero, D: ArrayLength<N>> Rand for VecN<N, D> {
|
||||
impl<N: Rand + Zero, D: ArrayLength<N>> Rand for VectorN<N, D> {
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> VecN<N, D> {
|
||||
let mut res: VecN<N, D> = unsafe { mem::uninitialized() };
|
||||
fn rand<R: Rng>(rng: &mut R) -> VectorN<N, D> {
|
||||
let mut res: VectorN<N, D> = unsafe { mem::uninitialized() };
|
||||
|
||||
for e in res.iter_mut() {
|
||||
*e = Rand::rand(rng)
|
||||
|
@ -81,10 +81,10 @@ impl<N: Rand + Zero, D: ArrayLength<N>> Rand for VecN<N, D> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + One + Zero, D: ArrayLength<N>> One for VecN<N, D> {
|
||||
impl<N: Copy + One + Zero, D: ArrayLength<N>> One for VectorN<N, D> {
|
||||
#[inline]
|
||||
fn one() -> VecN<N, D> {
|
||||
let mut res: VecN<N, D> = unsafe { mem::uninitialized() };
|
||||
fn one() -> VectorN<N, D> {
|
||||
let mut res: VectorN<N, D> = unsafe { mem::uninitialized() };
|
||||
|
||||
for e in res.iter_mut() {
|
||||
*e = ::one()
|
||||
|
@ -94,10 +94,10 @@ impl<N: Copy + One + Zero, D: ArrayLength<N>> One for VecN<N, D> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Copy + Zero, D: ArrayLength<N>> Zero for VecN<N, D> {
|
||||
impl<N: Copy + Zero, D: ArrayLength<N>> Zero for VectorN<N, D> {
|
||||
#[inline]
|
||||
fn zero() -> VecN<N, D> {
|
||||
let mut res: VecN<N, D> = unsafe { mem::uninitialized() };
|
||||
fn zero() -> VectorN<N, D> {
|
||||
let mut res: VectorN<N, D> = unsafe { mem::uninitialized() };
|
||||
|
||||
for e in res.iter_mut() {
|
||||
*e = ::zero()
|
||||
|
@ -113,11 +113,11 @@ impl<N: Copy + Zero, D: ArrayLength<N>> Zero for VecN<N, D> {
|
|||
}
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
impl<N: Arbitrary + Zero + Copy, D: 'static + ArrayLength<N>> Arbitrary for VecN<N, D> {
|
||||
impl<N: Arbitrary + Zero + Copy, D: 'static + ArrayLength<N>> Arbitrary for VectorN<N, D> {
|
||||
#[inline]
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> VecN<N, D> {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> VectorN<N, D> {
|
||||
(0 .. D::to_usize()).map(|_| Arbitrary::arbitrary(g)).collect()
|
||||
}
|
||||
}
|
||||
|
||||
vecn_dvec_common_impl!(VecN, D);
|
||||
vecn_dvec_common_impl!(VectorN, D);
|
|
@ -497,7 +497,7 @@ macro_rules! vecn_dvec_common_impl(
|
|||
*/
|
||||
impl<N: BaseFloat $(, $param : ArrayLength<N>)*> Norm<N> for $vecn<N $(, $param)*> {
|
||||
#[inline]
|
||||
fn sqnorm(&self) -> N {
|
||||
fn norm_squared(&self) -> N {
|
||||
Dot::dot(self, self)
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
//! Traits of operations having a well-known or explicit geometric meaning.
|
||||
|
||||
use std::ops::{Neg, Mul};
|
||||
use traits::structure::{BaseFloat, SquareMat};
|
||||
use traits::structure::{BaseFloat, SquareMatrix};
|
||||
|
||||
/// Trait of object which represent a translation, and to wich new translation
|
||||
/// can be appended.
|
||||
|
@ -11,7 +11,7 @@ pub trait Translation<V> {
|
|||
fn translation(&self) -> V;
|
||||
|
||||
/// Gets the inverse translation associated with this object.
|
||||
fn inv_translation(&self) -> V;
|
||||
fn inverse_translation(&self) -> V;
|
||||
|
||||
/// Appends a translation to this object.
|
||||
fn append_translation_mut(&mut self, &V);
|
||||
|
@ -36,7 +36,7 @@ pub trait Translate<V> {
|
|||
fn translate(&self, &V) -> V;
|
||||
|
||||
/// Apply an inverse translation to an object.
|
||||
fn inv_translate(&self, &V) -> V;
|
||||
fn inverse_translate(&self, &V) -> V;
|
||||
}
|
||||
|
||||
/// Trait of object which can represent a rotation, and to which new rotations can be appended. A
|
||||
|
@ -46,7 +46,7 @@ pub trait Rotation<V> {
|
|||
fn rotation(&self) -> V;
|
||||
|
||||
/// Gets the inverse rotation associated with `self`.
|
||||
fn inv_rotation(&self) -> V;
|
||||
fn inverse_rotation(&self) -> V;
|
||||
|
||||
/// Appends a rotation to this object.
|
||||
fn append_rotation_mut(&mut self, &V);
|
||||
|
@ -88,7 +88,7 @@ pub trait Rotate<V> {
|
|||
fn rotate(&self, v: &V) -> V;
|
||||
|
||||
/// Applies an inverse rotation to `v`.
|
||||
fn inv_rotate(&self, v: &V) -> V;
|
||||
fn inverse_rotate(&self, v: &V) -> V;
|
||||
}
|
||||
|
||||
/// Various composition of rotation and translation.
|
||||
|
@ -159,10 +159,10 @@ impl<LV: Neg<Output = LV> + Copy, AV, M: Rotation<AV> + Translation<LV>> Rotatio
|
|||
/// be implemented by quaternions to convert them to a rotation matrix.
|
||||
pub trait RotationMatrix<N, LV: Mul<Self::Output, Output = LV>, AV> : Rotation<AV> {
|
||||
/// The output rotation matrix type.
|
||||
type Output: SquareMat<N, LV> + Rotation<AV>;
|
||||
type Output: SquareMatrix<N, LV> + Rotation<AV>;
|
||||
|
||||
/// Gets the rotation matrix represented by `self`.
|
||||
fn to_rot_mat(&self) -> Self::Output;
|
||||
fn to_rotation_matrix(&self) -> Self::Output;
|
||||
}
|
||||
|
||||
/// Composition of a rotation and an absolute value.
|
||||
|
@ -187,7 +187,7 @@ pub trait Transformation<M> {
|
|||
fn transformation(&self) -> M;
|
||||
|
||||
/// Gets the inverse transformation of `self`.
|
||||
fn inv_transformation(&self) -> M;
|
||||
fn inverse_transformation(&self) -> M;
|
||||
|
||||
/// Appends a transformation to this object.
|
||||
fn append_transformation_mut(&mut self, &M);
|
||||
|
@ -213,7 +213,7 @@ pub trait Transform<V> {
|
|||
fn transform(&self, &V) -> V;
|
||||
|
||||
/// Applies an inverse transformation to `v`.
|
||||
fn inv_transform(&self, &V) -> V;
|
||||
fn inverse_transform(&self, &V) -> V;
|
||||
}
|
||||
|
||||
/// Traits of objects having a dot product.
|
||||
|
@ -228,13 +228,13 @@ pub trait Norm<N: BaseFloat> {
|
|||
/// Computes the norm of `self`.
|
||||
#[inline]
|
||||
fn norm(&self) -> N {
|
||||
self.sqnorm().sqrt()
|
||||
self.norm_squared().sqrt()
|
||||
}
|
||||
|
||||
/// Computes the squared norm of `self`.
|
||||
///
|
||||
/// This is usually faster than computing the norm itself.
|
||||
fn sqnorm(&self) -> N;
|
||||
fn norm_squared(&self) -> N;
|
||||
|
||||
/// Gets the normalized version of a copy of `v`.
|
||||
fn normalize(&self) -> Self;
|
||||
|
@ -288,10 +288,10 @@ pub trait UniformSphereSample : Sized {
|
|||
}
|
||||
|
||||
/// The zero element of a vector space, seen as an element of its embeding affine space.
|
||||
// XXX: once associated types are suported, move this to the `AnyPnt` trait.
|
||||
pub trait Orig {
|
||||
// XXX: once associated types are suported, move this to the `AnyPoint` trait.
|
||||
pub trait Origin {
|
||||
/// The trivial origin.
|
||||
fn orig() -> Self;
|
||||
fn origin() -> Self;
|
||||
/// Returns true if this points is exactly the trivial origin.
|
||||
fn is_orig(&self) -> bool;
|
||||
fn is_origin(&self) -> bool;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
use num::{Float, Signed};
|
||||
use std::ops::Mul;
|
||||
use std::cmp::Ordering;
|
||||
use traits::structure::SquareMat;
|
||||
use traits::structure::SquareMatrix;
|
||||
|
||||
/// Result of a partial ordering.
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
|
||||
pub enum POrdering {
|
||||
pub enum PartialOrdering {
|
||||
/// Result of a strict comparison.
|
||||
PartialLess,
|
||||
/// Equality relationship.
|
||||
|
@ -18,61 +18,61 @@ pub enum POrdering {
|
|||
NotComparable
|
||||
}
|
||||
|
||||
impl POrdering {
|
||||
impl PartialOrdering {
|
||||
/// Returns `true` if `self` is equal to `Equal`.
|
||||
pub fn is_eq(&self) -> bool {
|
||||
*self == POrdering::PartialEqual
|
||||
*self == PartialOrdering::PartialEqual
|
||||
}
|
||||
|
||||
/// Returns `true` if `self` is equal to `Less`.
|
||||
pub fn is_lt(&self) -> bool {
|
||||
*self == POrdering::PartialLess
|
||||
*self == PartialOrdering::PartialLess
|
||||
}
|
||||
|
||||
/// Returns `true` if `self` is equal to `Less` or `Equal`.
|
||||
pub fn is_le(&self) -> bool {
|
||||
*self == POrdering::PartialLess || *self == POrdering::PartialEqual
|
||||
*self == PartialOrdering::PartialLess || *self == PartialOrdering::PartialEqual
|
||||
}
|
||||
|
||||
/// Returns `true` if `self` is equal to `Greater`.
|
||||
pub fn is_gt(&self) -> bool {
|
||||
*self == POrdering::PartialGreater
|
||||
*self == PartialOrdering::PartialGreater
|
||||
}
|
||||
|
||||
/// Returns `true` if `self` is equal to `Greater` or `Equal`.
|
||||
pub fn is_ge(&self) -> bool {
|
||||
*self == POrdering::PartialGreater || *self == POrdering::PartialEqual
|
||||
*self == PartialOrdering::PartialGreater || *self == PartialOrdering::PartialEqual
|
||||
}
|
||||
|
||||
/// Returns `true` if `self` is equal to `NotComparable`.
|
||||
pub fn is_not_comparable(&self) -> bool {
|
||||
*self == POrdering::NotComparable
|
||||
*self == PartialOrdering::NotComparable
|
||||
}
|
||||
|
||||
/// Creates a `POrdering` from an `Ordering`.
|
||||
pub fn from_ordering(ord: Ordering) -> POrdering {
|
||||
/// Creates a `PartialOrdering` from an `Ordering`.
|
||||
pub fn from_ordering(ord: Ordering) -> PartialOrdering {
|
||||
match ord {
|
||||
Ordering::Less => POrdering::PartialLess,
|
||||
Ordering::Equal => POrdering::PartialEqual,
|
||||
Ordering::Greater => POrdering::PartialGreater
|
||||
Ordering::Less => PartialOrdering::PartialLess,
|
||||
Ordering::Equal => PartialOrdering::PartialEqual,
|
||||
Ordering::Greater => PartialOrdering::PartialGreater
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts this `POrdering` to an `Ordering`.
|
||||
/// Converts this `PartialOrdering` to an `Ordering`.
|
||||
///
|
||||
/// Returns `None` if `self` is `NotComparable`.
|
||||
pub fn to_ordering(self) -> Option<Ordering> {
|
||||
match self {
|
||||
POrdering::PartialLess => Some(Ordering::Less),
|
||||
POrdering::PartialEqual => Some(Ordering::Equal),
|
||||
POrdering::PartialGreater => Some(Ordering::Greater),
|
||||
POrdering::NotComparable => None
|
||||
PartialOrdering::PartialLess => Some(Ordering::Less),
|
||||
PartialOrdering::PartialEqual => Some(Ordering::Equal),
|
||||
PartialOrdering::PartialGreater => Some(Ordering::Greater),
|
||||
PartialOrdering::NotComparable => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pointwise ordering operations.
|
||||
pub trait POrd {
|
||||
pub trait PartialOrder {
|
||||
/// Returns the infimum of this value and another
|
||||
fn inf(&self, other: &Self) -> Self;
|
||||
|
||||
|
@ -80,49 +80,49 @@ pub trait POrd {
|
|||
fn sup(&self, other: &Self) -> Self;
|
||||
|
||||
/// Compare `self` and `other` using a partial ordering relation.
|
||||
fn partial_cmp(&self, other: &Self) -> POrdering;
|
||||
fn partial_cmp(&self, other: &Self) -> PartialOrdering;
|
||||
|
||||
/// Returns `true` iff `self` and `other` are comparable and `self <= other`.
|
||||
#[inline]
|
||||
fn partial_le(&self, other: &Self) -> bool {
|
||||
POrd::partial_cmp(self, other).is_le()
|
||||
PartialOrder::partial_cmp(self, other).is_le()
|
||||
}
|
||||
|
||||
/// Returns `true` iff `self` and `other` are comparable and `self < other`.
|
||||
#[inline]
|
||||
fn partial_lt(&self, other: &Self) -> bool {
|
||||
POrd::partial_cmp(self, other).is_lt()
|
||||
PartialOrder::partial_cmp(self, other).is_lt()
|
||||
}
|
||||
|
||||
/// Returns `true` iff `self` and `other` are comparable and `self >= other`.
|
||||
#[inline]
|
||||
fn partial_ge(&self, other: &Self) -> bool {
|
||||
POrd::partial_cmp(self, other).is_ge()
|
||||
PartialOrder::partial_cmp(self, other).is_ge()
|
||||
}
|
||||
|
||||
/// Returns `true` iff `self` and `other` are comparable and `self > other`.
|
||||
#[inline]
|
||||
fn partial_gt(&self, other: &Self) -> bool {
|
||||
POrd::partial_cmp(self, other).is_gt()
|
||||
PartialOrder::partial_cmp(self, other).is_gt()
|
||||
}
|
||||
|
||||
/// Return the minimum of `self` and `other` if they are comparable.
|
||||
#[inline]
|
||||
fn partial_min<'a>(&'a self, other: &'a Self) -> Option<&'a Self> {
|
||||
match POrd::partial_cmp(self, other) {
|
||||
POrdering::PartialLess | POrdering::PartialEqual => Some(self),
|
||||
POrdering::PartialGreater => Some(other),
|
||||
POrdering::NotComparable => None
|
||||
match PartialOrder::partial_cmp(self, other) {
|
||||
PartialOrdering::PartialLess | PartialOrdering::PartialEqual => Some(self),
|
||||
PartialOrdering::PartialGreater => Some(other),
|
||||
PartialOrdering::NotComparable => None
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the maximum of `self` and `other` if they are comparable.
|
||||
#[inline]
|
||||
fn partial_max<'a>(&'a self, other: &'a Self) -> Option<&'a Self> {
|
||||
match POrd::partial_cmp(self, other) {
|
||||
POrdering::PartialGreater | POrdering::PartialEqual => Some(self),
|
||||
POrdering::PartialLess => Some(other),
|
||||
POrdering::NotComparable => None
|
||||
match PartialOrder::partial_cmp(self, other) {
|
||||
PartialOrdering::PartialGreater | PartialOrdering::PartialEqual => Some(self),
|
||||
PartialOrdering::PartialLess => Some(other),
|
||||
PartialOrdering::NotComparable => None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,18 +276,18 @@ pub trait Absolute<A> {
|
|||
}
|
||||
|
||||
/// Trait of objects having an inverse. Typically used to implement matrix inverse.
|
||||
pub trait Inv: Sized {
|
||||
pub trait Inverse: Sized {
|
||||
/// Returns the inverse of `m`.
|
||||
fn inv(&self) -> Option<Self>;
|
||||
fn inverse(&self) -> Option<Self>;
|
||||
|
||||
/// In-place version of `inverse`.
|
||||
fn inv_mut(&mut self) -> bool;
|
||||
fn inverse_mut(&mut self) -> bool;
|
||||
}
|
||||
|
||||
/// Trait of objects having a determinant. Typically used by square matrices.
|
||||
pub trait Det<N> {
|
||||
pub trait Determinant<N> {
|
||||
/// Returns the determinant of `m`.
|
||||
fn det(&self) -> N;
|
||||
fn determinant(&self) -> N;
|
||||
}
|
||||
|
||||
/// Trait of objects which can be transposed.
|
||||
|
@ -309,19 +309,19 @@ pub trait Outer {
|
|||
}
|
||||
|
||||
/// Trait for computing the covariance of a set of data.
|
||||
pub trait Cov<M> {
|
||||
pub trait Covariance<M> {
|
||||
/// Computes the covariance of the obsevations stored by `m`:
|
||||
///
|
||||
/// * For matrices, observations are stored in its rows.
|
||||
/// * For vectors, observations are stored in its components (thus are 1-dimensional).
|
||||
fn cov(&self) -> M;
|
||||
fn covariance(&self) -> M;
|
||||
|
||||
/// Computes the covariance of the obsevations stored by `m`:
|
||||
///
|
||||
/// * For matrices, observations are stored in its rows.
|
||||
/// * For vectors, observations are stored in its components (thus are 1-dimensional).
|
||||
fn cov_to(&self, out: &mut M) {
|
||||
*out = self.cov()
|
||||
fn covariance_to(&self, out: &mut M) {
|
||||
*out = self.covariance()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -335,7 +335,7 @@ pub trait Mean<N> {
|
|||
}
|
||||
|
||||
/// Trait for computing the eigenvector and eigenvalues of a square matrix usin the QR algorithm.
|
||||
pub trait EigenQR<N, V: Mul<Self, Output = V>>: SquareMat<N, V> {
|
||||
pub trait EigenQR<N, V: Mul<Self, Output = V>>: SquareMatrix<N, V> {
|
||||
/// Computes the eigenvectors and eigenvalues of this matrix.
|
||||
fn eigen_qr(&self, eps: &N, niter: usize) -> (Self, V);
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ use std::ops::{Add, Sub, Mul, Div, Rem,
|
|||
AddAssign, SubAssign, MulAssign, DivAssign, RemAssign,
|
||||
Index, IndexMut, Neg};
|
||||
use num::{Float, Zero, One};
|
||||
use traits::operations::{Axpy, Transpose, Inv, Absolute};
|
||||
use traits::geometry::{Dot, Norm, Orig};
|
||||
use traits::operations::{Axpy, Transpose, Inverse, Absolute};
|
||||
use traits::geometry::{Dot, Norm, Origin};
|
||||
|
||||
/// Basic integral numeric trait.
|
||||
pub trait BaseNum: Copy + Zero + One +
|
||||
|
@ -64,31 +64,31 @@ pub trait Cast<T> {
|
|||
/// Trait of matrices.
|
||||
///
|
||||
/// A matrix has rows and columns and are able to multiply them.
|
||||
pub trait Mat<N, R, C: Mul<Self, Output = R>>: Sized +
|
||||
Row<R> + Col<C> + Mul<R, Output = C> +
|
||||
pub trait Matrix<N, R, C: Mul<Self, Output = R>>: Sized +
|
||||
Row<R> + Column<C> + Mul<R, Output = C> +
|
||||
Index<(usize, usize), Output = N>
|
||||
{ }
|
||||
|
||||
impl<N, M, R, C> Mat<N, R, C> for M
|
||||
where M: Row<R> + Col<C> + Mul<R, Output = C> + Index<(usize, usize), Output = N>,
|
||||
impl<N, M, R, C> Matrix<N, R, C> for M
|
||||
where M: Row<R> + Column<C> + Mul<R, Output = C> + Index<(usize, usize), Output = N>,
|
||||
C: Mul<M, Output = R>,
|
||||
{ }
|
||||
|
||||
/// Trait implemented by square matrices.
|
||||
pub trait SquareMat<N, V: Mul<Self, Output = V>>: Mat<N, V, V> +
|
||||
pub trait SquareMatrix<N, V: Mul<Self, Output = V>>: Matrix<N, V, V> +
|
||||
Mul<Self, Output = Self> +
|
||||
Eye + Transpose + Diag<V> + Inv + Dim + One {
|
||||
Eye + Transpose + Diagonal<V> + Inverse + Dimension + One {
|
||||
}
|
||||
|
||||
impl<N, V, M> SquareMat<N, V> for M
|
||||
where M: Mat<N, V, V> + Mul<M, Output = M> + Eye + Transpose + Diag<V> + Inv + Dim + One,
|
||||
impl<N, V, M> SquareMatrix<N, V> for M
|
||||
where M: Matrix<N, V, V> + Mul<M, Output = M> + Eye + Transpose + Diagonal<V> + Inverse + Dimension + One,
|
||||
V: Mul<M, Output = V> {
|
||||
}
|
||||
|
||||
/// Trait for constructing the identity matrix
|
||||
pub trait Eye {
|
||||
/// Return the identity matrix of specified dimension
|
||||
fn new_identity(dim: usize) -> Self;
|
||||
fn new_identity(dimension: usize) -> Self;
|
||||
}
|
||||
|
||||
/// Trait for constructiong an object repeating a value.
|
||||
|
@ -134,12 +134,12 @@ pub trait Row<R> {
|
|||
}
|
||||
|
||||
/// Trait to access columns of a matrix or vector.
|
||||
pub trait Col<C> {
|
||||
pub trait Column<C> {
|
||||
/// The number of column of this matrix or vector.
|
||||
fn ncols(&self) -> usize;
|
||||
|
||||
/// Reads the `i`-th column of `self`.
|
||||
fn col(&self, i: usize) -> C;
|
||||
fn column(&self, i: usize) -> C;
|
||||
|
||||
/// Writes the `i`-th column of `self`.
|
||||
fn set_col(&mut self, i: usize, C);
|
||||
|
@ -149,7 +149,7 @@ pub trait Col<C> {
|
|||
}
|
||||
|
||||
/// Trait to access part of a column of a matrix
|
||||
pub trait ColSlice<C> {
|
||||
pub trait ColumnSlice<C> {
|
||||
/// Returns a view to a slice of a column of a matrix.
|
||||
fn col_slice(&self, col_id: usize, row_start: usize, row_end: usize) -> C;
|
||||
}
|
||||
|
@ -161,24 +161,24 @@ pub trait RowSlice<R> {
|
|||
}
|
||||
|
||||
/// Trait of objects having a spacial dimension known at compile time.
|
||||
pub trait Dim: Sized {
|
||||
pub trait Dimension: Sized {
|
||||
/// The dimension of the object.
|
||||
fn dim(_unused: Option<Self>) -> usize;
|
||||
fn dimension(_unused: Option<Self>) -> usize;
|
||||
}
|
||||
|
||||
/// Trait to get the diagonal of square matrices.
|
||||
pub trait Diag<V> {
|
||||
pub trait Diagonal<V> {
|
||||
/// Creates a new matrix with the given diagonal.
|
||||
fn from_diag(diag: &V) -> Self;
|
||||
fn from_diag(diagonal: &V) -> Self;
|
||||
|
||||
/// The diagonal of this matrix.
|
||||
fn diag(&self) -> V;
|
||||
fn diagonal(&self) -> V;
|
||||
}
|
||||
|
||||
/// Trait to set the diagonal of square matrices.
|
||||
pub trait DiagMut<V>: Diag<V> {
|
||||
pub trait DiagMut<V>: Diagonal<V> {
|
||||
/// Sets the diagonal of this matrix.
|
||||
fn set_diag(&mut self, diag: &V);
|
||||
fn set_diag(&mut self, diagonal: &V);
|
||||
}
|
||||
|
||||
/// The shape of an indexable object.
|
||||
|
@ -223,10 +223,10 @@ pub trait IterableMut<N> {
|
|||
}
|
||||
|
||||
/*
|
||||
* Vec related traits.
|
||||
* Vector related traits.
|
||||
*/
|
||||
/// Trait grouping most common operations on vectors.
|
||||
pub trait NumVec<N>: Add<Self, Output = Self> + Sub<Self, Output = Self> +
|
||||
pub trait NumVector<N>: Add<Self, Output = Self> + Sub<Self, Output = Self> +
|
||||
Mul<Self, Output = Self> + Div<Self, Output = Self> +
|
||||
|
||||
Add<N, Output = Self> + Sub<N, Output = Self> +
|
||||
|
@ -238,67 +238,67 @@ pub trait NumVec<N>: Add<Self, Output = Self> + Sub<Self, Output = Self> +
|
|||
AddAssign<N> + SubAssign<N> +
|
||||
MulAssign<N> + DivAssign<N> +
|
||||
|
||||
Dim + Index<usize, Output = N> +
|
||||
Dimension + Index<usize, Output = N> +
|
||||
Zero + PartialEq + Dot<N> + Axpy<N> {
|
||||
}
|
||||
|
||||
/// Trait of vector with components implementing the `BaseFloat` trait.
|
||||
pub trait FloatVec<N: BaseFloat>: NumVec<N> + Norm<N> + Neg<Output = Self> + Basis {
|
||||
pub trait FloatVector<N: BaseFloat>: NumVector<N> + Norm<N> + Neg<Output = Self> + Basis {
|
||||
}
|
||||
|
||||
/*
|
||||
* Pnt related traits.
|
||||
* Point related traits.
|
||||
*/
|
||||
/// Trait that relates a point of an affine space to a vector of the associated vector space.
|
||||
pub trait PntAsVec {
|
||||
pub trait PointAsVector {
|
||||
/// The vector type of the vector space associated to this point's affine space.
|
||||
type Vec;
|
||||
type Vector;
|
||||
|
||||
/// Converts this point to its associated vector.
|
||||
fn to_vec(self) -> Self::Vec;
|
||||
fn to_vector(self) -> Self::Vector;
|
||||
|
||||
/// Converts a reference to this point to a reference to its associated vector.
|
||||
fn as_vec<'a>(&'a self) -> &'a Self::Vec;
|
||||
fn as_vector<'a>(&'a self) -> &'a Self::Vector;
|
||||
|
||||
// NOTE: this is used in some places to overcome some limitations untill the trait reform is
|
||||
// done on rustc.
|
||||
/// Sets the coordinates of this point to match those of a given vector.
|
||||
fn set_coords(&mut self, coords: Self::Vec);
|
||||
fn set_coords(&mut self, coords: Self::Vector);
|
||||
}
|
||||
|
||||
/// Trait grouping most common operations on points.
|
||||
// XXX: the vector space element `V` should be an associated type. Though this would prevent V from
|
||||
// having bounds (they are not supported yet). So, for now, we will just use a type parameter.
|
||||
pub trait NumPnt<N>:
|
||||
pub trait NumPoint<N>:
|
||||
Copy +
|
||||
PntAsVec +
|
||||
Dim +
|
||||
Orig +
|
||||
PointAsVector +
|
||||
Dimension +
|
||||
Origin +
|
||||
PartialEq +
|
||||
Axpy<N> +
|
||||
Sub<Self, Output = <Self as PntAsVec>::Vec> +
|
||||
Sub<Self, Output = <Self as PointAsVector>::Vector> +
|
||||
|
||||
Mul<N, Output = Self> + Div<N, Output = Self> +
|
||||
Add<<Self as PntAsVec>::Vec, Output = Self> +
|
||||
Add<<Self as PointAsVector>::Vector, Output = Self> +
|
||||
|
||||
MulAssign<N> + DivAssign<N> +
|
||||
AddAssign<<Self as PntAsVec>::Vec> +
|
||||
AddAssign<<Self as PointAsVector>::Vector> +
|
||||
|
||||
Index<usize, Output = N> { // FIXME: + Sub<V, Self>
|
||||
}
|
||||
|
||||
/// Trait of points with components implementing the `BaseFloat` trait.
|
||||
pub trait FloatPnt<N: BaseFloat>: NumPnt<N> + Sized
|
||||
where <Self as PntAsVec>::Vec: Norm<N> {
|
||||
pub trait FloatPoint<N: BaseFloat>: NumPoint<N> + Sized
|
||||
where <Self as PointAsVector>::Vector: Norm<N> {
|
||||
/// Computes the square distance between two points.
|
||||
#[inline]
|
||||
fn sqdist(&self, other: &Self) -> N {
|
||||
(*self - *other).sqnorm()
|
||||
fn distance_squared(&self, other: &Self) -> N {
|
||||
(*self - *other).norm_squared()
|
||||
}
|
||||
|
||||
/// Computes the distance between two points.
|
||||
#[inline]
|
||||
fn dist(&self, other: &Self) -> N {
|
||||
fn distance(&self, other: &Self) -> N {
|
||||
(*self - *other).norm()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,47 +18,47 @@ macro_rules! trivial_arb_test(
|
|||
)
|
||||
);
|
||||
|
||||
trivial_arb_test!(Vec1<f64>, arb_vec1);
|
||||
trivial_arb_test!(Vec2<f64>, arb_vec2);
|
||||
trivial_arb_test!(Vec3<f64>, arb_vec3);
|
||||
trivial_arb_test!(Vec4<f64>, arb_vec4);
|
||||
trivial_arb_test!(Vec5<f64>, arb_vec5);
|
||||
trivial_arb_test!(Vec6<f64>, arb_vec6);
|
||||
trivial_arb_test!(Vector1<f64>, arb_vec1);
|
||||
trivial_arb_test!(Vector2<f64>, arb_vec2);
|
||||
trivial_arb_test!(Vector3<f64>, arb_vec3);
|
||||
trivial_arb_test!(Vector4<f64>, arb_vec4);
|
||||
trivial_arb_test!(Vector5<f64>, arb_vec5);
|
||||
trivial_arb_test!(Vector6<f64>, arb_vec6);
|
||||
|
||||
trivial_arb_test!(Pnt1<f64>, arb_pnt1);
|
||||
trivial_arb_test!(Pnt2<f64>, arb_pnt2);
|
||||
trivial_arb_test!(Pnt3<f64>, arb_pnt3);
|
||||
trivial_arb_test!(Pnt4<f64>, arb_pnt4);
|
||||
trivial_arb_test!(Pnt5<f64>, arb_pnt5);
|
||||
trivial_arb_test!(Pnt6<f64>, arb_pnt6);
|
||||
trivial_arb_test!(Point1<f64>, arb_point1);
|
||||
trivial_arb_test!(Point2<f64>, arb_point2);
|
||||
trivial_arb_test!(Point3<f64>, arb_point3);
|
||||
trivial_arb_test!(Point4<f64>, arb_point4);
|
||||
trivial_arb_test!(Point5<f64>, arb_point5);
|
||||
trivial_arb_test!(Point6<f64>, arb_point6);
|
||||
|
||||
trivial_arb_test!(Mat1<f64>, arb_mat1);
|
||||
trivial_arb_test!(Mat2<f64>, arb_mat2);
|
||||
trivial_arb_test!(Mat3<f64>, arb_mat3);
|
||||
trivial_arb_test!(Mat4<f64>, arb_mat4);
|
||||
trivial_arb_test!(Mat5<f64>, arb_mat5);
|
||||
trivial_arb_test!(Mat6<f64>, arb_mat6);
|
||||
trivial_arb_test!(Matrix1<f64>, arb_mat1);
|
||||
trivial_arb_test!(Matrix2<f64>, arb_mat2);
|
||||
trivial_arb_test!(Matrix3<f64>, arb_mat3);
|
||||
trivial_arb_test!(Matrix4<f64>, arb_mat4);
|
||||
trivial_arb_test!(Matrix5<f64>, arb_mat5);
|
||||
trivial_arb_test!(Matrix6<f64>, arb_mat6);
|
||||
|
||||
trivial_arb_test!(DVec1<f64>, arb_dvec1);
|
||||
trivial_arb_test!(DVec2<f64>, arb_dvec2);
|
||||
trivial_arb_test!(DVec3<f64>, arb_dvec3);
|
||||
trivial_arb_test!(DVec4<f64>, arb_dvec4);
|
||||
trivial_arb_test!(DVec5<f64>, arb_dvec5);
|
||||
trivial_arb_test!(DVec6<f64>, arb_dvec6);
|
||||
trivial_arb_test!(DVector1<f64>, arb_dvec1);
|
||||
trivial_arb_test!(DVector2<f64>, arb_dvec2);
|
||||
trivial_arb_test!(DVector3<f64>, arb_dvec3);
|
||||
trivial_arb_test!(DVector4<f64>, arb_dvec4);
|
||||
trivial_arb_test!(DVector5<f64>, arb_dvec5);
|
||||
trivial_arb_test!(DVector6<f64>, arb_dvec6);
|
||||
|
||||
trivial_arb_test!(DMat<f64>, arb_dmat);
|
||||
trivial_arb_test!(DVec<f64>, arb_dvec);
|
||||
trivial_arb_test!(DMatrix<f64>, arb_dmatrix);
|
||||
trivial_arb_test!(DVector<f64>, arb_dvector);
|
||||
|
||||
trivial_arb_test!(Quat<f64>, arb_quat);
|
||||
trivial_arb_test!(UnitQuat<f64>, arb_unit_quat);
|
||||
trivial_arb_test!(Quaternion<f64>, arb_quaternion);
|
||||
trivial_arb_test!(UnitQuaternion<f64>, arb_unit_quaternion);
|
||||
|
||||
trivial_arb_test!(Iso2<f64>, arb_iso2);
|
||||
trivial_arb_test!(Iso3<f64>, arb_iso3);
|
||||
trivial_arb_test!(Isometry2<f64>, arb_iso2);
|
||||
trivial_arb_test!(Isometry3<f64>, arb_iso3);
|
||||
|
||||
trivial_arb_test!(Rot2<f64>, arb_rot2);
|
||||
trivial_arb_test!(Rot3<f64>, arb_rot3);
|
||||
trivial_arb_test!(Rotation2<f64>, arb_rot2);
|
||||
trivial_arb_test!(Rotation3<f64>, arb_rot3);
|
||||
|
||||
trivial_arb_test!(Ortho3<f64>, arb_ortho3);
|
||||
trivial_arb_test!(OrthoMat3<f64>, arb_ortho_mat3);
|
||||
trivial_arb_test!(Persp3<f64>, arb_persp3);
|
||||
trivial_arb_test!(PerspMat3<f64>, arb_persp_mat3);
|
||||
trivial_arb_test!(Orthographic3<f64>, arb_ortho3);
|
||||
trivial_arb_test!(OrthographicMatrix3<f64>, arb_ortho_mat3);
|
||||
trivial_arb_test!(Perspective3<f64>, arb_persp3);
|
||||
trivial_arb_test!(PerspectiveMatrix3<f64>, arb_perspective_mat3);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
358
tests/mat.rs
358
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<f64>);
|
||||
test_transpose_mat_impl!(Matrix1<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transpose_mat2() {
|
||||
test_transpose_mat_impl!(Mat2<f64>);
|
||||
test_transpose_mat_impl!(Matrix2<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transpose_mat3() {
|
||||
test_transpose_mat_impl!(Mat3<f64>);
|
||||
test_transpose_mat_impl!(Matrix3<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transpose_mat4() {
|
||||
test_transpose_mat_impl!(Mat4<f64>);
|
||||
test_transpose_mat_impl!(Matrix4<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transpose_mat5() {
|
||||
test_transpose_mat_impl!(Mat5<f64>);
|
||||
test_transpose_mat_impl!(Matrix5<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transpose_mat6() {
|
||||
test_transpose_mat_impl!(Mat6<f64>);
|
||||
test_transpose_mat_impl!(Matrix6<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_mat1() {
|
||||
test_inv_mat_impl!(Mat1<f64>);
|
||||
fn test_inverse_mat1() {
|
||||
test_inverse_mat_impl!(Matrix1<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_mat2() {
|
||||
test_inv_mat_impl!(Mat2<f64>);
|
||||
fn test_inverse_mat2() {
|
||||
test_inverse_mat_impl!(Matrix2<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_mat3() {
|
||||
test_inv_mat_impl!(Mat3<f64>);
|
||||
fn test_inverse_mat3() {
|
||||
test_inverse_mat_impl!(Matrix3<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_mat4() {
|
||||
test_inv_mat_impl!(Mat4<f64>);
|
||||
fn test_inverse_mat4() {
|
||||
test_inverse_mat_impl!(Matrix4<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_mat5() {
|
||||
test_inv_mat_impl!(Mat5<f64>);
|
||||
fn test_inverse_mat5() {
|
||||
test_inverse_mat_impl!(Matrix5<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_mat6() {
|
||||
test_inv_mat_impl!(Mat6<f64>);
|
||||
fn test_inverse_mat6() {
|
||||
test_inverse_mat_impl!(Matrix6<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_rot2() {
|
||||
test_inv_mat_impl!(Rot2<f64>);
|
||||
fn test_inverse_rot2() {
|
||||
test_inverse_mat_impl!(Rotation2<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_rot3() {
|
||||
test_inv_mat_impl!(Rot3<f64>);
|
||||
fn test_inverse_rot3() {
|
||||
test_inverse_mat_impl!(Rotation3<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_iso2() {
|
||||
test_inv_mat_impl!(Iso2<f64>);
|
||||
fn test_inverse_iso2() {
|
||||
test_inverse_mat_impl!(Isometry2<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_iso3() {
|
||||
test_inv_mat_impl!(Iso3<f64>);
|
||||
fn test_inverse_iso3() {
|
||||
test_inverse_mat_impl!(Isometry3<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_sim2() {
|
||||
test_inv_mat_impl!(Sim2<f64>);
|
||||
fn test_inverse_sim2() {
|
||||
test_inverse_mat_impl!(Similarity2<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_sim3() {
|
||||
test_inv_mat_impl!(Sim3<f64>);
|
||||
fn test_inverse_sim3() {
|
||||
test_inverse_mat_impl!(Similarity3<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_index_mat2() {
|
||||
let mat: Mat2<f64> = random();
|
||||
let matrix: Matrix2<f64> = random();
|
||||
|
||||
assert!(mat[(0, 1)] == na::transpose(&mat)[(1, 0)]);
|
||||
assert!(matrix[(0, 1)] == na::transpose(&matrix)[(1, 0)]);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_mean_dmat() {
|
||||
let mat = DMat::from_row_vec(
|
||||
fn test_mean_dmatrix() {
|
||||
let matrix = DMatrix::from_row_vector(
|
||||
3,
|
||||
3,
|
||||
&[
|
||||
|
@ -234,12 +234,12 @@ fn test_mean_dmat() {
|
|||
]
|
||||
);
|
||||
|
||||
assert!(na::approx_eq(&na::mean(&mat), &DVec::from_slice(3, &[4.0f64, 5.0, 6.0])));
|
||||
assert!(na::approx_eq(&na::mean(&matrix), &DVector::from_slice(3, &[4.0f64, 5.0, 6.0])));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cov_dmat() {
|
||||
let mat = DMat::from_row_vec(
|
||||
fn test_covariance_dmatrix() {
|
||||
let matrix = DMatrix::from_row_vector(
|
||||
5,
|
||||
3,
|
||||
&[
|
||||
|
@ -251,7 +251,7 @@ fn test_cov_dmat() {
|
|||
]
|
||||
);
|
||||
|
||||
let expected = DMat::from_row_vec(
|
||||
let expected = DMatrix::from_row_vector(
|
||||
3,
|
||||
3,
|
||||
&[
|
||||
|
@ -261,12 +261,12 @@ fn test_cov_dmat() {
|
|||
]
|
||||
);
|
||||
|
||||
assert!(na::approx_eq(&na::cov(&mat), &expected));
|
||||
assert!(na::approx_eq(&na::covariance(&matrix), &expected));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transpose_dmat() {
|
||||
let mat = DMat::from_row_vec(
|
||||
fn test_transpose_dmatrix() {
|
||||
let matrix = DMatrix::from_row_vector(
|
||||
8,
|
||||
4,
|
||||
&[
|
||||
|
@ -281,12 +281,12 @@ fn test_transpose_dmat() {
|
|||
]
|
||||
);
|
||||
|
||||
assert!(na::transpose(&na::transpose(&mat)) == mat);
|
||||
assert!(na::transpose(&na::transpose(&matrix)) == matrix);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_row_dmat() {
|
||||
let mat = DMat::from_row_vec(
|
||||
fn test_row_dmatrix() {
|
||||
let matrix = DMatrix::from_row_vector(
|
||||
8,
|
||||
4,
|
||||
&[
|
||||
|
@ -301,19 +301,19 @@ fn test_row_dmat() {
|
|||
]
|
||||
);
|
||||
|
||||
assert_eq!(&DVec::from_slice(4, &[1u32, 2, 3, 4]), &mat.row(0));
|
||||
assert_eq!(&DVec::from_slice(4, &[5u32, 6, 7, 8]), &mat.row(1));
|
||||
assert_eq!(&DVec::from_slice(4, &[9u32, 10, 11, 12]), &mat.row(2));
|
||||
assert_eq!(&DVec::from_slice(4, &[13u32, 14, 15, 16]), &mat.row(3));
|
||||
assert_eq!(&DVec::from_slice(4, &[17u32, 18, 19, 20]), &mat.row(4));
|
||||
assert_eq!(&DVec::from_slice(4, &[21u32, 22, 23, 24]), &mat.row(5));
|
||||
assert_eq!(&DVec::from_slice(4, &[25u32, 26, 27, 28]), &mat.row(6));
|
||||
assert_eq!(&DVec::from_slice(4, &[29u32, 30, 31, 32]), &mat.row(7));
|
||||
assert_eq!(&DVector::from_slice(4, &[1u32, 2, 3, 4]), &matrix.row(0));
|
||||
assert_eq!(&DVector::from_slice(4, &[5u32, 6, 7, 8]), &matrix.row(1));
|
||||
assert_eq!(&DVector::from_slice(4, &[9u32, 10, 11, 12]), &matrix.row(2));
|
||||
assert_eq!(&DVector::from_slice(4, &[13u32, 14, 15, 16]), &matrix.row(3));
|
||||
assert_eq!(&DVector::from_slice(4, &[17u32, 18, 19, 20]), &matrix.row(4));
|
||||
assert_eq!(&DVector::from_slice(4, &[21u32, 22, 23, 24]), &matrix.row(5));
|
||||
assert_eq!(&DVector::from_slice(4, &[25u32, 26, 27, 28]), &matrix.row(6));
|
||||
assert_eq!(&DVector::from_slice(4, &[29u32, 30, 31, 32]), &matrix.row(7));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_row_slice_dmat() {
|
||||
let mat = DMat::from_row_vec(
|
||||
fn test_row_slice_dmatrix() {
|
||||
let matrix = DMatrix::from_row_vector(
|
||||
5,
|
||||
4,
|
||||
&[
|
||||
|
@ -325,15 +325,15 @@ fn test_row_slice_dmat() {
|
|||
]
|
||||
);
|
||||
|
||||
assert_eq!(&DVec::from_slice(4, &[1u32, 2, 3, 4]), &mat.row_slice(0, 0, 4));
|
||||
assert_eq!(&DVec::from_slice(2, &[1u32, 2]), &mat.row_slice(0, 0, 2));
|
||||
assert_eq!(&DVec::from_slice(2, &[10u32, 11]), &mat.row_slice(2, 1, 3));
|
||||
assert_eq!(&DVec::from_slice(2, &[19u32, 20]), &mat.row_slice(4, 2, 4));
|
||||
assert_eq!(&DVector::from_slice(4, &[1u32, 2, 3, 4]), &matrix.row_slice(0, 0, 4));
|
||||
assert_eq!(&DVector::from_slice(2, &[1u32, 2]), &matrix.row_slice(0, 0, 2));
|
||||
assert_eq!(&DVector::from_slice(2, &[10u32, 11]), &matrix.row_slice(2, 1, 3));
|
||||
assert_eq!(&DVector::from_slice(2, &[19u32, 20]), &matrix.row_slice(4, 2, 4));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_col_dmat() {
|
||||
let mat = DMat::from_row_vec(
|
||||
fn test_col_dmatrix() {
|
||||
let matrix = DMatrix::from_row_vector(
|
||||
8,
|
||||
4,
|
||||
&[
|
||||
|
@ -348,15 +348,15 @@ fn test_col_dmat() {
|
|||
]
|
||||
);
|
||||
|
||||
assert_eq!(&DVec::from_slice(8, &[1u32, 5, 9, 13, 17, 21, 25, 29]), &mat.col(0));
|
||||
assert_eq!(&DVec::from_slice(8, &[2u32, 6, 10, 14, 18, 22, 26, 30]), &mat.col(1));
|
||||
assert_eq!(&DVec::from_slice(8, &[3u32, 7, 11, 15, 19, 23, 27, 31]), &mat.col(2));
|
||||
assert_eq!(&DVec::from_slice(8, &[4u32, 8, 12, 16, 20, 24, 28, 32]), &mat.col(3));
|
||||
assert_eq!(&DVector::from_slice(8, &[1u32, 5, 9, 13, 17, 21, 25, 29]), &matrix.column(0));
|
||||
assert_eq!(&DVector::from_slice(8, &[2u32, 6, 10, 14, 18, 22, 26, 30]), &matrix.column(1));
|
||||
assert_eq!(&DVector::from_slice(8, &[3u32, 7, 11, 15, 19, 23, 27, 31]), &matrix.column(2));
|
||||
assert_eq!(&DVector::from_slice(8, &[4u32, 8, 12, 16, 20, 24, 28, 32]), &matrix.column(3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_col_slice_dmat() {
|
||||
let mat = DMat::from_row_vec(
|
||||
fn test_col_slice_dmatrix() {
|
||||
let matrix = DMatrix::from_row_vector(
|
||||
8,
|
||||
4,
|
||||
&[
|
||||
|
@ -371,15 +371,15 @@ fn test_col_slice_dmat() {
|
|||
]
|
||||
);
|
||||
|
||||
assert_eq!(&DVec::from_slice(8, &[1u32, 5, 9, 13, 17, 21, 25, 29]), &mat.col_slice(0, 0, 8));
|
||||
assert_eq!(&DVec::from_slice(3, &[1u32, 5, 9]), &mat.col_slice(0, 0, 3));
|
||||
assert_eq!(&DVec::from_slice(5, &[11u32, 15, 19, 23, 27]), &mat.col_slice(2, 2, 7));
|
||||
assert_eq!(&DVec::from_slice(2, &[28u32, 32]), &mat.col_slice(3, 6, 8));
|
||||
assert_eq!(&DVector::from_slice(8, &[1u32, 5, 9, 13, 17, 21, 25, 29]), &matrix.col_slice(0, 0, 8));
|
||||
assert_eq!(&DVector::from_slice(3, &[1u32, 5, 9]), &matrix.col_slice(0, 0, 3));
|
||||
assert_eq!(&DVector::from_slice(5, &[11u32, 15, 19, 23, 27]), &matrix.col_slice(2, 2, 7));
|
||||
assert_eq!(&DVector::from_slice(2, &[28u32, 32]), &matrix.col_slice(3, 6, 8));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dmat_from_vec() {
|
||||
let mat1 = DMat::from_row_vec(
|
||||
fn test_dmat_from_vector() {
|
||||
let mat1 = DMatrix::from_row_vector(
|
||||
8,
|
||||
4,
|
||||
&[
|
||||
|
@ -394,7 +394,7 @@ fn test_dmat_from_vec() {
|
|||
]
|
||||
);
|
||||
|
||||
let mat2 = DMat::from_col_vec(
|
||||
let mat2 = DMatrix::from_col_vector(
|
||||
8,
|
||||
4,
|
||||
&[
|
||||
|
@ -412,7 +412,7 @@ fn test_dmat_from_vec() {
|
|||
|
||||
#[test]
|
||||
fn test_dmat_addition() {
|
||||
let mat1 = DMat::from_row_vec(
|
||||
let mat1 = DMatrix::from_row_vector(
|
||||
2,
|
||||
2,
|
||||
&[
|
||||
|
@ -421,7 +421,7 @@ fn test_dmat_addition() {
|
|||
]
|
||||
);
|
||||
|
||||
let mat2 = DMat::from_row_vec(
|
||||
let mat2 = DMatrix::from_row_vector(
|
||||
2,
|
||||
2,
|
||||
&[
|
||||
|
@ -430,7 +430,7 @@ fn test_dmat_addition() {
|
|||
]
|
||||
);
|
||||
|
||||
let res = DMat::from_row_vec(
|
||||
let res = DMatrix::from_row_vector(
|
||||
2,
|
||||
2,
|
||||
&[
|
||||
|
@ -444,7 +444,7 @@ fn test_dmat_addition() {
|
|||
|
||||
#[test]
|
||||
fn test_dmat_multiplication() {
|
||||
let mat1 = DMat::from_row_vec(
|
||||
let mat1 = DMatrix::from_row_vector(
|
||||
2,
|
||||
2,
|
||||
&[
|
||||
|
@ -453,7 +453,7 @@ fn test_dmat_multiplication() {
|
|||
]
|
||||
);
|
||||
|
||||
let mat2 = DMat::from_row_vec(
|
||||
let mat2 = DMatrix::from_row_vector(
|
||||
2,
|
||||
2,
|
||||
&[
|
||||
|
@ -462,7 +462,7 @@ fn test_dmat_multiplication() {
|
|||
]
|
||||
);
|
||||
|
||||
let res = DMat::from_row_vec(
|
||||
let res = DMatrix::from_row_vector(
|
||||
2,
|
||||
2,
|
||||
&[
|
||||
|
@ -477,7 +477,7 @@ fn test_dmat_multiplication() {
|
|||
// Tests multiplication of rectangular (non-square) matrices.
|
||||
#[test]
|
||||
fn test_dmat_multiplication_rect() {
|
||||
let mat1 = DMat::from_row_vec(
|
||||
let mat1 = DMatrix::from_row_vector(
|
||||
1,
|
||||
2,
|
||||
&[
|
||||
|
@ -485,7 +485,7 @@ fn test_dmat_multiplication_rect() {
|
|||
]
|
||||
);
|
||||
|
||||
let mat2 = DMat::from_row_vec(
|
||||
let mat2 = DMatrix::from_row_vector(
|
||||
2,
|
||||
3,
|
||||
&[
|
||||
|
@ -494,7 +494,7 @@ fn test_dmat_multiplication_rect() {
|
|||
]
|
||||
);
|
||||
|
||||
let res = DMat::from_row_vec(
|
||||
let res = DMatrix::from_row_vector(
|
||||
1,
|
||||
3,
|
||||
&[
|
||||
|
@ -510,7 +510,7 @@ fn test_dmat_multiplication_rect() {
|
|||
|
||||
#[test]
|
||||
fn test_dmat_subtraction() {
|
||||
let mat1 = DMat::from_row_vec(
|
||||
let mat1 = DMatrix::from_row_vector(
|
||||
2,
|
||||
2,
|
||||
&[
|
||||
|
@ -519,7 +519,7 @@ fn test_dmat_subtraction() {
|
|||
]
|
||||
);
|
||||
|
||||
let mat2 = DMat::from_row_vec(
|
||||
let mat2 = DMatrix::from_row_vector(
|
||||
2,
|
||||
2,
|
||||
&[
|
||||
|
@ -528,7 +528,7 @@ fn test_dmat_subtraction() {
|
|||
]
|
||||
);
|
||||
|
||||
let res = DMat::from_row_vec(
|
||||
let res = DMatrix::from_row_vector(
|
||||
2,
|
||||
2,
|
||||
&[
|
||||
|
@ -542,7 +542,7 @@ fn test_dmat_subtraction() {
|
|||
|
||||
#[test]
|
||||
fn test_dmat_col() {
|
||||
let mat = DMat::from_row_vec(
|
||||
let matrix = DMatrix::from_row_vector(
|
||||
3,
|
||||
3,
|
||||
&[
|
||||
|
@ -552,12 +552,12 @@ fn test_dmat_col() {
|
|||
]
|
||||
);
|
||||
|
||||
assert!(mat.col(1) == DVec::from_slice(3, &[2.0, 5.0, 8.0]));
|
||||
assert!(matrix.column(1) == DVector::from_slice(3, &[2.0, 5.0, 8.0]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dmat_set_col() {
|
||||
let mut mat = DMat::from_row_vec(
|
||||
let mut matrix = DMatrix::from_row_vector(
|
||||
3,
|
||||
3,
|
||||
&[
|
||||
|
@ -567,9 +567,9 @@ fn test_dmat_set_col() {
|
|||
]
|
||||
);
|
||||
|
||||
mat.set_col(1, DVec::from_slice(3, &[12.0, 15.0, 18.0]));
|
||||
matrix.set_col(1, DVector::from_slice(3, &[12.0, 15.0, 18.0]));
|
||||
|
||||
let expected = DMat::from_row_vec(
|
||||
let expected = DMatrix::from_row_vector(
|
||||
3,
|
||||
3,
|
||||
&[
|
||||
|
@ -579,12 +579,12 @@ fn test_dmat_set_col() {
|
|||
]
|
||||
);
|
||||
|
||||
assert!(mat == expected);
|
||||
assert!(matrix == expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dmat_row() {
|
||||
let mat = DMat::from_row_vec(
|
||||
let matrix = DMatrix::from_row_vector(
|
||||
3,
|
||||
3,
|
||||
&[
|
||||
|
@ -594,12 +594,12 @@ fn test_dmat_row() {
|
|||
]
|
||||
);
|
||||
|
||||
assert!(mat.row(1) == DVec::from_slice(3, &[4.0, 5.0, 6.0]));
|
||||
assert!(matrix.row(1) == DVector::from_slice(3, &[4.0, 5.0, 6.0]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dmat_set_row() {
|
||||
let mut mat = DMat::from_row_vec(
|
||||
let mut matrix = DMatrix::from_row_vector(
|
||||
3,
|
||||
3,
|
||||
&[
|
||||
|
@ -609,9 +609,9 @@ fn test_dmat_set_row() {
|
|||
]
|
||||
);
|
||||
|
||||
mat.set_row(1, DVec::from_slice(3, &[14.0, 15.0, 16.0]));
|
||||
matrix.set_row(1, DVector::from_slice(3, &[14.0, 15.0, 16.0]));
|
||||
|
||||
let expected = DMat::from_row_vec(
|
||||
let expected = DMatrix::from_row_vector(
|
||||
3,
|
||||
3,
|
||||
&[
|
||||
|
@ -621,10 +621,10 @@ fn test_dmat_set_row() {
|
|||
]
|
||||
);
|
||||
|
||||
assert!(mat == expected);
|
||||
assert!(matrix == expected);
|
||||
}
|
||||
|
||||
/* FIXME: review qr decomposition to make it work with DMat.
|
||||
/* FIXME: review qr decomposition to make it work with DMatrix.
|
||||
#[test]
|
||||
fn test_qr() {
|
||||
for _ in 0usize .. 10 {
|
||||
|
@ -632,79 +632,79 @@ fn test_qr() {
|
|||
let dim2: usize = random();
|
||||
let rows = min(40, max(dim1, dim2));
|
||||
let cols = min(40, min(dim1, dim2));
|
||||
let randmat: DMat<f64> = DMat::new_random(rows, cols);
|
||||
let (q, r) = na::qr(&randmat);
|
||||
let randmatrix: DMatrix<f64> = DMatrix::new_random(rows, cols);
|
||||
let (q, r) = na::qr(&randmatrix);
|
||||
let recomp = q * r;
|
||||
|
||||
assert!(na::approx_eq(&randmat, &recomp));
|
||||
assert!(na::approx_eq(&randmatrix, &recomp));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[test]
|
||||
fn test_qr_mat1() {
|
||||
test_qr_impl!(Mat1<f64>);
|
||||
test_qr_impl!(Matrix1<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_qr_mat2() {
|
||||
test_qr_impl!(Mat2<f64>);
|
||||
test_qr_impl!(Matrix2<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_qr_mat3() {
|
||||
test_qr_impl!(Mat3<f64>);
|
||||
test_qr_impl!(Matrix3<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_qr_mat4() {
|
||||
test_qr_impl!(Mat4<f64>);
|
||||
test_qr_impl!(Matrix4<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_qr_mat5() {
|
||||
test_qr_impl!(Mat5<f64>);
|
||||
test_qr_impl!(Matrix5<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_qr_mat6() {
|
||||
test_qr_impl!(Mat6<f64>);
|
||||
test_qr_impl!(Matrix6<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eigen_qr_mat1() {
|
||||
test_eigen_qr_impl!(Mat1<f64>);
|
||||
test_eigen_qr_impl!(Matrix1<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eigen_qr_mat2() {
|
||||
test_eigen_qr_impl!(Mat2<f64>);
|
||||
test_eigen_qr_impl!(Matrix2<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eigen_qr_mat3() {
|
||||
test_eigen_qr_impl!(Mat3<f64>);
|
||||
test_eigen_qr_impl!(Matrix3<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eigen_qr_mat4() {
|
||||
test_eigen_qr_impl!(Mat4<f64>);
|
||||
test_eigen_qr_impl!(Matrix4<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eigen_qr_mat5() {
|
||||
test_eigen_qr_impl!(Mat5<f64>);
|
||||
test_eigen_qr_impl!(Matrix5<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eigen_qr_mat6() {
|
||||
test_eigen_qr_impl!(Mat6<f64>);
|
||||
test_eigen_qr_impl!(Matrix6<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_fn() {
|
||||
let actual: DMat<usize> = DMat::from_fn(3, 4, |i, j| 10 * i + j);
|
||||
let expected: DMat<usize> = DMat::from_row_vec(3, 4,
|
||||
let actual: DMatrix<usize> = DMatrix::from_fn(3, 4, |i, j| 10 * i + j);
|
||||
let expected: DMatrix<usize> = DMatrix::from_row_vector(3, 4,
|
||||
&[ 0_0, 0_1, 0_2, 0_3,
|
||||
1_0, 1_1, 1_2, 1_3,
|
||||
2_0, 2_1, 2_2, 2_3 ]);
|
||||
|
@ -714,21 +714,21 @@ fn test_from_fn() {
|
|||
|
||||
#[test]
|
||||
fn test_row_3() {
|
||||
let mat = Mat3::new(0.0f32, 1.0, 2.0,
|
||||
let matrix = Matrix3::new(0.0f32, 1.0, 2.0,
|
||||
3.0, 4.0, 5.0,
|
||||
6.0, 7.0, 8.0);
|
||||
let second_row = mat.row(1);
|
||||
let second_col = mat.col(1);
|
||||
let second_row = matrix.row(1);
|
||||
let second_col = matrix.column(1);
|
||||
|
||||
assert!(second_row == Vec3::new(3.0, 4.0, 5.0));
|
||||
assert!(second_col == Vec3::new(1.0, 4.0, 7.0));
|
||||
assert!(second_row == Vector3::new(3.0, 4.0, 5.0));
|
||||
assert!(second_col == Vector3::new(1.0, 4.0, 7.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cholesky_const() {
|
||||
|
||||
let a : Mat3<f64> = Mat3::<f64>::new(1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 1.0, 2.0, 3.0);
|
||||
let g : Mat3<f64> = Mat3::<f64>::new(1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0);
|
||||
let a : Matrix3<f64> = Matrix3::<f64>::new(1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 1.0, 2.0, 3.0);
|
||||
let g : Matrix3<f64> = Matrix3::<f64>::new(1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0);
|
||||
|
||||
let result = na::cholesky(&a);
|
||||
|
||||
|
@ -744,7 +744,7 @@ fn test_cholesky_const() {
|
|||
#[test]
|
||||
fn test_cholesky_not_spd() {
|
||||
|
||||
let a : Mat3<f64> = Mat3::<f64>::new(1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 1.0, 1.0, 1.0);
|
||||
let a : Matrix3<f64> = Matrix3::<f64>::new(1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
let result = na::cholesky(&a);
|
||||
|
||||
|
@ -754,7 +754,7 @@ fn test_cholesky_not_spd() {
|
|||
#[test]
|
||||
fn test_cholesky_not_symmetric() {
|
||||
|
||||
let a : Mat2<f64> = Mat2::<f64>::new(1.0, 1.0, -1.0, 1.0);
|
||||
let a : Matrix2<f64> = Matrix2::<f64>::new(1.0, 1.0, -1.0, 1.0);
|
||||
|
||||
let result = na::cholesky(&a);
|
||||
|
||||
|
@ -763,83 +763,83 @@ fn test_cholesky_not_symmetric() {
|
|||
|
||||
#[test]
|
||||
fn test_cholesky_mat1() {
|
||||
test_cholesky_impl!(Mat1<f64>);
|
||||
test_cholesky_impl!(Matrix1<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cholesky_mat2() {
|
||||
test_cholesky_impl!(Mat2<f64>);
|
||||
test_cholesky_impl!(Matrix2<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cholesky_mat3() {
|
||||
test_cholesky_impl!(Mat3<f64>);
|
||||
test_cholesky_impl!(Matrix3<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cholesky_mat4() {
|
||||
test_cholesky_impl!(Mat4<f64>);
|
||||
test_cholesky_impl!(Matrix4<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cholesky_mat5() {
|
||||
test_cholesky_impl!(Mat5<f64>);
|
||||
test_cholesky_impl!(Matrix5<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cholesky_mat6() {
|
||||
test_cholesky_impl!(Mat6<f64>);
|
||||
test_cholesky_impl!(Matrix6<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hessenberg_mat1() {
|
||||
test_hessenberg_impl!(Mat1<f64>);
|
||||
test_hessenberg_impl!(Matrix1<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hessenberg_mat2() {
|
||||
test_hessenberg_impl!(Mat2<f64>);
|
||||
test_hessenberg_impl!(Matrix2<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hessenberg_mat3() {
|
||||
test_hessenberg_impl!(Mat3<f64>);
|
||||
test_hessenberg_impl!(Matrix3<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hessenberg_mat4() {
|
||||
test_hessenberg_impl!(Mat4<f64>);
|
||||
test_hessenberg_impl!(Matrix4<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hessenberg_mat5() {
|
||||
test_hessenberg_impl!(Mat5<f64>);
|
||||
test_hessenberg_impl!(Matrix5<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hessenberg_mat6() {
|
||||
test_hessenberg_impl!(Mat6<f64>);
|
||||
test_hessenberg_impl!(Matrix6<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transpose_square_mat() {
|
||||
let col_major_mat = &[0, 1, 2, 3,
|
||||
fn test_transpose_square_matrix() {
|
||||
let col_major_matrix = &[0, 1, 2, 3,
|
||||
0, 1, 2, 3,
|
||||
0, 1, 2, 3,
|
||||
0, 1, 2, 3];
|
||||
let num_rows = 4;
|
||||
let num_cols = 4;
|
||||
let mut mat = DMat::from_col_vec(num_rows, num_cols, col_major_mat);
|
||||
mat.transpose_mut();
|
||||
let mut matrix = DMatrix::from_col_vector(num_rows, num_cols, col_major_matrix);
|
||||
matrix.transpose_mut();
|
||||
for i in 0..num_rows {
|
||||
assert_eq!(&[0, 1, 2, 3], &mat.row_slice(i, 0, num_cols)[..]);
|
||||
assert_eq!(&[0, 1, 2, 3], &matrix.row_slice(i, 0, num_cols)[..]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_outer_dvec() {
|
||||
let vec = DVec::from_slice(5, &[ 1.0, 2.0, 3.0, 4.0, 5.0 ]);
|
||||
let row = DMat::from_row_vec(1, 5, &vec[..]);
|
||||
fn test_outer_dvector() {
|
||||
let vector = DVector::from_slice(5, &[ 1.0, 2.0, 3.0, 4.0, 5.0 ]);
|
||||
let row = DMatrix::from_row_vector(1, 5, &vector[..]);
|
||||
|
||||
assert_eq!(row.transpose() * row, na::outer(&vec, &vec))
|
||||
assert_eq!(row.transpose() * row, na::outer(&vector, &vector))
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ extern crate rand;
|
|||
|
||||
use std::ops::{Mul, Div, Add, Sub, MulAssign, DivAssign, AddAssign, SubAssign};
|
||||
use rand::random;
|
||||
use na::{Pnt3, Vec3, Mat3, Rot3, Iso3, Sim3, Quat, UnitQuat};
|
||||
use na::{Point3, Vector3, Matrix3, Rotation3, Isometry3, Similarity3, Quaternion, UnitQuaternion};
|
||||
|
||||
// NOTE: we test only the 3D version because the others share the same code anyway.
|
||||
|
||||
|
@ -25,52 +25,52 @@ macro_rules! test_op_vs_op_assign(
|
|||
);
|
||||
|
||||
// Multiplication.
|
||||
test_op_vs_op_assign!(test_vec3_f32_mul_assign, Vec3<f32>, f32, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_mat3_f32_mul_assign, Mat3<f32>, f32, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_quat_f32_mul_assign, Quat<f32>, f32, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_vec3_f32_mul_assign, Vector3<f32>, f32, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_mat3_f32_mul_assign, Matrix3<f32>, f32, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_quaternion_f32_mul_assign, Quaternion<f32>, f32, mul, mul_assign);
|
||||
|
||||
test_op_vs_op_assign!(test_vec3_vec3_mul_assign, Vec3<f32>, Vec3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_quat_quat_mul_assign, Quat<f32>, Quat<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_unit_quat_unit_quat_mul_assign, UnitQuat<f32>, UnitQuat<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_vec3_vec3_mul_assign, Vector3<f32>, Vector3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_quaternion_quaternion_mul_assign, Quaternion<f32>, Quaternion<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_unit_quaternion_unit_quaternion_mul_assign, UnitQuaternion<f32>, UnitQuaternion<f32>, mul, mul_assign);
|
||||
|
||||
test_op_vs_op_assign!(test_vec3_unit_quat_mul_assign, Vec3<f32>, UnitQuat<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_pnt3_unit_quat_mul_assign, Pnt3<f32>, UnitQuat<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_vec3_unit_quaternion_mul_assign, Vector3<f32>, UnitQuaternion<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_point3_unit_quaternion_mul_assign, Point3<f32>, UnitQuaternion<f32>, mul, mul_assign);
|
||||
|
||||
test_op_vs_op_assign!(test_mat3_mat3_mul_assign, Mat3<f32>, Mat3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_vec3_mat3_mul_assign, Vec3<f32>, Mat3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_pnt3_mat3_mul_assign, Pnt3<f32>, Mat3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_mat3_mat3_mul_assign, Matrix3<f32>, Matrix3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_vec3_mat3_mul_assign, Vector3<f32>, Matrix3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_point3_mat3_mul_assign, Point3<f32>, Matrix3<f32>, mul, mul_assign);
|
||||
|
||||
test_op_vs_op_assign!(test_rot3_rot3_mul_assign, Rot3<f32>, Rot3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_vec3_rot3_mul_assign, Vec3<f32>, Rot3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_pnt3_rot3_mul_assign, Pnt3<f32>, Rot3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_rot3_rot3_mul_assign, Rotation3<f32>, Rotation3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_vec3_rot3_mul_assign, Vector3<f32>, Rotation3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_point3_rot3_mul_assign, Point3<f32>, Rotation3<f32>, mul, mul_assign);
|
||||
|
||||
test_op_vs_op_assign!(test_iso3_iso3_mul_assign, Iso3<f32>, Iso3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_iso3_rot3_mul_assign, Iso3<f32>, Rot3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_iso3_iso3_mul_assign, Isometry3<f32>, Isometry3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_iso3_rot3_mul_assign, Isometry3<f32>, Rotation3<f32>, mul, mul_assign);
|
||||
|
||||
test_op_vs_op_assign!(test_sim3_sim3_mul_assign, Sim3<f32>, Sim3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_sim3_iso3_mul_assign, Sim3<f32>, Iso3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_sim3_rot3_mul_assign, Sim3<f32>, Rot3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_sim3_sim3_mul_assign, Similarity3<f32>, Similarity3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_sim3_iso3_mul_assign, Similarity3<f32>, Isometry3<f32>, mul, mul_assign);
|
||||
test_op_vs_op_assign!(test_sim3_rot3_mul_assign, Similarity3<f32>, Rotation3<f32>, mul, mul_assign);
|
||||
|
||||
// Division.
|
||||
test_op_vs_op_assign!(test_vec3_vec3_div_assign, Vec3<f32>, Vec3<f32>, div, div_assign);
|
||||
test_op_vs_op_assign!(test_quat_quat_div_assign, Quat<f32>, Quat<f32>, div, div_assign);
|
||||
test_op_vs_op_assign!(test_unit_quat_unit_quat_div_assign, UnitQuat<f32>, UnitQuat<f32>, div, div_assign);
|
||||
test_op_vs_op_assign!(test_vec3_vec3_div_assign, Vector3<f32>, Vector3<f32>, div, div_assign);
|
||||
test_op_vs_op_assign!(test_quaternion_quaternion_div_assign, Quaternion<f32>, Quaternion<f32>, div, div_assign);
|
||||
test_op_vs_op_assign!(test_unit_quaternion_unit_quaternion_div_assign, UnitQuaternion<f32>, UnitQuaternion<f32>, div, div_assign);
|
||||
|
||||
test_op_vs_op_assign!(test_vec3_f32_div_assign, Vec3<f32>, f32, div, div_assign);
|
||||
test_op_vs_op_assign!(test_mat3_f32_div_assign, Mat3<f32>, f32, div, div_assign);
|
||||
test_op_vs_op_assign!(test_vec3_f32_div_assign, Vector3<f32>, f32, div, div_assign);
|
||||
test_op_vs_op_assign!(test_mat3_f32_div_assign, Matrix3<f32>, f32, div, div_assign);
|
||||
|
||||
// Addition.
|
||||
test_op_vs_op_assign!(test_vec3_vec3_add_assign, Vec3<f32>, Vec3<f32>, add, add_assign);
|
||||
test_op_vs_op_assign!(test_mat3_mat3_add_assign, Mat3<f32>, Mat3<f32>, add, add_assign);
|
||||
test_op_vs_op_assign!(test_quat_quat_add_assign, Quat<f32>, Quat<f32>, add, add_assign);
|
||||
test_op_vs_op_assign!(test_vec3_vec3_add_assign, Vector3<f32>, Vector3<f32>, add, add_assign);
|
||||
test_op_vs_op_assign!(test_mat3_mat3_add_assign, Matrix3<f32>, Matrix3<f32>, add, add_assign);
|
||||
test_op_vs_op_assign!(test_quaternion_quaternion_add_assign, Quaternion<f32>, Quaternion<f32>, add, add_assign);
|
||||
|
||||
test_op_vs_op_assign!(test_vec3_f32_add_assign, Vec3<f32>, f32, add, add_assign);
|
||||
test_op_vs_op_assign!(test_mat3_f32_add_assign, Mat3<f32>, f32, add, add_assign);
|
||||
test_op_vs_op_assign!(test_vec3_f32_add_assign, Vector3<f32>, f32, add, add_assign);
|
||||
test_op_vs_op_assign!(test_mat3_f32_add_assign, Matrix3<f32>, f32, add, add_assign);
|
||||
|
||||
// Subtraction.
|
||||
test_op_vs_op_assign!(test_vec3_vec3_sub_assign, Vec3<f32>, Vec3<f32>, sub, sub_assign);
|
||||
test_op_vs_op_assign!(test_mat3_mat3_sub_assign, Mat3<f32>, Mat3<f32>, sub, sub_assign);
|
||||
test_op_vs_op_assign!(test_quat_quat_sub_assign, Quat<f32>, Quat<f32>, sub, sub_assign);
|
||||
test_op_vs_op_assign!(test_vec3_vec3_sub_assign, Vector3<f32>, Vector3<f32>, sub, sub_assign);
|
||||
test_op_vs_op_assign!(test_mat3_mat3_sub_assign, Matrix3<f32>, Matrix3<f32>, sub, sub_assign);
|
||||
test_op_vs_op_assign!(test_quaternion_quaternion_sub_assign, Quaternion<f32>, Quaternion<f32>, sub, sub_assign);
|
||||
|
||||
test_op_vs_op_assign!(test_vec3_f32_sub_assign, Vec3<f32>, f32, sub, sub_assign);
|
||||
test_op_vs_op_assign!(test_mat3_f32_sub_assign, Mat3<f32>, f32, sub, sub_assign);
|
||||
test_op_vs_op_assign!(test_vec3_f32_sub_assign, Vector3<f32>, f32, sub, sub_assign);
|
||||
test_op_vs_op_assign!(test_mat3_f32_sub_assign, Matrix3<f32>, f32, sub, sub_assign);
|
||||
|
|
|
@ -1,57 +1,57 @@
|
|||
extern crate nalgebra as na;
|
||||
extern crate rand;
|
||||
|
||||
use na::{Pnt3, Vec3, Rot3, UnitQuat, Rotation};
|
||||
use na::{Point3, Vector3, Rotation3, UnitQuaternion, Rotation};
|
||||
use rand::random;
|
||||
|
||||
#[test]
|
||||
fn test_quat_as_mat() {
|
||||
fn test_quaternion_as_matrix() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let axis_angle: Vec3<f64> = random();
|
||||
let axis_angle: Vector3<f64> = random();
|
||||
|
||||
assert!(na::approx_eq(&UnitQuat::new(axis_angle).to_rot(), &Rot3::new(axis_angle)))
|
||||
assert!(na::approx_eq(&UnitQuaternion::new(axis_angle).to_rotation_matrix(), &Rotation3::new(axis_angle)))
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_quat_mul_vec_or_pnt_as_mat() {
|
||||
fn test_quaternion_mul_vec_or_point_as_matrix() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let axis_angle: Vec3<f64> = random();
|
||||
let vec: Vec3<f64> = random();
|
||||
let pnt: Pnt3<f64> = random();
|
||||
let axis_angle: Vector3<f64> = random();
|
||||
let vector: Vector3<f64> = random();
|
||||
let point: Point3<f64> = random();
|
||||
|
||||
let mat = Rot3::new(axis_angle);
|
||||
let quat = UnitQuat::new(axis_angle);
|
||||
let matrix = Rotation3::new(axis_angle);
|
||||
let quaternion = UnitQuaternion::new(axis_angle);
|
||||
|
||||
assert!(na::approx_eq(&(mat * vec), &(quat * vec)));
|
||||
assert!(na::approx_eq(&(mat * pnt), &(quat * pnt)));
|
||||
assert!(na::approx_eq(&(vec * mat), &(vec * quat)));
|
||||
assert!(na::approx_eq(&(pnt * mat), &(pnt * quat)));
|
||||
assert!(na::approx_eq(&(matrix * vector), &(quaternion * vector)));
|
||||
assert!(na::approx_eq(&(matrix * point), &(quaternion * point)));
|
||||
assert!(na::approx_eq(&(vector * matrix), &(vector * quaternion)));
|
||||
assert!(na::approx_eq(&(point * matrix), &(point * quaternion)));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_quat_div_quat() {
|
||||
fn test_quaternion_div_quaternion() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let axis_angle1: Vec3<f64> = random();
|
||||
let axis_angle2: Vec3<f64> = random();
|
||||
let axis_angle1: Vector3<f64> = random();
|
||||
let axis_angle2: Vector3<f64> = random();
|
||||
|
||||
let r1 = Rot3::new(axis_angle1);
|
||||
let r2 = na::inv(&Rot3::new(axis_angle2)).unwrap();
|
||||
let r1 = Rotation3::new(axis_angle1);
|
||||
let r2 = na::inverse(&Rotation3::new(axis_angle2)).unwrap();
|
||||
|
||||
let q1 = UnitQuat::new(axis_angle1);
|
||||
let q2 = UnitQuat::new(axis_angle2);
|
||||
let q1 = UnitQuaternion::new(axis_angle1);
|
||||
let q2 = UnitQuaternion::new(axis_angle2);
|
||||
|
||||
assert!(na::approx_eq(&(q1 / q2).to_rot(), &(r1 * r2)))
|
||||
assert!(na::approx_eq(&(q1 / q2).to_rotation_matrix(), &(r1 * r2)))
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_quat_to_axis_angle() {
|
||||
fn test_quaternion_to_axis_angle() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let axis_angle: Vec3<f64> = random();
|
||||
let axis_angle: Vector3<f64> = random();
|
||||
|
||||
let q = UnitQuat::new(axis_angle);
|
||||
let q = UnitQuaternion::new(axis_angle);
|
||||
|
||||
println!("{:?} {:?}", q.rotation(), axis_angle);
|
||||
assert!(na::approx_eq(&q.rotation(), &axis_angle))
|
||||
|
@ -59,21 +59,21 @@ fn test_quat_to_axis_angle() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_quat_euler_angles() {
|
||||
fn test_quaternion_euler_angles() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let angles: Vec3<f64> = random();
|
||||
let angles: Vector3<f64> = random();
|
||||
|
||||
let q = UnitQuat::new_with_euler_angles(angles.x, angles.y, angles.z);
|
||||
let m = Rot3::new_with_euler_angles(angles.x, angles.y, angles.z);
|
||||
let q = UnitQuaternion::new_with_euler_angles(angles.x, angles.y, angles.z);
|
||||
let m = Rotation3::new_with_euler_angles(angles.x, angles.y, angles.z);
|
||||
|
||||
assert!(na::approx_eq(&q.to_rot(), &m))
|
||||
assert!(na::approx_eq(&q.to_rotation_matrix(), &m))
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_quat_rotation_between() {
|
||||
let q1: UnitQuat<f64> = random();
|
||||
let q2: UnitQuat<f64> = random();
|
||||
fn test_quaternion_rotation_between() {
|
||||
let q1: UnitQuaternion<f64> = random();
|
||||
let q2: UnitQuaternion<f64> = random();
|
||||
|
||||
let delta = na::rotation_between(&q1, &q2);
|
||||
|
||||
|
@ -81,9 +81,9 @@ fn test_quat_rotation_between() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_quat_angle_between() {
|
||||
let q1: UnitQuat<f64> = random();
|
||||
let q2: UnitQuat<f64> = random();
|
||||
fn test_quaternion_angle_between() {
|
||||
let q1: UnitQuaternion<f64> = random();
|
||||
let q2: UnitQuaternion<f64> = random();
|
||||
|
||||
let delta = na::rotation_between(&q1, &q2);
|
||||
let delta_angle = na::angle_between(&q1, &q2);
|
||||
|
|
|
@ -2,35 +2,35 @@ extern crate nalgebra as na;
|
|||
extern crate rand;
|
||||
|
||||
use rand::random;
|
||||
use na::{Pnt2, Pnt3, Vec2, Vec3, Vec1, Rot2, Rot3, Persp3, PerspMat3, Ortho3, OrthoMat3,
|
||||
Iso2, Iso3, Sim2, Sim3, BaseFloat, Transform};
|
||||
use na::{Point2, Point3, Vector2, Vector3, Vector1, Rotation2, Rotation3, Perspective3, PerspectiveMatrix3, Orthographic3, OrthographicMatrix3,
|
||||
Isometry2, Isometry3, Similarity2, Similarity3, BaseFloat, Transform};
|
||||
|
||||
#[test]
|
||||
fn test_rotation2() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let randmat: na::Rot2<f64> = na::one();
|
||||
let ang = Vec1::new(na::abs(&random::<f64>()) % <f64 as BaseFloat>::pi());
|
||||
let randmatrix: na::Rotation2<f64> = na::one();
|
||||
let ang = Vector1::new(na::abs(&random::<f64>()) % <f64 as BaseFloat>::pi());
|
||||
|
||||
assert!(na::approx_eq(&na::rotation(&na::append_rotation(&randmat, &ang)), &ang));
|
||||
assert!(na::approx_eq(&na::rotation(&na::append_rotation(&randmatrix, &ang)), &ang));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inv_rotation3() {
|
||||
fn test_inverse_rotation3() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let randmat: Rot3<f64> = na::one();
|
||||
let dir: Vec3<f64> = random();
|
||||
let randmatrix: Rotation3<f64> = na::one();
|
||||
let dir: Vector3<f64> = random();
|
||||
let ang = na::normalize(&dir) * (na::abs(&random::<f64>()) % <f64 as BaseFloat>::pi());
|
||||
let rot = na::append_rotation(&randmat, &ang);
|
||||
let rotation = na::append_rotation(&randmatrix, &ang);
|
||||
|
||||
assert!(na::approx_eq(&(na::transpose(&rot) * rot), &na::one()));
|
||||
assert!(na::approx_eq(&(na::transpose(&rotation) * rotation), &na::one()));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rot3_rotation_between() {
|
||||
let r1: Rot3<f64> = random();
|
||||
let r2: Rot3<f64> = random();
|
||||
let r1: Rotation3<f64> = random();
|
||||
let r2: Rotation3<f64> = random();
|
||||
|
||||
let delta = na::rotation_between(&r1, &r2);
|
||||
|
||||
|
@ -39,8 +39,8 @@ fn test_rot3_rotation_between() {
|
|||
|
||||
#[test]
|
||||
fn test_rot3_angle_between() {
|
||||
let r1: Rot3<f64> = random();
|
||||
let r2: Rot3<f64> = random();
|
||||
let r1: Rotation3<f64> = random();
|
||||
let r2: Rotation3<f64> = random();
|
||||
|
||||
let delta = na::rotation_between(&r1, &r2);
|
||||
let delta_angle = na::angle_between(&r1, &r2);
|
||||
|
@ -50,8 +50,8 @@ fn test_rot3_angle_between() {
|
|||
|
||||
#[test]
|
||||
fn test_rot2_rotation_between() {
|
||||
let r1: Rot2<f64> = random();
|
||||
let r2: Rot2<f64> = random();
|
||||
let r1: Rotation2<f64> = random();
|
||||
let r2: Rotation2<f64> = random();
|
||||
|
||||
let delta = na::rotation_between(&r1, &r2);
|
||||
|
||||
|
@ -60,8 +60,8 @@ fn test_rot2_rotation_between() {
|
|||
|
||||
#[test]
|
||||
fn test_rot2_angle_between() {
|
||||
let r1: Rot2<f64> = random();
|
||||
let r2: Rot2<f64> = random();
|
||||
let r1: Rotation2<f64> = random();
|
||||
let r2: Rotation2<f64> = random();
|
||||
|
||||
let delta = na::rotation_between(&r1, &r2);
|
||||
let delta_angle = na::angle_between(&r1, &r2);
|
||||
|
@ -73,58 +73,58 @@ fn test_rot2_angle_between() {
|
|||
#[test]
|
||||
fn test_look_at_rh_iso3() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let eye = random::<Pnt3<f64>>();
|
||||
let target = random::<Pnt3<f64>>();
|
||||
let up = random::<Vec3<f64>>();
|
||||
let viewmat = Iso3::look_at_rh(&eye, &target, &up);
|
||||
let eye = random::<Point3<f64>>();
|
||||
let target = random::<Point3<f64>>();
|
||||
let up = random::<Vector3<f64>>();
|
||||
let viewmatrix = Isometry3::look_at_rh(&eye, &target, &up);
|
||||
|
||||
let origin: Pnt3<f64> = na::orig();
|
||||
assert_eq!(&(viewmat * eye), &origin);
|
||||
assert!(na::approx_eq(&na::normalize(&(viewmat * (target - eye))), &-Vec3::z()));
|
||||
let origin: Point3<f64> = na::origin();
|
||||
assert_eq!(&(viewmatrix * eye), &origin);
|
||||
assert!(na::approx_eq(&na::normalize(&(viewmatrix * (target - eye))), &-Vector3::z()));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_look_at_rh_rot3() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let dir = random::<Vec3<f64>>();
|
||||
let up = random::<Vec3<f64>>();
|
||||
let viewmat = Rot3::look_at_rh(&dir, &up);
|
||||
let dir = random::<Vector3<f64>>();
|
||||
let up = random::<Vector3<f64>>();
|
||||
let viewmatrix = Rotation3::look_at_rh(&dir, &up);
|
||||
|
||||
println!("found: {}", viewmat * dir);
|
||||
assert!(na::approx_eq(&na::normalize(&(viewmat * dir)), &-Vec3::z()));
|
||||
println!("found: {}", viewmatrix * dir);
|
||||
assert!(na::approx_eq(&na::normalize(&(viewmatrix * dir)), &-Vector3::z()));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_observer_frame_iso3() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let eye = random::<Pnt3<f64>>();
|
||||
let target = random::<Pnt3<f64>>();
|
||||
let up = random::<Vec3<f64>>();
|
||||
let observer = Iso3::new_observer_frame(&eye, &target, &up);
|
||||
let eye = random::<Point3<f64>>();
|
||||
let target = random::<Point3<f64>>();
|
||||
let up = random::<Vector3<f64>>();
|
||||
let observer = Isometry3::new_observer_frame(&eye, &target, &up);
|
||||
|
||||
assert_eq!(&(observer * na::orig::<Pnt3<f64>>()), &eye);
|
||||
assert!(na::approx_eq(&(observer * Vec3::z()), &na::normalize(&(target - eye))));
|
||||
assert_eq!(&(observer * na::origin::<Point3<f64>>()), &eye);
|
||||
assert!(na::approx_eq(&(observer * Vector3::z()), &na::normalize(&(target - eye))));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_observer_frame_rot3() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let dir = random::<Vec3<f64>>();
|
||||
let up = random::<Vec3<f64>>();
|
||||
let observer = Rot3::new_observer_frame(&dir, &up);
|
||||
let dir = random::<Vector3<f64>>();
|
||||
let up = random::<Vector3<f64>>();
|
||||
let observer = Rotation3::new_observer_frame(&dir, &up);
|
||||
|
||||
assert!(na::approx_eq(&(observer * Vec3::z()), &na::normalize(&dir)));
|
||||
assert!(na::approx_eq(&(observer * Vector3::z()), &na::normalize(&dir)));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_persp() {
|
||||
let mut p = Persp3::new(42.0f64, 0.5, 1.5, 10.0);
|
||||
let mut pm = PerspMat3::new(42.0f64, 0.5, 1.5, 10.0);
|
||||
assert!(p.to_mat() == pm.to_mat());
|
||||
let mut p = Perspective3::new(42.0f64, 0.5, 1.5, 10.0);
|
||||
let mut pm = PerspectiveMatrix3::new(42.0f64, 0.5, 1.5, 10.0);
|
||||
assert!(p.to_matrix() == pm.to_matrix());
|
||||
assert!(p.aspect() == 42.0);
|
||||
assert!(p.fovy() == 0.5);
|
||||
assert!(p.znear() == 1.5);
|
||||
|
@ -136,19 +136,19 @@ fn test_persp() {
|
|||
|
||||
p.set_fovy(0.1);
|
||||
pm.set_fovy(0.1);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
|
||||
|
||||
p.set_znear(24.0);
|
||||
pm.set_znear(24.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
|
||||
|
||||
p.set_zfar(61.0);
|
||||
pm.set_zfar(61.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
|
||||
|
||||
p.set_aspect(23.0);
|
||||
pm.set_aspect(23.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
|
||||
|
||||
assert!(p.aspect() == 23.0);
|
||||
assert!(p.fovy() == 0.1);
|
||||
|
@ -162,9 +162,9 @@ fn test_persp() {
|
|||
|
||||
#[test]
|
||||
fn test_ortho() {
|
||||
let mut p = Ortho3::new(-0.3, 5.2, -3.9, -1.0, 1.5, 10.0);
|
||||
let mut pm = OrthoMat3::new(-0.3, 5.2, -3.9, -1.0, 1.5, 10.0);
|
||||
assert!(p.to_mat() == pm.to_mat());
|
||||
let mut p = Orthographic3::new(-0.3, 5.2, -3.9, -1.0, 1.5, 10.0);
|
||||
let mut pm = OrthographicMatrix3::new(-0.3, 5.2, -3.9, -1.0, 1.5, 10.0);
|
||||
assert!(p.to_matrix() == pm.to_matrix());
|
||||
assert!(p.left() == -0.3);
|
||||
assert!(p.right() == 5.2);
|
||||
assert!(p.bottom() == -3.9);
|
||||
|
@ -180,27 +180,27 @@ fn test_ortho() {
|
|||
|
||||
p.set_left(0.1);
|
||||
pm.set_left(0.1);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
|
||||
|
||||
p.set_right(10.1);
|
||||
pm.set_right(10.1);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
|
||||
|
||||
p.set_top(24.0);
|
||||
pm.set_top(24.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
|
||||
|
||||
p.set_bottom(-23.0);
|
||||
pm.set_bottom(-23.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
|
||||
|
||||
p.set_zfar(61.0);
|
||||
pm.set_zfar(61.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
|
||||
|
||||
p.set_znear(21.0);
|
||||
pm.set_znear(21.0);
|
||||
assert!(na::approx_eq(&p.to_mat(), pm.as_mat()));
|
||||
assert!(na::approx_eq(&p.to_matrix(), pm.as_matrix()));
|
||||
|
||||
assert!(p.znear() == 21.0);
|
||||
assert!(p.zfar() == 61.0);
|
||||
|
@ -208,15 +208,15 @@ fn test_ortho() {
|
|||
assert!(na::approx_eq(&pm.zfar(), &61.0));
|
||||
}
|
||||
|
||||
macro_rules! test_transform_inv_transform_impl(
|
||||
macro_rules! test_transform_inverse_transform_impl(
|
||||
($fnname: ident, $t: ty, $p: ty) => (
|
||||
#[test]
|
||||
fn $fnname() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let randmat: $t = random();
|
||||
let randmatrix: $t = random();
|
||||
let expected: $p = random();
|
||||
|
||||
let computed = randmat.inv_transform(&randmat.transform(&expected));
|
||||
let computed = randmatrix.inverse_transform(&randmatrix.transform(&expected));
|
||||
println!("computed: {}, expected: {}", computed, expected);
|
||||
|
||||
assert!(na::approx_eq(&computed, &expected));
|
||||
|
@ -225,12 +225,12 @@ macro_rules! test_transform_inv_transform_impl(
|
|||
);
|
||||
);
|
||||
|
||||
test_transform_inv_transform_impl!(test_transform_inv_transform_rot2, Rot2<f64>, Pnt2<f64>);
|
||||
test_transform_inv_transform_impl!(test_transform_inv_transform_rot3, Rot3<f64>, Pnt3<f64>);
|
||||
test_transform_inv_transform_impl!(test_transform_inv_transform_iso2, Iso2<f64>, Pnt2<f64>);
|
||||
test_transform_inv_transform_impl!(test_transform_inv_transform_iso3, Iso3<f64>, Pnt3<f64>);
|
||||
test_transform_inv_transform_impl!(test_transform_inv_transform_sim2, Sim2<f64>, Pnt2<f64>);
|
||||
test_transform_inv_transform_impl!(test_transform_inv_transform_sim3, Sim3<f64>, Pnt3<f64>);
|
||||
test_transform_inverse_transform_impl!(test_transform_inverse_transform_rot2, Rotation2<f64>, Point2<f64>);
|
||||
test_transform_inverse_transform_impl!(test_transform_inverse_transform_rot3, Rotation3<f64>, Point3<f64>);
|
||||
test_transform_inverse_transform_impl!(test_transform_inverse_transform_iso2, Isometry2<f64>, Point2<f64>);
|
||||
test_transform_inverse_transform_impl!(test_transform_inverse_transform_iso3, Isometry3<f64>, Point3<f64>);
|
||||
test_transform_inverse_transform_impl!(test_transform_inverse_transform_sim2, Similarity2<f64>, Point2<f64>);
|
||||
test_transform_inverse_transform_impl!(test_transform_inverse_transform_sim3, Similarity3<f64>, Point3<f64>);
|
||||
|
||||
macro_rules! test_transform_mul_assoc(
|
||||
($fnname: ident, $t1: ty, $t2: ty, $p: ty) => (
|
||||
|
@ -253,28 +253,28 @@ macro_rules! test_transform_mul_assoc(
|
|||
);
|
||||
);
|
||||
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_sim3_sim3_pnt3, Sim3<f64>, Sim3<f64>, Pnt3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_sim3_iso3_pnt3, Sim3<f64>, Iso3<f64>, Pnt3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_sim3_rot3_pnt3, Sim3<f64>, Rot3<f64>, Pnt3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_iso3_iso3_pnt3, Iso3<f64>, Iso3<f64>, Pnt3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_iso3_rot3_pnt3, Iso3<f64>, Rot3<f64>, Pnt3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_rot3_rot3_pnt3, Rot3<f64>, Rot3<f64>, Pnt3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_sim3_sim3_vec3, Sim3<f64>, Sim3<f64>, Vec3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_sim3_iso3_vec3, Sim3<f64>, Iso3<f64>, Vec3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_sim3_rot3_vec3, Sim3<f64>, Rot3<f64>, Vec3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_iso3_iso3_vec3, Iso3<f64>, Iso3<f64>, Vec3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_iso3_rot3_vec3, Iso3<f64>, Rot3<f64>, Vec3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_rot3_rot3_vec3, Rot3<f64>, Rot3<f64>, Vec3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_sim3_sim3_point3, Similarity3<f64>, Similarity3<f64>, Point3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_sim3_iso3_point3, Similarity3<f64>, Isometry3<f64>, Point3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_sim3_rot3_point3, Similarity3<f64>, Rotation3<f64>, Point3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_iso3_iso3_point3, Isometry3<f64>, Isometry3<f64>, Point3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_iso3_rot3_point3, Isometry3<f64>, Rotation3<f64>, Point3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_rot3_rot3_point3, Rotation3<f64>, Rotation3<f64>, Point3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_sim3_sim3_vec3, Similarity3<f64>, Similarity3<f64>, Vector3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_sim3_iso3_vec3, Similarity3<f64>, Isometry3<f64>, Vector3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_sim3_rot3_vec3, Similarity3<f64>, Rotation3<f64>, Vector3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_iso3_iso3_vec3, Isometry3<f64>, Isometry3<f64>, Vector3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_iso3_rot3_vec3, Isometry3<f64>, Rotation3<f64>, Vector3<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_rot3_rot3_vec3, Rotation3<f64>, Rotation3<f64>, Vector3<f64>);
|
||||
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_sim2_sim2_pnt2, Sim2<f64>, Sim2<f64>, Pnt2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_sim2_iso2_pnt2, Sim2<f64>, Iso2<f64>, Pnt2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_sim2_rot2_pnt2, Sim2<f64>, Rot2<f64>, Pnt2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_iso2_iso2_pnt2, Iso2<f64>, Iso2<f64>, Pnt2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_iso2_rot2_pnt2, Iso2<f64>, Rot2<f64>, Pnt2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_rot2_rot2_pnt2, Rot2<f64>, Rot2<f64>, Pnt2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_sim2_sim2_vec2, Sim2<f64>, Sim2<f64>, Vec2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_sim2_iso2_vec2, Sim2<f64>, Iso2<f64>, Vec2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_sim2_rot2_vec2, Sim2<f64>, Rot2<f64>, Vec2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_iso2_iso2_vec2, Iso2<f64>, Iso2<f64>, Vec2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_iso2_rot2_vec2, Iso2<f64>, Rot2<f64>, Vec2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inv_transform_rot2_rot2_vec2, Rot2<f64>, Rot2<f64>, Vec2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_sim2_sim2_point2, Similarity2<f64>, Similarity2<f64>, Point2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_sim2_iso2_point2, Similarity2<f64>, Isometry2<f64>, Point2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_sim2_rot2_point2, Similarity2<f64>, Rotation2<f64>, Point2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_iso2_iso2_point2, Isometry2<f64>, Isometry2<f64>, Point2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_iso2_rot2_point2, Isometry2<f64>, Rotation2<f64>, Point2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_rot2_rot2_point2, Rotation2<f64>, Rotation2<f64>, Point2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_sim2_sim2_vec2, Similarity2<f64>, Similarity2<f64>, Vector2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_sim2_iso2_vec2, Similarity2<f64>, Isometry2<f64>, Vector2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_sim2_rot2_vec2, Similarity2<f64>, Rotation2<f64>, Vector2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_iso2_iso2_vec2, Isometry2<f64>, Isometry2<f64>, Vector2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_iso2_rot2_vec2, Isometry2<f64>, Rotation2<f64>, Vector2<f64>);
|
||||
test_transform_mul_assoc!(test_transform_inverse_transform_rot2_rot2_vec2, Rotation2<f64>, Rotation2<f64>, Vector2<f64>);
|
||||
|
|
132
tests/vec.rs
132
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<f64> = random();
|
||||
let v2 : Vec3<f64> = random();
|
||||
let v3 : Vec3<f64> = na::cross(&v1, &v2);
|
||||
let v1 : Vector3<f64> = random();
|
||||
let v2 : Vector3<f64> = random();
|
||||
let v3 : Vector3<f64> = na::cross(&v1, &v2);
|
||||
|
||||
assert!(na::approx_eq(&na::dot(&v3, &v2), &na::zero()));
|
||||
assert!(na::approx_eq(&na::dot(&v3, &v1), &na::zero()));
|
||||
|
@ -120,182 +120,182 @@ fn test_cross_vec3() {
|
|||
|
||||
#[test]
|
||||
fn test_commut_dot_vec1() {
|
||||
test_commut_dot_impl!(Vec1<f64>);
|
||||
test_commut_dot_impl!(Vector1<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_commut_dot_vec2() {
|
||||
test_commut_dot_impl!(Vec2<f64>);
|
||||
test_commut_dot_impl!(Vector2<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_commut_dot_vec3() {
|
||||
test_commut_dot_impl!(Vec3<f64>);
|
||||
test_commut_dot_impl!(Vector3<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_commut_dot_vec4() {
|
||||
test_commut_dot_impl!(Vec4<f64>);
|
||||
test_commut_dot_impl!(Vector4<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_commut_dot_vec5() {
|
||||
test_commut_dot_impl!(Vec5<f64>);
|
||||
test_commut_dot_impl!(Vector5<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_commut_dot_vec6() {
|
||||
test_commut_dot_impl!(Vec6<f64>);
|
||||
test_commut_dot_impl!(Vector6<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basis_vec1() {
|
||||
test_basis_impl!(Vec1<f64>);
|
||||
test_basis_impl!(Vector1<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basis_vec2() {
|
||||
test_basis_impl!(Vec2<f64>);
|
||||
test_basis_impl!(Vector2<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basis_vec3() {
|
||||
test_basis_impl!(Vec3<f64>);
|
||||
test_basis_impl!(Vector3<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basis_vec4() {
|
||||
test_basis_impl!(Vec4<f64>);
|
||||
test_basis_impl!(Vector4<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basis_vec5() {
|
||||
test_basis_impl!(Vec5<f64>);
|
||||
test_basis_impl!(Vector5<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basis_vec6() {
|
||||
test_basis_impl!(Vec6<f64>);
|
||||
test_basis_impl!(Vector6<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subspace_basis_vec1() {
|
||||
test_subspace_basis_impl!(Vec1<f64>);
|
||||
test_subspace_basis_impl!(Vector1<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subspace_basis_vec2() {
|
||||
test_subspace_basis_impl!(Vec2<f64>);
|
||||
test_subspace_basis_impl!(Vector2<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subspace_basis_vec3() {
|
||||
test_subspace_basis_impl!(Vec3<f64>);
|
||||
test_subspace_basis_impl!(Vector3<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subspace_basis_vec4() {
|
||||
test_subspace_basis_impl!(Vec4<f64>);
|
||||
test_subspace_basis_impl!(Vector4<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subspace_basis_vec5() {
|
||||
test_subspace_basis_impl!(Vec5<f64>);
|
||||
test_subspace_basis_impl!(Vector5<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subspace_basis_vec6() {
|
||||
test_subspace_basis_impl!(Vec6<f64>);
|
||||
test_subspace_basis_impl!(Vector6<f64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scalar_op_vec1() {
|
||||
test_scalar_op_impl!(Vec1<f64>, f64);
|
||||
test_scalar_op_impl!(Vector1<f64>, f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scalar_op_vec2() {
|
||||
test_scalar_op_impl!(Vec2<f64>, f64);
|
||||
test_scalar_op_impl!(Vector2<f64>, f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scalar_op_vec3() {
|
||||
test_scalar_op_impl!(Vec3<f64>, f64);
|
||||
test_scalar_op_impl!(Vector3<f64>, f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scalar_op_vec4() {
|
||||
test_scalar_op_impl!(Vec4<f64>, f64);
|
||||
test_scalar_op_impl!(Vector4<f64>, f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scalar_op_vec5() {
|
||||
test_scalar_op_impl!(Vec5<f64>, f64);
|
||||
test_scalar_op_impl!(Vector5<f64>, f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scalar_op_vec6() {
|
||||
test_scalar_op_impl!(Vec6<f64>, f64);
|
||||
test_scalar_op_impl!(Vector6<f64>, f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_vec1() {
|
||||
test_iterator_impl!(Vec1<f64>, f64);
|
||||
test_iterator_impl!(Vector1<f64>, f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_vec2() {
|
||||
test_iterator_impl!(Vec2<f64>, f64);
|
||||
test_iterator_impl!(Vector2<f64>, f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_vec3() {
|
||||
test_iterator_impl!(Vec3<f64>, f64);
|
||||
test_iterator_impl!(Vector3<f64>, f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_vec4() {
|
||||
test_iterator_impl!(Vec4<f64>, f64);
|
||||
test_iterator_impl!(Vector4<f64>, f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_vec5() {
|
||||
test_iterator_impl!(Vec5<f64>, f64);
|
||||
test_iterator_impl!(Vector5<f64>, f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_vec6() {
|
||||
test_iterator_impl!(Vec6<f64>, f64);
|
||||
test_iterator_impl!(Vector6<f64>, f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ord_vec3() {
|
||||
// equality
|
||||
assert!(Vec3::new(0.5f64, 0.5, 0.5) == Vec3::new(0.5, 0.5, 0.5));
|
||||
assert!(!(Vec3::new(1.5f64, 0.5, 0.5) == Vec3::new(0.5, 0.5, 0.5)));
|
||||
assert!(Vec3::new(1.5f64, 0.5, 0.5) != Vec3::new(0.5, 0.5, 0.5));
|
||||
assert!(Vector3::new(0.5f64, 0.5, 0.5) == Vector3::new(0.5, 0.5, 0.5));
|
||||
assert!(!(Vector3::new(1.5f64, 0.5, 0.5) == Vector3::new(0.5, 0.5, 0.5)));
|
||||
assert!(Vector3::new(1.5f64, 0.5, 0.5) != Vector3::new(0.5, 0.5, 0.5));
|
||||
|
||||
// comparable
|
||||
assert!(na::partial_cmp(&Vec3::new(0.5f64, 0.3, 0.3), &Vec3::new(1.0, 2.0, 1.0)).is_le());
|
||||
assert!(na::partial_cmp(&Vec3::new(0.5f64, 0.3, 0.3), &Vec3::new(1.0, 2.0, 1.0)).is_lt());
|
||||
assert!(na::partial_cmp(&Vec3::new(2.0f64, 4.0, 2.0), &Vec3::new(1.0, 2.0, 1.0)).is_ge());
|
||||
assert!(na::partial_cmp(&Vec3::new(2.0f64, 4.0, 2.0), &Vec3::new(1.0, 2.0, 1.0)).is_gt());
|
||||
assert!(na::partial_cmp(&Vector3::new(0.5f64, 0.3, 0.3), &Vector3::new(1.0, 2.0, 1.0)).is_le());
|
||||
assert!(na::partial_cmp(&Vector3::new(0.5f64, 0.3, 0.3), &Vector3::new(1.0, 2.0, 1.0)).is_lt());
|
||||
assert!(na::partial_cmp(&Vector3::new(2.0f64, 4.0, 2.0), &Vector3::new(1.0, 2.0, 1.0)).is_ge());
|
||||
assert!(na::partial_cmp(&Vector3::new(2.0f64, 4.0, 2.0), &Vector3::new(1.0, 2.0, 1.0)).is_gt());
|
||||
|
||||
// not comparable
|
||||
assert!(na::partial_cmp(&Vec3::new(0.0f64, 3.0, 0.0), &Vec3::new(1.0, 2.0, 1.0)).is_not_comparable());
|
||||
assert!(na::partial_cmp(&Vector3::new(0.0f64, 3.0, 0.0), &Vector3::new(1.0, 2.0, 1.0)).is_not_comparable());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_min_max_vec3() {
|
||||
assert_eq!(na::sup(&Vec3::new(1.0f64, 2.0, 3.0), &Vec3::new(3.0, 2.0, 1.0)), Vec3::new(3.0, 2.0, 3.0));
|
||||
assert_eq!(na::inf(&Vec3::new(1.0f64, 2.0, 3.0), &Vec3::new(3.0, 2.0, 1.0)), Vec3::new(1.0, 2.0, 1.0));
|
||||
assert_eq!(na::sup(&Vector3::new(1.0f64, 2.0, 3.0), &Vector3::new(3.0, 2.0, 1.0)), Vector3::new(3.0, 2.0, 3.0));
|
||||
assert_eq!(na::inf(&Vector3::new(1.0f64, 2.0, 3.0), &Vector3::new(3.0, 2.0, 1.0)), Vector3::new(1.0, 2.0, 1.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_outer_vec3() {
|
||||
assert_eq!(
|
||||
na::outer(&Vec3::new(1.0f64, 2.0, 3.0), &Vec3::new(4.0, 5.0, 6.0)),
|
||||
Mat3::new(
|
||||
na::outer(&Vector3::new(1.0f64, 2.0, 3.0), &Vector3::new(4.0, 5.0, 6.0)),
|
||||
Matrix3::new(
|
||||
4.0, 5.0, 6.0,
|
||||
8.0, 10.0, 12.0,
|
||||
12.0, 15.0, 18.0));
|
||||
|
@ -305,7 +305,7 @@ fn test_outer_vec3() {
|
|||
#[test]
|
||||
fn test_vecn10_add_mul() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let v1: VecN<f64, U10> = random();
|
||||
let v1: VectorN<f64, U10> = random();
|
||||
|
||||
assert!(na::approx_eq(&(v1 + v1), &(v1 * 2.0)))
|
||||
}
|
||||
|
@ -315,29 +315,29 @@ fn test_vecn10_add_mul() {
|
|||
#[test]
|
||||
fn test_vec3_rotation_between() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let v1: Vec3<f64> = random();
|
||||
let v1: Vector3<f64> = random();
|
||||
|
||||
let mut v2: Vec3<f64> = random();
|
||||
let mut v2: Vector3<f64> = random();
|
||||
v2 = na::normalize(&v2) * na::norm(&v1);
|
||||
|
||||
let rot = na::rotation_between(&v1, &v2);
|
||||
let rotation = na::rotation_between(&v1, &v2);
|
||||
|
||||
assert!(na::approx_eq(&(rot * v1), &v2))
|
||||
assert!(na::approx_eq(&(rotation * v1), &v2))
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec3_angle_between() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let vec: Vec3<f64> = random();
|
||||
let other: Vec3<f64> = random();
|
||||
let vector: Vector3<f64> = random();
|
||||
let other: Vector3<f64> = random();
|
||||
|
||||
// Ensure the axis we are using is orthogonal to `vec`.
|
||||
let axis_ang = na::cross(&vec, &other);
|
||||
// Ensure the axis we are using is orthogonal to `vector`.
|
||||
let axis_ang = na::cross(&vector, &other);
|
||||
let ang = na::norm(&axis_ang);
|
||||
let rot = Rot3::new(axis_ang);
|
||||
let rotation = Rotation3::new(axis_ang);
|
||||
|
||||
let delta = na::angle_between(&vec, &(rot * vec));
|
||||
let delta = na::angle_between(&vector, &(rotation * vector));
|
||||
|
||||
assert!(na::approx_eq(&ang, &delta))
|
||||
}
|
||||
|
@ -347,27 +347,27 @@ fn test_vec3_angle_between() {
|
|||
#[test]
|
||||
fn test_vec2_rotation_between() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let v1: Vec2<f64> = random();
|
||||
let v1: Vector2<f64> = random();
|
||||
|
||||
let mut v2: Vec2<f64> = random();
|
||||
let mut v2: Vector2<f64> = random();
|
||||
v2 = na::normalize(&v2) * na::norm(&v1);
|
||||
|
||||
let rot = na::rotation_between(&v1, &v2);
|
||||
let rotation = na::rotation_between(&v1, &v2);
|
||||
|
||||
assert!(na::approx_eq(&(rot * v1), &v2))
|
||||
assert!(na::approx_eq(&(rotation * v1), &v2))
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec2_angle_between() {
|
||||
for _ in 0usize .. 10000 {
|
||||
let axis_ang: Vec1<f64> = random();
|
||||
let axis_ang: Vector1<f64> = random();
|
||||
let ang = na::norm(&axis_ang);
|
||||
|
||||
let rot: Rot2<f64> = Rot2::new(axis_ang);
|
||||
let vec: Vec2<f64> = random();
|
||||
let rotation: Rotation2<f64> = Rotation2::new(axis_ang);
|
||||
let vector: Vector2<f64> = random();
|
||||
|
||||
let delta = na::angle_between(&vec, &(rot * vec));
|
||||
let delta = na::angle_between(&vector, &(rotation * vector));
|
||||
|
||||
assert!(na::approx_eq(&ang, &delta))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue