Execute rustfmt.

This commit is contained in:
sebcrozet 2018-10-21 22:11:27 +02:00 committed by Sébastien Crozet
parent a3d363f397
commit b9ca074740
41 changed files with 798 additions and 465 deletions

View File

@ -1,9 +1,7 @@
use na::{MatrixMN, VectorN, use na::{
Matrix2, Matrix3, Matrix4, Matrix2, Matrix2x3, Matrix2x4, Matrix3, Matrix3x2, Matrix3x4, Matrix4, Matrix4x2, Matrix4x3,
Matrix2x3, Matrix3x2, Matrix4x2, MatrixMN, Quaternion, VectorN, U1, U2, U3, U4,
Matrix2x4, Matrix3x4, Matrix4x3, };
Quaternion,
U1, U2, U3, U4};
/// A matrix with components of type `N`. It has `R` rows, and `C` columns. /// A matrix with components of type `N`. It has `R` rows, and `C` columns.
/// ///
@ -194,13 +192,13 @@ pub type UVec3 = TVec3<u32>;
/// A 4D vector with `u32` components. /// A 4D vector with `u32` components.
pub type UVec4 = TVec4<u32>; pub type UVec4 = TVec4<u32>;
/// A 1D vector with `f32` components. /// A 1D vector with `f32` components.
pub type Vec1 = TVec1<f32>; pub type Vec1 = TVec1<f32>;
/// A 2D vector with `f32` components. /// A 2D vector with `f32` components.
pub type Vec2 = TVec2<f32>; pub type Vec2 = TVec2<f32>;
/// A 3D vector with `f32` components. /// A 3D vector with `f32` components.
pub type Vec3 = TVec3<f32>; pub type Vec3 = TVec3<f32>;
/// A 4D vector with `f32` components. /// A 4D vector with `f32` components.
pub type Vec4 = TVec4<f32>; pub type Vec4 = TVec4<f32>;
/// A 1D vector with `u64` components. /// A 1D vector with `u64` components.
pub type U64Vec1 = TVec1<u64>; pub type U64Vec1 = TVec1<u64>;
@ -270,7 +268,6 @@ pub type I8Vec3 = TVec3<i8>;
/// A 4D vector with `i8` components. /// A 4D vector with `i8` components.
pub type I8Vec4 = TVec4<i8>; pub type I8Vec4 = TVec4<i8>;
/// A 2x2 matrix with components of type `N`. /// A 2x2 matrix with components of type `N`.
pub type TMat2<N> = Matrix2<N>; pub type TMat2<N> = Matrix2<N>;
/// A 2x2 matrix with components of type `N`. /// A 2x2 matrix with components of type `N`.

View File

@ -1,5 +1,5 @@
use na::{Real, DefaultAllocator};
use aliases::TVec; use aliases::TVec;
use na::{DefaultAllocator, Real};
use traits::{Alloc, Dimension}; use traits::{Alloc, Dimension};
/// Component-wise exponential. /// Component-wise exponential.
@ -8,7 +8,9 @@ use traits::{Alloc, Dimension};
/// ///
/// * [`exp2`](fn.exp2.html) /// * [`exp2`](fn.exp2.html)
pub fn exp<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn exp<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| x.exp()) v.map(|x| x.exp())
} }
@ -18,7 +20,9 @@ pub fn exp<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
/// ///
/// * [`exp`](fn.exp.html) /// * [`exp`](fn.exp.html)
pub fn exp2<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn exp2<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| x.exp2()) v.map(|x| x.exp2())
} }
@ -28,9 +32,10 @@ pub fn exp2<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
/// ///
/// * [`sqrt`](fn.sqrt.html) /// * [`sqrt`](fn.sqrt.html)
pub fn inversesqrt<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn inversesqrt<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| N::one() / x.sqrt()) v.map(|x| N::one() / x.sqrt())
} }
/// Component-wise logarithm. /// Component-wise logarithm.
@ -39,7 +44,9 @@ pub fn inversesqrt<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
/// ///
/// * [`log2`](fn.log2.html) /// * [`log2`](fn.log2.html)
pub fn log<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn log<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| x.ln()) v.map(|x| x.ln())
} }
@ -49,13 +56,17 @@ pub fn log<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
/// ///
/// * [`log`](fn.log.html) /// * [`log`](fn.log.html)
pub fn log2<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn log2<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| x.log2()) v.map(|x| x.log2())
} }
/// Component-wise power. /// Component-wise power.
pub fn pow<N: Real, D: Dimension>(base: &TVec<N, D>, exponent: &TVec<N, D>) -> TVec<N, D> pub fn pow<N: Real, D: Dimension>(base: &TVec<N, D>, exponent: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
base.zip_map(exponent, |b, e| b.powf(e)) base.zip_map(exponent, |b, e| b.powf(e))
} }
@ -68,6 +79,8 @@ pub fn pow<N: Real, D: Dimension>(base: &TVec<N, D>, exponent: &TVec<N, D>) -> T
/// * [`inversesqrt`](fn.inversesqrt.html) /// * [`inversesqrt`](fn.inversesqrt.html)
/// * [`pow`](fn.pow.html) /// * [`pow`](fn.pow.html)
pub fn sqrt<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn sqrt<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| x.sqrt()) v.map(|x| x.sqrt())
} }

View File

@ -1,5 +1,5 @@
use na::{Real, Orthographic3, Perspective3};
use aliases::TMat4; use aliases::TMat4;
use na::{Orthographic3, Perspective3, Real};
//pub fn frustum<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> { //pub fn frustum<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
// unimplemented!() // unimplemented!()
@ -90,7 +90,6 @@ pub fn ortho<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -
// unimplemented!() // unimplemented!()
//} //}
/// Creates a matrix for a perspective-view frustum based on the right handedness and OpenGL near and far clip planes definition. /// Creates a matrix for a perspective-view frustum based on the right handedness and OpenGL near and far clip planes definition.
/// ///
/// # Important note /// # Important note

View File

