Update documentation, rename quaternion length
methods to magnitude
Although `magnitude` conflicts with the `length` in the vector implementations, it seems to be more in keeping with the correct mathematical terminology.
This commit is contained in:
parent
b8521f289c
commit
63f9cd38b7
2 changed files with 151 additions and 101 deletions
88
src/mat.rs
88
src/mat.rs
|
@ -123,6 +123,9 @@ pub trait Matrix<T,V>: Dimensional<V>, ToPtr<T>, Eq, Neg<self> {
|
|||
pure fn is_invertible(&self) -> bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* A mutable matrix
|
||||
*/
|
||||
pub trait MutableMatrix<T,V>: Matrix<T,V> {
|
||||
/**
|
||||
* Get a mutable reference to the column at `i`
|
||||
|
@ -151,7 +154,7 @@ pub trait MutableMatrix<T,V>: Matrix<T,V> {
|
|||
}
|
||||
|
||||
/**
|
||||
* A 2 x 2 square matrix with numeric elements
|
||||
* A 2 x 2 matrix
|
||||
*/
|
||||
pub trait Matrix2<T,V>: Matrix<T,V> {
|
||||
pure fn to_mat3(&self) -> Mat3<T>;
|
||||
|
@ -159,14 +162,14 @@ pub trait Matrix2<T,V>: Matrix<T,V> {
|
|||
}
|
||||
|
||||
/**
|
||||
* A 3 x 3 square matrix with numeric elements
|
||||
* A 3 x 3 matrix
|
||||
*/
|
||||
pub trait Matrix3<T,V>: Matrix<T,V> {
|
||||
pure fn to_mat4(&self) -> Mat4<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A 4 x 4 square matrix with numeric elements
|
||||
* A 4 x 4 matrix
|
||||
*/
|
||||
pub trait Matrix4<T,V>: Matrix<T,V> {
|
||||
}
|
||||
|
@ -178,12 +181,24 @@ pub trait Matrix4<T,V>: Matrix<T,V> {
|
|||
|
||||
/**
|
||||
* A 2 x 2 column major matrix
|
||||
*
|
||||
* # Fields
|
||||
*
|
||||
* * `x` - the first column vector of the matrix
|
||||
* * `y` - the second column vector of the matrix
|
||||
* * `z` - the third column vector of the matrix
|
||||
*/
|
||||
pub struct Mat2<T> { x: Vec2<T>, y: Vec2<T> }
|
||||
|
||||
pub impl<T:Copy Float> Mat2<T> {
|
||||
/**
|
||||
* Construct a 2 x 2 matrix
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `c0r0`, `c0r1` - the first column of the matrix
|
||||
* * `c1r0`, `c1r1` - the second column of the matrix
|
||||
*
|
||||
* ~~~
|
||||
* c0 c1
|
||||
* +------+------+
|
||||
|
@ -202,6 +217,12 @@ pub impl<T:Copy Float> Mat2<T> {
|
|||
|
||||
/**
|
||||
* Construct a 2 x 2 matrix from column vectors
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `c0` - the first column vector of the matrix
|
||||
* * `c1` - the second column vector of the matrix
|
||||
*
|
||||
* ~~~
|
||||
* c0 c1
|
||||
* +------+------+
|
||||
|
@ -219,6 +240,11 @@ pub impl<T:Copy Float> Mat2<T> {
|
|||
|
||||
/**
|
||||
* Construct a 2 x 2 diagonal matrix with the major diagonal set to `value`
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `value` - the value to set the major diagonal to
|
||||
*
|
||||
* ~~~
|
||||
* c0 c1
|
||||
* +-----+-----+
|
||||
|
@ -508,12 +534,25 @@ pub impl<T:Copy Float> Mat2<T>: FuzzyEq {
|
|||
|
||||
/**
|
||||
* A 3 x 3 column major matrix
|
||||
*
|
||||
* # Fields
|
||||
*
|
||||
* * `x` - the first column vector of the matrix
|
||||
* * `y` - the second column vector of the matrix
|
||||
* * `z` - the third column vector of the matrix
|
||||
*/
|
||||
pub struct Mat3<T> { x: Vec3<T>, y: Vec3<T>, z: Vec3<T> }
|
||||
|
||||
pub impl<T:Copy Float> Mat3<T> {
|
||||
/**
|
||||
* Construct a 3 x 3 matrix
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `c0r0`, `c0r1`, `c0r2` - the first column of the matrix
|
||||
* * `c1r0`, `c1r1`, `c1r2` - the second column of the matrix
|
||||
* * `c2r0`, `c2r1`, `c2r2` - the third column of the matrix
|
||||
*
|
||||
* ~~~
|
||||
* c0 c1 c2
|
||||
* +------+------+------+
|
||||
|
@ -536,6 +575,13 @@ pub impl<T:Copy Float> Mat3<T> {
|
|||
|
||||
/**
|
||||
* Construct a 3 x 3 matrix from column vectors
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `c0` - the first column vector of the matrix
|
||||
* * `c1` - the second column vector of the matrix
|
||||
* * `c2` - the third column vector of the matrix
|
||||
*
|
||||
* ~~~
|
||||
* c0 c1 c2
|
||||
* +------+------+------+
|
||||
|
@ -556,6 +602,11 @@ pub impl<T:Copy Float> Mat3<T> {
|
|||
|
||||
/**
|
||||
* Construct a 3 x 3 diagonal matrix with the major diagonal set to `value`
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `value` - the value to set the major diagonal to
|
||||
*
|
||||
* ~~~
|
||||
* c0 c1 c2
|
||||
* +-----+-----+-----+
|
||||
|
@ -932,12 +983,27 @@ pub impl<T:Copy Float> Mat3<T>: FuzzyEq {
|
|||
|
||||
/**
|
||||
* A 4 x 4 column major matrix
|
||||
*
|
||||
* # Fields
|
||||
*
|
||||
* * `x` - the first column vector of the matrix
|
||||
* * `y` - the second column vector of the matrix
|
||||
* * `z` - the third column vector of the matrix
|
||||
* * `w` - the fourth column vector of the matrix
|
||||
*/
|
||||
pub struct Mat4<T> { x: Vec4<T>, y: Vec4<T>, z: Vec4<T>, w: Vec4<T> }
|
||||
|
||||
pub impl<T:Copy Float> Mat4<T> {
|
||||
/**
|
||||
* Construct a 4 x 4 matrix
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `c0r0`, `c0r1`, `c0r2`, `c0r3` - the first column of the matrix
|
||||
* * `c1r0`, `c1r1`, `c1r2`, `c1r3` - the second column of the matrix
|
||||
* * `c2r0`, `c2r1`, `c2r2`, `c2r3` - the third column of the matrix
|
||||
* * `c3r0`, `c3r1`, `c3r2`, `c3r3` - the fourth column of the matrix
|
||||
*
|
||||
* ~~~
|
||||
* c0 c1 c2 c3
|
||||
* +------+------+------+------+
|
||||
|
@ -964,6 +1030,14 @@ pub impl<T:Copy Float> Mat4<T> {
|
|||
|
||||
/**
|
||||
* Construct a 4 x 4 matrix from column vectors
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `c0` - the first column vector of the matrix
|
||||
* * `c1` - the second column vector of the matrix
|
||||
* * `c2` - the third column vector of the matrix
|
||||
* * `c3` - the fourth column vector of the matrix
|
||||
*
|
||||
* ~~~
|
||||
* c0 c1 c2 c3
|
||||
* +------+------+------+------+
|
||||
|
@ -987,6 +1061,11 @@ pub impl<T:Copy Float> Mat4<T> {
|
|||
|
||||
/**
|
||||
* Construct a 4 x 4 diagonal matrix with the major diagonal set to `value`
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `value` - the value to set the major diagonal to
|
||||
*
|
||||
* ~~~
|
||||
* c0 c1 c2 c3
|
||||
* +-----+-----+-----+-----+
|
||||
|
@ -1187,6 +1266,9 @@ pub impl<T:Copy Float Sign> Mat4<T>: Matrix<T, Vec4<T>> {
|
|||
} else {
|
||||
|
||||
// Gauss Jordan Elimination with partial pivoting
|
||||
|
||||
// TODO: use column/row swapping methods. Check with Luqman to see
|
||||
// if the column-major layout has been used correctly
|
||||
|
||||
let mut a = *self;
|
||||
// let mut inv: Mat4<T> = Matrix::identity(); // FIXME: there's something wrong with static functions here!
|
||||
|
|
164
src/quat.rs
164
src/quat.rs
|
@ -64,14 +64,33 @@ pub trait Quaternion<T>: Dimensional<T>, ToPtr<T>, Eq, Neg<self> {
|
|||
*/
|
||||
pure fn dot(&self, other: &self) -> T;
|
||||
|
||||
/**
|
||||
* Returns the conjugate of the quaternion
|
||||
*/
|
||||
pure fn conjugate(&self) -> self;
|
||||
|
||||
/**
|
||||
* Returns the multiplicative inverse of the quaternion
|
||||
*/
|
||||
pure fn inverse(&self) -> self;
|
||||
pure fn length2(&self) -> T;
|
||||
pure fn length(&self) -> T;
|
||||
|
||||
/**
|
||||
* Returns the squared magnitude of the quaternion. This is useful for
|
||||
* magnitude comparisons where the exact magnitude does not need to be
|
||||
* calculated.
|
||||
*/
|
||||
pure fn magnitude2(&self) -> T;
|
||||
|
||||
/**
|
||||
* Returns the magnitude of the quaternion
|
||||
*
|
||||
* # Performance notes
|
||||
*
|
||||
* For instances where the exact magnitude of the vector does not need to be
|
||||
* known, for example for quaternion-quaternion magnitude comparisons,
|
||||
* it is advisable to use the `magnitude2` method instead.
|
||||
*/
|
||||
pure fn magnitude(&self) -> T;
|
||||
|
||||
/**
|
||||
* Returns the normalized quaternion
|
||||
|
@ -85,7 +104,11 @@ pub trait Quaternion<T>: Dimensional<T>, ToPtr<T>, Eq, Neg<self> {
|
|||
|
||||
/**
|
||||
* Perform a spherical linear interpolation between the quaternion and
|
||||
* `other`. This is more accutrate than `nlerp`, but is also more
|
||||
* `other`.
|
||||
*
|
||||
* # Performance notes
|
||||
*
|
||||
* This is more accurate than `nlerp` but is also more
|
||||
* computationally intensive.
|
||||
*/
|
||||
pure fn slerp(&self, other: &self, amount: T) -> self;
|
||||
|
@ -102,6 +125,9 @@ pub trait Quaternion<T>: Dimensional<T>, ToPtr<T>, Eq, Neg<self> {
|
|||
}
|
||||
|
||||
pub trait ToQuat<T> {
|
||||
/**
|
||||
* Convert `self` to a quaternion
|
||||
*/
|
||||
pure fn to_Quat() -> Quat<T>;
|
||||
}
|
||||
|
||||
|
@ -109,21 +135,40 @@ pub trait ToQuat<T> {
|
|||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A quaternion in scalar/vector form
|
||||
*
|
||||
* # Fields
|
||||
*
|
||||
* * `s` - the scalar component
|
||||
* * `v` - a vector containing the three imaginary components
|
||||
*/
|
||||
pub struct Quat<T> { s: T, v: Vec3<T> }
|
||||
|
||||
pub impl<T> Quat<T> {
|
||||
/**
|
||||
* Construct the quaternion from one scalar component and three
|
||||
* imaginary components
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `w` - the scalar component
|
||||
* * `xi` - the fist imaginary component
|
||||
* * `yj` - the second imaginary component
|
||||
* * `zk` - the third imaginary component
|
||||
*/
|
||||
#[inline(always)]
|
||||
static pure fn new(s: T, vx: T, vy: T, vz: T) -> Quat<T> {
|
||||
Quat::from_sv(move s, move Vec3::new(move vx, move vy, move vz))
|
||||
static pure fn new(w: T, xi: T, yj: T, zk: T) -> Quat<T> {
|
||||
Quat::from_sv(move w, move Vec3::new(move xi, move yj, move zk))
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the quaternion from a scalar and a vector
|
||||
*
|
||||
* # Arguments
|
||||
*
|
||||
* * `s` - the scalar component
|
||||
* * `v` - a vector containing the three imaginary components
|
||||
*/
|
||||
#[inline(always)]
|
||||
static pure fn from_sv(s: T, v: Vec3<T>) -> Quat<T> {
|
||||
|
@ -232,23 +277,23 @@ pub impl<T:Copy Float Exp Extent InvTrig> Quat<T>: Quaternion<T> {
|
|||
|
||||
#[inline(always)]
|
||||
pure fn inverse(&self) -> Quat<T> {
|
||||
self.conjugate().div_t(self.length2())
|
||||
self.conjugate().div_t(self.magnitude2())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn length2(&self) -> T {
|
||||
pure fn magnitude2(&self) -> T {
|
||||
self.s * self.s + self.v.length2()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn length(&self) -> T {
|
||||
self.length2().sqrt()
|
||||
pure fn magnitude(&self) -> T {
|
||||
self.magnitude2().sqrt()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn normalize(&self) -> Quat<T> {
|
||||
let mut n: T = Number::from(1);
|
||||
n /= self.length();
|
||||
n /= self.magnitude();
|
||||
return self.mul_t(n);
|
||||
}
|
||||
|
||||
|
@ -264,15 +309,16 @@ pub impl<T:Copy Float Exp Extent InvTrig> Quat<T>: Quaternion<T> {
|
|||
* Both quaternions should be normalized first, or else strange things will
|
||||
* will happen...
|
||||
*
|
||||
* Note: The `acos` used in `slerp` is an expensive operation, so unless your
|
||||
* quarternions a far away from each other it's generally more advisable to
|
||||
* use nlerp when you know your rotations are going to be small.
|
||||
* # Performance notes
|
||||
*
|
||||
* See *[Understanding Slerp, Then Not Using It]
|
||||
* (http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/)*
|
||||
* for more information. The [Arcsynthesis OpenGL tutorial]
|
||||
* (http://www.arcsynthesis.org/gltut/Positioning/Tut08%20Interpolation.html)
|
||||
* also provides a good explanation.
|
||||
* The `acos` operation used in `slerp` is an expensive operation, so unless
|
||||
* your quarternions a far away from each other it's generally more advisable
|
||||
* to use `nlerp` when you know your rotations are going to be small.
|
||||
*
|
||||
* - [Understanding Slerp, Then Not Using It]
|
||||
* (http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/)
|
||||
* - [Arcsynthesis OpenGL tutorial]
|
||||
* (http://www.arcsynthesis.org/gltut/Positioning/Tut08%20Interpolation.html)
|
||||
*/
|
||||
#[inline(always)]
|
||||
pure fn slerp(&self, other: &Quat<T>, amount: T) -> Quat<T> {
|
||||
|
@ -353,82 +399,4 @@ pub impl<T:Copy FuzzyEq> Quat<T>: FuzzyEq {
|
|||
self[2].fuzzy_eq(&other[2]) &&
|
||||
self[3].fuzzy_eq(&other[3])
|
||||
}
|
||||
}
|
||||
|
||||
// // Operator Overloads
|
||||
|
||||
// pub impl<T, Result, RHS: QuatAddRHS<T, Result>> Quat<T>: Add<RHS,Result> {
|
||||
// #[inline(always)]
|
||||
// pure fn add(rhs: &RHS) -> Result {
|
||||
// rhs.quat_add_rhs(&self)
|
||||
// }
|
||||
// }
|
||||
|
||||
// pub impl<T, Result, RHS: QuatSubRHS<T, Result>> Quat<T>: Sub<RHS,Result> {
|
||||
// #[inline(always)]
|
||||
// pure fn sub(&self, rhs: &RHS) -> Result {
|
||||
// rhs.quat_sub_rhs(self)
|
||||
// }
|
||||
// }
|
||||
|
||||
// pub impl<T, Result, RHS: QuatMulRHS<T, Result>> Quat<T>: Mul<RHS,Result> {
|
||||
// #[inline(always)]
|
||||
// pure fn mul(&self, rhs: &RHS) -> Result {
|
||||
// rhs.quat_mul_rhs(self)
|
||||
// }
|
||||
// }
|
||||
|
||||
// pub impl<T, Result, RHS: QuatDivRHS<T, Result>> Quat<T>: Div<RHS,Result> {
|
||||
// #[inline(always)]
|
||||
// pure fn div(&self, rhs: &RHS) -> Result {
|
||||
// rhs.quat_div_rhs(self)
|
||||
// }
|
||||
// }
|
||||
|
||||
// // RHS Traits for Operator overloads
|
||||
// pub trait QuatAddRHS<T, Result> { pure fn quat_add_rhs(&self, lhs: &Quat<T>) -> Result; }
|
||||
// pub trait QuatSubRHS<T, Result> { pure fn quat_sub_rhs(&self, lhs: &Quat<T>) -> Result; }
|
||||
// pub trait QuatMulRHS<T, Result> { pure fn quat_mul_rhs(&self, lhs: &Quat<T>) -> Result; }
|
||||
// pub trait QuatDivRHS<T, Result> { pure fn quat_div_rhs(&self, lhs: &Quat<T>) -> Result; }
|
||||
|
||||
// // Quat/Scalar Multiplication
|
||||
// pub impl f32: QuatMulRHS<f32, Quat<f32>> { #[inline(always)] pure fn quat_mul_rhs(&self, lhs: &Quat<f32>) -> Quat<f32> { lhs.mul_t(self) } }
|
||||
// pub impl f64: QuatMulRHS<f64, Quat<f64>> { #[inline(always)] pure fn quat_mul_rhs(&self, lhs: &Quat<f64>) -> Quat<f64> { lhs.mul_t(self) } }
|
||||
// pub impl float: QuatMulRHS<float, Quat<float>> { #[inline(always)] pure fn quat_mul_rhs(&self, lhs: &Quat<float>) -> Quat<float> { lhs.mul_t(self) } }
|
||||
|
||||
// // Quat/Scalar Division
|
||||
// pub impl f32: QuatDivRHS<f32, Quat<f32>> { #[inline(always)] pure fn quat_div_rhs(&self, lhs: &Quat<f32>) -> Quat<f32> { lhs.div_t(self) } }
|
||||
// pub impl f64: QuatDivRHS<f64, Quat<f64>> { #[inline(always)] pure fn quat_div_rhs(&self, lhs: &Quat<f64>) -> Quat<f64> { lhs.div_t(self) } }
|
||||
// pub impl float: QuatDivRHS<float, Quat<float>> { #[inline(always)] pure fn quat_div_rhs(&self, lhs: &Quat<float>) -> Quat<float> { lhs.div_t(self) } }
|
||||
|
||||
// // Quat/Vector Multiplication
|
||||
// pub impl<T:Copy Num NumCast Exp Extent Ord InvTrig> Vec3<T>: QuatMulRHS<T, Vec3<T>> {
|
||||
// #[inline(always)]
|
||||
// pure fn quat_mul_rhs(&self, lhs: &Quat<T>) -> Vec3<T> {
|
||||
// lhs.mul_v(self)
|
||||
// }
|
||||
// }
|
||||
|
||||
// // // Quat/Quat Addition
|
||||
// // pub impl<T:Copy Num NumCast Exp Extent Ord InvTrig> Quat<T>: QuatAddRHS<Quat<T>, Quat<T>> {
|
||||
// // #[inline(always)]
|
||||
// // pure fn quat_add_rhs(&self, lhs: &Quat<T>) -> Quat<T> {
|
||||
// // lhs.add_q(self)
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// // Quat/Quat Subtraction
|
||||
// pub impl<T:Copy Num NumCast Exp Extent Ord InvTrig> Quat<T>: QuatSubRHS<T, Quat<T>> {
|
||||
// #[inline(always)]
|
||||
// pure fn quat_sub_rhs(&self, lhs: &Quat<T>) -> Quat<T> {
|
||||
// lhs.sub_q(self)
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Quat/Quat Multiplication
|
||||
// pub impl<T:Copy Num NumCast Exp Extent Ord InvTrig> Quat<T>: QuatMulRHS<T, Quat<T>> {
|
||||
// #[inline(always)]
|
||||
// pure fn quat_mul_rhs(&self, lhs: &Quat<T>) -> Quat<T> {
|
||||
// lhs.mul_q(self)
|
||||
// }
|
||||
// }
|
||||
}
|
Loading…
Reference in a new issue