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
|
||||
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]
|
||||
### Modified
|
||||
* 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
|
||||
arbitrary = [ "quickcheck" ]
|
||||
generic_sizes = [ "generic-array", "typenum" ]
|
||||
abstract_algebra = [ "algebra" ]
|
||||
|
||||
[dependencies]
|
||||
rustc-serialize = "0.3.*"
|
||||
rand = "0.3.*"
|
||||
num = "0.1.*"
|
||||
# algebra = "*"
|
||||
|
||||
[dependencies.generic-array]
|
||||
optional = true
|
||||
@ -37,3 +37,7 @@ version = "1.3.*"
|
||||
[dependencies.quickcheck]
|
||||
optional = true
|
||||
version = "0.2.*"
|
||||
|
||||
[dependencies.algebra]
|
||||
optional = true
|
||||
version = "0.2.*"
|
||||
|
8
Makefile
8
Makefile
@ -1,18 +1,18 @@
|
||||
tmp=_git_distcheck
|
||||
|
||||
all:
|
||||
cargo build --release --features "arbitrary generic_sizes"
|
||||
cargo build --release --features "arbitrary generic_sizes abstract_algebra"
|
||||
|
||||
test:
|
||||
cargo test --features "arbitrary generic_sizes"
|
||||
cargo test --features "arbitrary generic_sizes abstract_algebra"
|
||||
|
||||
|
||||
bench:
|
||||
cargo bench --features "arbitrary generic_sizes"
|
||||
cargo bench --features "arbitrary generic_sizes abstract_algebra"
|
||||
|
||||
|
||||
doc:
|
||||
cargo doc --no-deps --features "arbitrary generic_sizes"
|
||||
cargo doc --no-deps --features "arbitrary generic_sizes abstract_algebra"
|
||||
|
||||
|
||||
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`.
|
||||
* Square matrices with static sizes: `Matrix1`, `Matrix2`, `Matrix3`, `Matrix4`, `Matrix5`, `Matrix6 `.
|
||||
* 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`
|
||||
* Similarity transformations (translation ⨯ rotation ⨯ uniform scale): `Similarity2`, `Similarity3`.
|
||||
* 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 `.
|
||||
* Rotation matrices: `Rotation2`, `Rotation3`
|
||||
* Quaternions: `Quaternion`, `UnitQuaternion`.
|
||||
* Unit-sized values (unit vectors, unit quaternions, etc.): `Unit<T>`, e.g., `Unit<Vector3<f32>>`.
|
||||
* Isometries (translation ⨯ rotation): `Isometry2`, `Isometry3`
|
||||
* Similarity transformations (translation ⨯ rotation ⨯ uniform scale): `Similarity2`, `Similarity3`.
|
||||
* 3D projections for computer graphics: `Perspective3`, `PerspectiveMatrix3`, `Orthographic3`, `OrthographicMatrix3`.
|
||||
@ -85,6 +86,9 @@ extern crate generic_array;
|
||||
#[cfg(feature="arbitrary")]
|
||||
extern crate quickcheck;
|
||||
|
||||
#[cfg(feature="abstract_algebra")]
|
||||
extern crate algebra;
|
||||
|
||||
use std::cmp;
|
||||
use std::ops::{Neg, Mul};
|
||||
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::geometry::{ToHomogeneous, FromHomogeneous, Origin};
|
||||
use linalg;
|
||||
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
#[cfg(feature="abstract_algebra")]
|
||||
use_matrix_group_modules!();
|
||||
|
||||
|
||||
/// Special identity matrix. All its operation are no-ops.
|
||||
#[repr(C)]
|
||||
|
@ -2,6 +2,9 @@
|
||||
|
||||
macro_rules! matrix_impl(
|
||||
($t: ident, $dimension: expr, $vector: ident, $dvector: ident, $($compN: ident),+) => (
|
||||
|
||||
matrix_group_approx_impl!($t, $($compN),+);
|
||||
|
||||
impl<N> $t<N> {
|
||||
#[inline]
|
||||
pub fn new($($compN: N ),+) -> $t<N> {
|
||||
|
@ -17,6 +17,7 @@ pub use self::unit::Unit;
|
||||
pub use self::vectorn::VectorN;
|
||||
|
||||
mod common_macros;
|
||||
mod algebra;
|
||||
mod dmatrix_macros;
|
||||
mod dmatrix;
|
||||
mod vectorn_macros;
|
||||
|
@ -12,9 +12,13 @@ use traits::structure::{Cast, Dimension, Indexable, Iterable, IterableMut, Point
|
||||
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};
|
||||
|
||||
#[cfg(feature="abstract_algebra")]
|
||||
use_euclidean_space_modules!();
|
||||
|
||||
|
||||
/// Point of dimension 1.
|
||||
///
|
||||
|
@ -3,6 +3,8 @@
|
||||
macro_rules! point_impl(
|
||||
($t: ident, $tv: ident | $($compN: ident),+) => (
|
||||
|
||||
euclidean_space_impl!($t, $tv);
|
||||
|
||||
/*
|
||||
*
|
||||
* Origin.
|
||||
|
@ -17,7 +17,7 @@ use traits::geometry::{Norm, Rotation, RotationMatrix, Rotate, RotationTo, Trans
|
||||
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)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Quaternion<N> {
|
||||
|
@ -11,9 +11,12 @@ 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};
|
||||
|
||||
#[cfg(feature="abstract_algebra")]
|
||||
use_special_orthogonal_group_modules!();
|
||||
|
||||
/// Two dimensional rotation matrix.
|
||||
#[repr(C)]
|
||||
|
@ -2,6 +2,9 @@
|
||||
|
||||
macro_rules! rotation_impl(
|
||||
($t: ident, $submatrix: ident, $vector: ident, $rotvector: ident, $point: ident, $homogeneous: ident) => (
|
||||
|
||||
special_orthogonal_group_impl!($t, $point, $vector);
|
||||
|
||||
impl<N> $t<N> {
|
||||
/// This rotation's underlying matrix.
|
||||
#[inline]
|
||||
|
@ -2,6 +2,8 @@ use traits::geometry::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)]
|
||||
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
||||
pub struct Unit<T> {
|
||||
@ -47,7 +49,7 @@ impl<T: Norm> Unit<T> {
|
||||
/// Normalizes this value again. This is useful when repeated computations
|
||||
/// 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]
|
||||
pub fn renormalize(&mut self) -> T::NormType {
|
||||
self.v.normalize_mut()
|
||||
|
@ -17,6 +17,9 @@ use structs::point::{Point1, Point2, Point3, Point4, Point5, Point6};
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
#[cfg(feature="abstract_algebra")]
|
||||
use_vector_space_modules!();
|
||||
|
||||
|
||||
/// Vector of dimension 1.
|
||||
///
|
||||
@ -29,7 +32,7 @@ pub struct Vector1<N> {
|
||||
pub x: N
|
||||
}
|
||||
|
||||
vector_impl!(Vector1, Point1, x);
|
||||
vector_impl!(Vector1, Point1, 1, x);
|
||||
vectorlike_impl!(Vector1, 1, x);
|
||||
from_iterator_impl!(Vector1, iterator);
|
||||
// (specialized); basis_impl!(Vector1, 1);
|
||||
@ -51,7 +54,7 @@ pub struct Vector2<N> {
|
||||
pub y: N
|
||||
}
|
||||
|
||||
vector_impl!(Vector2, Point2, x, y);
|
||||
vector_impl!(Vector2, Point2, 2, x, y);
|
||||
vectorlike_impl!(Vector2, 2, x, y);
|
||||
from_iterator_impl!(Vector2, iterator, iterator);
|
||||
// (specialized); basis_impl!(Vector2, 1);
|
||||
@ -75,7 +78,7 @@ pub struct Vector3<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);
|
||||
from_iterator_impl!(Vector3, iterator, iterator, iterator);
|
||||
// (specialized); basis_impl!(Vector3, 1);
|
||||
@ -100,7 +103,7 @@ pub struct Vector4<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);
|
||||
from_iterator_impl!(Vector4, iterator, iterator, iterator, iterator);
|
||||
basis_impl!(Vector4, 4);
|
||||
@ -128,7 +131,7 @@ pub struct Vector5<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);
|
||||
from_iterator_impl!(Vector5, iterator, iterator, iterator, iterator, iterator);
|
||||
basis_impl!(Vector5, 5);
|
||||
@ -157,7 +160,7 @@ pub struct Vector6<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);
|
||||
from_iterator_impl!(Vector6, iterator, iterator, iterator, iterator, iterator, iterator);
|
||||
|
||||
|
@ -270,7 +270,7 @@ macro_rules! vectorlike_impl(
|
||||
);
|
||||
|
||||
macro_rules! vector_impl(
|
||||
($t: ident, $tp: ident, $($compN: ident),+) => (
|
||||
($t: ident, $tp: ident, $dimension: expr, $($compN: ident),+) => (
|
||||
pointwise_add!($t, $($compN),+);
|
||||
pointwise_sub!($t, $($compN),+);
|
||||
pointwise_mul!($t, $($compN),+);
|
||||
@ -279,7 +279,7 @@ macro_rules! vector_impl(
|
||||
componentwise_one!($t, $($compN),+);
|
||||
componentwise_absolute!($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> {
|
||||
#[inline]
|
||||
fn dot(&self, other: &$t<N>) -> N {
|
||||
add!($(self.$compN * other.$compN ),+)
|
||||
fold_add!($(self.$compN * other.$compN ),+)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* 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(
|
||||
($t: ident, $param0: ident) => (
|
||||
|
@ -11,7 +11,7 @@ use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat, Base
|
||||
#[cfg(feature="arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
/// A static array of arbitrary dimension.
|
||||
/// A stack-allocated vector of arbitrary dimension.
|
||||
#[repr(C)]
|
||||
#[derive(Eq, PartialEq, Debug)] // FIXME: Hash, RustcEncodable, RustcDecodable
|
||||
pub struct VectorN<N, D: ArrayLength<N>> {
|
||||
|
Loading…
Reference in New Issue
Block a user