@ -1,6 +1,6 @@
use na::{self, Real, U3}; use na::{self, Real, U3};
use aliases::{TVec2, TVec3, TVec4, TMat4}; use aliases::{TMat4, TVec2, TVec3, TVec4};
/// Define a picking region. /// Define a picking region.
/// ///
@ -13,11 +13,15 @@ pub fn pick_matrix<N: Real>(center: &TVec2<N>, delta: &TVec2<N>, viewport: &TVec
let shift = TVec3::new( let shift = TVec3::new(
(viewport.z - (center.x - viewport.x) * na::convert(2.0)) / delta.x, (viewport.z - (center.x - viewport.x) * na::convert(2.0)) / delta.x,
(viewport.w - (center.y - viewport.y) * na::convert(2.0)) / delta.y, (viewport.w - (center.y - viewport.y) * na::convert(2.0)) / delta.y,
N::zero() N::zero(),
); );
let result = TMat4::new_translation(&shift); let result = TMat4::new_translation(&shift);
result.prepend_nonuniform_scaling(&TVec3::new(viewport.z / delta.x, viewport.w / delta.y, N::one())) result.prepend_nonuniform_scaling(&TVec3::new(
viewport.z / delta.x,
viewport.w / delta.y,
N::one(),
))
} }
/// Map the specified object coordinates `(obj.x, obj.y, obj.z)` into window coordinates using OpenGL near and far clip planes definition. /// Map the specified object coordinates `(obj.x, obj.y, obj.z)` into window coordinates using OpenGL near and far clip planes definition.
@ -36,7 +40,12 @@ pub fn pick_matrix<N: Real>(center: &TVec2<N>, delta: &TVec2<N>, viewport: &TVec
/// * [`unproject`](fn.unproject.html) /// * [`unproject`](fn.unproject.html)
/// * [`unproject_no`](fn.unproject_no.html) /// * [`unproject_no`](fn.unproject_no.html)
/// * [`unproject_zo`](fn.unproject_zo.html) /// * [`unproject_zo`](fn.unproject_zo.html)
pub fn project<N: Real>(obj: &TVec3<N>, model: &TMat4<N>, proj: &TMat4<N>, viewport: TVec4<N>) -> TVec3<N> { pub fn project<N: Real>(
obj: &TVec3<N>,
model: &TMat4<N>,
proj: &TMat4<N>,
viewport: TVec4<N>,
) -> TVec3<N> {
project_no(obj, model, proj, viewport) project_no(obj, model, proj, viewport)
} }
@ -58,7 +67,12 @@ pub fn project<N: Real>(obj: &TVec3<N>, model: &TMat4<N>, proj: &TMat4<N>, viewp
/// * [`unproject`](fn.unproject.html) /// * [`unproject`](fn.unproject.html)
/// * [`unproject_no`](fn.unproject_no.html) /// * [`unproject_no`](fn.unproject_no.html)
/// * [`unproject_zo`](fn.unproject_zo.html) /// * [`unproject_zo`](fn.unproject_zo.html)
pub fn project_no<N: Real>(obj: &TVec3<N>, model: &TMat4<N>, proj: &TMat4<N>, viewport: TVec4<N>) -> TVec3<N> { pub fn project_no<N: Real>(
obj: &TVec3<N>,
model: &TMat4<N>,
proj: &TMat4<N>,
viewport: TVec4<N>,
) -> TVec3<N> {
let proj = project_zo(obj, model, proj, viewport); let proj = project_zo(obj, model, proj, viewport);
TVec3::new(proj.x, proj.y, proj.z * na::convert(0.5) + na::convert(0.5)) TVec3::new(proj.x, proj.y, proj.z * na::convert(0.5) + na::convert(0.5))
} }
@ -81,7 +95,12 @@ pub fn project_no<N: Real>(obj: &TVec3<N>, model: &TMat4<N>, proj: &TMat4<N>, vi
/// * [`unproject`](fn.unproject.html) /// * [`unproject`](fn.unproject.html)
/// * [`unproject_no`](fn.unproject_no.html) /// * [`unproject_no`](fn.unproject_no.html)
/// * [`unproject_zo`](fn.unproject_zo.html) /// * [`unproject_zo`](fn.unproject_zo.html)
pub fn project_zo<N: Real>(obj: &TVec3<N>, model: &TMat4<N>, proj: &TMat4<N>, viewport: TVec4<N>) -> TVec3<N> { pub fn project_zo<N: Real>(
obj: &TVec3<N>,
model: &TMat4<N>,
proj: &TMat4<N>,
viewport: TVec4<N>,
) -> TVec3<N> {
let normalized = proj * model * TVec4::new(obj.x, obj.y, obj.z, N::one()); let normalized = proj * model * TVec4::new(obj.x, obj.y, obj.z, N::one());
let scale = N::one() / normalized.w; let scale = N::one() / normalized.w;
@ -108,7 +127,12 @@ pub fn project_zo<N: Real>(obj: &TVec3<N>, model: &TMat4<N>, proj: &TMat4<N>, vi
/// * [`project_zo`](fn.project_zo.html) /// * [`project_zo`](fn.project_zo.html)
/// * [`unproject_no`](fn.unproject_no.html) /// * [`unproject_no`](fn.unproject_no.html)
/// * [`unproject_zo`](fn.unproject_zo.html) /// * [`unproject_zo`](fn.unproject_zo.html)
pub fn unproject<N: Real>(win: &TVec3<N>, model: &TMat4<N>, proj: &TMat4<N>, viewport: TVec4<N>) -> TVec3<N> { pub fn unproject<N: Real>(
win: &TVec3<N>,
model: &TMat4<N>,
proj: &TMat4<N>,
viewport: TVec4<N>,
) -> TVec3<N> {
unproject_no(win, model, proj, viewport) unproject_no(win, model, proj, viewport)
} }
@ -130,7 +154,12 @@ pub fn unproject<N: Real>(win: &TVec3<N>, model: &TMat4<N>, proj: &TMat4<N>, vie
/// * [`project_zo`](fn.project_zo.html) /// * [`project_zo`](fn.project_zo.html)
/// * [`unproject`](fn.unproject.html) /// * [`unproject`](fn.unproject.html)
/// * [`unproject_zo`](fn.unproject_zo.html) /// * [`unproject_zo`](fn.unproject_zo.html)
pub fn unproject_no<N: Real>(win: &TVec3<N>, model: &TMat4<N>, proj: &TMat4<N>, viewport: TVec4<N>) -> TVec3<N> { pub fn unproject_no<N: Real>(
win: &TVec3<N>,
model: &TMat4<N>,
proj: &TMat4<N>,
viewport: TVec4<N>,
) -> TVec3<N> {
let _2: N = na::convert(2.0); let _2: N = na::convert(2.0);
let transform = (proj * model).try_inverse().unwrap_or_else(TMat4::zeros); let transform = (proj * model).try_inverse().unwrap_or_else(TMat4::zeros);
let pt = TVec4::new( let pt = TVec4::new(
@ -162,7 +191,12 @@ pub fn unproject_no<N: Real>(win: &TVec3<N>, model: &TMat4<N>, proj: &TMat4<N>,
/// * [`project_zo`](fn.project_zo.html) /// * [`project_zo`](fn.project_zo.html)
/// * [`unproject`](fn.unproject.html) /// * [`unproject`](fn.unproject.html)
/// * [`unproject_no`](fn.unproject_no.html) /// * [`unproject_no`](fn.unproject_no.html)
pub fn unproject_zo<N: Real>(win: &TVec3<N>, model: &TMat4<N>, proj: &TMat4<N>, viewport: TVec4<N>) -> TVec3<N> { pub fn unproject_zo<N: Real>(
win: &TVec3<N>,
model: &TMat4<N>,
proj: &TMat4<N>,
viewport: TVec4<N>,
) -> TVec3<N> {
let _2: N = na::convert(2.0); let _2: N = na::convert(2.0);
let transform = (proj * model).try_inverse().unwrap_or_else(TMat4::zeros); let transform = (proj * model).try_inverse().unwrap_or_else(TMat4::zeros);
let pt = TVec4::new( let pt = TVec4::new(

View File

@ -1,13 +1,18 @@
use na::DefaultAllocator; use na::DefaultAllocator;
use aliases::{TVec, TMat}; use aliases::{TMat, TVec};
use traits::{Alloc, Number, Dimension}; use traits::{Alloc, Dimension, Number};
/// Perform a component-wise equal-to comparison of two matrices. /// Perform a component-wise equal-to comparison of two matrices.
/// ///
/// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices. /// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices.
pub fn equal_columns<N: Number, R: Dimension, C: Dimension>(x: &TMat<N, R, C>, y: &TMat<N, R, C>) -> TVec<bool, C> pub fn equal_columns<N: Number, R: Dimension, C: Dimension>(
where DefaultAllocator: Alloc<N, R, C> { x: &TMat<N, R, C>,
y: &TMat<N, R, C>,
) -> TVec<bool, C>
where
DefaultAllocator: Alloc<N, R, C>,
{
let mut res = TVec::<_, C>::repeat(false); let mut res = TVec::<_, C>::repeat(false);
for i in 0..C::dim() { for i in 0..C::dim() {
@ -20,16 +25,28 @@ pub fn equal_columns<N: Number, R: Dimension, C: Dimension>(x: &TMat<N, R, C>, y
/// Returns the component-wise comparison of `|x - y| < epsilon`. /// Returns the component-wise comparison of `|x - y| < epsilon`.
/// ///
/// True if this expression is satisfied. /// True if this expression is satisfied.
pub fn equal_columns_eps<N: Number, R: Dimension, C: Dimension>(x: &TMat<N, R, C>, y: &TMat<N, R, C>, epsilon: N) -> TVec<bool, C> pub fn equal_columns_eps<N: Number, R: Dimension, C: Dimension>(
where DefaultAllocator: Alloc<N, R, C> { x: &TMat<N, R, C>,
y: &TMat<N, R, C>,
epsilon: N,
) -> TVec<bool, C>
where
DefaultAllocator: Alloc<N, R, C>,
{
equal_columns_eps_vec(x, y, &TVec::<_, C>::repeat(epsilon)) equal_columns_eps_vec(x, y, &TVec::<_, C>::repeat(epsilon))
} }
/// Returns the component-wise comparison on each matrix column `|x - y| < epsilon`. /// Returns the component-wise comparison on each matrix column `|x - y| < epsilon`.
/// ///
/// True if this expression is satisfied. /// True if this expression is satisfied.
pub fn equal_columns_eps_vec<N: Number, R: Dimension, C: Dimension>(x: &TMat<N, R, C>, y: &TMat<N, R, C>, epsilon: &TVec<N, C>) -> TVec<bool, C> pub fn equal_columns_eps_vec<N: Number, R: Dimension, C: Dimension>(
where DefaultAllocator: Alloc<N, R, C> { x: &TMat<N, R, C>,
y: &TMat<N, R, C>,
epsilon: &TVec<N, C>,
) -> TVec<bool, C>
where
DefaultAllocator: Alloc<N, R, C>,
{
let mut res = TVec::<_, C>::repeat(false); let mut res = TVec::<_, C>::repeat(false);
for i in 0..C::dim() { for i in 0..C::dim() {
@ -42,8 +59,13 @@ pub fn equal_columns_eps_vec<N: Number, R: Dimension, C: Dimension>(x: &TMat<N,
/// Perform a component-wise not-equal-to comparison of two matrices. /// Perform a component-wise not-equal-to comparison of two matrices.
/// ///
/// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices. /// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices.
pub fn not_equal_columns<N: Number, R: Dimension, C: Dimension>(x: &TMat<N, R, C>, y: &TMat<N, R, C>) -> TVec<bool, C> pub fn not_equal_columns<N: Number, R: Dimension, C: Dimension>(
where DefaultAllocator: Alloc<N, R, C> { x: &TMat<N, R, C>,
y: &TMat<N, R, C>,
) -> TVec<bool, C>
where
DefaultAllocator: Alloc<N, R, C>,
{
let mut res = TVec::<_, C>::repeat(false); let mut res = TVec::<_, C>::repeat(false);
for i in 0..C::dim() { for i in 0..C::dim() {
@ -56,16 +78,28 @@ pub fn not_equal_columns<N: Number, R: Dimension, C: Dimension>(x: &TMat<N, R, C
/// Returns the component-wise comparison of `|x - y| < epsilon`. /// Returns the component-wise comparison of `|x - y| < epsilon`.
/// ///
/// True if this expression is not satisfied. /// True if this expression is not satisfied.
pub fn not_equal_columns_eps<N: Number, R: Dimension, C: Dimension>(x: &TMat<N, R, C>, y: &TMat<N, R, C>, epsilon: N) -> TVec<bool, C> pub fn not_equal_columns_eps<N: Number, R: Dimension, C: Dimension>(
where DefaultAllocator: Alloc<N, R, C> { x: &TMat<N, R, C>,
y: &TMat<N, R, C>,
epsilon: N,
) -> TVec<bool, C>
where
DefaultAllocator: Alloc<N, R, C>,
{
not_equal_columns_eps_vec(x, y, &TVec::<_, C>::repeat(epsilon)) not_equal_columns_eps_vec(x, y, &TVec::<_, C>::repeat(epsilon))
} }
/// Returns the component-wise comparison of `|x - y| >= epsilon`. /// Returns the component-wise comparison of `|x - y| >= epsilon`.
/// ///
/// True if this expression is not satisfied. /// True if this expression is not satisfied.
pub fn not_equal_columns_eps_vec<N: Number, R: Dimension, C: Dimension>(x: &TMat<N, R, C>, y: &TMat<N, R, C>, epsilon: &TVec<N, C>) -> TVec<bool, C> pub fn not_equal_columns_eps_vec<N: Number, R: Dimension, C: Dimension>(
where DefaultAllocator: Alloc<N, R, C> { x: &TMat<N, R, C>,
y: &TMat<N, R, C>,
epsilon: &TVec<N, C>,
) -> TVec<bool, C>
where
DefaultAllocator: Alloc<N, R, C>,
{
let mut res = TVec::<_, C>::repeat(false); let mut res = TVec::<_, C>::repeat(false);
for i in 0..C::dim() { for i in 0..C::dim() {

View File

@ -1,11 +1,13 @@
use na::{DefaultAllocator, Real, Unit, Rotation3, Point3}; use na::{DefaultAllocator, Point3, Real, Rotation3, Unit};
use traits::{Dimension, Number, Alloc}; use aliases::{TMat, TMat4, TVec, TVec3};
use aliases::{TMat, TVec, TVec3, TMat4}; use traits::{Alloc, Dimension, Number};
/// The identity matrix. /// The identity matrix.
pub fn identity<N: Number, D: Dimension>() -> TMat<N, D, D> pub fn identity<N: Number, D: Dimension>() -> TMat<N, D, D>
where DefaultAllocator: Alloc<N, D, D> { where
DefaultAllocator: Alloc<N, D, D>,
{
TMat::<N, D, D>::identity() TMat::<N, D, D>::identity()
} }
@ -38,7 +40,11 @@ pub fn look_at<N: Real>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMa
/// * [`look_at`](fn.look_at.html) /// * [`look_at`](fn.look_at.html)
/// * [`look_at_rh`](fn.look_at_rh.html) /// * [`look_at_rh`](fn.look_at_rh.html)
pub fn look_at_lh<N: Real>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> { pub fn look_at_lh<N: Real>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
TMat::look_at_lh(&Point3::from_coordinates(*eye), &Point3::from_coordinates(*center), up) TMat::look_at_lh(
&Point3::from_coordinates(*eye),
&Point3::from_coordinates(*center),
up,
)
} }
/// Build a right handed look at view matrix. /// Build a right handed look at view matrix.
@ -54,7 +60,11 @@ pub fn look_at_lh<N: Real>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) ->
/// * [`look_at`](fn.look_at.html) /// * [`look_at`](fn.look_at.html)
/// * [`look_at_lh`](fn.look_at_lh.html) /// * [`look_at_lh`](fn.look_at_lh.html)
pub fn look_at_rh<N: Real>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> { pub fn look_at_rh<N: Real>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
TMat::look_at_rh(&Point3::from_coordinates(*eye), &Point3::from_coordinates(*center), up) TMat::look_at_rh(
&Point3::from_coordinates(*eye),
&Point3::from_coordinates(*center),
up,
)
} }
/// Builds a rotation 4 * 4 matrix created from an axis vector and an angle and right-multiply it to `m`. /// Builds a rotation 4 * 4 matrix created from an axis vector and an angle and right-multiply it to `m`.

View File

@ -1,30 +1,41 @@
//! (Reexported) Additional features not specified by GLSL specification //! (Reexported) Additional features not specified by GLSL specification
pub use self::matrix_clip_space::{ortho, perspective}; pub use self::matrix_clip_space::{ortho, perspective};
pub use self::matrix_projection::{pick_matrix, project, project_no, project_zo, unproject, unproject_no, unproject_zo}; pub use self::matrix_projection::{
pub use self::matrix_relationnal::{equal_columns, equal_columns_eps, equal_columns_eps_vec, not_equal_columns, not_equal_columns_eps, not_equal_columns_eps_vec}; pick_matrix, project, project_no, project_zo, unproject, unproject_no, unproject_zo,
pub use self::matrix_transform::{identity, look_at, look_at_lh, rotate, scale, look_at_rh, translate, rotate_x, rotate_y, rotate_z}; };
pub use self::matrix_relationnal::{
equal_columns, equal_columns_eps, equal_columns_eps_vec, not_equal_columns,
not_equal_columns_eps, not_equal_columns_eps_vec,
};
pub use self::matrix_transform::{
identity, look_at, look_at_lh, look_at_rh, rotate, rotate_x, rotate_y, rotate_z, scale,
translate,
};
pub use self::quaternion_common::{quat_conjugate, quat_inverse, quat_lerp, quat_slerp};
pub use self::quaternion_geometric::{
quat_cross, quat_dot, quat_length, quat_magnitude, quat_normalize,
};
pub use self::quaternion_relational::{
quat_equal, quat_equal_eps, quat_not_equal, quat_not_equal_eps,
};
pub use self::quaternion_transform::{quat_exp, quat_log, quat_pow, quat_rotate};
pub use self::quaternion_trigonometric::{quat_angle, quat_angle_axis, quat_axis};
pub use self::scalar_common::{max3_scalar, max4_scalar, min3_scalar, min4_scalar}; pub use self::scalar_common::{max3_scalar, max4_scalar, min3_scalar, min4_scalar};
pub use self::scalar_constants::{epsilon, pi}; pub use self::scalar_constants::{epsilon, pi};
pub use self::vector_common::{max, max2, max3, max4, min, min2, min3, min4}; pub use self::vector_common::{max, max2, max3, max4, min, min2, min3, min4};
pub use self::vector_relational::{equal_eps, equal_eps_vec, not_equal_eps, not_equal_eps_vec}; pub use self::vector_relational::{equal_eps, equal_eps_vec, not_equal_eps, not_equal_eps_vec};
pub use self::quaternion_common::{quat_conjugate, quat_inverse, quat_lerp, quat_slerp};
pub use self::quaternion_geometric::{quat_cross, quat_dot, quat_length, quat_magnitude, quat_normalize};
pub use self::quaternion_relational::{quat_equal, quat_equal_eps, quat_not_equal, quat_not_equal_eps};
pub use self::quaternion_transform::{quat_exp, quat_log, quat_pow, quat_rotate};
pub use self::quaternion_trigonometric::{quat_angle, quat_angle_axis, quat_axis};
mod matrix_clip_space; mod matrix_clip_space;
mod matrix_projection; mod matrix_projection;
mod matrix_relationnal; mod matrix_relationnal;
mod matrix_transform; mod matrix_transform;
mod scalar_common;
mod scalar_constants;
mod vector_common;
mod vector_relational;
mod quaternion_common; mod quaternion_common;
mod quaternion_geometric; mod quaternion_geometric;
mod quaternion_relational; mod quaternion_relational;
mod quaternion_transform; mod quaternion_transform;
mod quaternion_trigonometric; mod quaternion_trigonometric;
mod scalar_common;
mod scalar_constants;
mod vector_common;
mod vector_relational;

View File

@ -31,5 +31,7 @@ pub fn quat_lerp<N: Real>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
/// Interpolate spherically between `x` and `y`. /// Interpolate spherically between `x` and `y`.
pub fn quat_slerp<N: Real>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> { pub fn quat_slerp<N: Real>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
Unit::new_normalize(*x).slerp(&Unit::new_normalize(*y), a).unwrap() Unit::new_normalize(*x)
.slerp(&Unit::new_normalize(*y), a)
.unwrap()
} }

View File

@ -1,6 +1,5 @@
use na::{Real, U4}; use na::{Real, U4};
use aliases::{Qua, TVec}; use aliases::{Qua, TVec};
/// Component-wise equality comparison between two quaternions. /// Component-wise equality comparison between two quaternions.

View File

@ -1,4 +1,4 @@
use na::{Real, UnitQuaternion, Unit}; use na::{Real, Unit, UnitQuaternion};
use aliases::{Qua, TVec3}; use aliases::{Qua, TVec3};

View File

@ -1,7 +1,7 @@
use na::{self, DefaultAllocator}; use na::{self, DefaultAllocator};
use traits::{Alloc, Number, Dimension};
use aliases::TVec; use aliases::TVec;
use traits::{Alloc, Dimension, Number};
/// Component-wise maximum between a vector and a scalar. /// Component-wise maximum between a vector and a scalar.
/// ///
@ -17,7 +17,9 @@ use aliases::TVec;
/// * [`min3`](fn.min3.html) /// * [`min3`](fn.min3.html)
/// * [`min4`](fn.min4.html) /// * [`min4`](fn.min4.html)
pub fn max<N: Number, D: Dimension>(a: &TVec<N, D>, b: N) -> TVec<N, D> pub fn max<N: Number, D: Dimension>(a: &TVec<N, D>, b: N) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
a.map(|a| na::sup(&a, &b)) a.map(|a| na::sup(&a, &b))
} }
@ -35,7 +37,9 @@ pub fn max<N: Number, D: Dimension>(a: &TVec<N, D>, b: N) -> TVec<N, D>
/// * [`min3`](fn.min3.html) /// * [`min3`](fn.min3.html)
/// * [`min4`](fn.min4.html) /// * [`min4`](fn.min4.html)
pub fn max2<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>) -> TVec<N, D> pub fn max2<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
na::sup(a, b) na::sup(a, b)
} }
@ -53,7 +57,9 @@ pub fn max2<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>) -> TVec<N,
/// * [`min3`](fn.min3.html) /// * [`min3`](fn.min3.html)
/// * [`min4`](fn.min4.html) /// * [`min4`](fn.min4.html)
pub fn max3<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>, c: &TVec<N, D>) -> TVec<N, D> pub fn max3<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>, c: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
max2(&max2(a, b), c) max2(&max2(a, b), c)
} }
@ -70,8 +76,15 @@ pub fn max3<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>, c: &TVec<N,
/// * [`min2`](fn.min2.html) /// * [`min2`](fn.min2.html)
/// * [`min3`](fn.min3.html) /// * [`min3`](fn.min3.html)
/// * [`min4`](fn.min4.html) /// * [`min4`](fn.min4.html)
pub fn max4<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>, c: &TVec<N, D>, d: &TVec<N, D>) -> TVec<N, D> pub fn max4<N: Number, D: Dimension>(
where DefaultAllocator: Alloc<N, D> { a: &TVec<N, D>,
b: &TVec<N, D>,
c: &TVec<N, D>,
d: &TVec<N, D>,
) -> TVec<N, D>
where
DefaultAllocator: Alloc<N, D>,
{
max2(&max2(a, b), &max2(c, d)) max2(&max2(a, b), &max2(c, d))
} }
@ -89,7 +102,9 @@ pub fn max4<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>, c: &TVec<N,
/// * [`min3`](fn.min3.html) /// * [`min3`](fn.min3.html)
/// * [`min4`](fn.min4.html) /// * [`min4`](fn.min4.html)
pub fn min<N: Number, D: Dimension>(x: &TVec<N, D>, y: N) -> TVec<N, D> pub fn min<N: Number, D: Dimension>(x: &TVec<N, D>, y: N) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| na::inf(&x, &y)) x.map(|x| na::inf(&x, &y))
} }
@ -107,7 +122,9 @@ pub fn min<N: Number, D: Dimension>(x: &TVec<N, D>, y: N) -> TVec<N, D>
/// * [`min3`](fn.min3.html) /// * [`min3`](fn.min3.html)
/// * [`min4`](fn.min4.html) /// * [`min4`](fn.min4.html)
pub fn min2<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<N, D> pub fn min2<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
na::inf(x, y) na::inf(x, y)
} }
@ -125,7 +142,9 @@ pub fn min2<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<N,
/// * [`min2`](fn.min2.html) /// * [`min2`](fn.min2.html)
/// * [`min4`](fn.min4.html) /// * [`min4`](fn.min4.html)
pub fn min3<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>, c: &TVec<N, D>) -> TVec<N, D> pub fn min3<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>, c: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
min2(&min2(a, b), c) min2(&min2(a, b), c)
} }
@ -142,7 +161,14 @@ pub fn min3<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>, c: &TVec<N,
/// * [`min`](fn.min.html) /// * [`min`](fn.min.html)
/// * [`min2`](fn.min2.html) /// * [`min2`](fn.min2.html)
/// * [`min3`](fn.min3.html) /// * [`min3`](fn.min3.html)
pub fn min4<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>, c: &TVec<N, D>, d: &TVec<N, D>) -> TVec<N, D> pub fn min4<N: Number, D: Dimension>(
where DefaultAllocator: Alloc<N, D> { a: &TVec<N, D>,
b: &TVec<N, D>,
c: &TVec<N, D>,
d: &TVec<N, D>,
) -> TVec<N, D>
where
DefaultAllocator: Alloc<N, D>,
{
min2(&min2(a, b), &min2(c, d)) min2(&min2(a, b), &min2(c, d))
} }

View File

@ -1,7 +1,7 @@
use na::{DefaultAllocator}; use na::DefaultAllocator;
use traits::{Alloc, Number, Dimension};
use aliases::TVec; use aliases::TVec;
use traits::{Alloc, Dimension, Number};
/// Component-wise approximate equality of two vectors, using a scalar epsilon. /// Component-wise approximate equality of two vectors, using a scalar epsilon.
/// ///
@ -10,8 +10,14 @@ use aliases::TVec;
/// * [`equal_eps_vec`](fn.equal_eps_vec.html) /// * [`equal_eps_vec`](fn.equal_eps_vec.html)
/// * [`not_equal_eps`](fn.not_equal_eps.html) /// * [`not_equal_eps`](fn.not_equal_eps.html)
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html) /// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
pub fn equal_eps<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, epsilon: N) -> TVec<bool, D> pub fn equal_eps<N: Number, D: Dimension>(
where DefaultAllocator: Alloc<N, D> { x: &TVec<N, D>,
y: &TVec<N, D>,
epsilon: N,
) -> TVec<bool, D>
where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon)) x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon))
} }
@ -22,8 +28,14 @@ pub fn equal_eps<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, epsilo
/// * [`equal_eps`](fn.equal_eps.html) /// * [`equal_eps`](fn.equal_eps.html)
/// * [`not_equal_eps`](fn.not_equal_eps.html) /// * [`not_equal_eps`](fn.not_equal_eps.html)
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html) /// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
pub fn equal_eps_vec<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, epsilon: &TVec<N, D>) -> TVec<bool, D> pub fn equal_eps_vec<N: Number, D: Dimension>(
where DefaultAllocator: Alloc<N, D> { x: &TVec<N, D>,
y: &TVec<N, D>,
epsilon: &TVec<N, D>,
) -> TVec<bool, D>
where
DefaultAllocator: Alloc<N, D>,
{
x.zip_zip_map(y, epsilon, |x, y, eps| abs_diff_eq!(x, y, epsilon = eps)) x.zip_zip_map(y, epsilon, |x, y, eps| abs_diff_eq!(x, y, epsilon = eps))
} }
@ -34,8 +46,14 @@ pub fn equal_eps_vec<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, ep
/// * [`equal_eps`](fn.equal_eps.html) /// * [`equal_eps`](fn.equal_eps.html)
/// * [`equal_eps_vec`](fn.equal_eps_vec.html) /// * [`equal_eps_vec`](fn.equal_eps_vec.html)
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html) /// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
pub fn not_equal_eps<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, epsilon: N) -> TVec<bool, D> pub fn not_equal_eps<N: Number, D: Dimension>(
where DefaultAllocator: Alloc<N, D> { x: &TVec<N, D>,
y: &TVec<N, D>,
epsilon: N,
) -> TVec<bool, D>
where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon)) x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon))
} }
@ -46,7 +64,13 @@ pub fn not_equal_eps<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, ep
/// * [`equal_eps`](fn.equal_eps.html) /// * [`equal_eps`](fn.equal_eps.html)
/// * [`equal_eps_vec`](fn.equal_eps_vec.html) /// * [`equal_eps_vec`](fn.equal_eps_vec.html)
/// * [`not_equal_eps`](fn.not_equal_eps.html) /// * [`not_equal_eps`](fn.not_equal_eps.html)
pub fn not_equal_eps_vec<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, epsilon: &TVec<N, D>) -> TVec<bool, D> pub fn not_equal_eps_vec<N: Number, D: Dimension>(
where DefaultAllocator: Alloc<N, D> { x: &TVec<N, D>,
y: &TVec<N, D>,
epsilon: &TVec<N, D>,
) -> TVec<bool, D>
where
DefaultAllocator: Alloc<N, D>,
{
x.zip_zip_map(y, epsilon, |x, y, eps| abs_diff_ne!(x, y, epsilon = eps)) x.zip_zip_map(y, epsilon, |x, y, eps| abs_diff_ne!(x, y, epsilon = eps))
} }

