2013-05-21 23:25:01 +08:00
|
|
|
|
/*!
|
2013-10-06 22:54:09 +08:00
|
|
|
|
# nalgebra
|
2013-05-21 23:25:01 +08:00
|
|
|
|
|
2014-10-13 02:21:06 +08:00
|
|
|
|
**nalgebra** is a low-dimensional linear algebra library written for Rust targeting:
|
2013-10-06 22:54:09 +08:00
|
|
|
|
|
2014-06-10 03:48:24 +08:00
|
|
|
|
* general-purpose linear algebra (still lacks a lot of features…).
|
2013-10-06 22:54:09 +08:00
|
|
|
|
* real time computer graphics.
|
|
|
|
|
* real time computer physics.
|
|
|
|
|
|
2014-06-10 03:48:24 +08:00
|
|
|
|
An on-line version of this documentation is available [here](http://nalgebra.org).
|
2013-10-08 08:10:35 +08:00
|
|
|
|
|
2013-10-06 22:54:09 +08:00
|
|
|
|
## Using **nalgebra**
|
2014-10-13 14:46:39 +08:00
|
|
|
|
All the functionality of **nalgebra** is grouped in one place: the root module `nalgebra::`.
|
2013-10-14 16:22:32 +08:00
|
|
|
|
This module re-exports everything and includes free functions for all traits methods doing
|
|
|
|
|
out-of-place modifications.
|
2013-10-06 22:54:09 +08:00
|
|
|
|
|
2014-01-14 16:52:18 +08:00
|
|
|
|
* You can import the whole prelude using:
|
2013-10-06 22:54:09 +08:00
|
|
|
|
|
2014-02-18 19:13:40 +08:00
|
|
|
|
```.ignore
|
2014-09-29 01:20:22 +08:00
|
|
|
|
use nalgebra::*;
|
2013-10-06 22:54:09 +08:00
|
|
|
|
```
|
|
|
|
|
|
2014-01-14 16:52:18 +08:00
|
|
|
|
The preferred way to use **nalgebra** is to import types and traits explicitly, and call
|
2013-10-14 16:22:32 +08:00
|
|
|
|
free-functions using the `na::` prefix:
|
|
|
|
|
|
|
|
|
|
```.rust
|
2014-09-29 01:20:22 +08:00
|
|
|
|
extern crate "nalgebra" as na;
|
|
|
|
|
use na::{Vec3, Rot3, Rotation};
|
2013-10-14 16:22:32 +08:00
|
|
|
|
|
|
|
|
|
fn main() {
|
2013-10-14 17:22:38 +08:00
|
|
|
|
let a = Vec3::new(1.0f64, 1.0, 1.0);
|
|
|
|
|
let mut b = Rot3::new(na::zero());
|
2013-10-14 16:22:32 +08:00
|
|
|
|
|
2015-02-02 06:23:57 +08:00
|
|
|
|
b.append_rotation_mut(&a);
|
2013-10-14 16:22:32 +08:00
|
|
|
|
|
2014-01-14 16:52:18 +08:00
|
|
|
|
assert!(na::approx_eq(&na::rotation(&b), &a));
|
2013-10-14 16:22:32 +08:00
|
|
|
|
}
|
|
|
|
|
```
|
2013-10-06 22:54:09 +08:00
|
|
|
|
|
|
|
|
|
## Features
|
2014-10-13 14:46:39 +08:00
|
|
|
|
**nalgebra** is meant to be a general-purpose, low-dimensional, linear algebra library, with
|
|
|
|
|
an optimized set of tools for computer graphics and physics. Those features include:
|
2013-10-06 22:54:09 +08:00
|
|
|
|
|
2013-10-08 07:22:56 +08:00
|
|
|
|
* Vectors with static sizes: `Vec0`, `Vec1`, `Vec2`, `Vec3`, `Vec4`, `Vec5`, `Vec6`.
|
2015-01-10 06:01:46 +08:00
|
|
|
|
* Points with static sizes: `Pnt0`, `Pnt1`, `Pnt2`, `Pnt3`, `Pnt4`, `Pnt5`, `Pnt6`.
|
2013-10-08 07:22:56 +08:00
|
|
|
|
* Square matrices with static sizes: `Mat1`, `Mat2`, `Mat3`, `Mat4`, `Mat5`, `Mat6 `.
|
2013-10-06 22:54:09 +08:00
|
|
|
|
* Rotation matrices: `Rot2`, `Rot3`, `Rot4`.
|
2014-10-15 04:24:10 +08:00
|
|
|
|
* Quaternions: `Quat`, `UnitQuat`.
|
2013-10-06 22:54:09 +08:00
|
|
|
|
* Isometries: `Iso2`, `Iso3`, `Iso4`.
|
2014-10-13 02:21:06 +08:00
|
|
|
|
* 3D projections for computer graphics: `Persp3`, `PerspMat3`, `Ortho3`, `OrthoMat3`.
|
2013-10-06 22:54:09 +08:00
|
|
|
|
* Dynamically sized vector: `DVec`.
|
|
|
|
|
* Dynamically sized (square or rectangular) matrix: `DMat`.
|
2013-10-07 01:28:52 +08:00
|
|
|
|
* A few methods for data analysis: `Cov`, `Mean`.
|
2013-10-07 01:32:31 +08:00
|
|
|
|
* Almost one trait per functionality: useful for generic programming.
|
2014-11-26 21:36:50 +08:00
|
|
|
|
* Operator overloading using multidispatch.
|
2013-10-06 22:54:09 +08:00
|
|
|
|
|
|
|
|
|
## Compilation
|
2014-07-14 23:56:35 +08:00
|
|
|
|
You will need the last nightly build of the [rust compiler](http://www.rust-lang.org)
|
|
|
|
|
and the official package manager: [cargo](https://github.com/rust-lang/cargo).
|
2013-10-06 22:54:09 +08:00
|
|
|
|
|
2014-07-14 23:56:35 +08:00
|
|
|
|
Simply add the following to your `Cargo.toml` file:
|
2013-10-06 22:54:09 +08:00
|
|
|
|
|
2014-02-18 19:13:40 +08:00
|
|
|
|
```.ignore
|
2014-07-14 23:56:35 +08:00
|
|
|
|
[dependencies.nalgebra]
|
|
|
|
|
git = "https://github.com/sebcrozet/nalgebra"
|
2013-10-06 22:54:09 +08:00
|
|
|
|
```
|
|
|
|
|
|
2014-07-14 23:56:35 +08:00
|
|
|
|
|
2013-10-06 22:54:09 +08:00
|
|
|
|
## **nalgebra** in use
|
|
|
|
|
Here are some projects using **nalgebra**.
|
|
|
|
|
Feel free to add your project to this list if you happen to use **nalgebra**!
|
|
|
|
|
|
|
|
|
|
* [nphysics](https://github.com/sebcrozet/nphysics): a real-time physics engine.
|
|
|
|
|
* [ncollide](https://github.com/sebcrozet/ncollide): a collision detection library.
|
|
|
|
|
* [kiss3d](https://github.com/sebcrozet/kiss3d): a minimalistic graphics engine.
|
2014-10-12 16:35:56 +08:00
|
|
|
|
* [nrays](https://github.com/sebcrozet/nrays): a ray tracer.
|
2013-05-21 23:25:01 +08:00
|
|
|
|
*/
|
2013-12-24 18:46:16 +08:00
|
|
|
|
|
2014-04-02 04:58:06 +08:00
|
|
|
|
#![deny(non_camel_case_types)]
|
2014-11-01 00:40:47 +08:00
|
|
|
|
#![deny(unused_parens)]
|
|
|
|
|
#![deny(non_upper_case_globals)]
|
|
|
|
|
#![deny(unused_qualifications)]
|
|
|
|
|
#![deny(unused_results)]
|
|
|
|
|
#![warn(missing_docs)]
|
2015-01-07 07:46:50 +08:00
|
|
|
|
#![feature(unboxed_closures)]
|
2015-02-01 23:15:55 +08:00
|
|
|
|
#![feature(rand)]
|
|
|
|
|
#![feature(hash)]
|
|
|
|
|
#![feature(core)]
|
|
|
|
|
#![feature(std_misc)]
|
2014-06-10 03:48:24 +08:00
|
|
|
|
#![doc(html_root_url = "http://nalgebra.org/doc")]
|
2013-05-15 05:08:29 +08:00
|
|
|
|
|
2014-12-26 05:05:33 +08:00
|
|
|
|
extern crate "rustc-serialize" as rustc_serialize;
|
2013-05-15 05:08:29 +08:00
|
|
|
|
|
2015-01-10 08:36:13 +08:00
|
|
|
|
#[cfg(feature="arbitrary")]
|
|
|
|
|
extern crate quickcheck;
|
|
|
|
|
|
2014-02-22 16:09:04 +08:00
|
|
|
|
#[cfg(test)]
|
|
|
|
|
extern crate test;
|
|
|
|
|
|
2014-09-29 01:20:22 +08:00
|
|
|
|
use std::cmp;
|
2015-02-04 02:17:15 +08:00
|
|
|
|
use std::ops::{Neg, Mul};
|
2014-09-29 01:20:22 +08:00
|
|
|
|
pub use traits::{
|
|
|
|
|
Absolute,
|
|
|
|
|
AbsoluteRotate,
|
|
|
|
|
ApproxEq,
|
2014-10-12 15:17:17 +08:00
|
|
|
|
Axpy,
|
2014-09-29 01:20:22 +08:00
|
|
|
|
Basis,
|
2014-11-15 22:47:59 +08:00
|
|
|
|
BaseFloat,
|
2014-11-16 21:04:15 +08:00
|
|
|
|
BaseNum,
|
|
|
|
|
Bounded,
|
2014-09-29 01:20:22 +08:00
|
|
|
|
Cast,
|
|
|
|
|
Col,
|
|
|
|
|
ColSlice, RowSlice,
|
|
|
|
|
Cov,
|
|
|
|
|
Cross,
|
|
|
|
|
CrossMatrix,
|
|
|
|
|
Det,
|
|
|
|
|
Diag,
|
|
|
|
|
Dim,
|
|
|
|
|
Dot,
|
2014-10-27 00:24:33 +08:00
|
|
|
|
EigenQR,
|
2014-09-29 01:20:22 +08:00
|
|
|
|
Eye,
|
2014-10-10 17:23:52 +08:00
|
|
|
|
FloatPnt,
|
2014-09-29 01:20:22 +08:00
|
|
|
|
FloatVec,
|
|
|
|
|
FromHomogeneous,
|
|
|
|
|
Indexable,
|
|
|
|
|
Inv,
|
|
|
|
|
Iterable,
|
|
|
|
|
IterableMut,
|
|
|
|
|
LMul,
|
|
|
|
|
Mat,
|
|
|
|
|
Mean,
|
|
|
|
|
Norm,
|
2014-11-16 21:04:15 +08:00
|
|
|
|
NumPnt,
|
|
|
|
|
NumVec,
|
|
|
|
|
One,
|
2014-10-10 17:23:52 +08:00
|
|
|
|
Orig,
|
2014-09-29 01:20:22 +08:00
|
|
|
|
Outer,
|
2014-10-22 01:43:25 +08:00
|
|
|
|
POrd,
|
|
|
|
|
POrdering,
|
2014-10-10 17:23:52 +08:00
|
|
|
|
PntAsVec,
|
2014-09-29 01:20:22 +08:00
|
|
|
|
RMul,
|
|
|
|
|
Rotate, Rotation, RotationMatrix, RotationWithTranslation,
|
|
|
|
|
Row,
|
|
|
|
|
ScalarAdd, ScalarSub,
|
|
|
|
|
ScalarMul, ScalarDiv,
|
2014-10-26 17:46:51 +08:00
|
|
|
|
Shape,
|
2014-10-26 23:30:09 +08:00
|
|
|
|
SquareMat,
|
2014-09-29 01:20:22 +08:00
|
|
|
|
ToHomogeneous,
|
|
|
|
|
Transform, Transformation,
|
|
|
|
|
Translate, Translation,
|
|
|
|
|
Transpose,
|
|
|
|
|
UniformSphereSample,
|
2014-11-16 21:04:15 +08:00
|
|
|
|
VecAsPnt,
|
|
|
|
|
Zero
|
2014-09-29 01:20:22 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pub use structs::{
|
|
|
|
|
Identity,
|
|
|
|
|
DMat,
|
|
|
|
|
DVec, DVec1, DVec2, DVec3, DVec4, DVec5, DVec6,
|
|
|
|
|
Iso2, Iso3, Iso4,
|
|
|
|
|
Mat1, Mat2, Mat3, Mat4,
|
|
|
|
|
Mat5, Mat6,
|
|
|
|
|
Rot2, Rot3, Rot4,
|
2014-10-10 17:23:52 +08:00
|
|
|
|
Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6,
|
2014-10-13 02:21:06 +08:00
|
|
|
|
Pnt0, Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6,
|
|
|
|
|
Persp3, PerspMat3,
|
2014-10-15 03:37:44 +08:00
|
|
|
|
Ortho3, OrthoMat3,
|
|
|
|
|
Quat, UnitQuat
|
2014-09-29 01:20:22 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pub use linalg::{
|
|
|
|
|
qr,
|
|
|
|
|
householder_matrix
|
|
|
|
|
};
|
|
|
|
|
|
2014-01-14 16:40:12 +08:00
|
|
|
|
mod structs;
|
|
|
|
|
mod traits;
|
2014-05-10 04:14:37 +08:00
|
|
|
|
mod linalg;
|
2014-11-23 21:01:12 +08:00
|
|
|
|
mod macros;
|
2013-05-15 05:08:29 +08:00
|
|
|
|
|
2013-09-22 16:58:21 +08:00
|
|
|
|
// mod lower_triangular;
|
|
|
|
|
// mod chol;
|
|
|
|
|
|
2014-09-29 01:20:22 +08:00
|
|
|
|
/// Change the input value to ensure it is on the range `[min, max]`.
|
|
|
|
|
#[inline(always)]
|
2014-10-22 01:43:25 +08:00
|
|
|
|
pub fn clamp<T: PartialOrd>(val: T, min: T, max: T) -> T {
|
2014-09-29 01:20:22 +08:00
|
|
|
|
if val > min {
|
|
|
|
|
if val < max {
|
|
|
|
|
val
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
max
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
min
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Same as `cmp::max`.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn max<T: Ord>(a: T, b: T) -> T {
|
|
|
|
|
cmp::max(a, b)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Same as `cmp::min`.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn min<T: Ord>(a: T, b: T) -> T {
|
|
|
|
|
cmp::min(a, b)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns the infimum of `a` and `b`.
|
|
|
|
|
#[inline(always)]
|
2014-10-22 01:43:25 +08:00
|
|
|
|
pub fn inf<T: POrd>(a: &T, b: &T) -> T {
|
|
|
|
|
POrd::inf(a, b)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns the supremum of `a` and `b`.
|
|
|
|
|
#[inline(always)]
|
2014-10-22 01:43:25 +08:00
|
|
|
|
pub fn sup<T: POrd>(a: &T, b: &T) -> T {
|
|
|
|
|
POrd::sup(a, b)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Compare `a` and `b` using a partial ordering relation.
|
|
|
|
|
#[inline(always)]
|
2014-10-22 01:43:25 +08:00
|
|
|
|
pub fn partial_cmp<T: POrd>(a: &T, b: &T) -> POrdering {
|
|
|
|
|
POrd::partial_cmp(a, b)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns `true` iff `a` and `b` are comparable and `a < b`.
|
|
|
|
|
#[inline(always)]
|
2014-10-22 01:43:25 +08:00
|
|
|
|
pub fn partial_lt<T: POrd>(a: &T, b: &T) -> bool {
|
|
|
|
|
POrd::partial_lt(a, b)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns `true` iff `a` and `b` are comparable and `a <= b`.
|
|
|
|
|
#[inline(always)]
|
2014-10-22 01:43:25 +08:00
|
|
|
|
pub fn partial_le<T: POrd>(a: &T, b: &T) -> bool {
|
|
|
|
|
POrd::partial_le(a, b)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns `true` iff `a` and `b` are comparable and `a > b`.
|
|
|
|
|
#[inline(always)]
|
2014-10-22 01:43:25 +08:00
|
|
|
|
pub fn partial_gt<T: POrd>(a: &T, b: &T) -> bool {
|
|
|
|
|
POrd::partial_gt(a, b)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns `true` iff `a` and `b` are comparable and `a >= b`.
|
|
|
|
|
#[inline(always)]
|
2014-10-22 01:43:25 +08:00
|
|
|
|
pub fn partial_ge<T: POrd>(a: &T, b: &T) -> bool {
|
|
|
|
|
POrd::partial_ge(a, b)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Return the minimum of `a` and `b` if they are comparable.
|
|
|
|
|
#[inline(always)]
|
2014-10-22 01:43:25 +08:00
|
|
|
|
pub fn partial_min<'a, T: POrd>(a: &'a T, b: &'a T) -> Option<&'a T> {
|
|
|
|
|
POrd::partial_min(a, b)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Return the maximum of `a` and `b` if they are comparable.
|
|
|
|
|
#[inline(always)]
|
2014-10-22 01:43:25 +08:00
|
|
|
|
pub fn partial_max<'a, T: POrd>(a: &'a T, b: &'a T) -> Option<&'a T> {
|
|
|
|
|
POrd::partial_max(a, b)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Clamp `value` between `min` and `max`. Returns `None` if `value` is not comparable to
|
|
|
|
|
/// `min` or `max`.
|
|
|
|
|
#[inline(always)]
|
2014-10-22 01:43:25 +08:00
|
|
|
|
pub fn partial_clamp<'a, T: POrd>(value: &'a T, min: &'a T, max: &'a T) -> Option<&'a T> {
|
|
|
|
|
POrd::partial_clamp(value, min, max)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// Constructors
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
/// Create a special identity object.
|
|
|
|
|
///
|
|
|
|
|
/// Same as `Identity::new()`.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn identity() -> Identity {
|
|
|
|
|
Identity::new()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Create a zero-valued value.
|
|
|
|
|
///
|
|
|
|
|
/// This is the same as `std::num::zero()`.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn zero<T: Zero>() -> T {
|
|
|
|
|
Zero::zero()
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-16 21:04:15 +08:00
|
|
|
|
/// Tests is a value is iqual to zero.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn is_zero<T: Zero>(val: &T) -> bool {
|
|
|
|
|
val.is_zero()
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-29 01:20:22 +08:00
|
|
|
|
/// Create a one-valued value.
|
|
|
|
|
///
|
|
|
|
|
/// This is the same as `std::num::one()`.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn one<T: One>() -> T {
|
|
|
|
|
One::one()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// Geometry
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
|
2014-10-10 17:23:52 +08:00
|
|
|
|
/// Returns the trivial origin of an affine space.
|
|
|
|
|
#[inline(always)]
|
2014-10-11 03:24:18 +08:00
|
|
|
|
pub fn orig<P: Orig>() -> P {
|
2014-10-10 17:23:52 +08:00
|
|
|
|
Orig::orig()
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-10 06:01:46 +08:00
|
|
|
|
/// Returns the center of two points.
|
2014-10-11 03:24:18 +08:00
|
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
|
pub fn center<N: BaseFloat, P: FloatPnt<N, V>, V: Copy>(a: &P, b: &P) -> P {
|
2014-10-11 03:24:18 +08:00
|
|
|
|
let _2 = one::<N>() + one();
|
|
|
|
|
(*a + *b.as_vec()) / _2
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-10 17:23:52 +08:00
|
|
|
|
/*
|
|
|
|
|
* FloatPnt
|
|
|
|
|
*/
|
2015-01-10 06:01:46 +08:00
|
|
|
|
/// Returns the distance between two points.
|
2014-10-10 17:23:52 +08:00
|
|
|
|
#[inline(always)]
|
2014-11-15 22:47:59 +08:00
|
|
|
|
pub fn dist<N: BaseFloat, P: FloatPnt<N, V>, V: Norm<N>>(a: &P, b: &P) -> N {
|
2014-12-02 01:50:11 +08:00
|
|
|
|
a.dist(b)
|
2014-10-10 17:23:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
2015-01-10 06:01:46 +08:00
|
|
|
|
/// Returns the squared distance between two points.
|
2014-10-10 17:23:52 +08:00
|
|
|
|
#[inline(always)]
|
2014-11-15 22:47:59 +08:00
|
|
|
|
pub fn sqdist<N: BaseFloat, P: FloatPnt<N, V>, V: Norm<N>>(a: &P, b: &P) -> N {
|
2014-12-02 01:50:11 +08:00
|
|
|
|
a.sqdist(b)
|
2014-10-10 17:23:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
2014-09-29 01:20:22 +08:00
|
|
|
|
/*
|
|
|
|
|
* Perspective
|
|
|
|
|
*/
|
|
|
|
|
/// Computes a projection matrix given the frustrum near plane width, height, the field of
|
|
|
|
|
/// view, and the distance to the clipping planes (`znear` and `zfar`).
|
2014-10-13 02:21:06 +08:00
|
|
|
|
#[deprecated = "Use `Persp3::new(width / height, fov, znear, zfar).as_mat()` instead"]
|
2014-11-15 22:47:59 +08:00
|
|
|
|
pub fn perspective3d<N: BaseFloat + Cast<f64> + Zero + One>(width: N, height: N, fov: N, znear: N, zfar: N) -> Mat4<N> {
|
2014-09-29 01:20:22 +08:00
|
|
|
|
let aspect = width / height;
|
|
|
|
|
|
|
|
|
|
let _1: N = one();
|
|
|
|
|
let sy = _1 / (fov * cast(0.5)).tan();
|
|
|
|
|
let sx = -sy / aspect;
|
|
|
|
|
let sz = -(zfar + znear) / (znear - zfar);
|
|
|
|
|
let tz = zfar * znear * cast(2.0) / (znear - zfar);
|
|
|
|
|
|
|
|
|
|
Mat4::new(
|
|
|
|
|
sx, zero(), zero(), zero(),
|
|
|
|
|
zero(), sy, zero(), zero(),
|
|
|
|
|
zero(), zero(), sz, tz,
|
|
|
|
|
zero(), zero(), one(), zero())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Translation<V>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Gets the translation applicable by `m`.
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// extern crate "nalgebra" as na;
|
|
|
|
|
/// use na::{Vec3, Iso3};
|
|
|
|
|
///
|
|
|
|
|
/// fn main() {
|
|
|
|
|
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
|
|
|
|
|
/// let trans = na::translation(&t);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(trans == Vec3::new(1.0, 1.0, 1.0));
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn translation<V, M: Translation<V>>(m: &M) -> V {
|
|
|
|
|
m.translation()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Gets the inverse translation applicable by `m`.
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// extern crate "nalgebra" as na;
|
|
|
|
|
/// use na::{Vec3, Iso3};
|
|
|
|
|
///
|
|
|
|
|
/// fn main() {
|
|
|
|
|
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
|
|
|
|
|
/// let itrans = na::inv_translation(&t);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(itrans == Vec3::new(-1.0, -1.0, -1.0));
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn inv_translation<V, M: Translation<V>>(m: &M) -> V {
|
|
|
|
|
m.inv_translation()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Applies the translation `v` to a copy of `m`.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn append_translation<V, M: Translation<V>>(m: &M, v: &V) -> M {
|
2015-02-02 06:23:57 +08:00
|
|
|
|
Translation::append_translation(m, v)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
2014-10-10 17:23:52 +08:00
|
|
|
|
* Translate<P>
|
2014-09-29 01:20:22 +08:00
|
|
|
|
*/
|
|
|
|
|
|
2015-01-10 06:01:46 +08:00
|
|
|
|
/// Applies a translation to a point.
|
2014-09-29 01:20:22 +08:00
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// extern crate "nalgebra" as na;
|
2014-10-10 17:23:52 +08:00
|
|
|
|
/// use na::{Pnt3, Vec3, Iso3};
|
2014-09-29 01:20:22 +08:00
|
|
|
|
///
|
|
|
|
|
/// fn main() {
|
|
|
|
|
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
|
2014-10-10 17:23:52 +08:00
|
|
|
|
/// let p = Pnt3::new(2.0, 2.0, 2.0);
|
2014-09-29 01:20:22 +08:00
|
|
|
|
///
|
2014-10-10 17:23:52 +08:00
|
|
|
|
/// let tp = na::translate(&t, &p);
|
2014-09-29 01:20:22 +08:00
|
|
|
|
///
|
2014-10-10 17:23:52 +08:00
|
|
|
|
/// assert!(tp == Pnt3::new(3.0, 3.0, 3.0))
|
2014-09-29 01:20:22 +08:00
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline(always)]
|
2014-10-10 17:23:52 +08:00
|
|
|
|
pub fn translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
|
|
|
|
|
m.translate(p)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
2015-01-10 06:01:46 +08:00
|
|
|
|
/// Applies an inverse translation to a point.
|
2014-09-29 01:20:22 +08:00
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// extern crate "nalgebra" as na;
|
2014-10-10 17:23:52 +08:00
|
|
|
|
/// use na::{Pnt3, Vec3, Iso3};
|
2014-09-29 01:20:22 +08:00
|
|
|
|
///
|
|
|
|
|
/// fn main() {
|
|
|
|
|
/// let t = Iso3::new(Vec3::new(1.0f64, 1.0, 1.0), na::zero());
|
2014-10-10 17:23:52 +08:00
|
|
|
|
/// let p = Pnt3::new(2.0, 2.0, 2.0);
|
2014-09-29 01:20:22 +08:00
|
|
|
|
///
|
2014-10-10 17:23:52 +08:00
|
|
|
|
/// let tp = na::inv_translate(&t, &p);
|
2014-09-29 01:20:22 +08:00
|
|
|
|
///
|
2014-10-10 17:23:52 +08:00
|
|
|
|
/// assert!(na::approx_eq(&tp, &Pnt3::new(1.0, 1.0, 1.0)))
|
2014-09-29 01:20:22 +08:00
|
|
|
|
/// }
|
|
|
|
|
#[inline(always)]
|
2014-10-10 17:23:52 +08:00
|
|
|
|
pub fn inv_translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
|
|
|
|
|
m.inv_translate(p)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Rotation<V>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Gets the rotation applicable by `m`.
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// extern crate "nalgebra" as na;
|
|
|
|
|
/// use na::{Vec3, Rot3};
|
|
|
|
|
///
|
|
|
|
|
/// fn main() {
|
|
|
|
|
/// let t = Rot3::new(Vec3::new(1.0f64, 1.0, 1.0));
|
|
|
|
|
///
|
|
|
|
|
/// assert!(na::approx_eq(&na::rotation(&t), &Vec3::new(1.0, 1.0, 1.0)));
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn rotation<V, M: Rotation<V>>(m: &M) -> V {
|
|
|
|
|
m.rotation()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Gets the inverse rotation applicable by `m`.
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// extern crate "nalgebra" as na;
|
|
|
|
|
/// use na::{Vec3, Rot3};
|
|
|
|
|
///
|
|
|
|
|
/// fn main() {
|
|
|
|
|
/// let t = Rot3::new(Vec3::new(1.0f64, 1.0, 1.0));
|
|
|
|
|
///
|
|
|
|
|
/// assert!(na::approx_eq(&na::inv_rotation(&t), &Vec3::new(-1.0, -1.0, -1.0)));
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn inv_rotation<V, M: Rotation<V>>(m: &M) -> V {
|
|
|
|
|
m.inv_rotation()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FIXME: this example is a bit shity
|
|
|
|
|
/// Applies the rotation `v` to a copy of `m`.
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// extern crate "nalgebra" as na;
|
|
|
|
|
/// use na::{Vec3, Rot3};
|
|
|
|
|
///
|
|
|
|
|
/// fn main() {
|
|
|
|
|
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.0));
|
|
|
|
|
/// let v = Vec3::new(1.0, 1.0, 1.0);
|
|
|
|
|
/// let rt = na::append_rotation(&t, &v);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(na::approx_eq(&na::rotation(&rt), &Vec3::new(1.0, 1.0, 1.0)))
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn append_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
|
2015-02-02 06:23:57 +08:00
|
|
|
|
Rotation::append_rotation(m, v)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FIXME: this example is a bit shity
|
|
|
|
|
/// Pre-applies the rotation `v` to a copy of `m`.
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// extern crate "nalgebra" as na;
|
|
|
|
|
/// use na::{Vec3, Rot3};
|
|
|
|
|
///
|
|
|
|
|
/// fn main() {
|
|
|
|
|
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.0));
|
|
|
|
|
/// let v = Vec3::new(1.0, 1.0, 1.0);
|
|
|
|
|
/// let rt = na::prepend_rotation(&t, &v);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(na::approx_eq(&na::rotation(&rt), &Vec3::new(1.0, 1.0, 1.0)))
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn prepend_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
|
2015-02-02 06:23:57 +08:00
|
|
|
|
Rotation::prepend_rotation(m, v)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Rotate<V>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Applies a rotation to a vector.
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// extern crate "nalgebra" as na;
|
2014-11-25 18:11:50 +08:00
|
|
|
|
/// use na::{BaseFloat, Rot3, Vec3};
|
2014-09-29 01:20:22 +08:00
|
|
|
|
///
|
|
|
|
|
/// fn main() {
|
2014-11-25 18:11:50 +08:00
|
|
|
|
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.5 * BaseFloat::pi()));
|
2014-09-29 01:20:22 +08:00
|
|
|
|
/// let v = Vec3::new(1.0, 0.0, 0.0);
|
|
|
|
|
///
|
|
|
|
|
/// let tv = na::rotate(&t, &v);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(na::approx_eq(&tv, &Vec3::new(0.0, 1.0, 0.0)))
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
|
|
|
|
|
m.rotate(v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Applies an inverse rotation to a vector.
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// extern crate "nalgebra" as na;
|
2014-11-25 18:11:50 +08:00
|
|
|
|
/// use na::{BaseFloat, Rot3, Vec3};
|
2014-09-29 01:20:22 +08:00
|
|
|
|
///
|
|
|
|
|
/// fn main() {
|
2014-11-25 18:11:50 +08:00
|
|
|
|
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.5 * BaseFloat::pi()));
|
2014-09-29 01:20:22 +08:00
|
|
|
|
/// let v = Vec3::new(1.0, 0.0, 0.0);
|
|
|
|
|
///
|
|
|
|
|
/// let tv = na::inv_rotate(&t, &v);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(na::approx_eq(&tv, &Vec3::new(0.0, -1.0, 0.0)))
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn inv_rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
|
|
|
|
|
m.inv_rotate(v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* RotationWithTranslation<LV, AV>
|
|
|
|
|
*/
|
|
|
|
|
|
2015-01-10 06:01:46 +08:00
|
|
|
|
/// Rotates a copy of `m` by `amount` using `center` as the pivot point.
|
2014-09-29 01:20:22 +08:00
|
|
|
|
#[inline(always)]
|
2015-01-10 06:01:46 +08:00
|
|
|
|
pub fn append_rotation_wrt_point<LV: Neg<Output = LV> + Copy,
|
2014-09-29 01:20:22 +08:00
|
|
|
|
AV,
|
|
|
|
|
M: RotationWithTranslation<LV, AV>>(
|
|
|
|
|
m: &M,
|
|
|
|
|
amount: &AV,
|
|
|
|
|
center: &LV) -> M {
|
2015-02-02 06:23:57 +08:00
|
|
|
|
RotationWithTranslation::append_rotation_wrt_point(m, amount, center)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
2015-01-10 06:01:46 +08:00
|
|
|
|
/// Rotates a copy of `m` by `amount` using `m.translation()` as the pivot point.
|
2014-09-29 01:20:22 +08:00
|
|
|
|
#[inline(always)]
|
2015-01-05 02:03:28 +08:00
|
|
|
|
pub fn append_rotation_wrt_center<LV: Neg<Output = LV> + Copy,
|
2014-09-29 01:20:22 +08:00
|
|
|
|
AV,
|
|
|
|
|
M: RotationWithTranslation<LV, AV>>(
|
|
|
|
|
m: &M,
|
|
|
|
|
amount: &AV) -> M {
|
2015-02-02 06:23:57 +08:00
|
|
|
|
RotationWithTranslation::append_rotation_wrt_center(m, amount)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* RotationMatrix<LV, AV, R>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Builds a rotation matrix from `r`.
|
|
|
|
|
#[inline(always)]
|
2015-02-04 02:17:15 +08:00
|
|
|
|
pub fn to_rot_mat<N, LV, AV, R, M>(r: &R) -> M
|
|
|
|
|
where R: RotationMatrix<N, LV, AV, Output=M>,
|
|
|
|
|
M: Mat<N, LV, AV> + Rotation<AV> + Col<LV> + Copy,
|
|
|
|
|
LV: Mul<M, Output=LV> + Copy,
|
|
|
|
|
{
|
|
|
|
|
// FIXME: rust-lang/rust#20413
|
2014-09-29 01:20:22 +08:00
|
|
|
|
r.to_rot_mat()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* AbsoluteRotate<V>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Applies a rotation using the absolute values of its components.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn absolute_rotate<V, M: AbsoluteRotate<V>>(m: &M, v: &V) -> V {
|
|
|
|
|
m.absolute_rotate(v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Transformation<T>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Gets the transformation applicable by `m`.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn transformation<T, M: Transformation<T>>(m: &M) -> T {
|
|
|
|
|
m.transformation()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Gets the inverse transformation applicable by `m`.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn inv_transformation<T, M: Transformation<T>>(m: &M) -> T {
|
|
|
|
|
m.inv_transformation()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Gets a transformed copy of `m`.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn append_transformation<T, M: Transformation<T>>(m: &M, t: &T) -> M {
|
2015-02-02 06:23:57 +08:00
|
|
|
|
Transformation::append_transformation(m, t)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Transform<V>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Applies a transformation to a vector.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn transform<V, M: Transform<V>>(m: &M, v: &V) -> V {
|
|
|
|
|
m.transform(v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Applies an inverse transformation to a vector.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn inv_transform<V, M: Transform<V>>(m: &M, v: &V) -> V {
|
|
|
|
|
m.inv_transform(v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Dot<N>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Computes the dot product of two vectors.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn dot<V: Dot<N>, N>(a: &V, b: &V) -> N {
|
|
|
|
|
Dot::dot(a, b)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Norm<N>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Computes the L2 norm of a vector.
|
|
|
|
|
#[inline(always)]
|
2014-11-15 22:47:59 +08:00
|
|
|
|
pub fn norm<V: Norm<N>, N: BaseFloat>(v: &V) -> N {
|
2014-09-29 01:20:22 +08:00
|
|
|
|
Norm::norm(v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Computes the squared L2 norm of a vector.
|
|
|
|
|
#[inline(always)]
|
2014-11-15 22:47:59 +08:00
|
|
|
|
pub fn sqnorm<V: Norm<N>, N: BaseFloat>(v: &V) -> N {
|
2014-09-29 01:20:22 +08:00
|
|
|
|
Norm::sqnorm(v)
|
2013-05-19 01:04:03 +08:00
|
|
|
|
}
|
2014-09-29 01:20:22 +08:00
|
|
|
|
|
|
|
|
|
/// Gets the normalized version of a vector.
|
|
|
|
|
#[inline(always)]
|
2014-11-15 22:47:59 +08:00
|
|
|
|
pub fn normalize<V: Norm<N>, N: BaseFloat>(v: &V) -> V {
|
2015-02-02 06:23:57 +08:00
|
|
|
|
Norm::normalize(v)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Det<N>
|
|
|
|
|
*/
|
|
|
|
|
/// Computes the determinant of a square matrix.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn det<M: Det<N>, N>(m: &M) -> N {
|
|
|
|
|
Det::det(m)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Cross<V>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Computes the cross product of two vectors.
|
|
|
|
|
#[inline(always)]
|
2015-01-05 02:03:28 +08:00
|
|
|
|
pub fn cross<LV: Cross>(a: &LV, b: &LV) -> LV::Output {
|
2014-09-29 01:20:22 +08:00
|
|
|
|
Cross::cross(a, b)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* CrossMatrix<M>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Given a vector, computes the matrix which, when multiplied by another vector, computes a cross
|
|
|
|
|
/// product.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn cross_matrix<V: CrossMatrix<M>, M>(v: &V) -> M {
|
|
|
|
|
CrossMatrix::cross_matrix(v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ToHomogeneous<U>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Converts a matrix or vector to homogeneous coordinates.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn to_homogeneous<M: ToHomogeneous<Res>, Res>(m: &M) -> Res {
|
|
|
|
|
ToHomogeneous::to_homogeneous(m)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* FromHomogeneous<U>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Converts a matrix or vector from homogeneous coordinates.
|
|
|
|
|
///
|
|
|
|
|
/// w-normalization is appied.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn from_homogeneous<M, Res: FromHomogeneous<M>>(m: &M) -> Res {
|
|
|
|
|
FromHomogeneous::from(m)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* UniformSphereSample
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Samples the unit sphere living on the dimension as the samples types.
|
|
|
|
|
///
|
2015-01-10 06:01:46 +08:00
|
|
|
|
/// The number of sampling point is implementation-specific. It is always uniform.
|
2014-09-29 01:20:22 +08:00
|
|
|
|
#[inline(always)]
|
2015-01-08 04:16:56 +08:00
|
|
|
|
pub fn sample_sphere<V: UniformSphereSample, F: FnMut(V)>(f: F) {
|
2014-09-29 01:20:22 +08:00
|
|
|
|
UniformSphereSample::sample(f)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// Operations
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* AproxEq<N>
|
|
|
|
|
*/
|
|
|
|
|
/// Tests approximate equality.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn approx_eq<T: ApproxEq<N>, N>(a: &T, b: &T) -> bool {
|
|
|
|
|
ApproxEq::approx_eq(a, b)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Tests approximate equality using a custom epsilon.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn approx_eq_eps<T: ApproxEq<N>, N>(a: &T, b: &T, eps: &N) -> bool {
|
|
|
|
|
ApproxEq::approx_eq_eps(a, b, eps)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Absolute<A>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Computes a component-wise absolute value.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn abs<M: Absolute<Res>, Res>(m: &M) -> Res {
|
|
|
|
|
Absolute::abs(m)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Inv
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Gets an inverted copy of a matrix.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn inv<M: Inv>(m: &M) -> Option<M> {
|
2015-02-02 06:23:57 +08:00
|
|
|
|
Inv::inv(m)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Transpose
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Gets a transposed copy of a matrix.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn transpose<M: Transpose>(m: &M) -> M {
|
2015-02-02 06:23:57 +08:00
|
|
|
|
Transpose::transpose(m)
|
2014-09-29 01:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Outer<M>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Computes the outer product of two vectors.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn outer<V: Outer<M>, M>(a: &V, b: &V) -> M {
|
|
|
|
|
Outer::outer(a, b)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Cov<M>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Computes the covariance of a set of observations.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn cov<M: Cov<Res>, Res>(observations: &M) -> Res {
|
|
|
|
|
Cov::cov(observations)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Mean<N>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Computes the mean of a set of observations.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn mean<N, M: Mean<N>>(observations: &M) -> N {
|
|
|
|
|
Mean::mean(observations)
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-27 00:24:33 +08:00
|
|
|
|
/*
|
|
|
|
|
* EigenQR<N, V>
|
|
|
|
|
*/
|
|
|
|
|
/// Computes the eigenvalues and eigenvectors of a square matrix usin the QR algorithm.
|
|
|
|
|
#[inline(always)]
|
2015-01-10 05:26:05 +08:00
|
|
|
|
pub fn eigen_qr<N, V, M: EigenQR<N, V>>(m: &M, eps: &N, niter: usize) -> (M, V) {
|
2014-10-27 00:24:33 +08:00
|
|
|
|
EigenQR::eigen_qr(m, eps, niter)
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-29 01:20:22 +08:00
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// Structure
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Eye
|
|
|
|
|
*/
|
|
|
|
|
/// Construct the identity matrix for a given dimension
|
|
|
|
|
#[inline(always)]
|
2015-01-10 05:26:05 +08:00
|
|
|
|
pub fn new_identity<M: Eye>(dim: usize) -> M {
|
2014-09-29 01:20:22 +08:00
|
|
|
|
Eye::new_identity(dim)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Basis
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/// Computes the canonical basis for a given dimension.
|
|
|
|
|
#[inline(always)]
|
2015-01-08 04:16:56 +08:00
|
|
|
|
pub fn canonical_basis<V: Basis, F: FnMut(V) -> bool>(f: F) {
|
2014-09-29 01:20:22 +08:00
|
|
|
|
Basis::canonical_basis(f)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Computes the basis of the orthonormal subspace of a given vector.
|
|
|
|
|
#[inline(always)]
|
2015-01-08 04:16:56 +08:00
|
|
|
|
pub fn orthonormal_subspace_basis<V: Basis, F: FnMut(V) -> bool>(v: &V, f: F) {
|
2014-09-29 01:20:22 +08:00
|
|
|
|
Basis::orthonormal_subspace_basis(v, f)
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-27 06:16:44 +08:00
|
|
|
|
/// Gets the (0-based) i-th element of the canonical basis of V.
|
|
|
|
|
#[inline]
|
2015-01-10 05:26:05 +08:00
|
|
|
|
pub fn canonical_basis_element<V: Basis>(i: usize) -> Option<V> {
|
2014-10-27 06:16:44 +08:00
|
|
|
|
Basis::canonical_basis_element(i)
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-29 01:20:22 +08:00
|
|
|
|
/*
|
|
|
|
|
* Row<R>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Col<C>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Diag<V>
|
|
|
|
|
*/
|
|
|
|
|
/// Gets the diagonal of a square matrix.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn diag<M: Diag<V>, V>(m: &M) -> V {
|
|
|
|
|
m.diag()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Dim
|
|
|
|
|
*/
|
|
|
|
|
/// Gets the dimension an object lives in.
|
|
|
|
|
///
|
|
|
|
|
/// Same as `Dim::dim::(None::<V>)`.
|
|
|
|
|
#[inline(always)]
|
2015-01-10 05:26:05 +08:00
|
|
|
|
pub fn dim<V: Dim>() -> usize {
|
2014-09-29 01:20:22 +08:00
|
|
|
|
Dim::dim(None::<V>)
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-26 17:46:51 +08:00
|
|
|
|
/// Gets the indexable range of an object.
|
|
|
|
|
#[inline(always)]
|
2015-01-05 02:43:04 +08:00
|
|
|
|
pub fn shape<V: Shape<I>, I>(v: &V) -> I {
|
2014-10-26 17:46:51 +08:00
|
|
|
|
v.shape()
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-29 01:20:22 +08:00
|
|
|
|
/*
|
|
|
|
|
* Cast<T>
|
|
|
|
|
*/
|
|
|
|
|
/// Converts an object from one type to another.
|
|
|
|
|
///
|
|
|
|
|
/// For primitive types, this is the same as the `as` keywords.
|
|
|
|
|
/// The following properties are preserved by a cast:
|
|
|
|
|
///
|
|
|
|
|
/// * Type-level geometric invariants cannot be broken (eg. a cast from Rot3<f64> to Rot3<i64> is
|
|
|
|
|
/// not possible)
|
|
|
|
|
/// * A cast to a type with more type-level invariants cannot be done (eg. a cast from Mat<f64> to
|
|
|
|
|
/// Rot3<f64> is not possible)
|
|
|
|
|
/// * For primitive types an unbounded cast is done using the `as` keyword (this is different from
|
|
|
|
|
/// the standard library which makes bound-checking to ensure eg. that a i64 is not out of the
|
|
|
|
|
/// range of an i32 when a cast from i64 to i32 is done).
|
|
|
|
|
/// * A cast does not affect the dimension of an algebraic object. Note that this prevents an
|
|
|
|
|
/// isometric transform to be cast to a raw matrix. Use `to_homogeneous` for that special purpose.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub fn cast<T, U: Cast<T>>(t: T) -> U {
|
|
|
|
|
Cast::from(t)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Indexable
|
|
|
|
|
*/
|