Merge pull request #232 from bjz/move-matrix-constructors

Move some methods onto the Matrix trait
This commit is contained in:
Colin Sherratt 2015-09-29 02:20:40 -04:00
commit 4a1a97aaaa

View file

@ -21,7 +21,7 @@ use std::ops::*;
use rand::{Rand, Rng}; use rand::{Rand, Rng};
use rust_num::{Zero, zero, One, one}; use rust_num::{zero, one};
use rust_num::traits::cast; use rust_num::traits::cast;
use angle::{Rad, sin, cos, sin_cos}; use angle::{Rad, sin, cos, sin_cos};
@ -62,28 +62,6 @@ impl<S> Matrix2<S> {
} }
} }
impl<S: BaseNum> Matrix2<S> {
/// Create a new diagonal matrix, providing a single value to use for each
/// non-zero index.
#[inline]
pub fn from_value(value: S) -> Matrix2<S> {
Matrix2::new(value.clone(), zero(),
zero(), value.clone())
}
/// Create a zero matrix (all zeros).
#[inline]
pub fn zero() -> Matrix2<S> {
Matrix2::from_value(zero())
}
/// Create an identity matrix (diagonal matrix of ones).
#[inline]
pub fn identity() -> Matrix2<S> {
Matrix2::from_value(one())
}
}
impl<S: BaseFloat> Matrix2<S> { impl<S: BaseFloat> Matrix2<S> {
/// Create a transformation matrix that will cause a vector to point at /// Create a transformation matrix that will cause a vector to point at
/// `dir`, using `up` for orientation. /// `dir`, using `up` for orientation.
@ -129,29 +107,6 @@ impl<S> Matrix3<S> {
} }
} }
impl<S: BaseNum> Matrix3<S> {
/// Create a new diagonal matrix, providing a single value to use for each
/// non-zero index.
#[inline]
pub fn from_value(value: S) -> Matrix3<S> {
Matrix3::new(value.clone(), zero(), zero(),
zero(), value.clone(), zero(),
zero(), zero(), value.clone())
}
/// Create a zero matrix (all zeros).
#[inline]
pub fn zero() -> Matrix3<S> {
Matrix3::from_value(zero())
}
/// Create an identity matrix (diagonal matrix of ones).
#[inline]
pub fn identity() -> Matrix3<S> {
Matrix3::from_value(one())
}
}
impl<S: BaseFloat> Matrix3<S> { impl<S: BaseFloat> Matrix3<S> {
/// Create a transformation matrix that will cause a vector to point at /// Create a transformation matrix that will cause a vector to point at
/// `dir`, using `up` for orientation. /// `dir`, using `up` for orientation.
@ -225,13 +180,6 @@ impl<S: BaseFloat> Matrix3<S> {
_1subc * axis.y * axis.z - s * axis.x, _1subc * axis.y * axis.z - s * axis.x,
_1subc * axis.z * axis.z + c) _1subc * axis.z * axis.z + c)
} }
/// Create a matrix from a non-uniform scale
pub fn from_diagonal(value: &Vector3<S>) -> Matrix3<S> {
Matrix3::new(value.x, zero(), zero(),
zero(), value.y, zero(),
zero(), zero(), value.z)
}
} }
impl<S: Copy + Neg<Output = S>> Matrix3<S> { impl<S: Copy + Neg<Output = S>> Matrix3<S> {
@ -265,28 +213,6 @@ impl<S> Matrix4<S> {
} }
impl<S: BaseNum> Matrix4<S> { impl<S: BaseNum> Matrix4<S> {
/// Create a new diagonal matrix, providing a single value to use for each
/// non-zero index.
#[inline]
pub fn from_value(value: S) -> Matrix4<S> {
Matrix4::new(value.clone(), zero(), zero(), zero(),
zero(), value.clone(), zero(), zero(),
zero(), zero(), value.clone(), zero(),
zero(), zero(), zero(), value.clone())
}
/// Create a zero matrix (all zeros).
#[inline]
pub fn zero() -> Matrix4<S> {
Matrix4::from_value(zero())
}
/// Create an identity matrix (diagonal matrix of ones).
#[inline]
pub fn identity() -> Matrix4<S> {
Matrix4::from_value(one())
}
/// Create a translation matrix from a Vector3 /// Create a translation matrix from a Vector3
#[inline] #[inline]
pub fn from_translation(v: &Vector3<S>) -> Matrix4<S> { pub fn from_translation(v: &Vector3<S>) -> Matrix4<S> {
@ -324,9 +250,20 @@ impl<S: Copy + Neg<Output = S>> Matrix4<S> {
} }
pub trait Matrix<S: BaseFloat, V: Clone + Vector<S> + 'static>: Array2<V, V, S> pub trait Matrix<S: BaseFloat, V: Clone + Vector<S> + 'static>: Array2<V, V, S>
+ Zero + One
+ ApproxEq<S> + ApproxEq<S>
+ Sized { + Sized {
/// Create a new diagonal matrix using the supplied value.
fn from_value(value: S) -> Self;
/// Create a matrix from a non-uniform scale
fn from_diagonal(value: &V) -> Self;
/// Create a matrix with all elements equal to zero.
#[inline]
fn zero() -> Self { Self::from_value(zero()) }
/// Create a matrix where the each element of the diagonal is equal to one.
#[inline]
fn identity() -> Self { Self::from_value(one()) }
/// Multiply this matrix by a scalar, returning the new matrix. /// Multiply this matrix by a scalar, returning the new matrix.
#[must_use] #[must_use]
fn mul_s(&self, s: S) -> Self; fn mul_s(&self, s: S) -> Self;
@ -402,7 +339,7 @@ pub trait Matrix<S: BaseFloat, V: Clone + Vector<S> + 'static>: Array2<V, V, S>
/// Test if this matrix is the identity matrix. That is, it is diagonal /// Test if this matrix is the identity matrix. That is, it is diagonal
/// and every element in the diagonal is one. /// and every element in the diagonal is one.
#[inline] #[inline]
fn is_identity(&self) -> bool { self.approx_eq(&one()) } fn is_identity(&self) -> bool { self.approx_eq(&Self::identity()) }
/// Test if this is a diagonal matrix. That is, every element outside of /// Test if this is a diagonal matrix. That is, every element outside of
/// the diagonal is 0. /// the diagonal is 0.
@ -482,27 +419,6 @@ impl<S: Neg<Output = S>> Neg for Matrix4<S> {
} }
} }
impl<S: BaseFloat> Zero for Matrix2<S> {
#[inline]
fn zero() -> Matrix2<S> { Matrix2::zero() }
#[inline]
fn is_zero(&self) -> bool{ *self == zero() }
}
impl<S: BaseFloat> Zero for Matrix3<S> {
#[inline]
fn zero() -> Matrix3<S> { Matrix3::zero() }
#[inline]
fn is_zero(&self) -> bool{ *self == zero() }
}
impl<S: BaseFloat> Zero for Matrix4<S> {
#[inline]
fn zero() -> Matrix4<S> { Matrix4::zero() }
#[inline]
fn is_zero(&self) -> bool{ *self == zero() }
}
impl<S: BaseFloat> Mul for Matrix2<S> { impl<S: BaseFloat> Mul for Matrix2<S> {
type Output = Matrix2<S>; type Output = Matrix2<S>;
@ -545,18 +461,6 @@ impl<S: BaseFloat> Mul<S> for Matrix4<S> {
fn mul(self, other: S) -> Matrix4<S> { self.mul_s(other) } fn mul(self, other: S) -> Matrix4<S> { self.mul_s(other) }
} }
impl<S: BaseFloat> One for Matrix2<S> {
#[inline]
fn one() -> Matrix2<S> { Matrix2::identity() }
}
impl<S: BaseFloat> One for Matrix3<S> {
#[inline]
fn one() -> Matrix3<S> { Matrix3::identity() }
}
impl<S: BaseFloat> One for Matrix4<S> {
#[inline] fn one() -> Matrix4<S> { Matrix4::identity() }
}
impl<S: Copy + 'static> Array2<Vector2<S>, Vector2<S>, S> for Matrix2<S> { impl<S: Copy + 'static> Array2<Vector2<S>, Vector2<S>, S> for Matrix2<S> {
#[inline] #[inline]
fn row(&self, r: usize) -> Vector2<S> { fn row(&self, r: usize) -> Vector2<S> {
@ -630,6 +534,18 @@ impl<S: Copy + 'static> Array2<Vector4<S>, Vector4<S>, S> for Matrix4<S> {
} }
impl<S: BaseFloat> Matrix<S, Vector2<S>> for Matrix2<S> { impl<S: BaseFloat> Matrix<S, Vector2<S>> for Matrix2<S> {
#[inline]
fn from_value(value: S) -> Matrix2<S> {
Matrix2::new(value, zero(),
zero(), value)
}
#[inline]
fn from_diagonal(value: &Vector2<S>) -> Matrix2<S> {
Matrix2::new(value.x, zero(),
zero(), value.y)
}
#[inline] #[inline]
fn mul_s(&self, s: S) -> Matrix2<S> { fn mul_s(&self, s: S) -> Matrix2<S> {
Matrix2::from_cols(self[0].mul_s(s), Matrix2::from_cols(self[0].mul_s(s),
@ -748,6 +664,20 @@ impl<S: BaseFloat> Matrix<S, Vector2<S>> for Matrix2<S> {
} }
impl<S: BaseFloat> Matrix<S, Vector3<S>> for Matrix3<S> { impl<S: BaseFloat> Matrix<S, Vector3<S>> for Matrix3<S> {
#[inline]
fn from_value(value: S) -> Matrix3<S> {
Matrix3::new(value, zero(), zero(),
zero(), value, zero(),
zero(), zero(), value)
}
#[inline]
fn from_diagonal(value: &Vector3<S>) -> Matrix3<S> {
Matrix3::new(value.x, zero(), zero(),
zero(), value.y, zero(),
zero(), zero(), value.z)
}
#[inline] #[inline]
fn mul_s(&self, s: S) -> Matrix3<S> { fn mul_s(&self, s: S) -> Matrix3<S> {
Matrix3::from_cols(self[0].mul_s(s), Matrix3::from_cols(self[0].mul_s(s),
@ -902,6 +832,22 @@ macro_rules! dot_matrix4(
)); ));
impl<S: BaseFloat> Matrix<S, Vector4<S>> for Matrix4<S> { impl<S: BaseFloat> Matrix<S, Vector4<S>> for Matrix4<S> {
#[inline]
fn from_value(value: S) -> Matrix4<S> {
Matrix4::new(value, zero(), zero(), zero(),
zero(), value, zero(), zero(),
zero(), zero(), value, zero(),
zero(), zero(), zero(), value)
}
#[inline]
fn from_diagonal(value: &Vector4<S>) -> Matrix4<S> {
Matrix4::new(value.x, zero(), zero(), zero(),
zero(), value.y, zero(), zero(),
zero(), zero(), value.z, zero(),
zero(), zero(), zero(), value.w)
}
#[inline] #[inline]
fn mul_s(&self, s: S) -> Matrix4<S> { fn mul_s(&self, s: S) -> Matrix4<S> {
Matrix4::from_cols(self[0].mul_s(s), Matrix4::from_cols(self[0].mul_s(s),