View File

@ -1,7 +1,7 @@
use na::{Real, DefaultAllocator}; use na::{DefaultAllocator, Real};
use traits::{Number, Alloc, Dimension};
use aliases::{TVec, TVec3}; use aliases::{TVec, TVec3};
use traits::{Alloc, Dimension, Number};
/// The cross product of two vectors. /// The cross product of two vectors.
pub fn cross<N: Number, D: Dimension>(x: &TVec3<N>, y: &TVec3<N>) -> TVec3<N> { pub fn cross<N: Number, D: Dimension>(x: &TVec3<N>, y: &TVec3<N>) -> TVec3<N> {
@ -14,19 +14,29 @@ pub fn cross<N: Number, D: Dimension>(x: &TVec3<N>, y: &TVec3<N>) -> TVec3<N> {
/// ///
/// * [`distance2`](fn.distance2.html) /// * [`distance2`](fn.distance2.html)
pub fn distance<N: Real, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N pub fn distance<N: Real, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
(p1 - p0).norm() DefaultAllocator: Alloc<N, D>,
{
(p1 - p0).norm()
} }
/// The dot product of two vectors. /// The dot product of two vectors.
pub fn dot<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn dot<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.dot(y) x.dot(y)
} }
/// If `dot(nref, i) < 0.0`, return `n`, otherwise, return `-n`. /// If `dot(nref, i) < 0.0`, return `n`, otherwise, return `-n`.
pub fn faceforward<N: Number, D: Dimension>(n: &TVec<N, D>, i: &TVec<N, D>, nref: &TVec<N, D>) -> TVec<N, D> pub fn faceforward<N: Number, D: Dimension>(
where DefaultAllocator: Alloc<N, D> { n: &TVec<N, D>,
i: &TVec<N, D>,
nref: &TVec<N, D>,
) -> TVec<N, D>
where
DefaultAllocator: Alloc<N, D>,
{
if nref.dot(i) < N::zero() { if nref.dot(i) < N::zero() {
n.clone() n.clone()
} else { } else {
@ -44,7 +54,9 @@ pub fn faceforward<N: Number, D: Dimension>(n: &TVec<N, D>, i: &TVec<N, D>, nref
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2`](fn.magnitude2.html)
pub fn length<N: Real, D: Dimension>(x: &TVec<N, D>) -> N pub fn length<N: Real, D: Dimension>(x: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.norm() x.norm()
} }
@ -58,34 +70,40 @@ pub fn length<N: Real, D: Dimension>(x: &TVec<N, D>) -> N
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2`](fn.magnitude2.html)
/// * [`nalgebra::norm`](../nalgebra/fn.norm.html) /// * [`nalgebra::norm`](../nalgebra/fn.norm.html)
pub fn magnitude<N: Real, D: Dimension>(x: &TVec<N, D>) -> N pub fn magnitude<N: Real, D: Dimension>(x: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.norm() x.norm()
} }
/// Normalizes a vector. /// Normalizes a vector.
pub fn normalize<N: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn normalize<N: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.normalize() x.normalize()
} }
/// For the incident vector `i` and surface orientation `n`, returns the reflection direction : `result = i - 2.0 * dot(n, i) * n`. /// For the incident vector `i` and surface orientation `n`, returns the reflection direction : `result = i - 2.0 * dot(n, i) * n`.
pub fn reflect_vec<N: Number, D: Dimension>(i: &TVec<N, D>, n: &TVec<N, D>) -> TVec<N, D> pub fn reflect_vec<N: Number, D: Dimension>(i: &TVec<N, D>, n: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
let _2 = N::one() + N::one(); let _2 = N::one() + N::one();
i - n * (n.dot(i) * _2) i - n * (n.dot(i) * _2)
} }
/// For the incident vector `i` and surface normal `n`, and the ratio of indices of refraction `eta`, return the refraction vector. /// For the incident vector `i` and surface normal `n`, and the ratio of indices of refraction `eta`, return the refraction vector.
pub fn refract_vec<N: Real, D: Dimension>(i: &TVec<N, D>, n: &TVec<N, D>, eta: N) -> TVec<N, D> pub fn refract_vec<N: Real, D: Dimension>(i: &TVec<N, D>, n: &TVec<N, D>, eta: N) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
let ni = n.dot(i); let ni = n.dot(i);
let k = N::one() - eta * eta * (N::one() - ni * ni); let k = N::one() - eta * eta * (N::one() - ni * ni);
if k < N::zero() { if k < N::zero() {
TVec::<_, D>::zeros() TVec::<_, D>::zeros()
} } else {
else {
i * eta - n * (eta * dot(n, i) + k.sqrt()) i * eta - n * (eta * dot(n, i) + k.sqrt())
} }
} }

View File

