forked from M-Labs/nalgebra
Merge pull request #196 from sebcrozet/algebra
Implement traits from the algebra crate.
This commit is contained in:
commit
e68f8cdb08
@ -43,6 +43,10 @@ longer unsafe. Instead, their name end with `_unchecked`. In particular:
|
|||||||
well. It is clear that performing computations with floats requires
|
well. It is clear that performing computations with floats requires
|
||||||
approximate equality.
|
approximate equality.
|
||||||
|
|
||||||
|
Still WIP: add implementations of abstract algebra traits from the `algebra`
|
||||||
|
crate for vectors, rotations and points. To enable them, activate the
|
||||||
|
`abstract_algebra` feature.
|
||||||
|
|
||||||
## [0.8.0]
|
## [0.8.0]
|
||||||
### Modified
|
### Modified
|
||||||
* Almost everything (types, methods, and traits) now use full names instead
|
* Almost everything (types, methods, and traits) now use full names instead
|
||||||
|
@ -19,12 +19,12 @@ path = "src/lib.rs"
|
|||||||
# Generate arbitrary instances of nalgebra types for testing with quickcheck
|
# Generate arbitrary instances of nalgebra types for testing with quickcheck
|
||||||
arbitrary = [ "quickcheck" ]
|
arbitrary = [ "quickcheck" ]
|
||||||
generic_sizes = [ "generic-array", "typenum" ]
|
generic_sizes = [ "generic-array", "typenum" ]
|
||||||
|
abstract_algebra = [ "algebra" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rustc-serialize = "0.3.*"
|
rustc-serialize = "0.3.*"
|
||||||
rand = "0.3.*"
|
rand = "0.3.*"
|
||||||
num = "0.1.*"
|
num = "0.1.*"
|
||||||
# algebra = "*"
|
|
||||||
|
|
||||||
[dependencies.generic-array]
|
[dependencies.generic-array]
|
||||||
optional = true
|
optional = true
|
||||||
@ -37,3 +37,7 @@ version = "1.3.*"
|
|||||||
[dependencies.quickcheck]
|
[dependencies.quickcheck]
|
||||||
optional = true
|
optional = true
|
||||||
version = "0.2.*"
|
version = "0.2.*"
|
||||||
|
|
||||||
|
[dependencies.algebra]
|
||||||
|
optional = true
|
||||||
|
version = "0.2.*"
|
||||||
|
8
Makefile
8
Makefile
@ -1,18 +1,18 @@
|
|||||||
tmp=_git_distcheck
|
tmp=_git_distcheck
|
||||||
|
|
||||||
all:
|
all:
|
||||||
cargo build --release --features "arbitrary generic_sizes"
|
cargo build --release --features "arbitrary generic_sizes abstract_algebra"
|
||||||
|
|
||||||
test:
|
test:
|
||||||
cargo test --features "arbitrary generic_sizes"
|
cargo test --features "arbitrary generic_sizes abstract_algebra"
|
||||||
|
|
||||||
|
|
||||||
bench:
|
bench:
|
||||||
cargo bench --features "arbitrary generic_sizes"
|
cargo bench --features "arbitrary generic_sizes abstract_algebra"
|
||||||
|
|
||||||
|
|
||||||
doc:
|
doc:
|
||||||
cargo doc --no-deps --features "arbitrary generic_sizes"
|
cargo doc --no-deps --features "arbitrary generic_sizes abstract_algebra"
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
@ -59,7 +59,8 @@ an optimized set of tools for computer graphics and physics. Those features incl
|
|||||||
* Points with static sizes: `Point1`, `Point2`, `Point3`, `Point4`, `Point5`, `Point6`.
|
* Points with static sizes: `Point1`, `Point2`, `Point3`, `Point4`, `Point5`, `Point6`.
|
||||||
* Square matrices with static sizes: `Matrix1`, `Matrix2`, `Matrix3`, `Matrix4`, `Matrix5`, `Matrix6 `.
|
* Square matrices with static sizes: `Matrix1`, `Matrix2`, `Matrix3`, `Matrix4`, `Matrix5`, `Matrix6 `.
|
||||||
* Rotation matrices: `Rotation2`, `Rotation3`
|
* Rotation matrices: `Rotation2`, `Rotation3`
|
||||||
* Quaternions: `Quaternion`, `UnitQuaternion`.
|
* Quaternions: `Quaternion`, `Unit<Quaternion>`.
|
||||||
|
* Unit-sized values (unit vectors, unit quaternions, etc.): `Unit<T>`, e.g., `Unit<Vector3<f32>>`.
|
||||||
* Isometries (translation ⨯ rotation): `Isometry2`, `Isometry3`
|
* Isometries (translation ⨯ rotation): `Isometry2`, `Isometry3`
|
||||||
* Similarity transformations (translation ⨯ rotation ⨯ uniform scale): `Similarity2`, `Similarity3`.
|
* Similarity transformations (translation ⨯ rotation ⨯ uniform scale): `Similarity2`, `Similarity3`.
|
||||||
* 3D projections for computer graphics: `Persp3`, `PerspMatrix3`, `Ortho3`, `OrthoMatrix3`.
|
* 3D projections for computer graphics: `Persp3`, `PerspMatrix3`, `Ortho3`, `OrthoMatrix3`.
|
||||||
|
@ -47,6 +47,7 @@ an optimized set of tools for computer graphics and physics. Those features incl
|
|||||||
* Square matrices with static sizes: `Matrix1`, `Matrix2`, `Matrix3`, `Matrix4`, `Matrix5`, `Matrix6 `.
|
* Square matrices with static sizes: `Matrix1`, `Matrix2`, `Matrix3`, `Matrix4`, `Matrix5`, `Matrix6 `.
|
||||||
* Rotation matrices: `Rotation2`, `Rotation3`
|
* Rotation matrices: `Rotation2`, `Rotation3`
|
||||||
* Quaternions: `Quaternion`, `UnitQuaternion`.
|
* Quaternions: `Quaternion`, `UnitQuaternion`.
|
||||||
|
* Unit-sized values (unit vectors, unit quaternions, etc.): `Unit<T>`, e.g., `Unit<Vector3<f32>>`.
|
||||||
* Isometries (translation ⨯ rotation): `Isometry2`, `Isometry3`
|
* Isometries (translation ⨯ rotation): `Isometry2`, `Isometry3`
|
||||||
* Similarity transformations (translation ⨯ rotation ⨯ uniform scale): `Similarity2`, `Similarity3`.
|
* Similarity transformations (translation ⨯ rotation ⨯ uniform scale): `Similarity2`, `Similarity3`.
|
||||||
* 3D projections for computer graphics: `Perspective3`, `PerspectiveMatrix3`, `Orthographic3`, `OrthographicMatrix3`.
|
* 3D projections for computer graphics: `Perspective3`, `PerspectiveMatrix3`, `Orthographic3`, `OrthographicMatrix3`.
|
||||||
@ -85,6 +86,9 @@ extern crate generic_array;
|
|||||||
#[cfg(feature="arbitrary")]
|
#[cfg(feature="arbitrary")]
|
||||||
extern crate quickcheck;
|
extern crate quickcheck;
|
||||||
|
|
||||||
|
#[cfg(feature="abstract_algebra")]
|
||||||
|
extern crate algebra;
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::ops::{Neg, Mul};
|
use std::ops::{Neg, Mul};
|
||||||
use num::{Zero, One};
|
use num::{Zero, One};
|
||||||
|
17
src/structs/algebra/dummy.rs
Normal file
17
src/structs/algebra/dummy.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#![macro_use]
|
||||||
|
|
||||||
|
macro_rules! vector_space_impl(
|
||||||
|
($t: ident, $dimension: expr, $($compN: ident),+) => { }
|
||||||
|
);
|
||||||
|
|
||||||
|
macro_rules! special_orthogonal_group_impl(
|
||||||
|
($t: ident, $point: ident, $vector: ident) => { }
|
||||||
|
);
|
||||||
|
|
||||||
|
macro_rules! euclidean_space_impl(
|
||||||
|
($t: ident, $vector: ident) => { }
|
||||||
|
);
|
||||||
|
|
||||||
|
macro_rules! matrix_group_approx_impl(
|
||||||
|
($t: ident, $($compN: ident),+) => { }
|
||||||
|
);
|
25
src/structs/algebra/matrix.rs
Normal file
25
src/structs/algebra/matrix.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#![macro_use]
|
||||||
|
|
||||||
|
macro_rules! use_matrix_group_modules(
|
||||||
|
() => {
|
||||||
|
use algebra::cmp::ApproxEq as AlgebraApproxEq;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
macro_rules! matrix_group_approx_impl(
|
||||||
|
($t: ident, $($compN: ident),+) => {
|
||||||
|
impl<N: AlgebraApproxEq> AlgebraApproxEq for $t<N> {
|
||||||
|
type Eps = N::Eps;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn default_epsilon() -> N::Eps {
|
||||||
|
N::default_epsilon()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N::Eps) -> bool {
|
||||||
|
$(AlgebraApproxEq::approx_eq_eps(&self.$compN, &other.$compN, &epsilon))&&+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
13
src/structs/algebra/mod.rs
Normal file
13
src/structs/algebra/mod.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#![macro_use]
|
||||||
|
|
||||||
|
#[cfg(not(feature="abstract_algebra"))]
|
||||||
|
mod dummy;
|
||||||
|
|
||||||
|
#[cfg(feature="abstract_algebra")]
|
||||||
|
mod vector;
|
||||||
|
#[cfg(feature="abstract_algebra")]
|
||||||
|
mod rotation;
|
||||||
|
#[cfg(feature="abstract_algebra")]
|
||||||
|
mod point;
|
||||||
|
#[cfg(feature="abstract_algebra")]
|
||||||
|
mod matrix;
|
34
src/structs/algebra/point.rs
Normal file
34
src/structs/algebra/point.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#![macro_use]
|
||||||
|
|
||||||
|
macro_rules! use_euclidean_space_modules(
|
||||||
|
() => {
|
||||||
|
use algebra::structure::{AffineSpaceApprox, EuclideanSpaceApprox,
|
||||||
|
FieldApprox, RealApprox};
|
||||||
|
use algebra::cmp::ApproxEq as AlgebraApproxEq;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
macro_rules! euclidean_space_impl(
|
||||||
|
($t: ident, $vector: ident) => {
|
||||||
|
impl<N> AffineSpaceApprox<N> for $t<N>
|
||||||
|
where N: Copy + Neg<Output = N> + Add<N, Output = N> +
|
||||||
|
Sub<N, Output = N> + AlgebraApproxEq + FieldApprox {
|
||||||
|
type Translation = $vector<N>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn translate_by(&self, vector: &Self::Translation) -> Self {
|
||||||
|
*self + *vector
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn subtract(&self, other: &Self) -> Self::Translation {
|
||||||
|
*self - *other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: RealApprox> EuclideanSpaceApprox<N> for $t<N> {
|
||||||
|
type Vector = $vector<N>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
92
src/structs/algebra/rotation.rs
Normal file
92
src/structs/algebra/rotation.rs
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#![macro_use]
|
||||||
|
|
||||||
|
macro_rules! use_special_orthogonal_group_modules(
|
||||||
|
() => {
|
||||||
|
use algebra::structure::{EuclideanGroupApprox, SpecialEuclideanGroupApprox,
|
||||||
|
OrthogonalGroupApprox, SpecialOrthogonalGroupApprox,
|
||||||
|
GroupApprox, LoopApprox, MonoidApprox,
|
||||||
|
QuasigroupApprox, SemigroupApprox,
|
||||||
|
RealApprox};
|
||||||
|
use algebra::cmp::ApproxEq as AlgebraApproxEq;
|
||||||
|
use algebra::ident::Identity;
|
||||||
|
use algebra::ops::{Recip, Multiplicative};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
macro_rules! special_orthogonal_group_impl(
|
||||||
|
($t: ident, $point: ident, $vector: ident) => {
|
||||||
|
/*
|
||||||
|
* Operations.
|
||||||
|
*/
|
||||||
|
impl<N: BaseNum> Identity<Multiplicative> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn id() -> Self {
|
||||||
|
::one()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + AlgebraApproxEq<Eps = N>> AlgebraApproxEq for $t<N> {
|
||||||
|
type Eps = N;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn default_epsilon() -> N {
|
||||||
|
<N as AlgebraApproxEq>::default_epsilon()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N) -> bool {
|
||||||
|
AlgebraApproxEq::approx_eq_eps(&self.submatrix, &other.submatrix, &epsilon)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Copy> Recip for $t<N> {
|
||||||
|
type Result = $t<N>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn recip(mut self) -> $t<N> {
|
||||||
|
self.inverse_mut();
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Algebraic structures.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
// FIXME: in the end, we will keep only RealApprox.
|
||||||
|
impl<N: BaseNum + RealApprox> GroupApprox<Multiplicative> for $t<N> { }
|
||||||
|
impl<N: BaseNum + RealApprox> LoopApprox<Multiplicative> for $t<N> { }
|
||||||
|
impl<N: BaseNum + RealApprox> MonoidApprox<Multiplicative> for $t<N> { }
|
||||||
|
impl<N: BaseNum + RealApprox> QuasigroupApprox<Multiplicative> for $t<N> { }
|
||||||
|
impl<N: BaseNum + RealApprox> SemigroupApprox<Multiplicative> for $t<N> { }
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Matrix groups.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
impl<N: BaseNum + RealApprox> EuclideanGroupApprox<N, $point<N>> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn transform_point(&self, pt: &$point<N>) -> $point<N> {
|
||||||
|
*self * *pt
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn transform_vector(&self, v: &$vector<N>) -> $vector<N> {
|
||||||
|
*self * *v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: BaseNum + RealApprox> SpecialEuclideanGroupApprox<N, $point<N>> for $t<N> {
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: BaseNum + RealApprox> OrthogonalGroupApprox<N, $point<N>> for $t<N> {
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: BaseNum + RealApprox> SpecialOrthogonalGroupApprox<N, $point<N>> for $t<N> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
186
src/structs/algebra/vector.rs
Normal file
186
src/structs/algebra/vector.rs
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
#![macro_use]
|
||||||
|
|
||||||
|
macro_rules! use_vector_space_modules(
|
||||||
|
() => {
|
||||||
|
use algebra::structure::{FieldApprox, RingCommutativeApprox, GroupAbelianApprox,
|
||||||
|
GroupApprox, LoopApprox, MonoidApprox, QuasigroupApprox,
|
||||||
|
SemigroupApprox, VectorSpaceApprox, ModuleApprox,
|
||||||
|
NormedSpaceApprox, InnerSpaceApprox,
|
||||||
|
FiniteDimVectorSpaceApprox,
|
||||||
|
Field, RingCommutative, GroupAbelian,
|
||||||
|
Group, Loop, Monoid, Quasigroup,
|
||||||
|
Semigroup, VectorSpace, Module, RealApprox};
|
||||||
|
use algebra::cmp::ApproxEq as AlgebraApproxEq;
|
||||||
|
use algebra::ident::Identity;
|
||||||
|
use algebra::ops::Additive;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
macro_rules! vector_space_impl(
|
||||||
|
($t: ident, $dimension: expr, $($compN: ident),+) => {
|
||||||
|
/*
|
||||||
|
* Identity & ApproxEq
|
||||||
|
*/
|
||||||
|
impl<N: Copy + Identity<Additive>> Identity<Additive> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn id() -> Self {
|
||||||
|
Repeat::repeat(Identity::id())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: AlgebraApproxEq> AlgebraApproxEq for $t<N> {
|
||||||
|
type Eps = N::Eps;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn default_epsilon() -> N::Eps {
|
||||||
|
N::default_epsilon()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N::Eps) -> bool {
|
||||||
|
$(AlgebraApproxEq::approx_eq_eps(&self.$compN, &other.$compN, &epsilon))&&+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Approximate algebraic structures.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
product_space_inherit_structure!($t, GroupAbelianApprox<Additive>);
|
||||||
|
product_space_inherit_structure!($t, GroupApprox<Additive>);
|
||||||
|
product_space_inherit_structure!($t, LoopApprox<Additive>);
|
||||||
|
product_space_inherit_structure!($t, MonoidApprox<Additive>);
|
||||||
|
product_space_inherit_structure!($t, QuasigroupApprox<Additive>);
|
||||||
|
product_space_inherit_structure!($t, SemigroupApprox<Additive>);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module.
|
||||||
|
*/
|
||||||
|
impl<N> ModuleApprox<N> for $t<N> where N: Copy + Neg<Output = N> + Add<N, Output = N> +
|
||||||
|
AlgebraApproxEq + RingCommutativeApprox
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Vector spaces.
|
||||||
|
*/
|
||||||
|
impl<N> VectorSpaceApprox<N> for $t<N>
|
||||||
|
where N: Copy + Neg<Output = N> + Add<N, Output = N> +
|
||||||
|
AlgebraApproxEq + FieldApprox { }
|
||||||
|
|
||||||
|
impl<N> FiniteDimVectorSpaceApprox<N> for $t<N>
|
||||||
|
where N: Copy + Zero + One + Neg<Output = N> + Add<N, Output = N> +
|
||||||
|
AlgebraApproxEq + FieldApprox {
|
||||||
|
#[inline]
|
||||||
|
fn dimension() -> usize {
|
||||||
|
$dimension
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn canonical_basis<F: FnOnce(&[$t<N>])>(f: F) {
|
||||||
|
let basis = [
|
||||||
|
$($t::$compN()),*
|
||||||
|
];
|
||||||
|
|
||||||
|
f(&basis[..])
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn component(&self, i: usize) -> N {
|
||||||
|
self[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn component_unchecked(&self, i: usize) -> N {
|
||||||
|
self.at_fast(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: RealApprox> NormedSpaceApprox<N> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn norm_squared(&self) -> N {
|
||||||
|
self.inner_product(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn norm(&self) -> N {
|
||||||
|
self.norm_squared().sqrt()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn normalize(&self) -> Self {
|
||||||
|
*self / self.norm()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn normalize_mut(&mut self) -> N {
|
||||||
|
let n = self.norm();
|
||||||
|
*self /= n;
|
||||||
|
|
||||||
|
n
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn try_normalize(&self, min_norm: &N) -> Option<Self> {
|
||||||
|
let n = self.norm();
|
||||||
|
|
||||||
|
if n <= *min_norm {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Some(*self / n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn try_normalize_mut(&mut self, min_norm: &N) -> Option<N> {
|
||||||
|
let n = self.norm();
|
||||||
|
|
||||||
|
if n <= *min_norm {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*self /= n;
|
||||||
|
Some(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: RealApprox> InnerSpaceApprox<N> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn inner_product(&self, other: &Self) -> N {
|
||||||
|
fold_add!($(self.$compN * other.$compN ),+)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Exact algebraic structures.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
product_space_inherit_structure!($t, GroupAbelian<Additive>);
|
||||||
|
product_space_inherit_structure!($t, Group<Additive>);
|
||||||
|
product_space_inherit_structure!($t, Loop<Additive>);
|
||||||
|
product_space_inherit_structure!($t, Monoid<Additive>);
|
||||||
|
product_space_inherit_structure!($t, Quasigroup<Additive>);
|
||||||
|
product_space_inherit_structure!($t, Semigroup<Additive>);
|
||||||
|
|
||||||
|
impl<N> VectorSpace<N> for $t<N>
|
||||||
|
where N: Copy + Neg<Output = N> + Add<N, Output = N> + AlgebraApproxEq + Field
|
||||||
|
{ }
|
||||||
|
|
||||||
|
impl<N> Module<N> for $t<N>
|
||||||
|
where N: Copy + Neg<Output = N> + Add<N, Output = N> + AlgebraApproxEq + RingCommutative
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
macro_rules! product_space_inherit_structure(
|
||||||
|
($t: ident, $marker: ident<$operator: ident>) => {
|
||||||
|
impl<N> $marker<$operator> for $t<N>
|
||||||
|
where N: Copy + Neg<Output = N> + Add<N, Output = N> + AlgebraApproxEq +
|
||||||
|
$marker<$operator>
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
);
|
@ -349,3 +349,16 @@ macro_rules! component_new(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
macro_rules! fold_add(
|
||||||
|
// base case
|
||||||
|
($x:expr) => {
|
||||||
|
$x
|
||||||
|
};
|
||||||
|
// `$x` followed by at least one `$y,`
|
||||||
|
($x:expr, $($y:expr),+) => {
|
||||||
|
// call min! on the tail `$y`
|
||||||
|
Add::add($x, fold_add!($($y),+))
|
||||||
|
}
|
||||||
|
);
|
||||||
|
@ -18,9 +18,13 @@ use traits::structure::{Cast, Row, Column, Iterable, IterableMut, Dimension, Ind
|
|||||||
use traits::operations::{Absolute, Transpose, Inverse, Outer, EigenQR, Mean};
|
use traits::operations::{Absolute, Transpose, Inverse, Outer, EigenQR, Mean};
|
||||||
use traits::geometry::{ToHomogeneous, FromHomogeneous, Origin};
|
use traits::geometry::{ToHomogeneous, FromHomogeneous, Origin};
|
||||||
use linalg;
|
use linalg;
|
||||||
|
|
||||||
#[cfg(feature="arbitrary")]
|
#[cfg(feature="arbitrary")]
|
||||||
use quickcheck::{Arbitrary, Gen};
|
use quickcheck::{Arbitrary, Gen};
|
||||||
|
|
||||||
|
#[cfg(feature="abstract_algebra")]
|
||||||
|
use_matrix_group_modules!();
|
||||||
|
|
||||||
|
|
||||||
/// Special identity matrix. All its operation are no-ops.
|
/// Special identity matrix. All its operation are no-ops.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
macro_rules! matrix_impl(
|
macro_rules! matrix_impl(
|
||||||
($t: ident, $dimension: expr, $vector: ident, $dvector: ident, $($compN: ident),+) => (
|
($t: ident, $dimension: expr, $vector: ident, $dvector: ident, $($compN: ident),+) => (
|
||||||
|
|
||||||
|
matrix_group_approx_impl!($t, $($compN),+);
|
||||||
|
|
||||||
impl<N> $t<N> {
|
impl<N> $t<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new($($compN: N ),+) -> $t<N> {
|
pub fn new($($compN: N ),+) -> $t<N> {
|
||||||
|
@ -17,6 +17,7 @@ pub use self::unit::Unit;
|
|||||||
pub use self::vectorn::VectorN;
|
pub use self::vectorn::VectorN;
|
||||||
|
|
||||||
mod common_macros;
|
mod common_macros;
|
||||||
|
mod algebra;
|
||||||
mod dmatrix_macros;
|
mod dmatrix_macros;
|
||||||
mod dmatrix;
|
mod dmatrix;
|
||||||
mod vectorn_macros;
|
mod vectorn_macros;
|
||||||
|
@ -12,9 +12,13 @@ use traits::structure::{Cast, Dimension, Indexable, Iterable, IterableMut, Point
|
|||||||
NumPoint, FloatPoint, BaseFloat, BaseNum, Bounded, Repeat};
|
NumPoint, FloatPoint, BaseFloat, BaseNum, Bounded, Repeat};
|
||||||
use traits::geometry::{Origin, FromHomogeneous, ToHomogeneous};
|
use traits::geometry::{Origin, FromHomogeneous, ToHomogeneous};
|
||||||
use structs::vector::{Vector1, Vector2, Vector3, Vector4, Vector5, Vector6};
|
use structs::vector::{Vector1, Vector2, Vector3, Vector4, Vector5, Vector6};
|
||||||
|
|
||||||
#[cfg(feature="arbitrary")]
|
#[cfg(feature="arbitrary")]
|
||||||
use quickcheck::{Arbitrary, Gen};
|
use quickcheck::{Arbitrary, Gen};
|
||||||
|
|
||||||
|
#[cfg(feature="abstract_algebra")]
|
||||||
|
use_euclidean_space_modules!();
|
||||||
|
|
||||||
|
|
||||||
/// Point of dimension 1.
|
/// Point of dimension 1.
|
||||||
///
|
///
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
macro_rules! point_impl(
|
macro_rules! point_impl(
|
||||||
($t: ident, $tv: ident | $($compN: ident),+) => (
|
($t: ident, $tv: ident | $($compN: ident),+) => (
|
||||||
|
|
||||||
|
euclidean_space_impl!($t, $tv);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Origin.
|
* Origin.
|
||||||
|
@ -17,7 +17,7 @@ use traits::geometry::{Norm, Rotation, RotationMatrix, Rotate, RotationTo, Trans
|
|||||||
use quickcheck::{Arbitrary, Gen};
|
use quickcheck::{Arbitrary, Gen};
|
||||||
|
|
||||||
|
|
||||||
/// A quaternion. See `UnitQuaternion` for a quaternion that can be used as a rotation.
|
/// A quaternion. See the `UnitQuaternion` type alias for a quaternion that can be used as a rotation.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||||
pub struct Quaternion<N> {
|
pub struct Quaternion<N> {
|
||||||
|
@ -11,9 +11,12 @@ use traits::operations::{Absolute, Inverse, Transpose, ApproxEq};
|
|||||||
use structs::vector::{Vector1, Vector2, Vector3};
|
use structs::vector::{Vector1, Vector2, Vector3};
|
||||||
use structs::point::{Point2, Point3};
|
use structs::point::{Point2, Point3};
|
||||||
use structs::matrix::{Matrix2, Matrix3, Matrix4};
|
use structs::matrix::{Matrix2, Matrix3, Matrix4};
|
||||||
|
|
||||||
#[cfg(feature="arbitrary")]
|
#[cfg(feature="arbitrary")]
|
||||||
use quickcheck::{Arbitrary, Gen};
|
use quickcheck::{Arbitrary, Gen};
|
||||||
|
|
||||||
|
#[cfg(feature="abstract_algebra")]
|
||||||
|
use_special_orthogonal_group_modules!();
|
||||||
|
|
||||||
/// Two dimensional rotation matrix.
|
/// Two dimensional rotation matrix.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
macro_rules! rotation_impl(
|
macro_rules! rotation_impl(
|
||||||
($t: ident, $submatrix: ident, $vector: ident, $rotvector: ident, $point: ident, $homogeneous: ident) => (
|
($t: ident, $submatrix: ident, $vector: ident, $rotvector: ident, $point: ident, $homogeneous: ident) => (
|
||||||
|
|
||||||
|
special_orthogonal_group_impl!($t, $point, $vector);
|
||||||
|
|
||||||
impl<N> $t<N> {
|
impl<N> $t<N> {
|
||||||
/// This rotation's underlying matrix.
|
/// This rotation's underlying matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -2,6 +2,8 @@ use traits::geometry::Norm;
|
|||||||
|
|
||||||
|
|
||||||
/// A wrapper that ensures the undelying algebraic entity has a unit norm.
|
/// A wrapper that ensures the undelying algebraic entity has a unit norm.
|
||||||
|
///
|
||||||
|
/// Use `.as_ref()` or `.unwrap()` to obtain the undelying value by-reference or by-move.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||||
pub struct Unit<T> {
|
pub struct Unit<T> {
|
||||||
@ -47,7 +49,7 @@ impl<T: Norm> Unit<T> {
|
|||||||
/// Normalizes this value again. This is useful when repeated computations
|
/// Normalizes this value again. This is useful when repeated computations
|
||||||
/// might cause a drift in the norm because of float inaccuracies.
|
/// might cause a drift in the norm because of float inaccuracies.
|
||||||
///
|
///
|
||||||
/// Returns the norm beform re-normalization (should be close to `1.0`).
|
/// Returns the norm before re-normalization (should be close to `1.0`).
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn renormalize(&mut self) -> T::NormType {
|
pub fn renormalize(&mut self) -> T::NormType {
|
||||||
self.v.normalize_mut()
|
self.v.normalize_mut()
|
||||||
|
@ -17,6 +17,9 @@ use structs::point::{Point1, Point2, Point3, Point4, Point5, Point6};
|
|||||||
#[cfg(feature="arbitrary")]
|
#[cfg(feature="arbitrary")]
|
||||||
use quickcheck::{Arbitrary, Gen};
|
use quickcheck::{Arbitrary, Gen};
|
||||||
|
|
||||||
|
#[cfg(feature="abstract_algebra")]
|
||||||
|
use_vector_space_modules!();
|
||||||
|
|
||||||
|
|
||||||
/// Vector of dimension 1.
|
/// Vector of dimension 1.
|
||||||
///
|
///
|
||||||
@ -29,7 +32,7 @@ pub struct Vector1<N> {
|
|||||||
pub x: N
|
pub x: N
|
||||||
}
|
}
|
||||||
|
|
||||||
vector_impl!(Vector1, Point1, x);
|
vector_impl!(Vector1, Point1, 1, x);
|
||||||
vectorlike_impl!(Vector1, 1, x);
|
vectorlike_impl!(Vector1, 1, x);
|
||||||
from_iterator_impl!(Vector1, iterator);
|
from_iterator_impl!(Vector1, iterator);
|
||||||
// (specialized); basis_impl!(Vector1, 1);
|
// (specialized); basis_impl!(Vector1, 1);
|
||||||
@ -51,7 +54,7 @@ pub struct Vector2<N> {
|
|||||||
pub y: N
|
pub y: N
|
||||||
}
|
}
|
||||||
|
|
||||||
vector_impl!(Vector2, Point2, x, y);
|
vector_impl!(Vector2, Point2, 2, x, y);
|
||||||
vectorlike_impl!(Vector2, 2, x, y);
|
vectorlike_impl!(Vector2, 2, x, y);
|
||||||
from_iterator_impl!(Vector2, iterator, iterator);
|
from_iterator_impl!(Vector2, iterator, iterator);
|
||||||
// (specialized); basis_impl!(Vector2, 1);
|
// (specialized); basis_impl!(Vector2, 1);
|
||||||
@ -75,7 +78,7 @@ pub struct Vector3<N> {
|
|||||||
pub z: N
|
pub z: N
|
||||||
}
|
}
|
||||||
|
|
||||||
vector_impl!(Vector3, Point3, x, y, z);
|
vector_impl!(Vector3, Point3, 3, x, y, z);
|
||||||
vectorlike_impl!(Vector3, 3, x, y, z);
|
vectorlike_impl!(Vector3, 3, x, y, z);
|
||||||
from_iterator_impl!(Vector3, iterator, iterator, iterator);
|
from_iterator_impl!(Vector3, iterator, iterator, iterator);
|
||||||
// (specialized); basis_impl!(Vector3, 1);
|
// (specialized); basis_impl!(Vector3, 1);
|
||||||
@ -100,7 +103,7 @@ pub struct Vector4<N> {
|
|||||||
pub w: N
|
pub w: N
|
||||||
}
|
}
|
||||||
|
|
||||||
vector_impl!(Vector4, Point4, x, y, z, w);
|
vector_impl!(Vector4, Point4, 4, x, y, z, w);
|
||||||
vectorlike_impl!(Vector4, 4, x, y, z, w);
|
vectorlike_impl!(Vector4, 4, x, y, z, w);
|
||||||
from_iterator_impl!(Vector4, iterator, iterator, iterator, iterator);
|
from_iterator_impl!(Vector4, iterator, iterator, iterator, iterator);
|
||||||
basis_impl!(Vector4, 4);
|
basis_impl!(Vector4, 4);
|
||||||
@ -128,7 +131,7 @@ pub struct Vector5<N> {
|
|||||||
pub a: N
|
pub a: N
|
||||||
}
|
}
|
||||||
|
|
||||||
vector_impl!(Vector5, Point5, x, y, z, w, a);
|
vector_impl!(Vector5, Point5, 5, x, y, z, w, a);
|
||||||
vectorlike_impl!(Vector5, 5, x, y, z, w, a);
|
vectorlike_impl!(Vector5, 5, x, y, z, w, a);
|
||||||
from_iterator_impl!(Vector5, iterator, iterator, iterator, iterator, iterator);
|
from_iterator_impl!(Vector5, iterator, iterator, iterator, iterator, iterator);
|
||||||
basis_impl!(Vector5, 5);
|
basis_impl!(Vector5, 5);
|
||||||
@ -157,7 +160,7 @@ pub struct Vector6<N> {
|
|||||||
pub b: N
|
pub b: N
|
||||||
}
|
}
|
||||||
|
|
||||||
vector_impl!(Vector6, Point6, x, y, z, w, a, b);
|
vector_impl!(Vector6, Point6, 6, x, y, z, w, a, b);
|
||||||
vectorlike_impl!(Vector6, 6, x, y, z, w, a, b);
|
vectorlike_impl!(Vector6, 6, x, y, z, w, a, b);
|
||||||
from_iterator_impl!(Vector6, iterator, iterator, iterator, iterator, iterator, iterator);
|
from_iterator_impl!(Vector6, iterator, iterator, iterator, iterator, iterator, iterator);
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ macro_rules! vectorlike_impl(
|
|||||||
);
|
);
|
||||||
|
|
||||||
macro_rules! vector_impl(
|
macro_rules! vector_impl(
|
||||||
($t: ident, $tp: ident, $($compN: ident),+) => (
|
($t: ident, $tp: ident, $dimension: expr, $($compN: ident),+) => (
|
||||||
pointwise_add!($t, $($compN),+);
|
pointwise_add!($t, $($compN),+);
|
||||||
pointwise_sub!($t, $($compN),+);
|
pointwise_sub!($t, $($compN),+);
|
||||||
pointwise_mul!($t, $($compN),+);
|
pointwise_mul!($t, $($compN),+);
|
||||||
@ -279,7 +279,7 @@ macro_rules! vector_impl(
|
|||||||
componentwise_one!($t, $($compN),+);
|
componentwise_one!($t, $($compN),+);
|
||||||
componentwise_absolute!($t, $($compN),+);
|
componentwise_absolute!($t, $($compN),+);
|
||||||
component_basis_element!($t, $($compN),+);
|
component_basis_element!($t, $($compN),+);
|
||||||
|
vector_space_impl!($t, $dimension, $($compN),+);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
@ -289,11 +289,10 @@ macro_rules! vector_impl(
|
|||||||
impl<N: BaseNum> Dot<N> for $t<N> {
|
impl<N: BaseNum> Dot<N> for $t<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn dot(&self, other: &$t<N>) -> N {
|
fn dot(&self, other: &$t<N>) -> N {
|
||||||
add!($(self.$compN * other.$compN ),+)
|
fold_add!($(self.$compN * other.$compN ),+)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Norm
|
* Norm
|
||||||
@ -597,18 +596,6 @@ macro_rules! basis_impl(
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
macro_rules! add (
|
|
||||||
// base case
|
|
||||||
($x:expr) => {
|
|
||||||
$x
|
|
||||||
};
|
|
||||||
// `$x` followed by at least one `$y,`
|
|
||||||
($x:expr, $($y:expr),+) => {
|
|
||||||
// call min! on the tail `$y`
|
|
||||||
Add::add($x, add!($($y),+))
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
macro_rules! from_iterator_impl(
|
macro_rules! from_iterator_impl(
|
||||||
($t: ident, $param0: ident) => (
|
($t: ident, $param0: ident) => (
|
||||||
|
@ -11,7 +11,7 @@ use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat, Base
|
|||||||
#[cfg(feature="arbitrary")]
|
#[cfg(feature="arbitrary")]
|
||||||
use quickcheck::{Arbitrary, Gen};
|
use quickcheck::{Arbitrary, Gen};
|
||||||
|
|
||||||
/// A static array of arbitrary dimension.
|
/// A stack-allocated vector of arbitrary dimension.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Eq, PartialEq, Debug)] // FIXME: Hash, RustcEncodable, RustcDecodable
|
#[derive(Eq, PartialEq, Debug)] // FIXME: Hash, RustcEncodable, RustcDecodable
|
||||||
pub struct VectorN<N, D: ArrayLength<N>> {
|
pub struct VectorN<N, D: ArrayLength<N>> {
|
||||||
|
Loading…
Reference in New Issue
Block a user