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:
Brendan Zabarauskas 2012-12-05 11:38:30 +10:00
parent b8521f289c
commit 63f9cd38b7
2 changed files with 151 additions and 101 deletions

View file

@ -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!

View file

@ -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)
// }
// }
}