@ -1,7 +1,7 @@
use na::{Scalar, DefaultAllocator}; use na::{DefaultAllocator, Scalar};
use aliases::{TMat, TVec};
use traits::{Alloc, Dimension}; use traits::{Alloc, Dimension};
use aliases::{TVec, TMat};
/// The `index`-th column of the matrix `m`. /// The `index`-th column of the matrix `m`.
/// ///
@ -11,7 +11,9 @@ use aliases::{TVec, TMat};
/// * [`set_column`](fn.set_column.html) /// * [`set_column`](fn.set_column.html)
/// * [`set_row`](fn.set_row.html) /// * [`set_row`](fn.set_row.html)
pub fn column<N: Scalar, R: Dimension, C: Dimension>(m: &TMat<N, R, C>, index: usize) -> TVec<N, R> pub fn column<N: Scalar, R: Dimension, C: Dimension>(m: &TMat<N, R, C>, index: usize) -> TVec<N, R>
where DefaultAllocator: Alloc<N, R, C> { where
DefaultAllocator: Alloc<N, R, C>,
{
m.column(index).into_owned() m.column(index).into_owned()
} }
@ -22,8 +24,14 @@ pub fn column<N: Scalar, R: Dimension, C: Dimension>(m: &TMat<N, R, C>, index: u
/// * [`column`](fn.column.html) /// * [`column`](fn.column.html)
/// * [`row`](fn.row.html) /// * [`row`](fn.row.html)
/// * [`set_row`](fn.set_row.html) /// * [`set_row`](fn.set_row.html)
pub fn set_column<N: Scalar, R: Dimension, C: Dimension>(m: &TMat<N, R, C>, index: usize, x: &TVec<N, R>) -> TMat<N, R, C> pub fn set_column<N: Scalar, R: Dimension, C: Dimension>(
where DefaultAllocator: Alloc<N, R, C> { m: &TMat<N, R, C>,
index: usize,
x: &TVec<N, R>,
) -> TMat<N, R, C>
where
DefaultAllocator: Alloc<N, R, C>,
{
let mut res = m.clone(); let mut res = m.clone();
res.set_column(index, x); res.set_column(index, x);
res res
@ -37,7 +45,9 @@ pub fn set_column<N: Scalar, R: Dimension, C: Dimension>(m: &TMat<N, R, C>, inde
/// * [`set_column`](fn.set_column.html) /// * [`set_column`](fn.set_column.html)
/// * [`set_row`](fn.set_row.html) /// * [`set_row`](fn.set_row.html)
pub fn row<N: Scalar, R: Dimension, C: Dimension>(m: &TMat<N, R, C>, index: usize) -> TVec<N, C> pub fn row<N: Scalar, R: Dimension, C: Dimension>(m: &TMat<N, R, C>, index: usize) -> TVec<N, C>
where DefaultAllocator: Alloc<N, R, C> { where
DefaultAllocator: Alloc<N, R, C>,
{
m.row(index).into_owned().transpose() m.row(index).into_owned().transpose()
} }
@ -48,8 +58,14 @@ pub fn row<N: Scalar, R: Dimension, C: Dimension>(m: &TMat<N, R, C>, index: usiz
/// * [`column`](fn.column.html) /// * [`column`](fn.column.html)
/// * [`row`](fn.row.html) /// * [`row`](fn.row.html)
/// * [`set_column`](fn.set_column.html) /// * [`set_column`](fn.set_column.html)
pub fn set_row<N: Scalar, R: Dimension, C: Dimension>(m: &TMat<N, R, C>, index: usize, x: &TVec<N, C>) -> TMat<N, R, C> pub fn set_row<N: Scalar, R: Dimension, C: Dimension>(
where DefaultAllocator: Alloc<N, R, C> { m: &TMat<N, R, C>,
index: usize,
x: &TVec<N, C>,
) -> TMat<N, R, C>
where
DefaultAllocator: Alloc<N, R, C>,
{
let mut res = m.clone(); let mut res = m.clone();
res.set_row(index, &x.transpose()); res.set_row(index, &x.transpose());
res res

View File

@ -1,17 +1,23 @@
use na::{Real, DefaultAllocator}; use na::{DefaultAllocator, Real};
use traits::{Alloc, Dimension};
use aliases::TMat; use aliases::TMat;
use traits::{Alloc, Dimension};
/// Fast matrix inverse for affine matrix. /// Fast matrix inverse for affine matrix.
pub fn affine_inverse<N: Real, D: Dimension>(m: TMat<N, D, D>) -> TMat<N, D, D> pub fn affine_inverse<N: Real, D: Dimension>(m: TMat<N, D, D>) -> TMat<N, D, D>
where DefaultAllocator: Alloc<N, D, D> { where
DefaultAllocator: Alloc<N, D, D>,
{
// FIXME: this should be optimized. // FIXME: this should be optimized.
m.try_inverse().unwrap_or_else(TMat::<_, D, D>::zeros) m.try_inverse().unwrap_or_else(TMat::<_, D, D>::zeros)
} }
/// Compute the transpose of the inverse of a matrix. /// Compute the transpose of the inverse of a matrix.
pub fn inverse_transpose<N: Real, D: Dimension>(m: TMat<N, D, D>) -> TMat<N, D, D> pub fn inverse_transpose<N: Real, D: Dimension>(m: TMat<N, D, D>) -> TMat<N, D, D>
where DefaultAllocator: Alloc<N, D, D> { where
m.try_inverse().unwrap_or_else(TMat::<_, D, D>::zeros).transpose() DefaultAllocator: Alloc<N, D, D>,
{
m.try_inverse()
.unwrap_or_else(TMat::<_, D, D>::zeros)
.transpose()
} }

View File

@ -1,17 +1,32 @@
//! (Reexported) Recommended features not specified by GLSL specification //! (Reexported) Recommended features not specified by GLSL specification
//pub use self::bitfield::*; //pub use self::bitfield::*;
pub use self::constants::{e, two_pi, euler, four_over_pi, golden_ratio, half_pi, ln_ln_two, ln_ten, ln_two, one, one_over_pi, one_over_root_two, one_over_two_pi, quarter_pi, root_five, root_half_pi, root_ln_four, root_pi, root_three, root_two, root_two_pi, third, three_over_two_pi, two_over_pi, two_over_root_pi, two_thirds, zero}; pub use self::constants::{
e, euler, four_over_pi, golden_ratio, half_pi, ln_ln_two, ln_ten, ln_two, one, one_over_pi,
one_over_root_two, one_over_two_pi, quarter_pi, root_five, root_half_pi, root_ln_four, root_pi,
root_three, root_two, root_two_pi, third, three_over_two_pi, two_over_pi, two_over_root_pi,
two_pi, two_thirds, zero,
};
//pub use self::integer::*; //pub use self::integer::*;
pub use self::matrix_access::{column, row, set_column, set_row}; pub use self::matrix_access::{column, row, set_column, set_row};
pub use self::matrix_inverse::{affine_inverse, inverse_transpose}; pub use self::matrix_inverse::{affine_inverse, inverse_transpose};
//pub use self::packing::*; //pub use self::packing::*;
//pub use self::reciprocal::*; //pub use self::reciprocal::*;
//pub use self::round::*; //pub use self::round::*;
pub use self::type_ptr::{make_mat2, make_mat2x2, make_mat2x3, make_mat2x4, make_mat3, make_mat3x2, make_mat3x3, make_mat3x4, make_mat4, make_mat4x2, make_mat4x3, make_mat4x4, make_quat, make_vec1, make_vec2, make_vec3, make_vec4, value_ptr, value_ptr_mut, vec1_to_vec2, vec1_to_vec3, vec1_to_vec4, vec2_to_vec1, vec2_to_vec2, vec2_to_vec3, vec2_to_vec4, vec3_to_vec1, vec3_to_vec2, vec3_to_vec3, vec3_to_vec4, vec4_to_vec1, vec4_to_vec2, vec4_to_vec3, vec4_to_vec4, mat2_to_mat3, mat2_to_mat4, mat3_to_mat2, mat3_to_mat4, mat4_to_mat2, mat4_to_mat3}; pub use self::type_ptr::{
make_mat2, make_mat2x2, make_mat2x3, make_mat2x4, make_mat3, make_mat3x2, make_mat3x3,
make_mat3x4, make_mat4, make_mat4x2, make_mat4x3, make_mat4x4, make_quat, make_vec1, make_vec2,
make_vec3, make_vec4, mat2_to_mat3, mat2_to_mat4, mat3_to_mat2, mat3_to_mat4, mat4_to_mat2,
mat4_to_mat3, value_ptr, value_ptr_mut, vec1_to_vec2, vec1_to_vec3, vec1_to_vec4, vec2_to_vec1,
vec2_to_vec2, vec2_to_vec3, vec2_to_vec4, vec3_to_vec1, vec3_to_vec2, vec3_to_vec3,
vec3_to_vec4, vec4_to_vec1, vec4_to_vec2, vec4_to_vec3, vec4_to_vec4,
};
//pub use self::ulp::*; //pub use self::ulp::*;
pub use self::quaternion::{quat_cast, quat_euler_angles, quat_greater_than, quat_greater_than_equal, quat_less_than, quat_less_than_equal, quat_look_at, quat_look_at_lh, quat_look_at_rh, quat_pitch, quat_roll, quat_yaw}; pub use self::quaternion::{
quat_cast, quat_euler_angles, quat_greater_than, quat_greater_than_equal, quat_less_than,
quat_less_than_equal, quat_look_at, quat_look_at_lh, quat_look_at_rh, quat_pitch, quat_roll,
quat_yaw,
};
//mod bitfield; //mod bitfield;
mod constants; mod constants;

View File

@ -1,7 +1,6 @@
use na::{Real, U4, UnitQuaternion}; use na::{Real, UnitQuaternion, U4};
use aliases::{Qua, TVec, TVec3, TMat4};
use aliases::{Qua, TMat4, TVec, TVec3};
/// Euler angles of the quaternion `q` as (pitch, yaw, roll). /// Euler angles of the quaternion `q` as (pitch, yaw, roll).
pub fn quat_euler_angles<N: Real>(x: &Qua<N>) -> TVec3<N> { pub fn quat_euler_angles<N: Real>(x: &Qua<N>) -> TVec3<N> {

View File

@ -1,8 +1,10 @@
use na::{Scalar, Real, DefaultAllocator, Quaternion}; use na::{DefaultAllocator, Quaternion, Real, Scalar};
use traits::{Number, Alloc, Dimension}; use aliases::{
use aliases::{Qua, TMat, TMat2, TMat3, TMat4, TVec1, TVec2, TVec3, TVec4, Qua, TMat, TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3, TVec1,
TMat2x3, TMat2x4, TMat3x2, TMat3x4, TMat4x2, TMat4x3}; TVec2, TVec3, TVec4,
};
use traits::{Alloc, Dimension, Number};
/// Creates a 2x2 matrix from a slice arranged in column-major order. /// Creates a 2x2 matrix from a slice arranged in column-major order.
pub fn make_mat2<N: Scalar>(ptr: &[N]) -> TMat2<N> { pub fn make_mat2<N: Scalar>(ptr: &[N]) -> TMat2<N> {
@ -69,19 +71,12 @@ pub fn mat2_to_mat3<N: Number>(m: &TMat2<N>) -> TMat3<N> {
let _0 = N::zero(); let _0 = N::zero();
let _1 = N::one(); let _1 = N::one();
TMat3::new( TMat3::new(m.m11, m.m12, _0, m.m21, m.m22, _0, _0, _0, _1)
m.m11, m.m12, _0,
m.m21, m.m22, _0,
_0, _0, _1
)
} }
/// Converts a 3x3 matrix to a 2x2 matrix. /// Converts a 3x3 matrix to a 2x2 matrix.
pub fn mat3_to_mat2<N: Scalar>(m: &TMat3<N>) -> TMat2<N> { pub fn mat3_to_mat2<N: Scalar>(m: &TMat3<N>) -> TMat2<N> {
TMat2::new( TMat2::new(m.m11, m.m12, m.m21, m.m22)
m.m11, m.m12,
m.m21, m.m22
)
} }
/// Converts a 3x3 matrix to a 4x4 matrix. /// Converts a 3x3 matrix to a 4x4 matrix.
@ -90,19 +85,14 @@ pub fn mat3_to_mat4<N: Number>(m: &TMat3<N>) -> TMat4<N> {
let _1 = N::one(); let _1 = N::one();
TMat4::new( TMat4::new(
m.m11, m.m12, m.m13, _0, m.m11, m.m12, m.m13, _0, m.m21, m.m22, m.m23, _0, m.m31, m.m32, m.m33, _0, _0, _0, _0, _1,
m.m21, m.m22, m.m23, _0,
m.m31, m.m32, m.m33, _0,
_0, _0, _0, _1,
) )
} }
/// Converts a 4x4 matrix to a 3x3 matrix. /// Converts a 4x4 matrix to a 3x3 matrix.
pub fn mat4_to_mat3<N: Scalar>(m: &TMat4<N>) -> TMat3<N> { pub fn mat4_to_mat3<N: Scalar>(m: &TMat4<N>) -> TMat3<N> {
TMat3::new( TMat3::new(
m.m11, m.m12, m.m13, m.m11, m.m12, m.m13, m.m21, m.m22, m.m23, m.m31, m.m32, m.m33,
m.m21, m.m22, m.m23,
m.m31, m.m32, m.m33,
) )
} }
@ -112,19 +102,13 @@ pub fn mat2_to_mat4<N: Number>(m: &TMat2<N>) -> TMat4<N> {
let _1 = N::one(); let _1 = N::one();
TMat4::new( TMat4::new(
m.m11, m.m12, _0, _0, m.m11, m.m12, _0, _0, m.m21, m.m22, _0, _0, _0, _0, _1, _0, _0, _0, _0, _1,
m.m21, m.m22, _0, _0,
_0, _0, _1, _0,
_0, _0, _0, _1,
) )
} }
/// Converts a 4x4 matrix to a 2x2 matrix. /// Converts a 4x4 matrix to a 2x2 matrix.
pub fn mat4_to_mat2<N: Scalar>(m: &TMat4<N>) -> TMat2<N> { pub fn mat4_to_mat2<N: Scalar>(m: &TMat4<N>) -> TMat2<N> {
TMat2::new( TMat2::new(m.m11, m.m12, m.m21, m.m22)
m.m11, m.m12,
m.m21, m.m22,
)
} }
/// Creates a quaternion from a slice arranged as `[x, y, z, w]`. /// Creates a quaternion from a slice arranged as `[x, y, z, w]`.
@ -400,13 +384,16 @@ pub fn make_vec4<N: Scalar>(ptr: &[N]) -> TVec4<N> {
/// Converts a matrix or vector to a slice arranged in column-major order. /// Converts a matrix or vector to a slice arranged in column-major order.
pub fn value_ptr<N: Scalar, R: Dimension, C: Dimension>(x: &TMat<N, R, C>) -> &[N] pub fn value_ptr<N: Scalar, R: Dimension, C: Dimension>(x: &TMat<N, R, C>) -> &[N]
where DefaultAllocator: Alloc<N, R, C> { where
DefaultAllocator: Alloc<N, R, C>,
{
x.as_slice() x.as_slice()
} }
/// Converts a matrix or vector to a mutable slice arranged in column-major order. /// Converts a matrix or vector to a mutable slice arranged in column-major order.
pub fn value_ptr_mut<N: Scalar, R: Dimension, C: Dimension>(x: &mut TMat<N, R, C>) -> &mut [N] pub fn value_ptr_mut<N: Scalar, R: Dimension, C: Dimension>(x: &mut TMat<N, R, C>) -> &mut [N]
where DefaultAllocator: Alloc<N, R, C> { where
DefaultAllocator: Alloc<N, R, C>,
{
x.as_mut_slice() x.as_mut_slice()
} }

View File

@ -1,7 +1,7 @@
use na::{self, DefaultAllocator}; use na::{self, DefaultAllocator};
use traits::{Number, Alloc, Dimension};
use aliases::TMat; use aliases::TMat;
use traits::{Alloc, Dimension, Number};
/// The sum of every component of the given matrix or vector. /// The sum of every component of the given matrix or vector.
/// ///
@ -22,7 +22,9 @@ use aliases::TMat;
/// * [`comp_min`](fn.comp_min.html) /// * [`comp_min`](fn.comp_min.html)
/// * [`comp_mul`](fn.comp_mul.html) /// * [`comp_mul`](fn.comp_mul.html)
pub fn comp_add<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N pub fn comp_add<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N
where DefaultAllocator: Alloc<N, R, C> { where
DefaultAllocator: Alloc<N, R, C>,
{
m.iter().fold(N::zero(), |x, y| x + *y) m.iter().fold(N::zero(), |x, y| x + *y)
} }
@ -49,7 +51,9 @@ pub fn comp_add<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N
/// * [`max3`](fn.max3.html) /// * [`max3`](fn.max3.html)
/// * [`max4`](fn.max4.html) /// * [`max4`](fn.max4.html)
pub fn comp_max<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N pub fn comp_max<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N
where DefaultAllocator: Alloc<N, R, C> { where
DefaultAllocator: Alloc<N, R, C>,
{
m.iter().fold(N::min_value(), |x, y| na::sup(&x, y)) m.iter().fold(N::min_value(), |x, y| na::sup(&x, y))
} }
@ -76,7 +80,9 @@ pub fn comp_max<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N
/// * [`min3`](fn.min3.html) /// * [`min3`](fn.min3.html)
/// * [`min4`](fn.min4.html) /// * [`min4`](fn.min4.html)
pub fn comp_min<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N pub fn comp_min<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N
where DefaultAllocator: Alloc<N, R, C> { where
DefaultAllocator: Alloc<N, R, C>,
{
m.iter().fold(N::max_value(), |x, y| na::inf(&x, y)) m.iter().fold(N::max_value(), |x, y| na::inf(&x, y))
} }
@ -99,7 +105,9 @@ pub fn comp_min<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N
/// * [`comp_max`](fn.comp_max.html) /// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min`](fn.comp_min.html) /// * [`comp_min`](fn.comp_min.html)
pub fn comp_mul<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N pub fn comp_mul<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N
where DefaultAllocator: Alloc<N, R, C> { where
DefaultAllocator: Alloc<N, R, C>,
{
m.iter().fold(N::one(), |x, y| x * *y) m.iter().fold(N::one(), |x, y| x * *y)
} }

View File

@ -1,5 +1,5 @@
use traits::Number;
use aliases::TVec2; use aliases::TVec2;
use traits::Number;
/// The 2D perpendicular product between two vectors. /// The 2D perpendicular product between two vectors.
pub fn cross2d<N: Number>(v: &TVec2<N>, u: &TVec2<N>) -> N { pub fn cross2d<N: Number>(v: &TVec2<N>, u: &TVec2<N>) -> N {

View File

@ -1,5 +1,5 @@
use traits::Number;
use aliases::TVec3; use aliases::TVec3;
use traits::Number;
/// Returns `true` if `{a, b, c}` forms a left-handed trihedron. /// Returns `true` if `{a, b, c}` forms a left-handed trihedron.
/// ///

View File

@ -1,5 +1,7 @@
use aliases::{
TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3, TVec2, TVec3, TVec4,
};
use traits::Number; use traits::Number;
use aliases::{TVec2, TVec3, TVec4, TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3};
/// Builds a 2x2 diagonal matrix. /// Builds a 2x2 diagonal matrix.
/// ///

View File

@ -1,25 +1,37 @@
//! (Reexported) Experimental features not specified by GLSL specification. //! (Reexported) Experimental features not specified by GLSL specification.
pub use self::component_wise::{comp_add, comp_max, comp_min, comp_mul}; pub use self::component_wise::{comp_add, comp_max, comp_min, comp_mul};
//pub use self::euler_angles::*; //pub use self::euler_angles::*;
pub use self::exterior_product::{cross2d}; pub use self::exterior_product::cross2d;
pub use self::handed_coordinate_space::{left_handed, right_handed}; pub use self::handed_coordinate_space::{left_handed, right_handed};
pub use self::matrix_cross_product::{matrix_cross, matrix_cross3}; pub use self::matrix_cross_product::{matrix_cross, matrix_cross3};
pub use self::matrix_operation::{diagonal2x2, diagonal2x3, diagonal2x4, diagonal3x2, diagonal3x3, diagonal3x4, diagonal4x2, diagonal4x3, diagonal4x4}; pub use self::matrix_operation::{
diagonal2x2, diagonal2x3, diagonal2x4, diagonal3x2, diagonal3x3, diagonal3x4, diagonal4x2,
diagonal4x3, diagonal4x4,
};
pub use self::norm::{distance2, l1_distance, l1_norm, l2_distance, l2_norm, length2, magnitude2}; pub use self::norm::{distance2, l1_distance, l1_norm, l2_distance, l2_norm, length2, magnitude2};
pub use self::normal::{triangle_normal}; pub use self::normal::triangle_normal;
pub use self::normalize_dot::{fast_normalize_dot, normalize_dot}; pub use self::normalize_dot::{fast_normalize_dot, normalize_dot};
pub use self::quaternion::{
mat3_to_quat, quat_cross_vec, quat_extract_real_component, quat_fast_mix, quat_identity,
quat_inv_cross_vec, quat_length2, quat_magnitude2, quat_rotate_vec, quat_rotate_vec3,
quat_rotation, quat_short_mix, quat_to_mat3, quat_to_mat4, to_quat,
};
pub use self::rotate_normalized_axis::{quat_rotate_normalized_axis, rotate_normalized_axis}; pub use self::rotate_normalized_axis::{quat_rotate_normalized_axis, rotate_normalized_axis};
pub use self::rotate_vector::{orientation, rotate_vec2, rotate_vec3, rotate_vec4, rotate_x_vec4, rotate_x_vec3, rotate_y_vec4, rotate_y_vec3, rotate_z_vec4, rotate_z_vec3, slerp}; pub use self::rotate_vector::{
pub use self::transform::{rotation, scaling, translation, rotation2d, scaling2d, translation2d}; orientation, rotate_vec2, rotate_vec3, rotate_vec4, rotate_x_vec3, rotate_x_vec4,
pub use self::transform2::{proj, proj2d, reflect, reflect2d, scale_bias, scale_bias_matrix, shear2d_x, shear_x, shear_y, shear2d_y, shear_z}; rotate_y_vec3, rotate_y_vec4, rotate_z_vec3, rotate_z_vec4, slerp,
};
pub use self::transform::{rotation, rotation2d, scaling, scaling2d, translation, translation2d};
pub use self::transform2::{
proj, proj2d, reflect, reflect2d, scale_bias, scale_bias_matrix, shear2d_x, shear2d_y, shear_x,
shear_y, shear_z,
};
pub use self::transform2d::{rotate2d, scale2d, translate2d}; pub use self::transform2d::{rotate2d, scale2d, translate2d};
pub use self::vector_angle::{angle}; pub use self::vector_angle::angle;
pub use self::vector_query::{are_collinear, are_collinear2d, are_orthogonal, is_comp_null, is_normalized, is_null}; pub use self::vector_query::{
pub use self::quaternion::{quat_to_mat3, quat_rotate_vec, quat_cross_vec, mat3_to_quat, quat_extract_real_component, quat_fast_mix, quat_inv_cross_vec, quat_length2, quat_magnitude2, quat_identity, quat_rotate_vec3, quat_rotation, quat_short_mix, quat_to_mat4, to_quat}; are_collinear, are_collinear2d, are_orthogonal, is_comp_null, is_normalized, is_null,
};
mod component_wise; mod component_wise;
//mod euler_angles; //mod euler_angles;
@ -30,6 +42,7 @@ mod matrix_operation;
mod norm; mod norm;
mod normal; mod normal;
mod normalize_dot; mod normalize_dot;
mod quaternion;
mod rotate_normalized_axis; mod rotate_normalized_axis;
mod rotate_vector; mod rotate_vector;
mod transform; mod transform;
@ -37,4 +50,3 @@ mod transform2;
mod transform2d; mod transform2d;
mod vector_angle; mod vector_angle;
mod vector_query; mod vector_query;
mod quaternion;

View File

@ -1,7 +1,7 @@
use na::{Real, DefaultAllocator}; use na::{DefaultAllocator, Real};
use traits::{Alloc, Dimension};
use aliases::TVec; use aliases::TVec;
use traits::{Alloc, Dimension};
/// The squared distance between two points. /// The squared distance between two points.
/// ///
@ -9,7 +9,9 @@ use aliases::TVec;
/// ///
/// * [`distance`](fn.distance.html) /// * [`distance`](fn.distance.html)
pub fn distance2<N: Real, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N pub fn distance2<N: Real, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
(p1 - p0).norm_squared() (p1 - p0).norm_squared()
} }
@ -21,7 +23,9 @@ pub fn distance2<N: Real, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N
/// * [`l2_distance`](fn.l2_distance.html) /// * [`l2_distance`](fn.l2_distance.html)
/// * [`l2_norm`](fn.l2_norm.html) /// * [`l2_norm`](fn.l2_norm.html)
pub fn l1_distance<N: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn l1_distance<N: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
l1_norm(&(y - x)) l1_norm(&(y - x))
} }
@ -36,7 +40,9 @@ pub fn l1_distance<N: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
/// * [`l2_distance`](fn.l2_distance.html) /// * [`l2_distance`](fn.l2_distance.html)
/// * [`l2_norm`](fn.l2_norm.html) /// * [`l2_norm`](fn.l2_norm.html)
pub fn l1_norm<N: Real, D: Dimension>(v: &TVec<N, D>) -> N pub fn l1_norm<N: Real, D: Dimension>(v: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
::comp_add(&v.abs()) ::comp_add(&v.abs())
} }
@ -55,7 +61,9 @@ pub fn l1_norm<N: Real, D: Dimension>(v: &TVec<N, D>) -> N
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2`](fn.magnitude2.html)
pub fn l2_distance<N: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn l2_distance<N: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
l2_norm(&(y - x)) l2_norm(&(y - x))
} }
@ -76,7 +84,9 @@ pub fn l2_distance<N: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2`](fn.magnitude2.html)
pub fn l2_norm<N: Real, D: Dimension>(x: &TVec<N, D>) -> N pub fn l2_norm<N: Real, D: Dimension>(x: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.norm() x.norm()
} }
@ -92,7 +102,9 @@ pub fn l2_norm<N: Real, D: Dimension>(x: &TVec<N, D>) -> N
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2`](fn.magnitude2.html)
pub fn length2<N: Real, D: Dimension>(x: &TVec<N, D>) -> N pub fn length2<N: Real, D: Dimension>(x: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.norm_squared() x.norm_squared()
} }
@ -108,7 +120,9 @@ pub fn length2<N: Real, D: Dimension>(x: &TVec<N, D>) -> N
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude`](fn.magnitude.html)
/// * [`nalgebra::norm_squared`](../nalgebra/fn.norm_squared.html) /// * [`nalgebra::norm_squared`](../nalgebra/fn.norm_squared.html)
pub fn magnitude2<N: Real, D: Dimension>(x: &TVec<N, D>) -> N pub fn magnitude2<N: Real, D: Dimension>(x: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.norm_squared() x.norm_squared()
} }

View File

@ -1,7 +1,7 @@
use na::{Real, DefaultAllocator}; use na::{DefaultAllocator, Real};
use traits::{Dimension, Alloc};
use aliases::TVec; use aliases::TVec;
use traits::{Alloc, Dimension};
/// The dot product of the normalized version of `x` and `y`. /// The dot product of the normalized version of `x` and `y`.
/// ///
@ -11,7 +11,9 @@ use aliases::TVec;
/// ///
/// * [`normalize_dot`](fn.normalize_dot.html`) /// * [`normalize_dot`](fn.normalize_dot.html`)
pub fn fast_normalize_dot<N: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn fast_normalize_dot<N: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
// XXX: improve those. // XXX: improve those.
x.normalize().dot(&y.normalize()) x.normalize().dot(&y.normalize())
} }
@ -22,7 +24,9 @@ pub fn fast_normalize_dot<N: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>)
/// ///
/// * [`fast_normalize_dot`](fn.fast_normalize_dot.html`) /// * [`fast_normalize_dot`](fn.fast_normalize_dot.html`)
pub fn normalize_dot<N: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn normalize_dot<N: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
// XXX: improve those. // XXX: improve those.
x.normalize().dot(&y.normalize()) x.normalize().dot(&y.normalize())
} }

