2013-05-21 23:25:01 +08:00
/*!
2013-10-06 22:54:09 +08:00
# nalgebra
2013-05-21 23:25:01 +08:00
2013-10-06 22:54:09 +08:00
* * nalgebra * * is a linear algebra library written for Rust targeting :
2014-06-10 03:48:24 +08:00
* general - purpose linear algebra ( still lacks a lot of features … ) .
2013-10-06 22:54:09 +08:00
* real time computer graphics .
* real time computer physics .
2014-06-10 03:48:24 +08:00
An on - line version of this documentation is available [ here ] ( http ://nalgebra.org).
2013-10-08 08:10:35 +08:00
2013-10-06 22:54:09 +08:00
## Using * * nalgebra * *
2014-09-29 01:20:22 +08:00
All the functionalities of * * nalgebra * * are grouped in one place : the root ` nalgebra ::` module .
2013-10-14 16:22:32 +08:00
This module re - exports everything and includes free functions for all traits methods doing
out - of - place modifications .
2013-10-06 22:54:09 +08:00
2014-01-14 16:52:18 +08:00
* You can import the whole prelude using :
2013-10-06 22:54:09 +08:00
2014-02-18 19:13:40 +08:00
` ` ` . ignore
2014-09-29 01:20:22 +08:00
use nalgebra ::* ;
2013-10-06 22:54:09 +08:00
` ` `
2014-01-14 16:52:18 +08:00
The preferred way to use * * nalgebra * * is to import types and traits explicitly , and call
2013-10-14 16:22:32 +08:00
free - functions using the ` na ::` prefix :
` ` ` . rust
2014-09-29 01:20:22 +08:00
extern crate " nalgebra " as na ;
use na ::{ Vec3 , Rot3 , Rotation } ;
2013-10-14 16:22:32 +08:00
fn main ( ) {
2013-10-14 17:22:38 +08:00
let a = Vec3 ::new ( 1.0 f64 , 1.0 , 1.0 ) ;
let mut b = Rot3 ::new ( na ::zero ( ) ) ;
2013-10-14 16:22:32 +08:00
b . append_rotation ( & a ) ;
2014-01-14 16:52:18 +08:00
assert! ( na ::approx_eq ( & na ::rotation ( & b ) , & a ) ) ;
2013-10-14 16:22:32 +08:00
}
` ` `
2013-10-06 22:54:09 +08:00
## Features
* * nalgebra * * is meant to be a general - purpose linear algebra library ( but is very far from that … ) ,
and keeps an optimized set of tools for computational graphics and physics . Those features include :
2013-10-08 07:22:56 +08:00
* Vectors with static sizes : ` Vec0 ` , ` Vec1 ` , ` Vec2 ` , ` Vec3 ` , ` Vec4 ` , ` Vec5 ` , ` Vec6 ` .
* Square matrices with static sizes : ` Mat1 ` , ` Mat2 ` , ` Mat3 ` , ` Mat4 ` , ` Mat5 ` , ` Mat6 ` .
2013-10-06 22:54:09 +08:00
* Rotation matrices : ` Rot2 ` , ` Rot3 ` , ` Rot4 ` .
* Isometries : ` Iso2 ` , ` Iso3 ` , ` Iso4 ` .
* Dynamically sized vector : ` DVec ` .
* Dynamically sized ( square or rectangular ) matrix : ` DMat ` .
2013-10-07 01:28:52 +08:00
* A few methods for data analysis : ` Cov ` , ` Mean ` .
2013-10-07 01:32:31 +08:00
* Almost one trait per functionality : useful for generic programming .
2013-10-06 22:54:09 +08:00
* Operator overloading using the double trait dispatch
[ trick ] ( http ://smallcultfollowing.com/babysteps/blog/2012/10/04/refining-traits-slash-impls/).
2013-10-08 07:22:56 +08:00
For example , the following works :
2013-10-06 22:54:09 +08:00
` ` ` rust
2014-09-29 01:20:22 +08:00
extern crate " nalgebra " as na ;
use na ::{ Vec3 , Mat3 } ;
2013-10-06 22:54:09 +08:00
fn main ( ) {
2013-10-08 07:59:15 +08:00
let v : Vec3 < f64 > = na ::zero ( ) ;
let m : Mat3 < f64 > = na ::one ( ) ;
2013-10-06 22:54:09 +08:00
2014-07-05 16:24:43 +08:00
let _ = m * v ; // matrix-vector multiplication.
let _ = v * m ; // vector-matrix multiplication.
let _ = m * m ; // matrix-matrix multiplication.
let _ = v * 2.0 f64 ; // vector-scalar multiplication.
2013-10-06 22:54:09 +08:00
}
` ` `
## Compilation
2014-07-14 23:56:35 +08:00
You will need the last nightly build of the [ rust compiler ] ( http ://www.rust-lang.org)
and the official package manager : [ cargo ] ( https ://github.com/rust-lang/cargo).
2013-10-06 22:54:09 +08:00
2014-07-14 23:56:35 +08:00
Simply add the following to your ` Cargo . toml ` file :
2013-10-06 22:54:09 +08:00
2014-02-18 19:13:40 +08:00
` ` ` . ignore
2014-07-14 23:56:35 +08:00
[ dependencies . nalgebra ]
git = " https://github.com/sebcrozet/nalgebra "
2013-10-06 22:54:09 +08:00
` ` `
2014-07-14 23:56:35 +08:00
2013-10-06 22:54:09 +08:00
## * * nalgebra * * in use
Here are some projects using * * nalgebra * * .
Feel free to add your project to this list if you happen to use * * nalgebra * * !
* [ nphysics ] ( https ://github.com/sebcrozet/nphysics): a real-time physics engine.
* [ ncollide ] ( https ://github.com/sebcrozet/ncollide): a collision detection library.
* [ kiss3d ] ( https ://github.com/sebcrozet/kiss3d): a minimalistic graphics engine.
* [ frog ] ( https ://github.com/natal/frog): a machine learning library.
2013-05-21 23:25:01 +08:00
* /
2013-12-24 18:46:16 +08:00
2014-04-02 04:58:06 +08:00
#![ deny(non_camel_case_types) ]
#![ deny(unnecessary_parens) ]
#![ deny(non_uppercase_statics) ]
#![ deny(unnecessary_qualification) ]
#![ deny(unused_result) ]
#![ warn(missing_doc) ]
#![ feature(macro_rules) ]
2014-09-29 01:20:22 +08:00
#![ feature(globs) ]
2014-06-10 03:48:24 +08:00
#![ doc(html_root_url = " http://nalgebra.org/doc " ) ]
2013-05-15 05:08:29 +08:00
2014-03-14 05:44:14 +08:00
extern crate rand ;
2014-02-18 19:13:40 +08:00
extern crate serialize ;
2013-05-15 05:08:29 +08:00
2014-02-22 16:09:04 +08:00
#[ cfg(test) ]
extern crate test ;
2014-06-01 21:21:45 +08:00
#[ cfg(test) ]
extern crate debug ;
2014-02-22 16:09:04 +08:00
2014-09-29 01:20:22 +08:00
use std ::num ::{ Zero , One , FloatMath } ;
use std ::cmp ;
pub use traits ::{ PartialLess , PartialEqual , PartialGreater , NotComparable } ;
pub use traits ::{
Absolute ,
AbsoluteRotate ,
AnyVec ,
ApproxEq ,
Basis ,
Cast ,
Col ,
ColSlice , RowSlice ,
Cov ,
Cross ,
CrossMatrix ,
Det ,
Diag ,
Dim ,
Dot ,
Eye ,
FloatVec ,
FloatVecExt ,
FromHomogeneous ,
Indexable ,
Inv ,
Iterable ,
IterableMut ,
LMul ,
Mat ,
Mean ,
Norm ,
Outer ,
PartialOrd ,
PartialOrdering ,
RMul ,
Rotate , Rotation , RotationMatrix , RotationWithTranslation ,
Row ,
ScalarAdd , ScalarSub ,
ScalarMul , ScalarDiv ,
ToHomogeneous ,
Transform , Transformation ,
Translate , Translation ,
Transpose ,
UniformSphereSample ,
VecExt
} ;
pub use structs ::{
Identity ,
DMat ,
DVec , DVec1 , DVec2 , DVec3 , DVec4 , DVec5 , DVec6 ,
Iso2 , Iso3 , Iso4 ,
Mat1 , Mat2 , Mat3 , Mat4 ,
Mat5 , Mat6 ,
Rot2 , Rot3 , Rot4 ,
Vec0 , Vec1 , Vec2 , Vec3 , Vec4 , Vec5 , Vec6
} ;
pub use linalg ::{
qr ,
eigen_qr ,
householder_matrix
} ;
#[ deprecated = " use the root module `nalgebra::` directly instead of the `nalgebra::na::` module (you may create an alias `extern crate \" nalgebra \" as na;` when importing the crate) " ]
2013-10-06 22:54:09 +08:00
pub mod na ;
2014-01-14 16:40:12 +08:00
mod structs ;
mod traits ;
2014-05-10 04:14:37 +08:00
mod linalg ;
2013-05-15 05:08:29 +08:00
2013-09-22 16:58:21 +08:00
// mod lower_triangular;
// mod chol;
2014-09-29 01:20:22 +08:00
/*
* Reexport everything .
* /
/// Traits to work around the language limitations related to operator overloading.
///
/// The trait names are formed by:
///
/// * a type name (eg. Vec1, Vec2, Mat3, Mat4, etc.).
/// * the name of a binary operation (eg. Mul, Div, Add, Sub, etc.).
/// * the word `Rhs`.
///
/// When implemented by the type `T`, the trait makes it possible to overload the binary operator
/// between `T` and the type name given by the trait.
///
/// # Examples:
///
/// * `Vec3MulRhs` will allow the overload of the `*` operator between the implementor type and
/// `Vec3`. The `Vec3` being the first argument of the multiplication.
/// * `Mat4DivRhs` will allow the overload of the `/` operator between the implementor type and
/// `Mat4`. The `Mat4` being the first argument of the division.
pub mod overload {
pub use structs ::{ Vec1MulRhs , Vec2MulRhs , Vec3MulRhs , Vec4MulRhs , Vec5MulRhs , Vec6MulRhs ,
Vec1DivRhs , Vec2DivRhs , Vec3DivRhs , Vec4DivRhs , Vec5DivRhs , Vec6DivRhs ,
Vec1AddRhs , Vec2AddRhs , Vec3AddRhs , Vec4AddRhs , Vec5AddRhs , Vec6AddRhs ,
Vec1SubRhs , Vec2SubRhs , Vec3SubRhs , Vec4SubRhs , Vec5SubRhs , Vec6SubRhs ,
Mat1MulRhs , Mat2MulRhs , Mat3MulRhs , Mat4MulRhs , Mat5MulRhs , Mat6MulRhs ,
Mat1DivRhs , Mat2DivRhs , Mat3DivRhs , Mat4DivRhs , Mat5DivRhs , Mat6DivRhs ,
Mat1AddRhs , Mat2AddRhs , Mat3AddRhs , Mat4AddRhs , Mat5AddRhs , Mat6AddRhs ,
Mat1SubRhs , Mat2SubRhs , Mat3SubRhs , Mat4SubRhs , Mat5SubRhs , Mat6SubRhs } ;
2013-09-13 19:21:42 +08:00
}
2014-09-29 01:20:22 +08:00
/// Change the input value to ensure it is on the range `[min, max]`.
#[ inline(always) ]
pub fn clamp < T : cmp ::PartialOrd > ( val : T , min : T , max : T ) -> T {
if val > min {
if val < max {
val
}
else {
max
}
}
else {
min
}
}
/// Same as `cmp::max`.
#[ inline(always) ]
pub fn max < T : Ord > ( a : T , b : T ) -> T {
cmp ::max ( a , b )
}
/// Same as `cmp::min`.
#[ inline(always) ]
pub fn min < T : Ord > ( a : T , b : T ) -> T {
cmp ::min ( a , b )
}
/// Returns the infimum of `a` and `b`.
#[ inline(always) ]
pub fn inf < T : PartialOrd > ( a : & T , b : & T ) -> T {
PartialOrd ::inf ( a , b )
}
/// Returns the supremum of `a` and `b`.
#[ inline(always) ]
pub fn sup < T : PartialOrd > ( a : & T , b : & T ) -> T {
PartialOrd ::sup ( a , b )
}
/// Compare `a` and `b` using a partial ordering relation.
#[ inline(always) ]
pub fn partial_cmp < T : PartialOrd > ( a : & T , b : & T ) -> PartialOrdering {
PartialOrd ::partial_cmp ( a , b )
}
/// Returns `true` iff `a` and `b` are comparable and `a < b`.
#[ inline(always) ]
pub fn partial_lt < T : PartialOrd > ( a : & T , b : & T ) -> bool {
PartialOrd ::partial_lt ( a , b )
}
/// Returns `true` iff `a` and `b` are comparable and `a <= b`.
#[ inline(always) ]
pub fn partial_le < T : PartialOrd > ( a : & T , b : & T ) -> bool {
PartialOrd ::partial_le ( a , b )
}
/// Returns `true` iff `a` and `b` are comparable and `a > b`.
#[ inline(always) ]
pub fn partial_gt < T : PartialOrd > ( a : & T , b : & T ) -> bool {
PartialOrd ::partial_gt ( a , b )
}
/// Returns `true` iff `a` and `b` are comparable and `a >= b`.
#[ inline(always) ]
pub fn partial_ge < T : PartialOrd > ( a : & T , b : & T ) -> bool {
PartialOrd ::partial_ge ( a , b )
}
/// Return the minimum of `a` and `b` if they are comparable.
#[ inline(always) ]
pub fn partial_min < ' a , T : PartialOrd > ( a : & ' a T , b : & ' a T ) -> Option < & ' a T > {
PartialOrd ::partial_min ( a , b )
}
/// Return the maximum of `a` and `b` if they are comparable.
#[ inline(always) ]
pub fn partial_max < ' a , T : PartialOrd > ( a : & ' a T , b : & ' a T ) -> Option < & ' a T > {
PartialOrd ::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 : PartialOrd > ( value : & ' a T , min : & ' a T , max : & ' a T ) -> Option < & ' a T > {
PartialOrd ::partial_clamp ( value , min , max )
}
//
//
// Constructors
//
//
/// Create a special identity object.
///
/// Same as `Identity::new()`.
#[ inline(always) ]
pub fn identity ( ) -> Identity {
Identity ::new ( )
}
/// Create a zero-valued value.
///
/// This is the same as `std::num::zero()`.
#[ inline(always) ]
pub fn zero < T : Zero > ( ) -> T {
Zero ::zero ( )
}
/// Create a one-valued value.
///
/// This is the same as `std::num::one()`.
#[ inline(always) ]
pub fn one < T : One > ( ) -> T {
One ::one ( )
}
//
//
// Geometry
//
//
/*
* Perspective
* /
/// Computes a projection matrix given the frustrum near plane width, height, the field of
/// view, and the distance to the clipping planes (`znear` and `zfar`).
pub fn perspective3d < N : FloatMath + Cast < f32 > + Zero + One > ( width : N , height : N , fov : N , znear : N , zfar : N ) -> Mat4 < N > {
let aspect = width / height ;
let _1 : N = one ( ) ;
let sy = _1 / ( fov * cast ( 0.5 ) ) . tan ( ) ;
let sx = - sy / aspect ;
let sz = - ( zfar + znear ) / ( znear - zfar ) ;
let tz = zfar * znear * cast ( 2.0 ) / ( znear - zfar ) ;
Mat4 ::new (
sx , zero ( ) , zero ( ) , zero ( ) ,
zero ( ) , sy , zero ( ) , zero ( ) ,
zero ( ) , zero ( ) , sz , tz ,
zero ( ) , zero ( ) , one ( ) , zero ( ) )
}
/*
* Translation < V >
* /
/// Gets the translation applicable by `m`.
///
/// ```rust
/// extern crate "nalgebra" as na;
/// use na::{Vec3, Iso3};
///
/// fn main() {
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
/// let trans = na::translation(&t);
///
/// assert!(trans == Vec3::new(1.0, 1.0, 1.0));
/// }
/// ```
#[ inline(always) ]
pub fn translation < V , M : Translation < V > > ( m : & M ) -> V {
m . translation ( )
}
/// Gets the inverse translation applicable by `m`.
///
/// ```rust
/// extern crate "nalgebra" as na;
/// use na::{Vec3, Iso3};
///
/// fn main() {
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
/// let itrans = na::inv_translation(&t);
///
/// assert!(itrans == Vec3::new(-1.0, -1.0, -1.0));
/// }
/// ```
#[ inline(always) ]
pub fn inv_translation < V , M : Translation < V > > ( m : & M ) -> V {
m . inv_translation ( )
}
/// Applies the translation `v` to a copy of `m`.
#[ inline(always) ]
pub fn append_translation < V , M : Translation < V > > ( m : & M , v : & V ) -> M {
Translation ::append_translation_cpy ( m , v )
}
/*
* Translate < V >
* /
/// Applies a translation to a vector.
///
/// ```rust
/// extern crate "nalgebra" as na;
/// use na::{Vec3, Iso3};
///
/// fn main() {
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
/// let v = Vec3::new(2.0, 2.0, 2.0);
///
/// let tv = na::translate(&t, &v);
///
/// assert!(tv == Vec3::new(3.0, 3.0, 3.0))
/// }
/// ```
#[ inline(always) ]
pub fn translate < V , M : Translate < V > > ( m : & M , v : & V ) -> V {
m . translate ( v )
}
/// Applies an inverse translation to a vector.
///
/// ```rust
/// extern crate "nalgebra" as na;
/// use na::{Vec3, Iso3};
///
/// fn main() {
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
/// let v = Vec3::new(2.0, 2.0, 2.0);
///
/// let tv = na::inv_translate(&t, &v);
///
/// assert!(na::approx_eq(&tv, &Vec3::new(1.0, 1.0, 1.0)))
/// }
#[ inline(always) ]
pub fn inv_translate < V , M : Translate < V > > ( m : & M , v : & V ) -> V {
m . inv_translate ( v )
}
/*
* Rotation < V >
* /
/// Gets the rotation applicable by `m`.
///
/// ```rust
/// extern crate "nalgebra" as na;
/// use na::{Vec3, Rot3};
///
/// fn main() {
/// let t = Rot3::new(Vec3::new(1.0f64, 1.0, 1.0));
///
/// assert!(na::approx_eq(&na::rotation(&t), &Vec3::new(1.0, 1.0, 1.0)));
/// }
/// ```
#[ inline(always) ]
pub fn rotation < V , M : Rotation < V > > ( m : & M ) -> V {
m . rotation ( )
}
/// Gets the inverse rotation applicable by `m`.
///
/// ```rust
/// extern crate "nalgebra" as na;
/// use na::{Vec3, Rot3};
///
/// fn main() {
/// let t = Rot3::new(Vec3::new(1.0f64, 1.0, 1.0));
///
/// assert!(na::approx_eq(&na::inv_rotation(&t), &Vec3::new(-1.0, -1.0, -1.0)));
/// }
/// ```
#[ inline(always) ]
pub fn inv_rotation < V , M : Rotation < V > > ( m : & M ) -> V {
m . inv_rotation ( )
}
// FIXME: this example is a bit shity
/// Applies the rotation `v` to a copy of `m`.
///
/// ```rust
/// extern crate "nalgebra" as na;
/// use na::{Vec3, Rot3};
///
/// 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 rt = na::append_rotation(&t, &v);
///
/// assert!(na::approx_eq(&na::rotation(&rt), &Vec3::new(1.0, 1.0, 1.0)))
/// }
/// ```
#[ inline(always) ]
pub fn append_rotation < V , M : Rotation < V > > ( m : & M , v : & V ) -> M {
Rotation ::append_rotation_cpy ( m , v )
}
// FIXME: this example is a bit shity
/// Pre-applies the rotation `v` to a copy of `m`.
///
/// ```rust
/// extern crate "nalgebra" as na;
/// use na::{Vec3, Rot3};
///
/// 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 rt = na::prepend_rotation(&t, &v);
///
/// assert!(na::approx_eq(&na::rotation(&rt), &Vec3::new(1.0, 1.0, 1.0)))
/// }
/// ```
#[ inline(always) ]
pub fn prepend_rotation < V , M : Rotation < V > > ( m : & M , v : & V ) -> M {
Rotation ::prepend_rotation_cpy ( m , v )
}
/*
* Rotate < V >
* /
/// Applies a rotation to a vector.
///
/// ```rust
/// extern crate "nalgebra" as na;
/// use std::num::Float;
/// use na::{Rot3, Vec3};
///
/// fn main() {
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.5 * Float::pi()));
/// let v = Vec3::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)))
/// }
/// ```
#[ inline(always) ]
pub fn rotate < V , M : Rotate < V > > ( m : & M , v : & V ) -> V {
m . rotate ( v )
}
/// Applies an inverse rotation to a vector.
///
/// ```rust
/// extern crate "nalgebra" as na;
/// use std::num::Float;
/// use na::{Rot3, Vec3};
///
/// fn main() {
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.5 * Float::pi()));
/// let v = Vec3::new(1.0, 0.0, 0.0);
///
/// let tv = na::inv_rotate(&t, &v);
///
/// assert!(na::approx_eq(&tv, &Vec3::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 )
}
/*
* RotationWithTranslation < LV , AV >
* /
/// Rotates a copy of `m` by `amount` using `center` as the pivot point.
#[ inline(always) ]
pub fn append_rotation_wrt_point < LV : Neg < LV > ,
AV ,
M : RotationWithTranslation < LV , AV > > (
m : & M ,
amount : & AV ,
center : & LV ) -> M {
RotationWithTranslation ::append_rotation_wrt_point_cpy ( m , amount , center )
}
/// Rotates a copy of `m` by `amount` using `m.translation()` as the pivot point.
#[ inline(always) ]
pub fn append_rotation_wrt_center < LV : Neg < LV > ,
AV ,
M : RotationWithTranslation < LV , AV > > (
m : & M ,
amount : & AV ) -> M {
RotationWithTranslation ::append_rotation_wrt_center_cpy ( m , amount )
}
/*
* RotationMatrix < LV , AV , R >
* /
/// Builds a rotation matrix from `r`.
#[ inline(always) ]
pub fn to_rot_mat < LV , AV , M : Mat < LV , LV > + Rotation < AV > , R : RotationMatrix < LV , AV , M > > ( r : & R ) -> M {
r . to_rot_mat ( )
}
/*
* AbsoluteRotate < V >
* /
/// Applies a rotation using the absolute values of its components.
#[ inline(always) ]
pub fn absolute_rotate < V , M : AbsoluteRotate < V > > ( m : & M , v : & V ) -> V {
m . absolute_rotate ( v )
}
/*
* Transformation < T >
* /
/// Gets the transformation applicable by `m`.
#[ inline(always) ]
pub fn transformation < T , M : Transformation < T > > ( m : & M ) -> T {
m . transformation ( )
}
/// Gets the inverse transformation applicable by `m`.
#[ inline(always) ]
pub fn inv_transformation < T , M : Transformation < T > > ( m : & M ) -> T {
m . inv_transformation ( )
}
/// Gets a transformed copy of `m`.
#[ inline(always) ]
pub fn append_transformation < T , M : Transformation < T > > ( m : & M , t : & T ) -> M {
Transformation ::append_transformation_cpy ( m , t )
}
/*
* Transform < V >
* /
/// Applies a transformation to a vector.
#[ inline(always) ]
pub fn transform < V , M : Transform < V > > ( m : & M , v : & V ) -> V {
m . transform ( 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 )
}
/*
* Dot < N >
* /
/// Computes the dot product of two vectors.
#[ inline(always) ]
pub fn dot < V : Dot < N > , N > ( a : & V , b : & V ) -> N {
Dot ::dot ( a , b )
}
/// Computes a subtraction followed by a dot product.
#[ inline(always) ]
pub fn sub_dot < V : Dot < N > , N > ( a : & V , b : & V , c : & V ) -> N {
Dot ::sub_dot ( a , b , c )
}
/*
* Norm < N >
* /
/// Computes the L2 norm of a vector.
#[ inline(always) ]
pub fn norm < V : Norm < N > , N : Float > ( v : & V ) -> N {
Norm ::norm ( v )
}
/// Computes the squared L2 norm of a vector.
#[ inline(always) ]
pub fn sqnorm < V : Norm < N > , N : Float > ( v : & V ) -> N {
Norm ::sqnorm ( v )
2013-05-19 01:04:03 +08:00
}
2014-09-29 01:20:22 +08:00
/// Gets the normalized version of a vector.
#[ inline(always) ]
pub fn normalize < V : Norm < N > , N : Float > ( v : & V ) -> V {
Norm ::normalize_cpy ( v )
}
/*
* Det < N >
* /
/// Computes the determinant of a square matrix.
#[ inline(always) ]
pub fn det < M : Det < N > , N > ( m : & M ) -> N {
Det ::det ( m )
}
/*
* Cross < V >
* /
/// Computes the cross product of two vectors.
#[ inline(always) ]
pub fn cross < LV : Cross < AV > , AV > ( a : & LV , b : & LV ) -> AV {
Cross ::cross ( a , b )
}
/*
* CrossMatrix < M >
* /
/// Given a vector, computes the matrix which, when multiplied by another vector, computes a cross
/// product.
#[ inline(always) ]
pub fn cross_matrix < V : CrossMatrix < M > , M > ( v : & V ) -> M {
CrossMatrix ::cross_matrix ( v )
}
/*
* ToHomogeneous < U >
* /
/// Converts a matrix or vector to homogeneous coordinates.
#[ inline(always) ]
pub fn to_homogeneous < M : ToHomogeneous < Res > , Res > ( m : & M ) -> Res {
ToHomogeneous ::to_homogeneous ( m )
}
/*
* FromHomogeneous < U >
* /
/// Converts a matrix or vector from homogeneous coordinates.
///
/// w-normalization is appied.
#[ inline(always) ]
pub fn from_homogeneous < M , Res : FromHomogeneous < M > > ( m : & M ) -> Res {
FromHomogeneous ::from ( m )
}
/*
* UniformSphereSample
* /
/// Samples the unit sphere living on the dimension as the samples types.
///
/// The number of sampling point is implementation-specific. It is always uniform.
#[ inline(always) ]
pub fn sample_sphere < V : UniformSphereSample > ( f : | V | -> ( ) ) {
UniformSphereSample ::sample ( f )
}
//
//
// Operations
//
//
/*
* AproxEq < N >
* /
/// Tests approximate equality.
#[ inline(always) ]
pub fn approx_eq < T : ApproxEq < N > , N > ( a : & T , b : & T ) -> bool {
ApproxEq ::approx_eq ( a , b )
}
/// Tests approximate equality using a custom epsilon.
#[ inline(always) ]
pub fn approx_eq_eps < T : ApproxEq < N > , N > ( a : & T , b : & T , eps : & N ) -> bool {
ApproxEq ::approx_eq_eps ( a , b , eps )
}
/*
* Absolute < A >
* /
/// Computes a component-wise absolute value.
#[ inline(always) ]
pub fn abs < M : Absolute < Res > , Res > ( m : & M ) -> Res {
Absolute ::abs ( m )
}
/*
* Inv
* /
/// Gets an inverted copy of a matrix.
#[ inline(always) ]
pub fn inv < M : Inv > ( m : & M ) -> Option < M > {
Inv ::inv_cpy ( m )
}
/*
* Transpose
* /
/// Gets a transposed copy of a matrix.
#[ inline(always) ]
pub fn transpose < M : Transpose > ( m : & M ) -> M {
Transpose ::transpose_cpy ( m )
}
/*
* Outer < M >
* /
/// Computes the outer product of two vectors.
#[ inline(always) ]
pub fn outer < V : Outer < M > , M > ( a : & V , b : & V ) -> M {
Outer ::outer ( a , b )
}
/*
* Cov < M >
* /
/// Computes the covariance of a set of observations.
#[ inline(always) ]
pub fn cov < M : Cov < Res > , Res > ( observations : & M ) -> Res {
Cov ::cov ( observations )
}
/*
* Mean < N >
* /
/// Computes the mean of a set of observations.
#[ inline(always) ]
pub fn mean < N , M : Mean < N > > ( observations : & M ) -> N {
Mean ::mean ( observations )
}
//
//
// Structure
//
//
/*
* Eye
* /
/// Construct the identity matrix for a given dimension
#[ inline(always) ]
pub fn new_identity < M : Eye > ( dim : uint ) -> M {
Eye ::new_identity ( dim )
}
/*
* Basis
* /
/// Computes the canonical basis for a given dimension.
#[ inline(always) ]
pub fn canonical_basis < V : Basis > ( f : | V | -> bool ) {
Basis ::canonical_basis ( f )
}
/// Computes the basis of the orthonormal subspace of a given vector.
#[ inline(always) ]
pub fn orthonormal_subspace_basis < V : Basis > ( v : & V , f : | V | -> bool ) {
Basis ::orthonormal_subspace_basis ( v , f )
}
/*
* Row < R >
* /
/*
* Col < C >
* /
/*
* Diag < V >
* /
/// Gets the diagonal of a square matrix.
#[ inline(always) ]
pub fn diag < M : Diag < V > , V > ( m : & M ) -> V {
m . diag ( )
}
/*
* Dim
* /
/// Gets the dimension an object lives in.
///
/// Same as `Dim::dim::(None::<V>)`.
#[ inline(always) ]
pub fn dim < V : Dim > ( ) -> uint {
Dim ::dim ( None ::< V > )
}
/*
* Cast < T >
* /
/// Converts an object from one type to another.
///
/// 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
/// 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)
/// * 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).
/// * A cast does not affect the dimension of an algebraic object. Note that this prevents an
/// isometric transform to be cast to a raw matrix. Use `to_homogeneous` for that special purpose.
#[ inline(always) ]
pub fn cast < T , U : Cast < T > > ( t : T ) -> U {
Cast ::from ( t )
}
/*
* Indexable
* /