diff --git a/README.md b/README.md index b71abd92..e31a8137 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,8 @@ An on-line version of this documentation is available [here](http://crozet.re/na ## Using **nalgebra** All the functionalities of **nalgebra** are grouped in one place: the `na` module. -This module re-exports everything and includes free functions for all traits methods. -Free functions are useful if you prefer doing something like `na::dot(v1, v2)` instead of -`v1.dot(v2)`. +This module re-exports everything and includes free functions for all traits methods doing +out-of-place modifications. * You can import the whole prelude, including free functions, using: @@ -31,8 +30,23 @@ use nalgebra::traits::*; ```.rust use nalgebra::structs::*; ``` -Of course, you can still import `nalgebra::na` alone, and get anything you want using the prefix -`na`. +The preffered way to use **nalgebra** is to import types and traits explicitly, and call +free-functions using the `na::` prefix: + +```.rust +extern mod nalgebra; +use nalgebra::na::{Vec3, Rot3, Rotation}; +use nalgebra::na; + +fn main() { + let a = Vec3::new(1.0f64, 1.0, 1.0); + let mut b = Rot3::new(na::zero()); + + b.append_rotation(&a); + + assert!(na::rotation(&b).approx_eq(&a)); +} +``` ## Features **nalgebra** is meant to be a general-purpose linear algebra library (but is very far from that…), diff --git a/src/lib.rs b/src/lib.rs index aadc5418..366b977b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,12 +36,12 @@ free-functions using the `na::` prefix: ```.rust extern mod nalgebra; -use nalgebra::na::{Rot3, Rotation}; +use nalgebra::na::{Vec3, Rot3, Rotation}; use nalgebra::na; fn main() { - let a = na::vec3(1.0f64, 1.0, 1.0); - let mut b: Rot3 = na::one(); + let a = Vec3::new(1.0f64, 1.0, 1.0); + let mut b = Rot3::new(na::zero()); b.append_rotation(&a); diff --git a/src/na.rs b/src/na.rs index 421a3c91..c920825f 100644 --- a/src/na.rs +++ b/src/na.rs @@ -77,85 +77,6 @@ pub fn one() -> T { One::one() } -/// Creates a new 1d vector. -/// -/// This is the same as `Vec1::new(x)`. -#[inline(always)] -pub fn vec1(x: N) -> Vec1 { - Vec1::new(x) -} - -/// Creates a new 2d vector. -/// -/// This is the same as `Vec2::new(x, y)`. -#[inline(always)] -pub fn vec2(x: N, y: N) -> Vec2 { - Vec2::new(x, y) -} - -/// Creates a new 3d vector. -/// -/// This is the same as `Vec3::new(x, y, z)`. -#[inline(always)] -pub fn vec3(x: N, y: N, z: N) -> Vec3 { - Vec3::new(x, y, z) -} - -/// Creates a new 4d vector. -/// -/// This is the same as `Vec4::new(x, y, z, w)`. -#[inline(always)] -pub fn vec4(x: N, y: N, z: N, w: N) -> Vec4 { - Vec4::new(x, y, z, w) -} - -/// Creates a new 1d matrix. -/// -/// This is the same as `Mat1::new(...)`. -#[inline(always)] -pub fn mat1(m11: N) -> Mat1 { - Mat1::new(m11) -} - -/// Creates a new 2d matrix. -/// -/// This is the same as `Mat2::new(...)`. -#[inline(always)] -pub fn mat2(m11: N, m12: N, - m21: N, m22: N) -> Mat2 { - Mat2::new( - m11, m12, - m21, m22) -} - -/// Creates a new 3d matrix. -/// -/// This is the same as `Mat3::new(...)`. -#[inline(always)] -pub fn mat3(m11: N, m12: N, m13: N, - m21: N, m22: N, m23: N, - m31: N, m32: N, m33: N) -> Mat3 { - Mat3::new( - m11, m12, m13, - m21, m22, m23, - m31, m32, m33) -} - -/// Creates a new 4d matrix. -/// -/// This is the same as `Mat4::new(...)`. -#[inline(always)] -pub fn mat4(m11: N, m12: N, m13: N, m14: N, - m21: N, m22: N, m23: N, m24: N, - m31: N, m32: N, m33: N, m34: N, - m41: N, m42: N, m43: N, m44: N) -> Mat4 { - Mat4::new( - m11, m12, m13, m14, - m21, m22, m23, m24, - m31, m32, m33, m34, - m41, m42, m43, m44) -} - // // // Geometry @@ -170,11 +91,11 @@ pub fn mat4(m11: N, m12: N, m13: N, m14: N, /// /// ```rust /// extern mod nalgebra; -/// use nalgebra::types::{Vec3, Affmat}; +/// use nalgebra::types::{Vec3, Iso3}; /// use nalgebra::na; /// /// pub main() { -/// let t = Affmat::new_translation3d(1.0, 1.0, 1.0); +/// let t = Iso3::new(Vec3::new(1.0, 1.0, 1.0), na::zero()); /// let trans = na::translation(t); /// /// assert!(trans == Vec3::new(1.0, 1.0, 1.0)); @@ -189,11 +110,11 @@ pub fn translation>(m: &M) -> V { /// /// ```rust /// extern mod nalgebra; -/// use nalgebra::types::{Vec3, Affmat}; +/// use nalgebra::types::{Vec3, Iso3}; /// use nalgebra::na; /// /// pub main() { -/// let t = Affmat::new_translation3d(1.0, 1.0, 1.0); +/// let t = Iso3::new(Vec3::new(1.0, 1.0, 1.0), na::zero()); /// let itrans = na::inv_translation(t); /// /// assert!(itrans == Vec3::new(-1.0, -1.0, -1.0)); @@ -218,15 +139,16 @@ pub fn append_translation>(m: &M, v: &V) -> M { /// /// ```rust /// extern mod nalgebra; +/// use nalgebra::na::{Vec3, Iso3}; /// use nalgebra::na; /// /// pub main() { -/// let t = na::translation3d(1.0, 1.0, 1.0); -/// let v = na::vec3(2.0, 2.0, 2.0); +/// let t = Iso3::new(Vec3::new(1.0, 1.0, 1.0), na::zero()); +/// let v = Vec3::new(2.0, 2.0, 2.0); /// /// let tv = na::translate(&t, &v); /// -/// assert!(tv == na::vec3(3.0, 3.0, 3.0)) +/// assert!(tv == Vec3::new(3.0, 3.0, 3.0)) /// } /// ``` #[inline(always)] @@ -238,15 +160,16 @@ pub fn translate>(m: &M, v: &V) -> V { /// /// ```rust /// extern mod nalgebra; +/// use nalgebra::na::{Vec3, Iso3}; /// use nalgebra::na; /// /// pub main() { -/// let t = na::translation3d(1.0, 1.0, 1.0); -/// let v = na::vec3(2.0, 2.0, 2.0); +/// let t = Iso3::new(Vec3::new(1.0, 1.0, 1.0), na::zero()); +/// let v = Vec3::new(2.0, 2.0, 2.0); /// /// let tv = na::translate(&t, &v); /// -/// assert!(tv == na::vec3(1.0, 1.0, 1.0)) +/// assert!(tv == Vec3::new(1.0, 1.0, 1.0)) /// } #[inline(always)] pub fn inv_translate>(m: &M, v: &V) -> V { @@ -261,12 +184,13 @@ pub fn inv_translate>(m: &M, v: &V) -> V { /// /// ```rust /// extern mod nalgebra; +/// use nalgebra::na::{Vec3, Rot3}; /// use nalgebra::na; /// /// pub main() { -/// let t = na::rot3(1.0, 1.0, 1.0); +/// let t = Rot3::new(Vec3::new(1.0, 1.0, 1.0)); /// -/// assert!(na::rotation(t) == na::vec3(1.0, 1.0, 1.0)); +/// assert!(na::rotation(t) == Vec3::new(1.0, 1.0, 1.0)); /// } /// ``` #[inline(always)] @@ -279,12 +203,13 @@ pub fn rotation>(m: &M) -> V { /// /// ```rust /// extern mod nalgebra; +/// use nalgebra::na::{Vec3, Rot3}; /// use nalgebra::na; /// /// pub main() { -/// let t = na::rot3(1.0, 1.0, 1.0); +/// let t = Rot3::new(Vec3::new(1.0, 1.0, 1.0)); /// -/// assert!(na::inv_rotation(t) == na::vec3(-1.0, -1.0, -1.0)); +/// assert!(na::inv_rotation(t) == Vec3::new(-1.0, -1.0, -1.0)); /// } /// ``` #[inline(always)] @@ -296,14 +221,15 @@ pub fn inv_rotation>(m: &M) -> V { /// /// ```rust /// extern mod nalgebra; +/// use nalgebra::na::{Vec3, Rot3}; /// use nalgebra::na; /// /// pub main() { -/// let t = na::rot3(0.0, 0.0, 0.0); -/// let v = na::vec3(1.0, 1.0, 1.0); +/// let t = Rot3::new(Vec3::new(0.0, 0.0, 0.0)); +/// let v = Vec3::new(1.0, 1.0, 1.0); /// let rt = na::append_rotation(&t, &v); /// -/// assert!(na::rotation(&rt) == na::vec3(1.0, 1.0, 1.0)) +/// assert!(na::rotation(&rt) == Vec3::new(1.0, 1.0, 1.0)) /// } /// ``` #[inline(always)] @@ -319,15 +245,16 @@ pub fn append_rotation>(m: &M, v: &V) -> M { /// /// ```rust /// extern mod nalgebra; +/// use nalgebra::na::{Rot3, Vec3}; /// use nalgebra::na; /// /// pub main() { -/// let t = na::rot3(1.0, 0.0, 0.0); -/// let v = na::vec3(0.0, 0.0, na::pi() / 2.0); +/// let t = Rot3::new(Vec3::new(1.0, 0.0, 0.0)); +/// let v = Vec3::new(0.0, 0.0, na::pi() / 2.0); /// /// let tv = na::rotate(&t, &v); /// -/// assert!(tv == na::vec3(0.0, 1.0, 0.0)) +/// assert!(tv == Vec3::new(0.0, 1.0, 0.0)) /// } /// ``` #[inline(always)] @@ -343,12 +270,12 @@ pub fn rotate>(m: &M, v: &V) -> V { /// use nalgebra::na; /// /// pub main() { -/// let t = na::rot3(na::vec3(1.0, 0.0, 0.0)); -/// let v = na::vec3(0.0, 0.0, na::pi() / 2.0); +/// let t = Rot3::new(Vec3::new(1.0, 0.0, 0.0)); +/// let v = Vec3::new(0.0, 0.0, na::pi() / 2.0); /// /// let tv = na::rotate(&t, &v); /// -/// assert!(tv == na::vec3(0.0, -1.0, 0.0)) +/// assert!(tv == Vec3::new(0.0, -1.0, 0.0)) /// } /// ``` #[inline(always)] diff --git a/src/structs/iso.rs b/src/structs/iso.rs index 31f8ea97..2dd9c324 100644 --- a/src/structs/iso.rs +++ b/src/structs/iso.rs @@ -4,13 +4,13 @@ use std::num::{Zero, One}; use std::rand::{Rand, Rng}; -use structs::mat::{Mat3, Mat4, Mat5}; +use structs::mat::{Mat3, Mat4}; use traits::structure::{Cast, Dim, Col}; use traits::operations::{Inv}; use traits::geometry::{RotationMatrix, Rotation, Rotate, AbsoluteRotate, Transform, Transformation, Translate, Translation, ToHomogeneous}; -use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec2MulRhs, Vec3MulRhs, Vec4MulRhs}; +use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec2MulRhs, Vec3MulRhs}; use structs::rot::{Rot2, Rot3, Rot4}; mod metal; @@ -82,7 +82,7 @@ impl Iso3 { } } -iso_impl!(Iso2, Rot2, Vec2) +iso_impl!(Iso2, Rot2, Vec2, Vec1) double_dispatch_binop_decl_trait!(Iso2, Iso2MulRhs) mul_redispatch_impl!(Iso2, Iso2MulRhs) rotation_matrix_impl!(Iso2, Rot2, Vec2, Vec1) @@ -103,7 +103,7 @@ iso_mul_iso_impl!(Iso2, Iso2MulRhs) iso_mul_vec_impl!(Iso2, Vec2, Iso2MulRhs) vec_mul_iso_impl!(Iso2, Vec2, Vec2MulRhs) -iso_impl!(Iso3, Rot3, Vec3) +iso_impl!(Iso3, Rot3, Vec3, Vec3) double_dispatch_binop_decl_trait!(Iso3, Iso3MulRhs) mul_redispatch_impl!(Iso3, Iso3MulRhs) rotation_matrix_impl!(Iso3, Rot3, Vec3, Vec3) @@ -124,7 +124,8 @@ iso_mul_iso_impl!(Iso3, Iso3MulRhs) iso_mul_vec_impl!(Iso3, Vec3, Iso3MulRhs) vec_mul_iso_impl!(Iso3, Vec3, Vec3MulRhs) -iso_impl!(Iso4, Rot4, Vec4) +/* +iso_impl!(Iso4, Rot4, Vec4, Vec4) double_dispatch_binop_decl_trait!(Iso4, Iso4MulRhs) mul_redispatch_impl!(Iso4, Iso4MulRhs) // rotation_matrix_impl!(Iso4, Rot4, Vec4, Vec4) @@ -144,3 +145,4 @@ translate_impl!(Iso4, Vec4) iso_mul_iso_impl!(Iso4, Iso4MulRhs) iso_mul_vec_impl!(Iso4, Vec4, Iso4MulRhs) vec_mul_iso_impl!(Iso4, Vec4, Vec4MulRhs) +*/ diff --git a/src/structs/iso_macros.rs b/src/structs/iso_macros.rs index b2dc92e1..16bdf7de 100644 --- a/src/structs/iso_macros.rs +++ b/src/structs/iso_macros.rs @@ -1,11 +1,20 @@ #[macro_escape]; macro_rules! iso_impl( - ($t: ident, $submat: ident, $subvec: ident) => ( - impl $t { + ($t: ident, $submat: ident, $subvec: ident, $subrotvec: ident) => ( + impl $t { /// Creates a new isometry from a rotation matrix and a vector. #[inline] - pub fn new(translation: $subvec, rotation: $submat) -> $t { + pub fn new(translation: $subvec, rotation: $subrotvec) -> $t { + $t { + rotation: $submat::new(rotation), + translation: translation + } + } + + /// Creates a new isometry from a rotation matrix and a vector. + #[inline] + pub fn new_with_rotmat(translation: $subvec, rotation: $submat) -> $t { $t { rotation: rotation, translation: translation @@ -41,10 +50,10 @@ macro_rules! dim_impl( macro_rules! one_impl( ($t: ident) => ( - impl One for $t { + impl One for $t { #[inline] fn one() -> $t { - $t::new(Zero::zero(), One::one()) + $t::new_with_rotmat(Zero::zero(), One::one()) } } ) @@ -52,10 +61,12 @@ macro_rules! one_impl( macro_rules! iso_mul_iso_impl( ($t: ident, $tmul: ident) => ( - impl $tmul> for $t { + impl $tmul> for $t { #[inline] fn binop(left: &$t, right: &$t) -> $t { - $t::new(left.translation + left.rotation * right.translation, left.rotation * right.rotation) + $t::new_with_rotmat( + left.translation + left.rotation * right.translation, + left.rotation * right.rotation) } } ) @@ -85,7 +96,7 @@ macro_rules! vec_mul_iso_impl( macro_rules! translation_impl( ($t: ident, $tv: ident) => ( - impl + Add + Num + Clone> Translation<$tv> for $t { + impl Translation<$tv> for $t { #[inline] fn translation(&self) -> $tv { self.translation.clone() @@ -103,7 +114,7 @@ macro_rules! translation_impl( #[inline] fn append_translation_cpy(iso: &$t, t: &$tv) -> $t { - $t::new(*t + iso.translation, iso.rotation.clone()) + $t::new_with_rotmat(*t + iso.translation, iso.rotation.clone()) } #[inline] @@ -113,7 +124,7 @@ macro_rules! translation_impl( #[inline] fn prepend_translation_cpy(iso: &$t, t: &$tv) -> $t { - $t::new(iso.translation + iso.rotation * *t, iso.rotation.clone()) + $t::new_with_rotmat(iso.translation + iso.rotation * *t, iso.rotation.clone()) } #[inline] @@ -165,7 +176,7 @@ macro_rules! rotation_impl( fn append_rotation_cpy(t: &$t, rot: &$tav) -> $t { let delta = $trot::new(rot.clone()); - $t::new(delta * t.translation, delta * t.rotation) + $t::new_with_rotmat(delta * t.translation, delta * t.rotation) } #[inline] @@ -179,7 +190,7 @@ macro_rules! rotation_impl( fn prepend_rotation_cpy(t: &$t, rot: &$tav) -> $t { let delta = $trot::new(rot.clone()); - $t::new(t.translation.clone(), t.rotation * delta) + $t::new_with_rotmat(t.translation.clone(), t.rotation * delta) } #[inline] @@ -209,7 +220,7 @@ macro_rules! rotate_impl( macro_rules! transformation_impl( ($t: ident) => ( - impl Transformation<$t> for $t { + impl Transformation<$t> for $t { fn transformation(&self) -> $t { self.clone() } diff --git a/src/tests/mat.rs b/src/tests/mat.rs index 7c10e525..e8e62937 100644 --- a/src/tests/mat.rs +++ b/src/tests/mat.rs @@ -1,7 +1,7 @@ use std::num::{Real, abs}; use std::rand::random; use std::cmp::ApproxEq; -use na::{DMat, DVec}; +use na::{Vec1, DMat, DVec}; use na::Indexable; // FIXME: get rid of that use na; @@ -89,7 +89,7 @@ fn test_inv_mat6() { fn test_rotation2() { do 10000.times { let randmat: na::Rot2 = na::one(); - let ang = na::vec1(abs::(random()) % Real::pi()); + let ang = Vec1::new(abs::(random()) % Real::pi()); assert!(na::rotation(&na::append_rotation(&randmat, &ang)).approx_eq(&ang)); } diff --git a/src/tests/vec.rs b/src/tests/vec.rs index b5cac522..ac2a6c78 100644 --- a/src/tests/vec.rs +++ b/src/tests/vec.rs @@ -1,7 +1,7 @@ use std::rand::{random}; use std::cmp::ApproxEq; use na::{Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6}; -use na::{Iterable, IterableMut}; // FIXME: get rid of that +use na::{Mat3, Iterable, IterableMut}; // FIXME: get rid of that use na; macro_rules! test_iterator_impl( @@ -288,35 +288,35 @@ fn test_iterator_vec6() { #[test] fn test_ord_vec3() { // equality - assert!(na::vec3(0.5, 0.5, 0.5) == na::vec3(0.5, 0.5, 0.5)); - assert!(!(na::vec3(1.5, 0.5, 0.5) == na::vec3(0.5, 0.5, 0.5))); - assert!(na::vec3(1.5, 0.5, 0.5) != na::vec3(0.5, 0.5, 0.5)); + assert!(Vec3::new(0.5, 0.5, 0.5) == Vec3::new(0.5, 0.5, 0.5)); + assert!(!(Vec3::new(1.5, 0.5, 0.5) == Vec3::new(0.5, 0.5, 0.5))); + assert!(Vec3::new(1.5, 0.5, 0.5) != Vec3::new(0.5, 0.5, 0.5)); // comparable - assert!(na::vec3(0.5, 0.3, 0.3) < na::vec3(1.0, 2.0, 1.0)); - assert!(na::vec3(0.5, 0.3, 0.3) <= na::vec3(1.0, 2.0, 1.0)); - assert!(na::vec3(2.0, 4.0, 2.0) > na::vec3(1.0, 2.0, 1.0)); - assert!(na::vec3(2.0, 4.0, 2.0) >= na::vec3(1.0, 2.0, 1.0)); + assert!(Vec3::new(0.5, 0.3, 0.3) < Vec3::new(1.0, 2.0, 1.0)); + assert!(Vec3::new(0.5, 0.3, 0.3) <= Vec3::new(1.0, 2.0, 1.0)); + assert!(Vec3::new(2.0, 4.0, 2.0) > Vec3::new(1.0, 2.0, 1.0)); + assert!(Vec3::new(2.0, 4.0, 2.0) >= Vec3::new(1.0, 2.0, 1.0)); // not comparable - assert!(!(na::vec3(0.0, 3.0, 0.0) < na::vec3(1.0, 2.0, 1.0))); - assert!(!(na::vec3(0.0, 3.0, 0.0) > na::vec3(1.0, 2.0, 1.0))); - assert!(!(na::vec3(0.0, 3.0, 0.0) <= na::vec3(1.0, 2.0, 1.0))); - assert!(!(na::vec3(0.0, 3.0, 0.0) >= na::vec3(1.0, 2.0, 1.0))); + assert!(!(Vec3::new(0.0, 3.0, 0.0) < Vec3::new(1.0, 2.0, 1.0))); + assert!(!(Vec3::new(0.0, 3.0, 0.0) > Vec3::new(1.0, 2.0, 1.0))); + assert!(!(Vec3::new(0.0, 3.0, 0.0) <= Vec3::new(1.0, 2.0, 1.0))); + assert!(!(Vec3::new(0.0, 3.0, 0.0) >= Vec3::new(1.0, 2.0, 1.0))); } #[test] fn test_min_max_vec3() { - assert_eq!(na::vec3(1, 2, 3).max(&na::vec3(3, 2, 1)), na::vec3(3, 2, 3)); - assert_eq!(na::vec3(1, 2, 3).min(&na::vec3(3, 2, 1)), na::vec3(1, 2, 1)); - assert_eq!(na::vec3(0, 2, 4).clamp(&na::vec3(1, 1, 1), &na::vec3(3, 3, 3)), na::vec3(1, 2, 3)); + assert_eq!(Vec3::new(1, 2, 3).max(&Vec3::new(3, 2, 1)), Vec3::new(3, 2, 3)); + assert_eq!(Vec3::new(1, 2, 3).min(&Vec3::new(3, 2, 1)), Vec3::new(1, 2, 1)); + assert_eq!(Vec3::new(0, 2, 4).clamp(&Vec3::new(1, 1, 1), &Vec3::new(3, 3, 3)), Vec3::new(1, 2, 3)); } #[test] fn test_outer_vec3() { assert_eq!( - na::outer(&na::vec3(1, 2, 3), &na::vec3(4, 5, 6)), - na::mat3( + na::outer(&Vec3::new(1, 2, 3), &Vec3::new(4, 5, 6)), + Mat3::new( 4, 5, 6, 8, 10, 12, 12, 15, 18));