View File

@ -1,4 +1,4 @@
use na::{Real, Unit, Rotation3, UnitQuaternion, U3}; use na::{Real, Rotation3, Unit, UnitQuaternion, U3};
use aliases::{Qua, TMat3, TMat4, TVec3, TVec4}; use aliases::{Qua, TMat3, TMat4, TVec3, TVec4};
@ -19,7 +19,9 @@ pub fn quat_extract_real_component<N: Real>(q: &Qua<N>) -> N {
/// Normalized linear interpolation between two quaternions. /// Normalized linear interpolation between two quaternions.
pub fn quat_fast_mix<N: Real>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> { pub fn quat_fast_mix<N: Real>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
Unit::new_unchecked(*x).nlerp(&Unit::new_unchecked(*y), a).unwrap() Unit::new_unchecked(*x)
.nlerp(&Unit::new_unchecked(*y), a)
.unwrap()
} }
//pub fn quat_intermediate<N: Real>(prev: &Qua<N>, curr: &Qua<N>, next: &Qua<N>) -> Qua<N> { //pub fn quat_intermediate<N: Real>(prev: &Qua<N>, curr: &Qua<N>, next: &Qua<N>) -> Qua<N> {
@ -54,12 +56,16 @@ pub fn quat_rotate_vec<N: Real>(q: &Qua<N>, v: &TVec4<N>) -> TVec4<N> {
/// The rotation required to align `orig` to `dest`. /// The rotation required to align `orig` to `dest`.
pub fn quat_rotation<N: Real>(orig: &TVec3<N>, dest: &TVec3<N>) -> Qua<N> { pub fn quat_rotation<N: Real>(orig: &TVec3<N>, dest: &TVec3<N>) -> Qua<N> {
UnitQuaternion::rotation_between(orig, dest).unwrap_or_else(UnitQuaternion::identity).unwrap() UnitQuaternion::rotation_between(orig, dest)
.unwrap_or_else(UnitQuaternion::identity)
.unwrap()
} }
/// The spherical linear interpolation between two quaternions. /// The spherical linear interpolation between two quaternions.
pub fn quat_short_mix<N: Real>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> { pub fn quat_short_mix<N: Real>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
Unit::new_normalize(*x).slerp(&Unit::new_normalize(*y), a).unwrap() Unit::new_normalize(*x)
.slerp(&Unit::new_normalize(*y), a)
.unwrap()
} }
//pub fn quat_squad<N: Real>(q1: &Qua<N>, q2: &Qua<N>, s1: &Qua<N>, s2: &Qua<N>, h: N) -> Qua<N> { //pub fn quat_squad<N: Real>(q1: &Qua<N>, q2: &Qua<N>, s1: &Qua<N>, s2: &Qua<N>, h: N) -> Qua<N> {
@ -68,7 +74,9 @@ pub fn quat_short_mix<N: Real>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
/// Converts a quaternion to a rotation matrix. /// Converts a quaternion to a rotation matrix.
pub fn quat_to_mat3<N: Real>(x: &Qua<N>) -> TMat3<N> { pub fn quat_to_mat3<N: Real>(x: &Qua<N>) -> TMat3<N> {
UnitQuaternion::new_unchecked(*x).to_rotation_matrix().unwrap() UnitQuaternion::new_unchecked(*x)
.to_rotation_matrix()
.unwrap()
} }
/// Converts a quaternion to a rotation matrix in homogenous coordinates. /// Converts a quaternion to a rotation matrix in homogenous coordinates.
@ -87,4 +95,3 @@ pub fn to_quat<N: Real>(x: &TMat4<N>) -> Qua<N> {
let rot = x.fixed_slice::<U3, U3>(0, 0).into_owned(); let rot = x.fixed_slice::<U3, U3>(0, 0).into_owned();
mat3_to_quat(&rot) mat3_to_quat(&rot)
} }

View File

@ -1,6 +1,6 @@
use na::{Real, Rotation3, Unit, UnitComplex}; use na::{Real, Rotation3, Unit, UnitComplex};
use aliases::{TVec2, TVec3, TVec4, TMat4}; use aliases::{TMat4, TVec2, TVec3, TVec4};
/// Build the rotation matrix needed to align `normal` and `up`. /// Build the rotation matrix needed to align `normal` and `up`.
pub fn orientation<N: Real>(normal: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> { pub fn orientation<N: Real>(normal: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
@ -58,5 +58,7 @@ pub fn rotate_z_vec4<N: Real>(v: &TVec4<N>, angle: N) -> TVec4<N> {
/// Computes a spherical linear interpolation between the vectors `x` and `y` assumed to be normalized. /// Computes a spherical linear interpolation between the vectors `x` and `y` assumed to be normalized.
pub fn slerp<N: Real>(x: &TVec3<N>, y: &TVec3<N>, a: N) -> TVec3<N> { pub fn slerp<N: Real>(x: &TVec3<N>, y: &TVec3<N>, a: N) -> TVec3<N> {
Unit::new_unchecked(*x).slerp(&Unit::new_unchecked(*y), a).unwrap() Unit::new_unchecked(*x)
.slerp(&Unit::new_unchecked(*y), a)
.unwrap()
} }

View File

@ -1,7 +1,7 @@
use na::{Real, Unit, Rotation2, Rotation3}; use na::{Real, Rotation2, Rotation3, Unit};
use aliases::{TMat3, TMat4, TVec2, TVec3};
use traits::Number; use traits::Number;
use aliases::{TVec3, TVec2, TMat3, TMat4};
/// A rotation 4 * 4 matrix created from an axis of 3 scalars and an angle expressed in radians. /// A rotation 4 * 4 matrix created from an axis of 3 scalars and an angle expressed in radians.
/// ///
@ -42,7 +42,6 @@ pub fn translation<N: Number>(v: &TVec3<N>) -> TMat4<N> {
TMat4::new_translation(v) TMat4::new_translation(v)
} }
/// A rotation 3 * 3 matrix created from an angle expressed in radians. /// A rotation 3 * 3 matrix created from an angle expressed in radians.
/// ///
/// # See also: /// # See also:

View File

@ -1,7 +1,7 @@
use na::{U2, U3}; use na::{U2, U3};
use aliases::{TMat3, TMat4, TVec2, TVec3};
use traits::Number; use traits::Number;
use aliases::{TVec2, TVec3, TMat3, TMat4};
/// Build planar projection matrix along normal axis and right-multiply it to `m`. /// Build planar projection matrix along normal axis and right-multiply it to `m`.
pub fn proj2d<N: Number>(m: &TMat3<N>, normal: &TVec2<N>) -> TMat3<N> { pub fn proj2d<N: Number>(m: &TMat3<N>, normal: &TVec2<N>) -> TMat3<N> {
@ -57,10 +57,7 @@ pub fn scale_bias_matrix<N: Number>(scale: N, bias: N) -> TMat4<N> {
let _1 = N::one(); let _1 = N::one();
TMat4::new( TMat4::new(
scale, _0, _0, bias, scale, _0, _0, bias, _0, scale, _0, bias, _0, _0, scale, bias, _0, _0, _0, _1,
_0, scale, _0, bias,
_0, _0, scale, bias,
_0, _0, _0, _1,
) )
} }
@ -74,11 +71,7 @@ pub fn shear2d_x<N: Number>(m: &TMat3<N>, y: N) -> TMat3<N> {
let _0 = N::zero(); let _0 = N::zero();
let _1 = N::one(); let _1 = N::one();
let shear = TMat3::new( let shear = TMat3::new(_1, y, _0, _0, _1, _0, _0, _0, _1);
_1, y, _0,
_0, _1, _0,
_0, _0, _1
);
m * shear m * shear
} }
@ -86,12 +79,7 @@ pub fn shear2d_x<N: Number>(m: &TMat3<N>, y: N) -> TMat3<N> {
pub fn shear_x<N: Number>(m: &TMat4<N>, y: N, z: N) -> TMat4<N> { pub fn shear_x<N: Number>(m: &TMat4<N>, y: N, z: N) -> TMat4<N> {
let _0 = N::zero(); let _0 = N::zero();
let _1 = N::one(); let _1 = N::one();
let shear = TMat4::new( let shear = TMat4::new(_1, _0, _0, _0, y, _1, _0, _0, z, _0, _1, _0, _0, _0, _0, _1);
_1, _0, _0, _0,
y, _1, _0, _0,
z, _0, _1, _0,
_0, _0, _0, _1,
);
m * shear m * shear
} }
@ -101,11 +89,7 @@ pub fn shear2d_y<N: Number>(m: &TMat3<N>, x: N) -> TMat3<N> {
let _0 = N::zero(); let _0 = N::zero();
let _1 = N::one(); let _1 = N::one();
let shear = TMat3::new( let shear = TMat3::new(_1, _0, _0, x, _1, _0, _0, _0, _1);
_1, _0, _0,
x, _1, _0,
_0, _0, _1
);
m * shear m * shear
} }
@ -113,12 +97,7 @@ pub fn shear2d_y<N: Number>(m: &TMat3<N>, x: N) -> TMat3<N> {
pub fn shear_y<N: Number>(m: &TMat4<N>, x: N, z: N) -> TMat4<N> { pub fn shear_y<N: Number>(m: &TMat4<N>, x: N, z: N) -> TMat4<N> {
let _0 = N::zero(); let _0 = N::zero();
let _1 = N::one(); let _1 = N::one();
let shear = TMat4::new( let shear = TMat4::new(_1, x, _0, _0, _0, _1, _0, _0, _0, z, _1, _0, _0, _0, _0, _1);
_1, x, _0, _0,
_0, _1, _0, _0,
_0, z, _1, _0,
_0, _0, _0, _1,
);
m * shear m * shear
} }
@ -127,12 +106,7 @@ pub fn shear_y<N: Number>(m: &TMat4<N>, x: N, z: N) -> TMat4<N> {
pub fn shear_z<N: Number>(m: &TMat4<N>, x: N, y: N) -> TMat4<N> { pub fn shear_z<N: Number>(m: &TMat4<N>, x: N, y: N) -> TMat4<N> {
let _0 = N::zero(); let _0 = N::zero();
let _1 = N::one(); let _1 = N::one();
let shear = TMat4::new( let shear = TMat4::new(_1, _0, x, _0, _0, _1, y, _0, _0, _0, _1, _0, _0, _0, _0, _1);
_1, _0, x, _0,
_0, _1, y, _0,
_0, _0, _1, _0,
_0, _0, _0, _1,
);
m * shear m * shear
} }

View File

@ -1,7 +1,7 @@
use na::{Real, UnitComplex}; use na::{Real, UnitComplex};
use traits::Number;
use aliases::{TMat3, TVec2}; use aliases::{TMat3, TVec2};
use traits::Number;
/// Builds a 2D rotation matrix from an angle and right-multiply it to `m`. /// Builds a 2D rotation matrix from an angle and right-multiply it to `m`.
/// ///

View File

@ -1,12 +1,13 @@
use na::{DefaultAllocator, Real}; use na::{DefaultAllocator, Real};
use traits::{Dimension, Alloc};
use aliases::TVec; use aliases::TVec;
use traits::{Alloc, Dimension};
/// The angle between two vectors. /// The angle between two vectors.
pub fn angle<N: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn angle<N: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.angle(y) x.angle(y)
} }

View File

@ -1,7 +1,7 @@
use na::{Real, DefaultAllocator}; use na::{DefaultAllocator, Real};
use traits::{Number, Dimension, Alloc};
use aliases::{TVec, TVec2, TVec3}; use aliases::{TVec, TVec2, TVec3};
use traits::{Alloc, Dimension, Number};
/// Returns `true` if two vectors are collinear (up to an epsilon). /// Returns `true` if two vectors are collinear (up to an epsilon).
/// ///
@ -23,7 +23,9 @@ pub fn are_collinear2d<N: Number>(v0: &TVec2<N>, v1: &TVec2<N>, epsilon: N) -> b
/// Returns `true` if two vectors are orthogonal (up to an epsilon). /// Returns `true` if two vectors are orthogonal (up to an epsilon).
pub fn are_orthogonal<N: Number, D: Dimension>(v0: &TVec<N, D>, v1: &TVec<N, D>, epsilon: N) -> bool pub fn are_orthogonal<N: Number, D: Dimension>(v0: &TVec<N, D>, v1: &TVec<N, D>, epsilon: N) -> bool
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
abs_diff_eq!(v0.dot(v1), N::zero(), epsilon = epsilon) abs_diff_eq!(v0.dot(v1), N::zero(), epsilon = epsilon)
} }
@ -34,18 +36,24 @@ pub fn are_orthogonal<N: Number, D: Dimension>(v0: &TVec<N, D>, v1: &TVec<N, D>,
/// Returns `true` if all the components of `v` are zero (up to an epsilon). /// Returns `true` if all the components of `v` are zero (up to an epsilon).
pub fn is_comp_null<N: Number, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> TVec<bool, D> pub fn is_comp_null<N: Number, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> TVec<bool, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| abs_diff_eq!(x, N::zero(), epsilon = epsilon)) v.map(|x| abs_diff_eq!(x, N::zero(), epsilon = epsilon))
} }
/// Returns `true` if `v` has a magnitude of 1 (up to an epsilon). /// Returns `true` if `v` has a magnitude of 1 (up to an epsilon).
pub fn is_normalized<N: Real, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> bool pub fn is_normalized<N: Real, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> bool
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
abs_diff_eq!(v.norm_squared(), N::one(), epsilon = epsilon * epsilon) abs_diff_eq!(v.norm_squared(), N::one(), epsilon = epsilon * epsilon)
} }
/// Returns `true` if `v` is zero (up to an epsilon). /// Returns `true` if `v` is zero (up to an epsilon).
pub fn is_null<N: Number, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> bool pub fn is_null<N: Number, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> bool
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
abs_diff_eq!(*v, TVec::<N, D>::zeros(), epsilon = epsilon) abs_diff_eq!(*v, TVec::<N, D>::zeros(), epsilon = epsilon)
} }

