Merge pull request #254 from bjz/matrix-and-array-api-changes
Matrix and Array api changes
This commit is contained in:
commit
e05a8737fa
7 changed files with 412 additions and 304 deletions
76
src/array.rs
76
src/array.rs
|
@ -13,85 +13,47 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::mem;
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::ops::*;
|
use std::ops::*;
|
||||||
|
|
||||||
|
use num::PartialOrd;
|
||||||
|
|
||||||
/// An array containing elements of type `Element`
|
/// An array containing elements of type `Element`
|
||||||
pub trait Array1 where
|
pub trait Array where
|
||||||
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
||||||
Self: Index<usize, Output = <Self as Array1>::Element>,
|
Self: Index<usize, Output = <Self as Array>::Element>,
|
||||||
Self: IndexMut<usize, Output = <Self as Array1>::Element>,
|
Self: IndexMut<usize, Output = <Self as Array>::Element>,
|
||||||
{
|
{
|
||||||
type Element: Copy;
|
type Element: Copy;
|
||||||
|
|
||||||
/// Get the pointer to the first element of the array.
|
/// Get the pointer to the first element of the array.
|
||||||
fn ptr<'a>(&'a self) -> &'a Self::Element {
|
#[inline]
|
||||||
|
fn as_ptr(&self) -> *const Self::Element {
|
||||||
&self[0]
|
&self[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a mutable pointer to the first element of the array.
|
/// Get a mutable pointer to the first element of the array.
|
||||||
fn mut_ptr<'a>(&'a mut self) -> &'a mut Self::Element {
|
#[inline]
|
||||||
|
fn as_mut_ptr(&mut self) -> *mut Self::Element {
|
||||||
&mut self[0]
|
&mut self[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Swap the elements at indices `i` and `j` in-place.
|
/// Swap the elements at indices `i` and `j` in-place.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn swap_elems(&mut self, i: usize, j: usize) {
|
fn swap_elements(&mut self, i: usize, j: usize) {
|
||||||
// Yeah, ok borrow checker – I know what I'm doing here
|
// Yeah, ok borrow checker – I know what I'm doing here
|
||||||
unsafe { ptr::swap(&mut self[i], &mut self[j]) };
|
unsafe { ptr::swap(&mut self[i], &mut self[j]) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replace an element in the array.
|
/// The sum of the elements of the array.
|
||||||
#[inline]
|
fn sum(self) -> Self::Element where Self::Element: Add<Output = <Self as Array>::Element>;
|
||||||
fn replace_elem(&mut self, i: usize, src: Self::Element) -> Self::Element {
|
|
||||||
mem::replace(&mut self[i], src)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A column-major array
|
/// The product of the elements of the array.
|
||||||
pub trait Array2 where
|
fn product(self) -> Self::Element where Self::Element: Mul<Output = <Self as Array>::Element>;
|
||||||
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
|
||||||
Self: Index<usize, Output = <Self as Array2>::Column>,
|
|
||||||
Self: IndexMut<usize, Output = <Self as Array2>::Column>,
|
|
||||||
{
|
|
||||||
type Element: Copy;
|
|
||||||
type Column: Array1<Element = Self::Element>;
|
|
||||||
type Row: Array1<Element = Self::Element>;
|
|
||||||
|
|
||||||
/// Get the pointer to the first element of the array.
|
/// The minimum element of the array.
|
||||||
fn ptr<'a>(&'a self) -> &'a Self::Element {
|
fn min(self) -> Self::Element where Self::Element: PartialOrd;
|
||||||
&self[0][0]
|
|
||||||
}
|
/// The maximum element of the array.
|
||||||
|
fn max(self) -> Self::Element where Self::Element: PartialOrd;
|
||||||
/// Get a mutable pointer to the first element of the array.
|
|
||||||
fn mut_ptr<'a>(&'a mut self) -> &'a mut Self::Element {
|
|
||||||
&mut self[0][0]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Swap two columns of this array.
|
|
||||||
#[inline]
|
|
||||||
fn swap_cols(&mut self, a: usize, b: usize) {
|
|
||||||
unsafe { ptr::swap(&mut self[a], &mut self[b]) };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Replace a column in the array.
|
|
||||||
#[inline]
|
|
||||||
fn replace_col(&mut self, c: usize, src: Self::Column) -> Self::Column {
|
|
||||||
mem::replace(&mut self[c], src)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a row from this array by-value.
|
|
||||||
fn row(&self, r: usize) -> Self::Row;
|
|
||||||
|
|
||||||
/// Swap two rows of this array.
|
|
||||||
fn swap_rows(&mut self, a: usize, b: usize);
|
|
||||||
|
|
||||||
/// Swap the values at index `a` and `b`
|
|
||||||
#[inline]
|
|
||||||
fn swap_elems(&mut self, a: (usize, usize), b: (usize, usize)) {
|
|
||||||
let (ac, ar) = a;
|
|
||||||
let (bc, br) = b;
|
|
||||||
unsafe { ptr::swap(&mut self[ac][ar], &mut self[bc][br]) };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
509
src/matrix.rs
509
src/matrix.rs
|
@ -18,6 +18,7 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::*;
|
use std::ops::*;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ use rust_num::traits::cast;
|
||||||
|
|
||||||
use angle::{Rad, sin, cos, sin_cos};
|
use angle::{Rad, sin, cos, sin_cos};
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
use array::{Array1, Array2};
|
use array::Array;
|
||||||
use num::{BaseFloat, BaseNum};
|
use num::{BaseFloat, BaseNum};
|
||||||
use point::{Point, Point3};
|
use point::{Point, Point3};
|
||||||
use quaternion::Quaternion;
|
use quaternion::Quaternion;
|
||||||
|
@ -249,15 +250,12 @@ impl<S: Copy + Neg<Output = S>> Matrix4<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A column-major matrix of arbitrary dimensions.
|
||||||
pub trait Matrix where
|
pub trait Matrix where
|
||||||
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
||||||
Self: Array2<
|
Self: Index<usize, Output = <Self as Matrix>::Column>,
|
||||||
Element = <<Self as Matrix>::ColumnRow as Vector>::Scalar,
|
Self: IndexMut<usize, Output = <Self as Matrix>::Column>,
|
||||||
Column = <Self as Matrix>::ColumnRow,
|
Self: ApproxEq<Epsilon = <Self as Matrix>::Element>,
|
||||||
Row = <Self as Matrix>::ColumnRow,
|
|
||||||
>,
|
|
||||||
Self: ApproxEq<Epsilon = <<Self as Matrix>::ColumnRow as Vector>::Scalar> + Sized,
|
|
||||||
Self::Element: BaseFloat,
|
|
||||||
// FIXME: blocked by rust-lang/rust#20671
|
// FIXME: blocked by rust-lang/rust#20671
|
||||||
//
|
//
|
||||||
// for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>,
|
// for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>,
|
||||||
|
@ -269,65 +267,106 @@ pub trait Matrix where
|
||||||
// for<'a> &'a Self: Div<S, Output = Self>,
|
// for<'a> &'a Self: Div<S, Output = Self>,
|
||||||
// for<'a> &'a Self: Rem<S, Output = Self>,
|
// for<'a> &'a Self: Rem<S, Output = Self>,
|
||||||
{
|
{
|
||||||
// FIXME: Will not be needed once equality constraints in where clauses is implemented
|
/// The type of the elements in the matrix.
|
||||||
type ColumnRow: Vector;
|
type Element: BaseFloat;
|
||||||
|
|
||||||
|
/// The row vector of the matrix.
|
||||||
|
type Row: Array<Element = Self::Element>;
|
||||||
|
/// The column vector of the matrix.
|
||||||
|
type Column: Array<Element = Self::Element>;
|
||||||
|
|
||||||
|
/// The type of the transposed matrix
|
||||||
|
type Transpose: Matrix<Element = Self::Element, Row = Self::Column, Column = Self::Row>;
|
||||||
|
|
||||||
|
/// Get the pointer to the first element of the array.
|
||||||
|
#[inline]
|
||||||
|
fn as_ptr(&self) -> *const Self::Element {
|
||||||
|
&self[0][0]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a mutable pointer to the first element of the array.
|
||||||
|
#[inline]
|
||||||
|
fn as_mut_ptr(&mut self) -> *mut Self::Element {
|
||||||
|
&mut self[0][0]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Replace a column in the array.
|
||||||
|
#[inline]
|
||||||
|
fn replace_col(&mut self, c: usize, src: Self::Column) -> Self::Column {
|
||||||
|
mem::replace(&mut self[c], src)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a row from this matrix by-value.
|
||||||
|
fn row(&self, r: usize) -> Self::Row;
|
||||||
|
|
||||||
|
/// Swap two rows of this array.
|
||||||
|
fn swap_rows(&mut self, a: usize, b: usize);
|
||||||
|
/// Swap two columns of this array.
|
||||||
|
fn swap_columns(&mut self, a: usize, b: usize);
|
||||||
|
/// Swap the values at index `a` and `b`
|
||||||
|
fn swap_elements(&mut self, a: (usize, usize), b: (usize, usize));
|
||||||
|
|
||||||
|
/// Create a matrix with all of the elements set to zero.
|
||||||
|
fn zero() -> Self;
|
||||||
|
|
||||||
|
/// Multiply the matrix by another matrix,
|
||||||
|
fn mul_m(&self, other: &Self::Transpose) -> Self;
|
||||||
|
|
||||||
|
/// Multiply the matrix by a column vector.
|
||||||
|
fn mul_v(&self, column: Self::Column) -> Self::Column;
|
||||||
|
|
||||||
|
/// Multiply this matrix by a scalar, returning the new matrix.
|
||||||
|
fn mul_s(&self, scalar: Self::Element) -> Self;
|
||||||
|
/// Divide this matrix by a scalar, returning the new matrix.
|
||||||
|
fn div_s(&self, scalar: Self::Element) -> Self;
|
||||||
|
|
||||||
|
/// Multiply this matrix by a scalar, in-place.
|
||||||
|
fn mul_self_s(&mut self, scalar: Self::Element);
|
||||||
|
/// Divide this matrix by a scalar, in-place.
|
||||||
|
fn div_self_s(&mut self, scalar: Self::Element);
|
||||||
|
|
||||||
|
/// Transpose this matrix, returning a new matrix.
|
||||||
|
fn transpose(&self) -> Self::Transpose;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A column-major major matrix where the rows and column vectors are of the same dimensions.
|
||||||
|
pub trait SquareMatrix where
|
||||||
|
Self: Matrix<
|
||||||
|
// FIXME: Can be cleaned up once equality constraints in where clauses are implemented
|
||||||
|
Column = <Self as SquareMatrix>::ColumnRow,
|
||||||
|
Row = <Self as SquareMatrix>::ColumnRow,
|
||||||
|
Transpose = Self,
|
||||||
|
>,
|
||||||
|
{
|
||||||
|
// FIXME: Will not be needed once equality constraints in where clauses are implemented
|
||||||
|
/// The row/column vector of the matrix.
|
||||||
|
///
|
||||||
|
/// This is used to constrain the column and rows to be of the same type in lieu of equality
|
||||||
|
/// constraints being implemented for `where` clauses. Once those are added, this type will
|
||||||
|
/// likely go away.
|
||||||
|
type ColumnRow: Array<Element = Self::Element>;
|
||||||
|
|
||||||
/// Create a new diagonal matrix using the supplied value.
|
/// Create a new diagonal matrix using the supplied value.
|
||||||
fn from_value(value: Self::Element) -> Self;
|
fn from_value(value: Self::Element) -> Self;
|
||||||
/// Create a matrix from a non-uniform scale
|
/// Create a matrix from a non-uniform scale
|
||||||
fn from_diagonal(diagonal: Self::Column) -> Self;
|
fn from_diagonal(diagonal: Self::Column) -> Self;
|
||||||
|
|
||||||
/// Create a matrix with all elements equal to zero.
|
|
||||||
#[inline]
|
|
||||||
fn zero() -> Self { Self::from_value(Self::Element::zero()) }
|
|
||||||
/// Create a matrix where the each element of the diagonal is equal to one.
|
/// Create a matrix where the each element of the diagonal is equal to one.
|
||||||
#[inline]
|
fn one() -> Self;
|
||||||
fn one() -> Self { Self::from_value(Self::Element::one()) }
|
|
||||||
|
|
||||||
/// Multiply this matrix by a scalar, returning the new matrix.
|
|
||||||
#[must_use]
|
|
||||||
fn mul_s(&self, s: Self::Element) -> Self;
|
|
||||||
/// Divide this matrix by a scalar, returning the new matrix.
|
|
||||||
#[must_use]
|
|
||||||
fn div_s(&self, s: Self::Element) -> Self;
|
|
||||||
/// Take the remainder of this matrix by a scalar, returning the new
|
|
||||||
/// matrix.
|
|
||||||
#[must_use]
|
|
||||||
fn rem_s(&self, s: Self::Element) -> Self;
|
|
||||||
|
|
||||||
/// Add this matrix with another matrix, returning the new metrix.
|
/// Add this matrix with another matrix, returning the new metrix.
|
||||||
#[must_use]
|
|
||||||
fn add_m(&self, m: &Self) -> Self;
|
fn add_m(&self, m: &Self) -> Self;
|
||||||
/// Subtract another matrix from this matrix, returning the new matrix.
|
/// Subtract another matrix from this matrix, returning the new matrix.
|
||||||
#[must_use]
|
|
||||||
fn sub_m(&self, m: &Self) -> Self;
|
fn sub_m(&self, m: &Self) -> Self;
|
||||||
|
|
||||||
/// Multiplay a vector by this matrix, returning a new vector.
|
|
||||||
fn mul_v(&self, v: Self::Column) -> Self::Column;
|
|
||||||
|
|
||||||
/// Multiply this matrix by another matrix, returning the new matrix.
|
|
||||||
#[must_use]
|
|
||||||
fn mul_m(&self, m: &Self) -> Self;
|
|
||||||
|
|
||||||
/// Multiply this matrix by a scalar, in-place.
|
|
||||||
fn mul_self_s(&mut self, s: Self::Element);
|
|
||||||
/// Divide this matrix by a scalar, in-place.
|
|
||||||
fn div_self_s(&mut self, s: Self::Element);
|
|
||||||
/// Take the remainder of this matrix, in-place.
|
|
||||||
fn rem_self_s(&mut self, s: Self::Element);
|
|
||||||
|
|
||||||
/// Add this matrix with another matrix, in-place.
|
/// Add this matrix with another matrix, in-place.
|
||||||
fn add_self_m(&mut self, m: &Self);
|
fn add_self_m(&mut self, m: &Self);
|
||||||
/// Subtract another matrix from this matrix, in-place.
|
/// Subtract another matrix from this matrix, in-place.
|
||||||
fn sub_self_m(&mut self, m: &Self);
|
fn sub_self_m(&mut self, m: &Self);
|
||||||
|
|
||||||
/// Multiply this matrix by another matrix, in-place.
|
/// Multiply this matrix by another matrix, in-place.
|
||||||
#[inline]
|
|
||||||
fn mul_self_m(&mut self, m: &Self) { *self = self.mul_m(m); }
|
fn mul_self_m(&mut self, m: &Self) { *self = self.mul_m(m); }
|
||||||
|
|
||||||
/// Transpose this matrix, returning a new matrix.
|
|
||||||
#[must_use]
|
|
||||||
fn transpose(&self) -> Self;
|
|
||||||
/// Transpose this matrix in-place.
|
/// Transpose this matrix in-place.
|
||||||
fn transpose_self(&mut self);
|
fn transpose_self(&mut self);
|
||||||
/// Take the determinant of this matrix.
|
/// Take the determinant of this matrix.
|
||||||
|
@ -370,10 +409,11 @@ pub trait Matrix where
|
||||||
fn is_symmetric(&self) -> bool;
|
fn is_symmetric(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Copy> Array2 for Matrix2<S> {
|
impl<S: BaseFloat> Matrix for Matrix2<S> {
|
||||||
type Element = S;
|
type Element = S;
|
||||||
type Column = Vector2<S>;
|
type Column = Vector2<S>;
|
||||||
type Row = Vector2<S>;
|
type Row = Vector2<S>;
|
||||||
|
type Transpose = Matrix2<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn row(&self, r: usize) -> Vector2<S> {
|
fn row(&self, r: usize) -> Vector2<S> {
|
||||||
|
@ -383,54 +423,59 @@ impl<S: Copy> Array2 for Matrix2<S> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn swap_rows(&mut self, a: usize, b: usize) {
|
fn swap_rows(&mut self, a: usize, b: usize) {
|
||||||
self[0].swap_elems(a, b);
|
self[0].swap_elements(a, b);
|
||||||
self[1].swap_elems(a, b);
|
self[1].swap_elements(a, b);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: Copy> Array2 for Matrix3<S> {
|
|
||||||
type Element = S;
|
|
||||||
type Column = Vector3<S>;
|
|
||||||
type Row = Vector3<S>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn row(&self, r: usize) -> Vector3<S> {
|
|
||||||
Vector3::new(self[0][r],
|
|
||||||
self[1][r],
|
|
||||||
self[2][r])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn swap_rows(&mut self, a: usize, b: usize) {
|
fn swap_columns(&mut self, a: usize, b: usize) {
|
||||||
self[0].swap_elems(a, b);
|
unsafe { ptr::swap(&mut self[a], &mut self[b]) };
|
||||||
self[1].swap_elems(a, b);
|
|
||||||
self[2].swap_elems(a, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: Copy> Array2 for Matrix4<S> {
|
|
||||||
type Element = S;
|
|
||||||
type Column = Vector4<S>;
|
|
||||||
type Row = Vector4<S>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn row(&self, r: usize) -> Vector4<S> {
|
|
||||||
Vector4::new(self[0][r],
|
|
||||||
self[1][r],
|
|
||||||
self[2][r],
|
|
||||||
self[3][r])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn swap_rows(&mut self, a: usize, b: usize) {
|
fn swap_elements(&mut self, a: (usize, usize), b: (usize, usize)) {
|
||||||
self[0].swap_elems(a, b);
|
let (ac, ar) = a;
|
||||||
self[1].swap_elems(a, b);
|
let (bc, br) = b;
|
||||||
self[2].swap_elems(a, b);
|
unsafe { ptr::swap(&mut self[ac][ar], &mut self[bc][br]) };
|
||||||
self[3].swap_elems(a, b);
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn zero() -> Matrix2<S> {
|
||||||
|
Matrix2::new(S::zero(), S::zero(),
|
||||||
|
S::zero(), S::zero())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul_m(&self, other: &Matrix2<S>) -> Matrix2<S> { self * other }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul_v(&self, v: Vector2<S>) -> Vector2<S> { self * v }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul_s(&self, s: S) -> Matrix2<S> { self * s }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div_s(&self, s: S) -> Matrix2<S> { self / s }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul_self_s(&mut self, s: S) {
|
||||||
|
self[0].mul_self_s(s);
|
||||||
|
self[1].mul_self_s(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div_self_s(&mut self, s: S) {
|
||||||
|
self[0].div_self_s(s);
|
||||||
|
self[1].div_self_s(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transpose(&self) -> Matrix2<S> {
|
||||||
|
Matrix2::new(self[0][0], self[1][0],
|
||||||
|
self[0][1], self[1][1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> Matrix for Matrix2<S> {
|
impl<S: BaseFloat> SquareMatrix for Matrix2<S> {
|
||||||
type ColumnRow = Vector2<S>;
|
type ColumnRow = Vector2<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -445,31 +490,17 @@ impl<S: BaseFloat> Matrix for Matrix2<S> {
|
||||||
S::zero(), value.y)
|
S::zero(), value.y)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline] fn mul_s(&self, s: S) -> Matrix2<S> { self * s }
|
|
||||||
#[inline] fn div_s(&self, s: S) -> Matrix2<S> { self / s }
|
|
||||||
#[inline] fn rem_s(&self, s: S) -> Matrix2<S> { self % s }
|
|
||||||
#[inline] fn add_m(&self, m: &Matrix2<S>) -> Matrix2<S> { self + m }
|
|
||||||
#[inline] fn sub_m(&self, m: &Matrix2<S>) -> Matrix2<S> { self - m }
|
|
||||||
fn mul_m(&self, other: &Matrix2<S>) -> Matrix2<S> { self * other }
|
|
||||||
#[inline] fn mul_v(&self, v: Vector2<S>) -> Vector2<S> { self * v }
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_self_s(&mut self, s: S) {
|
fn one() -> Matrix2<S> {
|
||||||
self[0].mul_self_s(s);
|
Matrix2::new(S::one(), S::zero(),
|
||||||
self[1].mul_self_s(s);
|
S::zero(), S::one())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn div_self_s(&mut self, s: S) {
|
fn add_m(&self, m: &Matrix2<S>) -> Matrix2<S> { self + m }
|
||||||
self[0].div_self_s(s);
|
|
||||||
self[1].div_self_s(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rem_self_s(&mut self, s: S) {
|
fn sub_m(&self, m: &Matrix2<S>) -> Matrix2<S> { self - m }
|
||||||
self[0].rem_self_s(s);
|
|
||||||
self[1].rem_self_s(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add_self_m(&mut self, m: &Matrix2<S>) {
|
fn add_self_m(&mut self, m: &Matrix2<S>) {
|
||||||
|
@ -483,14 +514,9 @@ impl<S: BaseFloat> Matrix for Matrix2<S> {
|
||||||
self[1].sub_self_v(m[1]);
|
self[1].sub_self_v(m[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transpose(&self) -> Matrix2<S> {
|
|
||||||
Matrix2::new(self[0][0], self[1][0],
|
|
||||||
self[0][1], self[1][1])
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transpose_self(&mut self) {
|
fn transpose_self(&mut self) {
|
||||||
self.swap_elems((0, 1), (1, 0));
|
self.swap_elements((0, 1), (1, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -530,6 +556,78 @@ impl<S: BaseFloat> Matrix for Matrix2<S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> Matrix for Matrix3<S> {
|
impl<S: BaseFloat> Matrix for Matrix3<S> {
|
||||||
|
type Element = S;
|
||||||
|
type Column = Vector3<S>;
|
||||||
|
type Row = Vector3<S>;
|
||||||
|
type Transpose = Matrix3<S>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn row(&self, r: usize) -> Vector3<S> {
|
||||||
|
Vector3::new(self[0][r],
|
||||||
|
self[1][r],
|
||||||
|
self[2][r])
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn swap_rows(&mut self, a: usize, b: usize) {
|
||||||
|
self[0].swap_elements(a, b);
|
||||||
|
self[1].swap_elements(a, b);
|
||||||
|
self[2].swap_elements(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn swap_columns(&mut self, a: usize, b: usize) {
|
||||||
|
unsafe { ptr::swap(&mut self[a], &mut self[b]) };
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn swap_elements(&mut self, a: (usize, usize), b: (usize, usize)) {
|
||||||
|
let (ac, ar) = a;
|
||||||
|
let (bc, br) = b;
|
||||||
|
unsafe { ptr::swap(&mut self[ac][ar], &mut self[bc][br]) };
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn zero() -> Matrix3<S> {
|
||||||
|
Matrix3::new(S::zero(), S::zero(), S::zero(),
|
||||||
|
S::zero(), S::zero(), S::zero(),
|
||||||
|
S::zero(), S::zero(), S::zero())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul_m(&self, other: &Matrix3<S>) -> Matrix3<S> { self * other }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul_v(&self, v: Vector3<S>) -> Vector3<S> { self * v}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul_s(&self, s: S) -> Matrix3<S> { self * s }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div_s(&self, s: S) -> Matrix3<S> { self / s }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul_self_s(&mut self, s: S) {
|
||||||
|
self[0].mul_self_s(s);
|
||||||
|
self[1].mul_self_s(s);
|
||||||
|
self[2].mul_self_s(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div_self_s(&mut self, s: S) {
|
||||||
|
self[0].div_self_s(s);
|
||||||
|
self[1].div_self_s(s);
|
||||||
|
self[2].div_self_s(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transpose(&self) -> Matrix3<S> {
|
||||||
|
Matrix3::new(self[0][0], self[1][0], self[2][0],
|
||||||
|
self[0][1], self[1][1], self[2][1],
|
||||||
|
self[0][2], self[1][2], self[2][2])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: BaseFloat> SquareMatrix for Matrix3<S> {
|
||||||
type ColumnRow = Vector3<S>;
|
type ColumnRow = Vector3<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -546,34 +644,18 @@ impl<S: BaseFloat> Matrix for Matrix3<S> {
|
||||||
S::zero(), S::zero(), value.z)
|
S::zero(), S::zero(), value.z)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline] fn mul_s(&self, s: S) -> Matrix3<S> { self * s }
|
|
||||||
#[inline] fn div_s(&self, s: S) -> Matrix3<S> { self / s }
|
|
||||||
#[inline] fn rem_s(&self, s: S) -> Matrix3<S> { self % s }
|
|
||||||
#[inline] fn add_m(&self, m: &Matrix3<S>) -> Matrix3<S> { self + m }
|
|
||||||
#[inline] fn sub_m(&self, m: &Matrix3<S>) -> Matrix3<S> { self - m }
|
|
||||||
fn mul_m(&self, other: &Matrix3<S>) -> Matrix3<S> { self * other }
|
|
||||||
#[inline] fn mul_v(&self, v: Vector3<S>) -> Vector3<S> { self * v}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_self_s(&mut self, s: S) {
|
fn one() -> Matrix3<S> {
|
||||||
self[0].mul_self_s(s);
|
Matrix3::new(S::one(), S::zero(), S::zero(),
|
||||||
self[1].mul_self_s(s);
|
S::zero(), S::one(), S::zero(),
|
||||||
self[2].mul_self_s(s);
|
S::zero(), S::zero(), S::one())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn div_self_s(&mut self, s: S) {
|
fn add_m(&self, m: &Matrix3<S>) -> Matrix3<S> { self + m }
|
||||||
self[0].div_self_s(s);
|
|
||||||
self[1].div_self_s(s);
|
|
||||||
self[2].div_self_s(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rem_self_s(&mut self, s: S) {
|
fn sub_m(&self, m: &Matrix3<S>) -> Matrix3<S> { self - m }
|
||||||
self[0].rem_self_s(s);
|
|
||||||
self[1].rem_self_s(s);
|
|
||||||
self[2].rem_self_s(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add_self_m(&mut self, m: &Matrix3<S>) {
|
fn add_self_m(&mut self, m: &Matrix3<S>) {
|
||||||
|
@ -589,17 +671,11 @@ impl<S: BaseFloat> Matrix for Matrix3<S> {
|
||||||
self[2].sub_self_v(m[2]);
|
self[2].sub_self_v(m[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transpose(&self) -> Matrix3<S> {
|
|
||||||
Matrix3::new(self[0][0], self[1][0], self[2][0],
|
|
||||||
self[0][1], self[1][1], self[2][1],
|
|
||||||
self[0][2], self[1][2], self[2][2])
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transpose_self(&mut self) {
|
fn transpose_self(&mut self) {
|
||||||
self.swap_elems((0, 1), (1, 0));
|
self.swap_elements((0, 1), (1, 0));
|
||||||
self.swap_elems((0, 2), (2, 0));
|
self.swap_elements((0, 2), (2, 0));
|
||||||
self.swap_elems((1, 2), (2, 1));
|
self.swap_elements((1, 2), (2, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn determinant(&self) -> S {
|
fn determinant(&self) -> S {
|
||||||
|
@ -648,6 +724,84 @@ impl<S: BaseFloat> Matrix for Matrix3<S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseFloat> Matrix for Matrix4<S> {
|
impl<S: BaseFloat> Matrix for Matrix4<S> {
|
||||||
|
type Element = S;
|
||||||
|
type Column = Vector4<S>;
|
||||||
|
type Row = Vector4<S>;
|
||||||
|
type Transpose = Matrix4<S>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn row(&self, r: usize) -> Vector4<S> {
|
||||||
|
Vector4::new(self[0][r],
|
||||||
|
self[1][r],
|
||||||
|
self[2][r],
|
||||||
|
self[3][r])
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn swap_rows(&mut self, a: usize, b: usize) {
|
||||||
|
self[0].swap_elements(a, b);
|
||||||
|
self[1].swap_elements(a, b);
|
||||||
|
self[2].swap_elements(a, b);
|
||||||
|
self[3].swap_elements(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn swap_columns(&mut self, a: usize, b: usize) {
|
||||||
|
unsafe { ptr::swap(&mut self[a], &mut self[b]) };
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn swap_elements(&mut self, a: (usize, usize), b: (usize, usize)) {
|
||||||
|
let (ac, ar) = a;
|
||||||
|
let (bc, br) = b;
|
||||||
|
unsafe { ptr::swap(&mut self[ac][ar], &mut self[bc][br]) };
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn zero() -> Matrix4<S> {
|
||||||
|
Matrix4::new(S::zero(), S::zero(), S::zero(), S::zero(),
|
||||||
|
S::zero(), S::zero(), S::zero(), S::zero(),
|
||||||
|
S::zero(), S::zero(), S::zero(), S::zero(),
|
||||||
|
S::zero(), S::zero(), S::zero(), S::zero())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul_m(&self, other: &Matrix4<S>) -> Matrix4<S> { self * other }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul_v(&self, v: Vector4<S>) -> Vector4<S> { self * v }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul_s(&self, s: S) -> Matrix4<S> { self * s }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div_s(&self, s: S) -> Matrix4<S> { self / s }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul_self_s(&mut self, s: S) {
|
||||||
|
self[0].mul_self_s(s);
|
||||||
|
self[1].mul_self_s(s);
|
||||||
|
self[2].mul_self_s(s);
|
||||||
|
self[3].mul_self_s(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div_self_s(&mut self, s: S) {
|
||||||
|
self[0].div_self_s(s);
|
||||||
|
self[1].div_self_s(s);
|
||||||
|
self[2].div_self_s(s);
|
||||||
|
self[3].div_self_s(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transpose(&self) -> Matrix4<S> {
|
||||||
|
Matrix4::new(self[0][0], self[1][0], self[2][0], self[3][0],
|
||||||
|
self[0][1], self[1][1], self[2][1], self[3][1],
|
||||||
|
self[0][2], self[1][2], self[2][2], self[3][2],
|
||||||
|
self[0][3], self[1][3], self[2][3], self[3][3])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: BaseFloat> SquareMatrix for Matrix4<S> {
|
||||||
type ColumnRow = Vector4<S>;
|
type ColumnRow = Vector4<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -666,37 +820,19 @@ impl<S: BaseFloat> Matrix for Matrix4<S> {
|
||||||
S::zero(), S::zero(), S::zero(), value.w)
|
S::zero(), S::zero(), S::zero(), value.w)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline] fn mul_s(&self, s: S) -> Matrix4<S> { self * s }
|
|
||||||
#[inline] fn div_s(&self, s: S) -> Matrix4<S> { self / s }
|
|
||||||
#[inline] fn rem_s(&self, s: S) -> Matrix4<S> { self % s }
|
|
||||||
#[inline] fn add_m(&self, m: &Matrix4<S>) -> Matrix4<S> { self + m }
|
|
||||||
#[inline] fn sub_m(&self, m: &Matrix4<S>) -> Matrix4<S> { self - m }
|
|
||||||
fn mul_m(&self, other: &Matrix4<S>) -> Matrix4<S> { self * other }
|
|
||||||
#[inline] fn mul_v(&self, v: Vector4<S>) -> Vector4<S> { self * v }
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_self_s(&mut self, s: S) {
|
fn one() -> Matrix4<S> {
|
||||||
self[0].mul_self_s(s);
|
Matrix4::new(S::one(), S::zero(), S::zero(), S::zero(),
|
||||||
self[1].mul_self_s(s);
|
S::zero(), S::one(), S::zero(), S::zero(),
|
||||||
self[2].mul_self_s(s);
|
S::zero(), S::zero(), S::one(), S::zero(),
|
||||||
self[3].mul_self_s(s);
|
S::zero(), S::zero(), S::zero(), S::one())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn div_self_s(&mut self, s: S) {
|
fn add_m(&self, m: &Matrix4<S>) -> Matrix4<S> { self + m }
|
||||||
self[0].div_self_s(s);
|
|
||||||
self[1].div_self_s(s);
|
|
||||||
self[2].div_self_s(s);
|
|
||||||
self[3].div_self_s(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rem_self_s(&mut self, s: S) {
|
fn sub_m(&self, m: &Matrix4<S>) -> Matrix4<S> { self - m }
|
||||||
self[0].rem_self_s(s);
|
|
||||||
self[1].rem_self_s(s);
|
|
||||||
self[2].rem_self_s(s);
|
|
||||||
self[3].rem_self_s(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add_self_m(&mut self, m: &Matrix4<S>) {
|
fn add_self_m(&mut self, m: &Matrix4<S>) {
|
||||||
|
@ -714,20 +850,13 @@ impl<S: BaseFloat> Matrix for Matrix4<S> {
|
||||||
self[3].sub_self_v(m[3]);
|
self[3].sub_self_v(m[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transpose(&self) -> Matrix4<S> {
|
|
||||||
Matrix4::new(self[0][0], self[1][0], self[2][0], self[3][0],
|
|
||||||
self[0][1], self[1][1], self[2][1], self[3][1],
|
|
||||||
self[0][2], self[1][2], self[2][2], self[3][2],
|
|
||||||
self[0][3], self[1][3], self[2][3], self[3][3])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transpose_self(&mut self) {
|
fn transpose_self(&mut self) {
|
||||||
self.swap_elems((0, 1), (1, 0));
|
self.swap_elements((0, 1), (1, 0));
|
||||||
self.swap_elems((0, 2), (2, 0));
|
self.swap_elements((0, 2), (2, 0));
|
||||||
self.swap_elems((0, 3), (3, 0));
|
self.swap_elements((0, 3), (3, 0));
|
||||||
self.swap_elems((1, 2), (2, 1));
|
self.swap_elements((1, 2), (2, 1));
|
||||||
self.swap_elems((1, 3), (3, 1));
|
self.swap_elements((1, 3), (3, 1));
|
||||||
self.swap_elems((2, 3), (3, 2));
|
self.swap_elements((2, 3), (3, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn determinant(&self) -> S {
|
fn determinant(&self) -> S {
|
||||||
|
@ -852,7 +981,7 @@ impl<S: BaseFloat> ApproxEq for Matrix4<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Neg<Output = S>> Neg for Matrix2<S> {
|
impl<S: BaseFloat> Neg for Matrix2<S> {
|
||||||
type Output = Matrix2<S>;
|
type Output = Matrix2<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -861,7 +990,7 @@ impl<S: Neg<Output = S>> Neg for Matrix2<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Neg<Output = S>> Neg for Matrix3<S> {
|
impl<S: BaseFloat> Neg for Matrix3<S> {
|
||||||
type Output = Matrix3<S>;
|
type Output = Matrix3<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -870,7 +999,7 @@ impl<S: Neg<Output = S>> Neg for Matrix3<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Neg<Output = S>> Neg for Matrix4<S> {
|
impl<S: BaseFloat> Neg for Matrix4<S> {
|
||||||
type Output = Matrix4<S>;
|
type Output = Matrix4<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -881,7 +1010,7 @@ impl<S: Neg<Output = S>> Neg for Matrix4<S> {
|
||||||
|
|
||||||
macro_rules! impl_scalar_binary_operator {
|
macro_rules! impl_scalar_binary_operator {
|
||||||
($Binop:ident :: $binop:ident, $MatrixN:ident { $($field:ident),+ }) => {
|
($Binop:ident :: $binop:ident, $MatrixN:ident { $($field:ident),+ }) => {
|
||||||
impl<'a, S: BaseNum> $Binop<S> for &'a $MatrixN<S> {
|
impl<'a, S: BaseFloat> $Binop<S> for &'a $MatrixN<S> {
|
||||||
type Output = $MatrixN<S>;
|
type Output = $MatrixN<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -904,7 +1033,7 @@ impl_scalar_binary_operator!(Rem::rem, Matrix4 { x, y, z, w });
|
||||||
|
|
||||||
macro_rules! impl_binary_operator {
|
macro_rules! impl_binary_operator {
|
||||||
($Binop:ident :: $binop:ident, $MatrixN:ident { $($field:ident),+ }) => {
|
($Binop:ident :: $binop:ident, $MatrixN:ident { $($field:ident),+ }) => {
|
||||||
impl<'a, 'b, S: BaseNum> $Binop<&'a $MatrixN<S>> for &'b $MatrixN<S> {
|
impl<'a, 'b, S: BaseFloat> $Binop<&'a $MatrixN<S>> for &'b $MatrixN<S> {
|
||||||
type Output = $MatrixN<S>;
|
type Output = $MatrixN<S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -924,7 +1053,7 @@ impl_binary_operator!(Sub::sub, Matrix4 { x, y, z, w });
|
||||||
|
|
||||||
macro_rules! impl_vector_mul_operators {
|
macro_rules! impl_vector_mul_operators {
|
||||||
($MatrixN:ident, $VectorN:ident { $($row_index:expr),+ }) => {
|
($MatrixN:ident, $VectorN:ident { $($row_index:expr),+ }) => {
|
||||||
impl<'a, S: BaseNum> Mul<$VectorN<S>> for &'a $MatrixN<S> {
|
impl<'a, S: BaseFloat> Mul<$VectorN<S>> for &'a $MatrixN<S> {
|
||||||
type Output = $VectorN<S>;
|
type Output = $VectorN<S>;
|
||||||
|
|
||||||
fn mul(self, v: $VectorN<S>) -> $VectorN<S> {
|
fn mul(self, v: $VectorN<S>) -> $VectorN<S> {
|
||||||
|
@ -932,7 +1061,7 @@ macro_rules! impl_vector_mul_operators {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, S: BaseNum> Mul<&'a $VectorN<S>> for &'b $MatrixN<S> {
|
impl<'a, 'b, S: BaseFloat> Mul<&'a $VectorN<S>> for &'b $MatrixN<S> {
|
||||||
type Output = $VectorN<S>;
|
type Output = $VectorN<S>;
|
||||||
|
|
||||||
fn mul(self, v: &'a $VectorN<S>) -> $VectorN<S> {
|
fn mul(self, v: &'a $VectorN<S>) -> $VectorN<S> {
|
||||||
|
@ -946,7 +1075,7 @@ impl_vector_mul_operators!(Matrix2, Vector2 { 0, 1 });
|
||||||
impl_vector_mul_operators!(Matrix3, Vector3 { 0, 1, 2 });
|
impl_vector_mul_operators!(Matrix3, Vector3 { 0, 1, 2 });
|
||||||
impl_vector_mul_operators!(Matrix4, Vector4 { 0, 1, 2, 3 });
|
impl_vector_mul_operators!(Matrix4, Vector4 { 0, 1, 2, 3 });
|
||||||
|
|
||||||
impl<'a, 'b, S: BaseNum> Mul<&'a Matrix2<S>> for &'b Matrix2<S> {
|
impl<'a, 'b, S: BaseFloat> Mul<&'a Matrix2<S>> for &'b Matrix2<S> {
|
||||||
type Output = Matrix2<S>;
|
type Output = Matrix2<S>;
|
||||||
|
|
||||||
fn mul(self, other: &'a Matrix2<S>) -> Matrix2<S> {
|
fn mul(self, other: &'a Matrix2<S>) -> Matrix2<S> {
|
||||||
|
@ -955,7 +1084,7 @@ impl<'a, 'b, S: BaseNum> Mul<&'a Matrix2<S>> for &'b Matrix2<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, S: BaseNum> Mul<&'a Matrix3<S>> for &'b Matrix3<S> {
|
impl<'a, 'b, S: BaseFloat> Mul<&'a Matrix3<S>> for &'b Matrix3<S> {
|
||||||
type Output = Matrix3<S>;
|
type Output = Matrix3<S>;
|
||||||
|
|
||||||
fn mul(self, other: &'a Matrix3<S>) -> Matrix3<S> {
|
fn mul(self, other: &'a Matrix3<S>) -> Matrix3<S> {
|
||||||
|
@ -965,7 +1094,7 @@ impl<'a, 'b, S: BaseNum> Mul<&'a Matrix3<S>> for &'b Matrix3<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, S: BaseNum> Mul<&'a Matrix4<S>> for &'b Matrix4<S> {
|
impl<'a, 'b, S: BaseFloat> Mul<&'a Matrix4<S>> for &'b Matrix4<S> {
|
||||||
type Output = Matrix4<S>;
|
type Output = Matrix4<S>;
|
||||||
|
|
||||||
fn mul(self, other: &'a Matrix4<S>) -> Matrix4<S> {
|
fn mul(self, other: &'a Matrix4<S>) -> Matrix4<S> {
|
||||||
|
|
40
src/point.rs
40
src/point.rs
|
@ -24,7 +24,7 @@ use std::ops::*;
|
||||||
use rust_num::{One, Zero};
|
use rust_num::{One, Zero};
|
||||||
|
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
use array::Array1;
|
use array::Array;
|
||||||
use matrix::Matrix;
|
use matrix::Matrix;
|
||||||
use num::{BaseNum, BaseFloat};
|
use num::{BaseNum, BaseFloat};
|
||||||
use vector::*;
|
use vector::*;
|
||||||
|
@ -68,7 +68,7 @@ impl<S: BaseNum> Point3<S> {
|
||||||
/// Specifies the numeric operations for point types.
|
/// Specifies the numeric operations for point types.
|
||||||
pub trait Point: Copy + Clone where
|
pub trait Point: Copy + Clone where
|
||||||
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
||||||
Self: Array1<Element = <Self as Point>::Scalar>,
|
Self: Array<Element = <Self as Point>::Scalar>,
|
||||||
// FIXME: blocked by rust-lang/rust#20671
|
// FIXME: blocked by rust-lang/rust#20671
|
||||||
//
|
//
|
||||||
// for<'a, 'b> &'a Self: Add<&'b V, Output = Self>,
|
// for<'a, 'b> &'a Self: Add<&'b V, Output = Self>,
|
||||||
|
@ -130,8 +130,24 @@ pub trait Point: Copy + Clone where
|
||||||
fn max(self, p: Self) -> Self;
|
fn max(self, p: Self) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum> Array1 for Point2<S> {
|
impl<S: BaseNum> Array for Point2<S> {
|
||||||
type Element = S;
|
type Element = S;
|
||||||
|
|
||||||
|
fn sum(self) -> S {
|
||||||
|
self.x + self.y
|
||||||
|
}
|
||||||
|
|
||||||
|
fn product(self) -> S {
|
||||||
|
self.x * self.y
|
||||||
|
}
|
||||||
|
|
||||||
|
fn min(self) -> S {
|
||||||
|
self.x.partial_min(self.y)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn max(self) -> S {
|
||||||
|
self.x.partial_max(self.y)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum> Point for Point2<S> {
|
impl<S: BaseNum> Point for Point2<S> {
|
||||||
|
@ -210,8 +226,24 @@ impl<S: BaseFloat> ApproxEq for Point2<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum> Array1 for Point3<S> {
|
impl<S: BaseNum> Array for Point3<S> {
|
||||||
type Element = S;
|
type Element = S;
|
||||||
|
|
||||||
|
fn sum(self) -> S {
|
||||||
|
self.x + self.y + self.z
|
||||||
|
}
|
||||||
|
|
||||||
|
fn product(self) -> S {
|
||||||
|
self.x * self.y * self.z
|
||||||
|
}
|
||||||
|
|
||||||
|
fn min(self) -> S {
|
||||||
|
self.x.partial_min(self.y).partial_min(self.z)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn max(self) -> S {
|
||||||
|
self.x.partial_max(self.y).partial_max(self.z)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum> Point for Point3<S> {
|
impl<S: BaseNum> Point for Point3<S> {
|
||||||
|
|
|
@ -24,7 +24,6 @@ use rust_num::traits::cast;
|
||||||
|
|
||||||
use angle::{Angle, Rad, acos, sin, sin_cos, rad};
|
use angle::{Angle, Rad, acos, sin, sin_cos, rad};
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
use array::Array1;
|
|
||||||
use matrix::{Matrix3, Matrix4};
|
use matrix::{Matrix3, Matrix4};
|
||||||
use num::BaseFloat;
|
use num::BaseFloat;
|
||||||
use point::Point3;
|
use point::Point3;
|
||||||
|
@ -40,10 +39,6 @@ pub struct Quaternion<S> {
|
||||||
pub v: Vector3<S>,
|
pub v: Vector3<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Copy + BaseFloat> Array1 for Quaternion<S> {
|
|
||||||
type Element = S;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: BaseFloat> Quaternion<S> {
|
impl<S: BaseFloat> Quaternion<S> {
|
||||||
/// Construct a new quaternion from one scalar component and three
|
/// Construct a new quaternion from one scalar component and three
|
||||||
/// imaginary components
|
/// imaginary components
|
||||||
|
|
|
@ -15,9 +15,8 @@
|
||||||
|
|
||||||
use angle::{Rad, acos};
|
use angle::{Rad, acos};
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
use matrix::Matrix;
|
use matrix::{Matrix, SquareMatrix};
|
||||||
use matrix::Matrix2;
|
use matrix::{Matrix2, Matrix3};
|
||||||
use matrix::Matrix3;
|
|
||||||
use num::BaseFloat;
|
use num::BaseFloat;
|
||||||
use point::{Point, Point2, Point3};
|
use point::{Point, Point2, Point3};
|
||||||
use quaternion::Quaternion;
|
use quaternion::Quaternion;
|
||||||
|
|
|
@ -88,7 +88,7 @@
|
||||||
//!
|
//!
|
||||||
//! Several other useful methods are provided as well. Vector fields can be
|
//! Several other useful methods are provided as well. Vector fields can be
|
||||||
//! accessed using array syntax (i.e. `vector[0] == vector.x`), or by using
|
//! accessed using array syntax (i.e. `vector[0] == vector.x`), or by using
|
||||||
//! the methods provided by the [`Array1`](../array/trait.Array1.html) trait.
|
//! the methods provided by the [`Array`](../array/trait.Array.html) trait.
|
||||||
//! This trait also provides a `map()` method for applying arbitrary functions.
|
//! This trait also provides a `map()` method for applying arbitrary functions.
|
||||||
//!
|
//!
|
||||||
//! The [`Vector`](../trait.Vector.html) trait presents the most general
|
//! The [`Vector`](../trait.Vector.html) trait presents the most general
|
||||||
|
@ -105,15 +105,15 @@ use rust_num::{NumCast, Zero, One};
|
||||||
|
|
||||||
use angle::{Rad, atan2, acos};
|
use angle::{Rad, atan2, acos};
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
use array::Array1;
|
use array::Array;
|
||||||
use num::{BaseNum, BaseFloat};
|
use num::{BaseNum, BaseFloat, PartialOrd};
|
||||||
|
|
||||||
/// A trait that specifies a range of numeric operations for vectors. Not all
|
/// A trait that specifies a range of numeric operations for vectors. Not all
|
||||||
/// of these make sense from a linear algebra point of view, but are included
|
/// of these make sense from a linear algebra point of view, but are included
|
||||||
/// for pragmatic reasons.
|
/// for pragmatic reasons.
|
||||||
pub trait Vector: Copy + Clone where
|
pub trait Vector: Copy + Clone where
|
||||||
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
||||||
Self: Array1<Element = <Self as Vector>::Scalar>,
|
Self: Array<Element = <Self as Vector>::Scalar>,
|
||||||
// FIXME: blocked by rust-lang/rust#20671
|
// FIXME: blocked by rust-lang/rust#20671
|
||||||
//
|
//
|
||||||
// for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>,
|
// for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>,
|
||||||
|
@ -196,19 +196,8 @@ pub trait Vector: Copy + Clone where
|
||||||
/// Take the remainder of this vector by another, in-place.
|
/// Take the remainder of this vector by another, in-place.
|
||||||
fn rem_self_v(&mut self, v: Self);
|
fn rem_self_v(&mut self, v: Self);
|
||||||
|
|
||||||
/// The sum of the components of the vector.
|
/// Vector dot product
|
||||||
fn sum(self) -> Self::Scalar;
|
fn dot(self, other: Self) -> Self::Scalar;
|
||||||
/// The product of the components of the vector.
|
|
||||||
fn product(self) -> Self::Scalar;
|
|
||||||
|
|
||||||
/// Vector dot product.
|
|
||||||
#[inline]
|
|
||||||
fn dot(self, v: Self) -> Self::Scalar { self.mul_v(v).sum() }
|
|
||||||
|
|
||||||
/// The minimum component of the vector.
|
|
||||||
fn comp_min(self) -> Self::Scalar;
|
|
||||||
/// The maximum component of the vector.
|
|
||||||
fn comp_max(self) -> Self::Scalar;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dot product of two vectors.
|
/// Dot product of two vectors.
|
||||||
|
@ -250,8 +239,13 @@ macro_rules! vec {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Copy> Array1 for $VectorN<S> {
|
impl<S: Copy> Array for $VectorN<S> {
|
||||||
type Element = S;
|
type Element = S;
|
||||||
|
|
||||||
|
#[inline] fn sum(self) -> S where S: Add<Output = S> { fold!(add, { $(self.$field),+ }) }
|
||||||
|
#[inline] fn product(self) -> S where S: Mul<Output = S> { fold!(mul, { $(self.$field),+ }) }
|
||||||
|
#[inline] fn min(self) -> S where S: PartialOrd { fold!(partial_min, { $(self.$field),+ }) }
|
||||||
|
#[inline] fn max(self) -> S where S: PartialOrd { fold!(partial_max, { $(self.$field),+ }) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum> Vector for $VectorN<S> {
|
impl<S: BaseNum> Vector for $VectorN<S> {
|
||||||
|
@ -283,10 +277,7 @@ macro_rules! vec {
|
||||||
#[inline] fn div_self_v(&mut self, v: $VectorN<S>) { *self = &*self / v; }
|
#[inline] fn div_self_v(&mut self, v: $VectorN<S>) { *self = &*self / v; }
|
||||||
#[inline] fn rem_self_v(&mut self, v: $VectorN<S>) { *self = &*self % v; }
|
#[inline] fn rem_self_v(&mut self, v: $VectorN<S>) { *self = &*self % v; }
|
||||||
|
|
||||||
#[inline] fn sum(self) -> S { fold!(add, { $(self.$field),+ }) }
|
#[inline] fn dot(self, other: $VectorN<S>) -> S { (self * other).sum() }
|
||||||
#[inline] fn product(self) -> S { fold!(mul, { $(self.$field),+ }) }
|
|
||||||
#[inline] fn comp_min(self) -> S { fold!(partial_min, { $(self.$field),+ }) }
|
|
||||||
#[inline] fn comp_max(self) -> S { fold!(partial_max, { $(self.$field),+ }) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Neg<Output = S>> Neg for $VectorN<S> {
|
impl<S: Neg<Output = S>> Neg for $VectorN<S> {
|
||||||
|
|
|
@ -63,25 +63,25 @@ fn test_product() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_comp_min() {
|
fn test_min() {
|
||||||
assert_eq!(Vector2::new(1isize, 2isize).comp_min(), 1isize);
|
assert_eq!(Vector2::new(1isize, 2isize).min(), 1isize);
|
||||||
assert_eq!(Vector3::new(1isize, 2isize, 3isize).comp_min(), 1isize);
|
assert_eq!(Vector3::new(1isize, 2isize, 3isize).min(), 1isize);
|
||||||
assert_eq!(Vector4::new(1isize, 2isize, 3isize, 4isize).comp_min(), 1isize);
|
assert_eq!(Vector4::new(1isize, 2isize, 3isize, 4isize).min(), 1isize);
|
||||||
|
|
||||||
assert_eq!(Vector2::new(3.0f64, 4.0f64).comp_min(), 3.0f64);
|
assert_eq!(Vector2::new(3.0f64, 4.0f64).min(), 3.0f64);
|
||||||
assert_eq!(Vector3::new(4.0f64, 5.0f64, 6.0f64).comp_min(), 4.0f64);
|
assert_eq!(Vector3::new(4.0f64, 5.0f64, 6.0f64).min(), 4.0f64);
|
||||||
assert_eq!(Vector4::new(5.0f64, 6.0f64, 7.0f64, 8.0f64).comp_min(), 5.0f64);
|
assert_eq!(Vector4::new(5.0f64, 6.0f64, 7.0f64, 8.0f64).min(), 5.0f64);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_comp_max() {
|
fn test_max() {
|
||||||
assert_eq!(Vector2::new(1isize, 2isize).comp_max(), 2isize);
|
assert_eq!(Vector2::new(1isize, 2isize).max(), 2isize);
|
||||||
assert_eq!(Vector3::new(1isize, 2isize, 3isize).comp_max(), 3isize);
|
assert_eq!(Vector3::new(1isize, 2isize, 3isize).max(), 3isize);
|
||||||
assert_eq!(Vector4::new(1isize, 2isize, 3isize, 4isize).comp_max(), 4isize);
|
assert_eq!(Vector4::new(1isize, 2isize, 3isize, 4isize).max(), 4isize);
|
||||||
|
|
||||||
assert_eq!(Vector2::new(3.0f64, 4.0f64).comp_max(), 4.0f64);
|
assert_eq!(Vector2::new(3.0f64, 4.0f64).max(), 4.0f64);
|
||||||
assert_eq!(Vector3::new(4.0f64, 5.0f64, 6.0f64).comp_max(), 6.0f64);
|
assert_eq!(Vector3::new(4.0f64, 5.0f64, 6.0f64).max(), 6.0f64);
|
||||||
assert_eq!(Vector4::new(5.0f64, 6.0f64, 7.0f64, 8.0f64).comp_max(), 8.0f64);
|
assert_eq!(Vector4::new(5.0f64, 6.0f64, 7.0f64, 8.0f64).max(), 8.0f64);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in a new issue