View File

@ -1,114 +1,114 @@
/*! # nalgebra-glm nalgebra in _easy mode_ /*! # nalgebra-glm nalgebra in _easy mode_
**nalgebra-glm** is a GLM-like interface for the **nalgebra** general-purpose linear algebra library. **nalgebra-glm** is a GLM-like interface for the **nalgebra** general-purpose linear algebra library.
[GLM](https://glm.g-truc.net) itself is a popular C++ linear algebra library essentially targeting computer graphics. Therefore [GLM](https://glm.g-truc.net) itself is a popular C++ linear algebra library essentially targeting computer graphics. Therefore
**nalgebra-glm** draws inspiration from GLM to define a nice and easy-to-use API for simple graphics application. **nalgebra-glm** draws inspiration from GLM to define a nice and easy-to-use API for simple graphics application.
All the types of **nalgebra-glm** are aliases of types from **nalgebra**. Therefore there is a complete and All the types of **nalgebra-glm** are aliases of types from **nalgebra**. Therefore there is a complete and
seamless inter-operability between both. seamless inter-operability between both.
## Getting started ## Getting started
First of all, you should start by taking a look at the official [GLM API documentation](http://glm.g-truc.net/0.9.9/api/index.html) First of all, you should start by taking a look at the official [GLM API documentation](http://glm.g-truc.net/0.9.9/api/index.html)
since **nalgebra-glm** implements a large subset of it. To use **nalgebra-glm** to your project, you since **nalgebra-glm** implements a large subset of it. To use **nalgebra-glm** to your project, you
should add it as a dependency to your `Crates.toml`: should add it as a dependency to your `Crates.toml`:
```toml ```toml
[dependencies] [dependencies]
nalgebra-glm = "0.1" nalgebra-glm = "0.1"
``` ```
Then, you should add an `extern crate` statement to your `lib.rs` or `main.rs` file. It is **strongly Then, you should add an `extern crate` statement to your `lib.rs` or `main.rs` file. It is **strongly
recommended** to add a crate alias to `glm` as well so that you will be able to call functions of recommended** to add a crate alias to `glm` as well so that you will be able to call functions of
**nalgebra-glm** using the module prefix `glm::`. For example you will write `glm::rotate(...)` instead **nalgebra-glm** using the module prefix `glm::`. For example you will write `glm::rotate(...)` instead
of the more verbose `nalgebra_glm::rotate(...)`: of the more verbose `nalgebra_glm::rotate(...)`:
```rust ```rust
extern crate nalgebra_glm as glm; extern crate nalgebra_glm as glm;
``` ```
## Features overview ## Features overview
**nalgebra-glm** supports most linear-algebra related features of the C++ GLM library. Mathematically **nalgebra-glm** supports most linear-algebra related features of the C++ GLM library. Mathematically
speaking, it supports all the common transformations like rotations, translations, scaling, shearing, speaking, it supports all the common transformations like rotations, translations, scaling, shearing,
and projections but operating in homogeneous coordinates. This means all the 2D transformations are and projections but operating in homogeneous coordinates. This means all the 2D transformations are
expressed as 3x3 matrices, and all the 3D transformations as 4x4 matrices. This is less computationally-efficient expressed as 3x3 matrices, and all the 3D transformations as 4x4 matrices. This is less computationally-efficient
and memory-efficient than nalgebra's [transformation types](https://www.nalgebra.org/points_and_transformations/#transformations), and memory-efficient than nalgebra's [transformation types](https://www.nalgebra.org/points_and_transformations/#transformations),
but this has the benefit of being simpler to use. but this has the benefit of being simpler to use.
### Main differences compared to GLM ### Main differences compared to GLM
While **nalgebra-glm** follows the feature line of the C++ GLM library, quite a few differences While **nalgebra-glm** follows the feature line of the C++ GLM library, quite a few differences
remain and they are mostly syntactic. The main ones are: remain and they are mostly syntactic. The main ones are:
* All function names use `snake_case`, which is the Rust convention. * All function names use `snake_case`, which is the Rust convention.
* All type names use `CamelCase`, which is the Rust convention. * All type names use `CamelCase`, which is the Rust convention.
* All function arguments, except for scalars, are all passed by-reference. * All function arguments, except for scalars, are all passed by-reference.
* The most generic vector and matrix types are [`TMat`](type.TMat.html) and [`TVec`](type.TVec.html) instead of `mat` and `vec`. * The most generic vector and matrix types are [`TMat`](type.TMat.html) and [`TVec`](type.TVec.html) instead of `mat` and `vec`.
* Some feature are not yet implemented and should be added in the future. In particular, no packing * Some feature are not yet implemented and should be added in the future. In particular, no packing
functions are available. functions are available.
* A few features are not implemented and will never be. This includes functions related to color * A few features are not implemented and will never be. This includes functions related to color
spaces, and closest points computations. Other crates should be used for those. For example, closest spaces, and closest points computations. Other crates should be used for those. For example, closest
points computation can be handled by the [ncollide](https://ncollide.org) project. points computation can be handled by the [ncollide](https://ncollide.org) project.
In addition, because Rust does not allows function overloading, all functions must be given a unique name. In addition, because Rust does not allows function overloading, all functions must be given a unique name.
Here are a few rules chosen arbitrarily for **nalgebra-glm**: Here are a few rules chosen arbitrarily for **nalgebra-glm**:
* Functions operating in 2d will usually end with the `2d` suffix, e.g., [`glm::rotate2d`](fn.rotate2d.html) is for 2D while [`glm::rotate`](fn.rotate.html) is for 3D. * Functions operating in 2d will usually end with the `2d` suffix, e.g., [`glm::rotate2d`](fn.rotate2d.html) is for 2D while [`glm::rotate`](fn.rotate.html) is for 3D.
* Functions operating on vectors will often end with the `_vec` suffix, possibly followed by the dimension of vector, e.g., [`glm::rotate_vec2`](fn.rotate_vec2.html). * Functions operating on vectors will often end with the `_vec` suffix, possibly followed by the dimension of vector, e.g., [`glm::rotate_vec2`](fn.rotate_vec2.html).
* Every function related to quaternions start with the `quat_` prefix, e.g., [`glm::quat_dot(q1, q2)`](fn.quat_dot.html). * Every function related to quaternions start with the `quat_` prefix, e.g., [`glm::quat_dot(q1, q2)`](fn.quat_dot.html).
* All the conversion functions have unique names as described [below](#conversions). * All the conversion functions have unique names as described [below](#conversions).
### Vector and matrix construction ### Vector and matrix construction
Vectors, matrices, and quaternions can be constructed using several approaches: Vectors, matrices, and quaternions can be constructed using several approaches:
* Using functions with the same name as their type in lower-case. For example [`glm::vec3(x, y, z)`](fn.vec3.html) will create a 3D vector. * Using functions with the same name as their type in lower-case. For example [`glm::vec3(x, y, z)`](fn.vec3.html) will create a 3D vector.
* Using the `::new` constructor. For example [`Vec3::new(x, y, z)`](../nalgebra/base/type.MatrixMN.html#method.new-27) will create a 3D vector. * Using the `::new` constructor. For example [`Vec3::new(x, y, z)`](../nalgebra/base/type.MatrixMN.html#method.new-27) will create a 3D vector.
* Using the functions prefixed by `make_` to build a vector a matrix from a slice. For example [`glm::make_vec3(&[x, y, z])`](fn.make_vec3.html) will create a 3D vector. * Using the functions prefixed by `make_` to build a vector a matrix from a slice. For example [`glm::make_vec3(&[x, y, z])`](fn.make_vec3.html) will create a 3D vector.
Keep in mind that constructing a matrix using this type of functions require its components to be arranged in column-major order on the slice. Keep in mind that constructing a matrix using this type of functions require its components to be arranged in column-major order on the slice.
* Using a geometric construction function. For example [`glm::rotation(angle, axis)`](fn.rotation.html) will build a 4x4 homogeneous rotation matrix from an angle (in radians) and an axis. * Using a geometric construction function. For example [`glm::rotation(angle, axis)`](fn.rotation.html) will build a 4x4 homogeneous rotation matrix from an angle (in radians) and an axis.
* Using swizzling and conversions as described in the next sections. * Using swizzling and conversions as described in the next sections.
### Swizzling ### Swizzling
Vector swizzling is a native feature of **nalgebra** itself. Therefore, you can use it with all Vector swizzling is a native feature of **nalgebra** itself. Therefore, you can use it with all
the vectors of **nalgebra-glm** as well. Swizzling is supported as methods and works only up to the vectors of **nalgebra-glm** as well. Swizzling is supported as methods and works only up to
dimension 3, i.e., you can only refer to the components `x`, `y` and `z` and can only create a dimension 3, i.e., you can only refer to the components `x`, `y` and `z` and can only create a
2D or 3D vector using this technique. Here is some examples, assuming `v` is a vector with float 2D or 3D vector using this technique. Here is some examples, assuming `v` is a vector with float
components here: components here:
* `v.xx()` is equivalent to `glm::vec2(v.x, v.x)` and to `Vec2::new(v.x, v.x)`. * `v.xx()` is equivalent to `glm::vec2(v.x, v.x)` and to `Vec2::new(v.x, v.x)`.
* `v.zx()` is equivalent to `glm::vec2(v.z, v.x)` and to `Vec2::new(v.z, v.x)`. * `v.zx()` is equivalent to `glm::vec2(v.z, v.x)` and to `Vec2::new(v.z, v.x)`.
* `v.yxz()` is equivalent to `glm::vec3(v.y, v.x, v.z)` and to `Vec3::new(v.y, v.x, v.z)`. * `v.yxz()` is equivalent to `glm::vec3(v.y, v.x, v.z)` and to `Vec3::new(v.y, v.x, v.z)`.
* `v.zzy()` is equivalent to `glm::vec3(v.z, v.z, v.y)` and to `Vec3::new(v.z, v.z, v.y)`. * `v.zzy()` is equivalent to `glm::vec3(v.z, v.z, v.y)` and to `Vec3::new(v.z, v.z, v.y)`.
Any combination of two or three components picked among `x`, `y`, and `z` will work. Any combination of two or three components picked among `x`, `y`, and `z` will work.
### Conversions ### Conversions
It is often useful to convert one algebraic type to another. There are two main approaches for converting It is often useful to convert one algebraic type to another. There are two main approaches for converting
between types in `nalgebra-glm`: between types in `nalgebra-glm`:
* Using function with the form `type1_to_type2` in order to convert an instance of `type1` into an instance of `type2`. * Using function with the form `type1_to_type2` in order to convert an instance of `type1` into an instance of `type2`.
For example [`glm::mat3_to_mat4(m)`](fn.mat3_to_mat4.html) will convert the 3x3 matrix `m` to a 4x4 matrix by appending one column on the right For example [`glm::mat3_to_mat4(m)`](fn.mat3_to_mat4.html) will convert the 3x3 matrix `m` to a 4x4 matrix by appending one column on the right
and one row on the left. Those now row and columns are filled with 0 except for the diagonal element which is set to 1. and one row on the left. Those now row and columns are filled with 0 except for the diagonal element which is set to 1.
* Using one of the [`convert`](fn.convert.html), [`try_convert`](fn.try_convert.html), or [`convert_unchecked`](fn.convert_unchecked.html) functions. * Using one of the [`convert`](fn.convert.html), [`try_convert`](fn.try_convert.html), or [`convert_unchecked`](fn.convert_unchecked.html) functions.
These functions are directly re-exported from nalgebra and are extremely versatile: These functions are directly re-exported from nalgebra and are extremely versatile:
1. The `convert` function can convert any type (especially geometric types from nalgebra like `Isometry3`) into another algebraic type which is equivalent but more general. For example, 1. The `convert` function can convert any type (especially geometric types from nalgebra like `Isometry3`) into another algebraic type which is equivalent but more general. For example,
`let sim: Similarity3<_> = na::convert(isometry)` will convert an `Isometry3` into a `Similarity3`. `let sim: Similarity3<_> = na::convert(isometry)` will convert an `Isometry3` into a `Similarity3`.
In addition, `let mat: Mat4 = glm::convert(isometry)` will convert an `Isometry3` to a 4x4 matrix. This will also convert the scalar types, In addition, `let mat: Mat4 = glm::convert(isometry)` will convert an `Isometry3` to a 4x4 matrix. This will also convert the scalar types,
therefore: `let mat: DMat4 = glm::convert(m)` where `m: Mat4` will work. However, conversion will not work the other way round: you therefore: `let mat: DMat4 = glm::convert(m)` where `m: Mat4` will work. However, conversion will not work the other way round: you
can't convert a `Matrix4` to an `Isometry3` using `glm::convert` because that could cause unexpected results if the matrix does can't convert a `Matrix4` to an `Isometry3` using `glm::convert` because that could cause unexpected results if the matrix does
not complies to the requirements of the isometry. not complies to the requirements of the isometry.
2. If you need this kind of conversions anyway, you can use `try_convert` which will test if the object being converted complies with the algebraic requirements of the target type. 2. If you need this kind of conversions anyway, you can use `try_convert` which will test if the object being converted complies with the algebraic requirements of the target type.
This will return `None` if the requirements are not satisfied. This will return `None` if the requirements are not satisfied.
3. The `convert_unchecked` will ignore those tests and always perform the conversion, even if that breaks the invariants of the target type. 3. The `convert_unchecked` will ignore those tests and always perform the conversion, even if that breaks the invariants of the target type.
This must be used with care! This is actually the recommended method to convert between homogeneous transformations generated by `nalgebra-glm` and This must be used with care! This is actually the recommended method to convert between homogeneous transformations generated by `nalgebra-glm` and
specific transformation types from **nalgebra** like `Isometry3`. Just be careful you know your conversions make sense. specific transformation types from **nalgebra** like `Isometry3`. Just be careful you know your conversions make sense.
### Should I use nalgebra or nalgebra-glm? ### Should I use nalgebra or nalgebra-glm?
Well that depends on your tastes and your background. **nalgebra** is more powerful overall since it allows stronger typing, Well that depends on your tastes and your background. **nalgebra** is more powerful overall since it allows stronger typing,
and goes much further than simple computer graphics math. However, has a bit of a learning curve for and goes much further than simple computer graphics math. However, has a bit of a learning curve for
those not used to the abstract mathematical concepts for transformations. **nalgebra-glm** however those not used to the abstract mathematical concepts for transformations. **nalgebra-glm** however
have more straightforward functions and benefit from the various tutorials existing on the internet have more straightforward functions and benefit from the various tutorials existing on the internet
for the original C++ GLM library. for the original C++ GLM library.
Overall, if you are already used to the C++ GLM library, or to working with homogeneous coordinates (like 4D Overall, if you are already used to the C++ GLM library, or to working with homogeneous coordinates (like 4D
matrices for 3D transformations), then you will have more success with **nalgebra-glm**. If on the other matrices for 3D transformations), then you will have more success with **nalgebra-glm**. If on the other
hand you prefer more rigorous treatments of transformations, with type-level restrictions, then go for **nalgebra**. hand you prefer more rigorous treatments of transformations, with type-level restrictions, then go for **nalgebra**.
If you need dynamically-sized matrices, you should go for **nalgebra** as well. If you need dynamically-sized matrices, you should go for **nalgebra** as well.
Keep in mind that **nalgebra-glm** is just a different API for **nalgebra**. So you can very well use both Keep in mind that **nalgebra-glm** is just a different API for **nalgebra**. So you can very well use both
and benefit from both their advantages: use **nalgebra-glm** when mathematical rigor is not that important, and benefit from both their advantages: use **nalgebra-glm** when mathematical rigor is not that important,
and **nalgebra** itself when you need more expressive types, and more powerful linear algebra operations like and **nalgebra** itself when you need more expressive types, and more powerful linear algebra operations like
matrix factorizations and slicing. Just remember that all the **nalgebra-glm** types are just aliases to **nalgebra** types, matrix factorizations and slicing. Just remember that all the **nalgebra-glm** types are just aliases to **nalgebra** types,
and keep in mind it is possible to convert, e.g., an `Isometry3` to a `Mat4` and vice-versa (see the [conversions section](#conversions)). and keep in mind it is possible to convert, e.g., an `Isometry3` to a `Mat4` and vice-versa (see the [conversions section](#conversions)).
*/ */
#![doc(html_favicon_url = "http://nalgebra.org/img/favicon.ico")] #![doc(html_favicon_url = "http://nalgebra.org/img/favicon.ico")]
@ -119,68 +119,83 @@ extern crate alga;
extern crate nalgebra as na; extern crate nalgebra as na;
pub use aliases::*; pub use aliases::*;
pub use common::{
abs, ceil, clamp, clamp_scalar, clamp_vec, float_bits_to_int, float_bits_to_int_vec,
float_bits_to_uint, float_bits_to_uint_vec, floor, fract, int_bits_to_float,
int_bits_to_float_vec, lerp, lerp_scalar, lerp_vec, mix, mix_scalar, mix_vec, modf, modf_vec,
round, sign, smoothstep, step, step_scalar, step_vec, trunc, uint_bits_to_float,
uint_bits_to_float_scalar,
};
pub use constructors::*; pub use constructors::*;
pub use common::{abs, ceil, clamp, clamp_scalar, clamp_vec, float_bits_to_int, float_bits_to_int_vec, float_bits_to_uint, float_bits_to_uint_vec, floor, fract, int_bits_to_float, int_bits_to_float_vec, mix, modf, modf_vec, round, sign, smoothstep, step, step_scalar, step_vec, trunc, uint_bits_to_float, uint_bits_to_float_scalar};
pub use geometric::{reflect_vec, cross, distance, dot, faceforward, length, magnitude, normalize, refract_vec};
pub use matrix::{transpose, determinant, inverse, matrix_comp_mult, outer_product};
pub use traits::{Dimension, Number, Alloc};
pub use trigonometric::{acos, acosh, asin, asinh, atan, atan2, atanh, cos, cosh, degrees, radians, sin, sinh, tan, tanh};
pub use vector_relational::{all, any, equal, greater_than, greater_than_equal, less_than, less_than_equal, not, not_equal};
pub use exponential::{exp, exp2, inversesqrt, log, log2, pow, sqrt}; pub use exponential::{exp, exp2, inversesqrt, log, log2, pow, sqrt};
pub use geometric::{
cross, distance, dot, faceforward, length, magnitude, normalize, reflect_vec, refract_vec,
};
pub use matrix::{determinant, inverse, matrix_comp_mult, outer_product, transpose};
pub use traits::{Alloc, Dimension, Number};
pub use trigonometric::{
acos, acosh, asin, asinh, atan, atan2, atanh, cos, cosh, degrees, radians, sin, sinh, tan, tanh,
};
pub use vector_relational::{
all, any, equal, greater_than, greater_than_equal, less_than, less_than_equal, not, not_equal,
};
pub use gtx::{ pub use ext::{
comp_add, comp_max, comp_min, comp_mul, epsilon, equal_columns, equal_columns_eps, equal_columns_eps_vec, equal_eps, equal_eps_vec,
cross2d, identity, look_at, look_at_lh, look_at_rh, max, max2, max3, max3_scalar, max4, max4_scalar,
left_handed, right_handed, min, min2, min3, min3_scalar, min4, min4_scalar, not_equal_columns, not_equal_columns_eps,
matrix_cross, matrix_cross3, not_equal_columns_eps_vec, not_equal_eps, not_equal_eps_vec, ortho, perspective, pi,
diagonal2x2, diagonal2x3, diagonal2x4, diagonal3x2, diagonal3x3, diagonal3x4, diagonal4x2, diagonal4x3, diagonal4x4, pick_matrix, project, project_no, project_zo, quat_angle, quat_angle_axis, quat_axis,
distance2, l1_distance, l1_norm, l2_distance, l2_norm, length2, magnitude2, quat_conjugate, quat_cross, quat_dot, quat_equal, quat_equal_eps, quat_exp, quat_inverse,
triangle_normal, quat_length, quat_lerp, quat_log, quat_magnitude, quat_normalize, quat_not_equal,
fast_normalize_dot, normalize_dot, quat_not_equal_eps, quat_pow, quat_rotate, quat_slerp, rotate, rotate_x, rotate_y, rotate_z,
quat_rotate_normalized_axis, rotate_normalized_axis, scale, translate, unproject, unproject_no, unproject_zo,
orientation, rotate_vec2, rotate_vec3, rotate_vec4, rotate_x_vec4, rotate_x_vec3, rotate_y_vec4, rotate_y_vec3, rotate_z_vec4, rotate_z_vec3, slerp,
rotation, scaling, translation, rotation2d, scaling2d, translation2d,
proj, proj2d, reflect, reflect2d, scale_bias, scale_bias_matrix, shear2d_x, shear_x, shear_y, shear2d_y, shear_z,
rotate2d, scale2d, translate2d,
angle,
are_collinear, are_collinear2d, are_orthogonal, is_comp_null, is_normalized, is_null,
quat_to_mat3, quat_rotate_vec, quat_cross_vec, mat3_to_quat, quat_extract_real_component, quat_fast_mix, quat_inv_cross_vec, quat_length2, quat_magnitude2, quat_identity, quat_rotate_vec3, quat_rotation, quat_short_mix, quat_to_mat4, to_quat
}; };
pub use gtc::{ pub use gtc::{
e, two_pi, euler, four_over_pi, golden_ratio, half_pi, ln_ln_two, ln_ten, ln_two, one, one_over_pi, one_over_root_two, one_over_two_pi, quarter_pi, root_five, root_half_pi, root_ln_four, root_pi, root_three, root_two, root_two_pi, third, three_over_two_pi, two_over_pi, two_over_root_pi, two_thirds, zero, affine_inverse, column, e, euler, four_over_pi, golden_ratio, half_pi, inverse_transpose,
column, row, set_column, set_row, ln_ln_two, ln_ten, ln_two, make_mat2, make_mat2x2, make_mat2x3, make_mat2x4, make_mat3,
affine_inverse, inverse_transpose, make_mat3x2, make_mat3x3, make_mat3x4, make_mat4, make_mat4x2, make_mat4x3, make_mat4x4,
make_mat2, make_mat2x2, make_mat2x3, make_mat2x4, make_mat3, make_mat3x2, make_mat3x3, make_mat3x4, make_mat4, make_mat4x2, make_mat4x3, make_mat4x4, make_quat, make_vec1, make_vec2, make_vec3, make_vec4, value_ptr, value_ptr_mut, vec1_to_vec2, vec1_to_vec3, vec1_to_vec4, vec2_to_vec1, vec2_to_vec2, vec2_to_vec3, vec2_to_vec4, vec3_to_vec1, vec3_to_vec2, vec3_to_vec3, vec3_to_vec4, vec4_to_vec1, vec4_to_vec2, vec4_to_vec3, vec4_to_vec4, mat2_to_mat3, mat2_to_mat4, mat3_to_mat2, mat3_to_mat4, mat4_to_mat2, mat4_to_mat3, make_quat, make_vec1, make_vec2, make_vec3, make_vec4, mat2_to_mat3, mat2_to_mat4,
quat_cast, quat_euler_angles, quat_greater_than, quat_greater_than_equal, quat_less_than, quat_less_than_equal, quat_look_at, quat_look_at_lh, quat_look_at_rh, quat_pitch, quat_roll, quat_yaw mat3_to_mat2, mat3_to_mat4, mat4_to_mat2, mat4_to_mat3, one, one_over_pi, one_over_root_two,
one_over_two_pi, quarter_pi, quat_cast, quat_euler_angles, quat_greater_than,
quat_greater_than_equal, quat_less_than, quat_less_than_equal, quat_look_at, quat_look_at_lh,
quat_look_at_rh, quat_pitch, quat_roll, quat_yaw, root_five, root_half_pi, root_ln_four,
root_pi, root_three, root_two, root_two_pi, row, set_column, set_row, third, three_over_two_pi,
two_over_pi, two_over_root_pi, two_pi, two_thirds, value_ptr, value_ptr_mut, vec1_to_vec2,
vec1_to_vec3, vec1_to_vec4, vec2_to_vec1, vec2_to_vec2, vec2_to_vec3, vec2_to_vec4,
vec3_to_vec1, vec3_to_vec2, vec3_to_vec3, vec3_to_vec4, vec4_to_vec1, vec4_to_vec2,
vec4_to_vec3, vec4_to_vec4, zero,
}; };
pub use ext::{ pub use gtx::{
ortho, perspective, angle, are_collinear, are_collinear2d, are_orthogonal, comp_add, comp_max, comp_min, comp_mul,
pick_matrix, project, project_no, project_zo, unproject, unproject_no, unproject_zo, cross2d, diagonal2x2, diagonal2x3, diagonal2x4, diagonal3x2, diagonal3x3, diagonal3x4,
equal_columns, equal_columns_eps, equal_columns_eps_vec, not_equal_columns, not_equal_columns_eps, not_equal_columns_eps_vec, diagonal4x2, diagonal4x3, diagonal4x4, distance2, fast_normalize_dot, is_comp_null,
identity, look_at, look_at_lh, rotate, scale, look_at_rh, translate, rotate_x, rotate_y, rotate_z, is_normalized, is_null, l1_distance, l1_norm, l2_distance, l2_norm, left_handed, length2,
max3_scalar, max4_scalar, min3_scalar, min4_scalar, magnitude2, mat3_to_quat, matrix_cross, matrix_cross3, normalize_dot, orientation, proj,
epsilon, pi, proj2d, quat_cross_vec, quat_extract_real_component, quat_fast_mix, quat_identity,
max, max2, max3, max4, min, min2, min3, min4, quat_inv_cross_vec, quat_length2, quat_magnitude2, quat_rotate_normalized_axis,
equal_eps, equal_eps_vec, not_equal_eps, not_equal_eps_vec, quat_rotate_vec, quat_rotate_vec3, quat_rotation, quat_short_mix, quat_to_mat3, quat_to_mat4,
quat_conjugate, quat_inverse, quat_lerp, quat_slerp, reflect, reflect2d, right_handed, rotate2d, rotate_normalized_axis, rotate_vec2, rotate_vec3,
quat_cross, quat_dot, quat_length, quat_magnitude, quat_normalize, rotate_vec4, rotate_x_vec3, rotate_x_vec4, rotate_y_vec3, rotate_y_vec4, rotate_z_vec3,
quat_equal, quat_equal_eps, quat_not_equal, quat_not_equal_eps, rotate_z_vec4, rotation, rotation2d, scale2d, scale_bias, scale_bias_matrix, scaling,
quat_exp, quat_log, quat_pow, quat_rotate, scaling2d, shear2d_x, shear2d_y, shear_x, shear_y, shear_z, slerp, to_quat, translate2d,
quat_angle, quat_angle_axis, quat_axis translation, translation2d, triangle_normal,
}; };
pub use na::{convert, convert_ref, convert_unchecked, convert_ref_unchecked, try_convert, try_convert_ref}; pub use na::{
pub use na::{Scalar, Real, DefaultAllocator, U1, U2, U3, U4}; convert, convert_ref, convert_ref_unchecked, convert_unchecked, try_convert, try_convert_ref,
};
pub use na::{DefaultAllocator, Real, Scalar, U1, U2, U3, U4};
mod aliases; mod aliases;
mod constructors;
mod common; mod common;
mod matrix; mod constructors;
mod exponential;
mod geometric; mod geometric;
mod matrix;
mod traits; mod traits;
mod trigonometric; mod trigonometric;
mod vector_relational; mod vector_relational;
mod exponential;
//mod integer; //mod integer;
//mod packing; //mod packing;

View File

@ -1,34 +1,52 @@
use na::{Scalar, Real, DefaultAllocator}; use na::{DefaultAllocator, Real, Scalar};
use traits::{Alloc, Dimension, Number};
use aliases::{TMat, TVec}; use aliases::{TMat, TVec};
use traits::{Alloc, Dimension, Number};
/// The determinant of the matrix `m`. /// The determinant of the matrix `m`.
pub fn determinant<N: Real, D: Dimension>(m: &TMat<N, D, D>) -> N pub fn determinant<N: Real, D: Dimension>(m: &TMat<N, D, D>) -> N
where DefaultAllocator: Alloc<N, D, D> { where
DefaultAllocator: Alloc<N, D, D>,
{
m.determinant() m.determinant()
} }
/// The inverse of the matrix `m`. /// The inverse of the matrix `m`.
pub fn inverse<N: Real, D: Dimension>(m: &TMat<N, D, D>) -> TMat<N, D, D> pub fn inverse<N: Real, D: Dimension>(m: &TMat<N, D, D>) -> TMat<N, D, D>
where DefaultAllocator: Alloc<N, D, D> { where
m.clone().try_inverse().unwrap_or_else(TMat::<N, D, D>::zeros) DefaultAllocator: Alloc<N, D, D>,
{
m.clone()
.try_inverse()
.unwrap_or_else(TMat::<N, D, D>::zeros)
} }
/// Component-wise multiplication of two matrices. /// Component-wise multiplication of two matrices.
pub fn matrix_comp_mult<N: Number, R: Dimension, C: Dimension>(x: &TMat<N, R, C>, y: &TMat<N, R, C>) -> TMat<N, R, C> pub fn matrix_comp_mult<N: Number, R: Dimension, C: Dimension>(
where DefaultAllocator: Alloc<N, R, C> { x: &TMat<N, R, C>,
y: &TMat<N, R, C>,
) -> TMat<N, R, C>
where
DefaultAllocator: Alloc<N, R, C>,
{
x.component_mul(y) x.component_mul(y)
} }
/// Treats the first parameter `c` as a column vector and the second parameter `r` as a row vector and does a linear algebraic matrix multiply `c * r`. /// Treats the first parameter `c` as a column vector and the second parameter `r` as a row vector and does a linear algebraic matrix multiply `c * r`.
pub fn outer_product<N: Number, R: Dimension, C: Dimension>(c: &TVec<N, R>, r: &TVec<N, C>) -> TMat<N, R, C> pub fn outer_product<N: Number, R: Dimension, C: Dimension>(
where DefaultAllocator: Alloc<N, R, C> { c: &TVec<N, R>,
r: &TVec<N, C>,
) -> TMat<N, R, C>
where
DefaultAllocator: Alloc<N, R, C>,
{
c * r.transpose() c * r.transpose()
} }
/// The transpose of the matrix `m`. /// The transpose of the matrix `m`.
pub fn transpose<N: Scalar, R: Dimension, C: Dimension>(x: &TMat<N, R, C>) -> TMat<N, C, R> pub fn transpose<N: Scalar, R: Dimension, C: Dimension>(x: &TMat<N, R, C>) -> TMat<N, C, R>
where DefaultAllocator: Alloc<N, R, C> { where
DefaultAllocator: Alloc<N, R, C>,
{
x.transpose() x.transpose()
} }

View File

@ -1,48 +1,80 @@
use num::{Signed, FromPrimitive, Bounded};
use approx::AbsDiffEq; use approx::AbsDiffEq;
use num::{Bounded, FromPrimitive, Signed};
use alga::general::{Ring, Lattice}; use alga::general::{Lattice, Ring};
use na::{Scalar, DimName, DimMin, U1};
use na::allocator::Allocator; use na::allocator::Allocator;
use na::{DimMin, DimName, Scalar, U1};
/// A type-level number representing a vector, matrix row, or matrix column, dimension. /// A type-level number representing a vector, matrix row, or matrix column, dimension.
pub trait Dimension: DimName + DimMin<Self, Output = Self> {} pub trait Dimension: DimName + DimMin<Self, Output = Self> {}
impl<D: DimName + DimMin<D, Output = Self>> Dimension for D {} impl<D: DimName + DimMin<D, Output = Self>> Dimension for D {}
/// A number that can either be an integer or a float. /// A number that can either be an integer or a float.
pub trait Number: Scalar + Ring + Lattice + AbsDiffEq<Epsilon = Self> + Signed + FromPrimitive + Bounded { pub trait Number:
Scalar + Ring + Lattice + AbsDiffEq<Epsilon = Self> + Signed + FromPrimitive + Bounded
{
} }
impl<T: Scalar + Ring + Lattice + AbsDiffEq<Epsilon = Self> + Signed + FromPrimitive + Bounded> Number for T { impl<T: Scalar + Ring + Lattice + AbsDiffEq<Epsilon = Self> + Signed + FromPrimitive + Bounded>
} Number for T
{}
#[doc(hidden)] #[doc(hidden)]
pub trait Alloc<N: Scalar, R: Dimension, C: Dimension = U1>: pub trait Alloc<N: Scalar, R: Dimension, C: Dimension = U1>:
Allocator<N, R> + Allocator<N, C> + Allocator<N, U1, R> + Allocator<N, U1, C> + Allocator<N, R, C> + Allocator<N, C, R> + Allocator<N, R, R> + Allocator<N, C, C> + Allocator<N, R>
Allocator<bool, R> + Allocator<bool, C> + + Allocator<N, C>
Allocator<f32, R> + Allocator<f32, C> + + Allocator<N, U1, R>
Allocator<u32, R> + Allocator<u32, C> + + Allocator<N, U1, C>
Allocator<i32, R> + Allocator<i32, C> + + Allocator<N, R, C>
Allocator<f64, R> + Allocator<f64, C> + + Allocator<N, C, R>
Allocator<u64, R> + Allocator<u64, C> + + Allocator<N, R, R>
Allocator<i64, R> + Allocator<i64, C> + + Allocator<N, C, C>
Allocator<i16, R> + Allocator<i16, C> + + Allocator<bool, R>
Allocator<(usize, usize), R> + Allocator<(usize, usize), C> + Allocator<bool, C>
+ Allocator<f32, R>
+ Allocator<f32, C>
+ Allocator<u32, R>
+ Allocator<u32, C>
+ Allocator<i32, R>
+ Allocator<i32, C>
+ Allocator<f64, R>
+ Allocator<f64, C>
+ Allocator<u64, R>
+ Allocator<u64, C>
+ Allocator<i64, R>
+ Allocator<i64, C>
+ Allocator<i16, R>
+ Allocator<i16, C>
+ Allocator<(usize, usize), R>
+ Allocator<(usize, usize), C>
{ {
} }
impl<N: Scalar, R: Dimension, C: Dimension, T> impl<N: Scalar, R: Dimension, C: Dimension, T> Alloc<N, R, C> for T where
Alloc<N, R, C> for T T: Allocator<N, R>
where T: Allocator<N, R> + Allocator<N, C> + Allocator<N, U1, R> + Allocator<N, U1, C> + Allocator<N, R, C> + Allocator<N, C, R> + Allocator<N, R, R> + Allocator<N, C, C> + + Allocator<N, C>
Allocator<bool, R> + Allocator<bool, C> + + Allocator<N, U1, R>
Allocator<f32, R> + Allocator<f32, C> + + Allocator<N, U1, C>
Allocator<u32, R> + Allocator<u32, C> + + Allocator<N, R, C>
Allocator<i32, R> + Allocator<i32, C> + + Allocator<N, C, R>
Allocator<f64, R> + Allocator<f64, C> + + Allocator<N, R, R>
Allocator<u64, R> + Allocator<u64, C> + + Allocator<N, C, C>
Allocator<i64, R> + Allocator<i64, C> + + Allocator<bool, R>
Allocator<i16, R> + Allocator<i16, C> + + Allocator<bool, C>
Allocator<(usize, usize), R> + Allocator<(usize, usize), C> + Allocator<f32, R>
{ + Allocator<f32, C>
} + Allocator<u32, R>
+ Allocator<u32, C>
+ Allocator<i32, R>
+ Allocator<i32, C>
+ Allocator<f64, R>
+ Allocator<f64, C>
+ Allocator<u64, R>
+ Allocator<u64, C>
+ Allocator<i64, R>
+ Allocator<i64, C>
+ Allocator<i16, R>
+ Allocator<i16, C>
+ Allocator<(usize, usize), R>
+ Allocator<(usize, usize), C>
{}

View File

@ -1,95 +1,124 @@
use na::{self, Real, DefaultAllocator}; use na::{self, DefaultAllocator, Real};
use aliases::TVec; use aliases::TVec;
use traits::{Alloc, Dimension}; use traits::{Alloc, Dimension};
/// Component-wise arc-cosinus. /// Component-wise arc-cosinus.
pub fn acos<N: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn acos<N: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|e| e.acos()) x.map(|e| e.acos())
} }
/// Component-wise hyperbolic arc-cosinus. /// Component-wise hyperbolic arc-cosinus.
pub fn acosh<N: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn acosh<N: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|e| e.acosh()) x.map(|e| e.acosh())
} }
/// Component-wise arc-sinus. /// Component-wise arc-sinus.
pub fn asin<N: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn asin<N: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|e| e.asin()) x.map(|e| e.asin())
} }
/// Component-wise hyperbolic arc-sinus. /// Component-wise hyperbolic arc-sinus.
pub fn asinh<N: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn asinh<N: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|e| e.asinh()) x.map(|e| e.asinh())
} }
/// Component-wise arc-tangent of `y / x`. /// Component-wise arc-tangent of `y / x`.
pub fn atan2<N: Real, D: Dimension>(y: &TVec<N, D>, x: &TVec<N, D>) -> TVec<N, D> pub fn atan2<N: Real, D: Dimension>(y: &TVec<N, D>, x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
y.zip_map(x, |y, x| y.atan2(x)) y.zip_map(x, |y, x| y.atan2(x))
} }
/// Component-wise arc-tangent. /// Component-wise arc-tangent.
pub fn atan<N: Real, D: Dimension>(y_over_x: &TVec<N, D>) -> TVec<N, D> pub fn atan<N: Real, D: Dimension>(y_over_x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
y_over_x.map(|e| e.atan()) y_over_x.map(|e| e.atan())
} }
/// Component-wise hyperbolic arc-tangent. /// Component-wise hyperbolic arc-tangent.
pub fn atanh<N: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn atanh<N: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|e| e.atanh()) x.map(|e| e.atanh())
} }
/// Component-wise cosinus. /// Component-wise cosinus.
pub fn cos<N: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn cos<N: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.cos()) angle.map(|e| e.cos())
} }
/// Component-wise hyperbolic cosinus. /// Component-wise hyperbolic cosinus.
pub fn cosh<N: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn cosh<N: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.cosh()) angle.map(|e| e.cosh())
} }
/// Component-wise conversion from radians to degrees. /// Component-wise conversion from radians to degrees.
pub fn degrees<N: Real, D: Dimension>(radians: &TVec<N, D>) -> TVec<N, D> pub fn degrees<N: Real, D: Dimension>(radians: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
radians.map(|e| e * na::convert(180.0) / N::pi()) radians.map(|e| e * na::convert(180.0) / N::pi())
} }
/// Component-wise conversion fro degrees to radians. /// Component-wise conversion fro degrees to radians.
pub fn radians<N: Real, D: Dimension>(degrees: &TVec<N, D>) -> TVec<N, D> pub fn radians<N: Real, D: Dimension>(degrees: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
degrees.map(|e| e * N::pi() / na::convert(180.0)) degrees.map(|e| e * N::pi() / na::convert(180.0))
} }
/// Component-wise sinus. /// Component-wise sinus.
pub fn sin<N: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn sin<N: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.sin()) angle.map(|e| e.sin())
} }
/// Component-wise hyperbolic sinus. /// Component-wise hyperbolic sinus.
pub fn sinh<N: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn sinh<N: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.sinh()) angle.map(|e| e.sinh())
} }
/// Component-wise tangent. /// Component-wise tangent.
pub fn tan<N: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn tan<N: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.tan()) angle.map(|e| e.tan())
} }
/// Component-wise hyperbolic tangent. /// Component-wise hyperbolic tangent.
pub fn tanh<N: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn tanh<N: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.tanh()) angle.map(|e| e.tanh())
} }

View File

@ -1,7 +1,7 @@
use na::{DefaultAllocator}; use na::DefaultAllocator;
use aliases::TVec; use aliases::TVec;
use traits::{Number, Alloc, Dimension}; use traits::{Alloc, Dimension, Number};
/// Checks that all the vector components are `true`. /// Checks that all the vector components are `true`.
/// ///
@ -21,7 +21,9 @@ use traits::{Number, Alloc, Dimension};
/// * [`any`](fn.any.html) /// * [`any`](fn.any.html)
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
pub fn all<D: Dimension>(v: &TVec<bool, D>) -> bool pub fn all<D: Dimension>(v: &TVec<bool, D>) -> bool
where DefaultAllocator: Alloc<bool, D> { where
DefaultAllocator: Alloc<bool, D>,
{
v.iter().all(|x| *x) v.iter().all(|x| *x)
} }
@ -46,7 +48,9 @@ pub fn all<D: Dimension>(v: &TVec<bool, D>) -> bool
/// * [`all`](fn.all.html) /// * [`all`](fn.all.html)
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
pub fn any<D: Dimension>(v: &TVec<bool, D>) -> bool pub fn any<D: Dimension>(v: &TVec<bool, D>) -> bool
where DefaultAllocator: Alloc<bool, D> { where
DefaultAllocator: Alloc<bool, D>,
{
v.iter().any(|x| *x) v.iter().any(|x| *x)
} }
@ -70,7 +74,9 @@ pub fn any<D: Dimension>(v: &TVec<bool, D>) -> bool
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x == y) x.zip_map(y, |x, y| x == y)
} }
@ -94,7 +100,9 @@ pub fn equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bo
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn greater_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn greater_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x > y) x.zip_map(y, |x, y| x > y)
} }
@ -118,7 +126,9 @@ pub fn greater_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) ->
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn greater_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn greater_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x >= y) x.zip_map(y, |x, y| x >= y)
} }
@ -142,7 +152,9 @@ pub fn greater_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn less_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn less_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x < y) x.zip_map(y, |x, y| x < y)
} }
@ -166,7 +178,9 @@ pub fn less_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVe
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn less_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn less_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x <= y) x.zip_map(y, |x, y| x <= y)
} }
@ -191,7 +205,9 @@ pub fn less_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>)
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn not<D: Dimension>(v: &TVec<bool, D>) -> TVec<bool, D> pub fn not<D: Dimension>(v: &TVec<bool, D>) -> TVec<bool, D>
where DefaultAllocator: Alloc<bool, D> { where
DefaultAllocator: Alloc<bool, D>,
{
v.map(|x| !x) v.map(|x| !x)
} }
@ -215,6 +231,8 @@ pub fn not<D: Dimension>(v: &TVec<bool, D>) -> TVec<bool, D>
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
pub fn not_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn not_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x != y) x.zip_map(y, |x, y| x != y)
} }