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
80
src/array.rs
80
src/array.rs
|
@ -13,85 +13,47 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use std::ops::*;
|
||||
|
||||
use num::PartialOrd;
|
||||
|
||||
/// 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
|
||||
Self: Index<usize, Output = <Self as Array1>::Element>,
|
||||
Self: IndexMut<usize, Output = <Self as Array1>::Element>,
|
||||
Self: Index<usize, Output = <Self as Array>::Element>,
|
||||
Self: IndexMut<usize, Output = <Self as Array>::Element>,
|
||||
{
|
||||
type Element: Copy;
|
||||
|
||||
/// 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]
|
||||
}
|
||||
|
||||
/// 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]
|
||||
}
|
||||
|
||||
/// Swap the elements at indices `i` and `j` in-place.
|
||||
#[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
|
||||
unsafe { ptr::swap(&mut self[i], &mut self[j]) };
|
||||
}
|
||||
|
||||
/// Replace an element in the array.
|
||||
#[inline]
|
||||
fn replace_elem(&mut self, i: usize, src: Self::Element) -> Self::Element {
|
||||
mem::replace(&mut self[i], src)
|
||||
}
|
||||
}
|
||||
|
||||
/// A column-major array
|
||||
pub trait Array2 where
|
||||
// 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.
|
||||
fn ptr<'a>(&'a self) -> &'a Self::Element {
|
||||
&self[0][0]
|
||||
}
|
||||
|
||||
/// 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]) };
|
||||
}
|
||||
/// The sum of the elements of the array.
|
||||
fn sum(self) -> Self::Element where Self::Element: Add<Output = <Self as Array>::Element>;
|
||||
|
||||
/// The product of the elements of the array.
|
||||
fn product(self) -> Self::Element where Self::Element: Mul<Output = <Self as Array>::Element>;
|
||||
|
||||
/// The minimum element of the array.
|
||||
fn min(self) -> Self::Element where Self::Element: PartialOrd;
|
||||
|
||||
/// The maximum element of the array.
|
||||
fn max(self) -> Self::Element where Self::Element: PartialOrd;
|
||||
}
|
||||
|
|
523
src/matrix.rs
523
src/matrix.rs
|
@ -18,6 +18,7 @@
|
|||
use std::fmt;
|
||||
use std::mem;
|
||||
use std::ops::*;
|
||||
use std::ptr;
|
||||
|
||||
use rand::{Rand, Rng};
|
||||
|
||||
|
@ -26,7 +27,7 @@ use rust_num::traits::cast;
|
|||
|
||||
use angle::{Rad, sin, cos, sin_cos};
|
||||
use approx::ApproxEq;
|
||||
use array::{Array1, Array2};
|
||||
use array::Array;
|
||||
use num::{BaseFloat, BaseNum};
|
||||
use point::{Point, Point3};
|
||||
use quaternion::Quaternion;
|
||||
|
@ -249,15 +250,12 @@ impl<S: Copy + Neg<Output = S>> Matrix4<S> {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait Matrix where
|
||||
/// A column-major matrix of arbitrary dimensions.
|
||||
pub trait Matrix where
|
||||
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
||||
Self: Array2<
|
||||
Element = <<Self as Matrix>::ColumnRow as Vector>::Scalar,
|
||||
Column = <Self as Matrix>::ColumnRow,
|
||||
Row = <Self as Matrix>::ColumnRow,
|
||||
>,
|
||||
Self: ApproxEq<Epsilon = <<Self as Matrix>::ColumnRow as Vector>::Scalar> + Sized,
|
||||
Self::Element: BaseFloat,
|
||||
Self: Index<usize, Output = <Self as Matrix>::Column>,
|
||||
Self: IndexMut<usize, Output = <Self as Matrix>::Column>,
|
||||
Self: ApproxEq<Epsilon = <Self as Matrix>::Element>,
|
||||
// FIXME: blocked by rust-lang/rust#20671
|
||||
//
|
||||
// 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: Rem<S, Output = Self>,
|
||||
{
|
||||
// FIXME: Will not be needed once equality constraints in where clauses is implemented
|
||||
type ColumnRow: Vector;
|
||||
/// The type of the elements in the matrix.
|
||||
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.
|
||||
fn from_value(value: Self::Element) -> Self;
|
||||
/// Create a matrix from a non-uniform scale
|
||||
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.
|
||||
#[inline]
|
||||
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;
|
||||
fn one() -> Self;
|
||||
|
||||
/// Add this matrix with another matrix, returning the new metrix.
|
||||
#[must_use]
|
||||
fn add_m(&self, m: &Self) -> Self;
|
||||
/// Subtract another matrix from this matrix, returning the new matrix.
|
||||
#[must_use]
|
||||
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.
|
||||
fn add_self_m(&mut self, m: &Self);
|
||||
/// Subtract another matrix from this matrix, in-place.
|
||||
fn sub_self_m(&mut self, m: &Self);
|
||||
|
||||
/// Multiply this matrix by another matrix, in-place.
|
||||
#[inline]
|
||||
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.
|
||||
fn transpose_self(&mut self);
|
||||
/// Take the determinant of this matrix.
|
||||
|
@ -370,10 +409,11 @@ pub trait Matrix where
|
|||
fn is_symmetric(&self) -> bool;
|
||||
}
|
||||
|
||||
impl<S: Copy> Array2 for Matrix2<S> {
|
||||
impl<S: BaseFloat> Matrix for Matrix2<S> {
|
||||
type Element = S;
|
||||
type Column = Vector2<S>;
|
||||
type Row = Vector2<S>;
|
||||
type Transpose = Matrix2<S>;
|
||||
|
||||
#[inline]
|
||||
fn row(&self, r: usize) -> Vector2<S> {
|
||||
|
@ -383,54 +423,59 @@ impl<S: Copy> Array2 for Matrix2<S> {
|
|||
|
||||
#[inline]
|
||||
fn swap_rows(&mut self, a: usize, b: usize) {
|
||||
self[0].swap_elems(a, b);
|
||||
self[1].swap_elems(a, b);
|
||||
self[0].swap_elements(a, b);
|
||||
self[1].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() -> 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: 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]
|
||||
fn swap_rows(&mut self, a: usize, b: usize) {
|
||||
self[0].swap_elems(a, 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]
|
||||
fn swap_rows(&mut self, a: usize, b: usize) {
|
||||
self[0].swap_elems(a, b);
|
||||
self[1].swap_elems(a, b);
|
||||
self[2].swap_elems(a, b);
|
||||
self[3].swap_elems(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> Matrix for Matrix2<S> {
|
||||
impl<S: BaseFloat> SquareMatrix for Matrix2<S> {
|
||||
type ColumnRow = Vector2<S>;
|
||||
|
||||
#[inline]
|
||||
|
@ -445,31 +490,17 @@ impl<S: BaseFloat> Matrix for Matrix2<S> {
|
|||
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]
|
||||
fn mul_self_s(&mut self, s: S) {
|
||||
self[0].mul_self_s(s);
|
||||
self[1].mul_self_s(s);
|
||||
fn one() -> Matrix2<S> {
|
||||
Matrix2::new(S::one(), S::zero(),
|
||||
S::zero(), S::one())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn div_self_s(&mut self, s: S) {
|
||||
self[0].div_self_s(s);
|
||||
self[1].div_self_s(s);
|
||||
}
|
||||
fn add_m(&self, m: &Matrix2<S>) -> Matrix2<S> { self + m }
|
||||
|
||||
#[inline]
|
||||
fn rem_self_s(&mut self, s: S) {
|
||||
self[0].rem_self_s(s);
|
||||
self[1].rem_self_s(s);
|
||||
}
|
||||
fn sub_m(&self, m: &Matrix2<S>) -> Matrix2<S> { self - m }
|
||||
|
||||
#[inline]
|
||||
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]);
|
||||
}
|
||||
|
||||
fn transpose(&self) -> Matrix2<S> {
|
||||
Matrix2::new(self[0][0], self[1][0],
|
||||
self[0][1], self[1][1])
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn transpose_self(&mut self) {
|
||||
self.swap_elems((0, 1), (1, 0));
|
||||
self.swap_elements((0, 1), (1, 0));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -530,6 +556,78 @@ impl<S: BaseFloat> Matrix for Matrix2<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>;
|
||||
|
||||
#[inline]
|
||||
|
@ -546,34 +644,18 @@ impl<S: BaseFloat> Matrix for Matrix3<S> {
|
|||
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]
|
||||
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);
|
||||
fn one() -> Matrix3<S> {
|
||||
Matrix3::new(S::one(), S::zero(), S::zero(),
|
||||
S::zero(), S::one(), S::zero(),
|
||||
S::zero(), S::zero(), S::one())
|
||||
}
|
||||
|
||||
#[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 add_m(&self, m: &Matrix3<S>) -> Matrix3<S> { self + m }
|
||||
|
||||
#[inline]
|
||||
fn rem_self_s(&mut self, s: S) {
|
||||
self[0].rem_self_s(s);
|
||||
self[1].rem_self_s(s);
|
||||
self[2].rem_self_s(s);
|
||||
}
|
||||
fn sub_m(&self, m: &Matrix3<S>) -> Matrix3<S> { self - m }
|
||||
|
||||
#[inline]
|
||||
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]);
|
||||
}
|
||||
|
||||
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]
|
||||
fn transpose_self(&mut self) {
|
||||
self.swap_elems((0, 1), (1, 0));
|
||||
self.swap_elems((0, 2), (2, 0));
|
||||
self.swap_elems((1, 2), (2, 1));
|
||||
self.swap_elements((0, 1), (1, 0));
|
||||
self.swap_elements((0, 2), (2, 0));
|
||||
self.swap_elements((1, 2), (2, 1));
|
||||
}
|
||||
|
||||
fn determinant(&self) -> S {
|
||||
|
@ -648,6 +724,84 @@ impl<S: BaseFloat> Matrix for Matrix3<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>;
|
||||
|
||||
#[inline]
|
||||
|
@ -666,37 +820,19 @@ impl<S: BaseFloat> Matrix for Matrix4<S> {
|
|||
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]
|
||||
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);
|
||||
fn one() -> Matrix4<S> {
|
||||
Matrix4::new(S::one(), S::zero(), S::zero(), S::zero(),
|
||||
S::zero(), S::one(), S::zero(), S::zero(),
|
||||
S::zero(), S::zero(), S::one(), S::zero(),
|
||||
S::zero(), S::zero(), S::zero(), S::one())
|
||||
}
|
||||
|
||||
#[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 add_m(&self, m: &Matrix4<S>) -> Matrix4<S> { self + m }
|
||||
|
||||
#[inline]
|
||||
fn rem_self_s(&mut self, s: S) {
|
||||
self[0].rem_self_s(s);
|
||||
self[1].rem_self_s(s);
|
||||
self[2].rem_self_s(s);
|
||||
self[3].rem_self_s(s);
|
||||
}
|
||||
fn sub_m(&self, m: &Matrix4<S>) -> Matrix4<S> { self - m }
|
||||
|
||||
#[inline]
|
||||
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]);
|
||||
}
|
||||
|
||||
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) {
|
||||
self.swap_elems((0, 1), (1, 0));
|
||||
self.swap_elems((0, 2), (2, 0));
|
||||
self.swap_elems((0, 3), (3, 0));
|
||||
self.swap_elems((1, 2), (2, 1));
|
||||
self.swap_elems((1, 3), (3, 1));
|
||||
self.swap_elems((2, 3), (3, 2));
|
||||
self.swap_elements((0, 1), (1, 0));
|
||||
self.swap_elements((0, 2), (2, 0));
|
||||
self.swap_elements((0, 3), (3, 0));
|
||||
self.swap_elements((1, 2), (2, 1));
|
||||
self.swap_elements((1, 3), (3, 1));
|
||||
self.swap_elements((2, 3), (3, 2));
|
||||
}
|
||||
|
||||
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>;
|
||||
|
||||
#[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>;
|
||||
|
||||
#[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>;
|
||||
|
||||
#[inline]
|
||||
|
@ -881,7 +1010,7 @@ impl<S: Neg<Output = S>> Neg for Matrix4<S> {
|
|||
|
||||
macro_rules! impl_scalar_binary_operator {
|
||||
($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>;
|
||||
|
||||
#[inline]
|
||||
|
@ -904,7 +1033,7 @@ impl_scalar_binary_operator!(Rem::rem, Matrix4 { x, y, z, w });
|
|||
|
||||
macro_rules! impl_binary_operator {
|
||||
($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>;
|
||||
|
||||
#[inline]
|
||||
|
@ -924,7 +1053,7 @@ impl_binary_operator!(Sub::sub, Matrix4 { x, y, z, w });
|
|||
|
||||
macro_rules! impl_vector_mul_operators {
|
||||
($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>;
|
||||
|
||||
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>;
|
||||
|
||||
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!(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>;
|
||||
|
||||
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>;
|
||||
|
||||
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>;
|
||||
|
||||
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 approx::ApproxEq;
|
||||
use array::Array1;
|
||||
use array::Array;
|
||||
use matrix::Matrix;
|
||||
use num::{BaseNum, BaseFloat};
|
||||
use vector::*;
|
||||
|
@ -68,7 +68,7 @@ impl<S: BaseNum> Point3<S> {
|
|||
/// Specifies the numeric operations for point types.
|
||||
pub trait Point: Copy + Clone where
|
||||
// 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
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
impl<S: BaseNum> Array1 for Point2<S> {
|
||||
impl<S: BaseNum> Array for Point2<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> {
|
||||
|
@ -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;
|
||||
|
||||
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> {
|
||||
|
|
|
@ -24,7 +24,6 @@ use rust_num::traits::cast;
|
|||
|
||||
use angle::{Angle, Rad, acos, sin, sin_cos, rad};
|
||||
use approx::ApproxEq;
|
||||
use array::Array1;
|
||||
use matrix::{Matrix3, Matrix4};
|
||||
use num::BaseFloat;
|
||||
use point::Point3;
|
||||
|
@ -40,10 +39,6 @@ pub struct Quaternion<S> {
|
|||
pub v: Vector3<S>,
|
||||
}
|
||||
|
||||
impl<S: Copy + BaseFloat> Array1 for Quaternion<S> {
|
||||
type Element = S;
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> Quaternion<S> {
|
||||
/// Construct a new quaternion from one scalar component and three
|
||||
/// imaginary components
|
||||
|
|
|
@ -15,9 +15,8 @@
|
|||
|
||||
use angle::{Rad, acos};
|
||||
use approx::ApproxEq;
|
||||
use matrix::Matrix;
|
||||
use matrix::Matrix2;
|
||||
use matrix::Matrix3;
|
||||
use matrix::{Matrix, SquareMatrix};
|
||||
use matrix::{Matrix2, Matrix3};
|
||||
use num::BaseFloat;
|
||||
use point::{Point, Point2, Point3};
|
||||
use quaternion::Quaternion;
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
//!
|
||||
//! 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
|
||||
//! 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.
|
||||
//!
|
||||
//! 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 approx::ApproxEq;
|
||||
use array::Array1;
|
||||
use num::{BaseNum, BaseFloat};
|
||||
use array::Array;
|
||||
use num::{BaseNum, BaseFloat, PartialOrd};
|
||||
|
||||
/// 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
|
||||
/// for pragmatic reasons.
|
||||
pub trait Vector: Copy + Clone where
|
||||
// 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
|
||||
//
|
||||
// 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.
|
||||
fn rem_self_v(&mut self, v: Self);
|
||||
|
||||
/// The sum of the components of the vector.
|
||||
fn sum(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;
|
||||
/// Vector dot product
|
||||
fn dot(self, other: Self) -> Self::Scalar;
|
||||
}
|
||||
|
||||
/// 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;
|
||||
|
||||
#[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> {
|
||||
|
@ -283,10 +277,7 @@ macro_rules! vec {
|
|||
#[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 sum(self) -> S { fold!(add, { $(self.$field),+ }) }
|
||||
#[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),+ }) }
|
||||
#[inline] fn dot(self, other: $VectorN<S>) -> S { (self * other).sum() }
|
||||
}
|
||||
|
||||
impl<S: Neg<Output = S>> Neg for $VectorN<S> {
|
||||
|
|
|
@ -63,25 +63,25 @@ fn test_product() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_comp_min() {
|
||||
assert_eq!(Vector2::new(1isize, 2isize).comp_min(), 1isize);
|
||||
assert_eq!(Vector3::new(1isize, 2isize, 3isize).comp_min(), 1isize);
|
||||
assert_eq!(Vector4::new(1isize, 2isize, 3isize, 4isize).comp_min(), 1isize);
|
||||
fn test_min() {
|
||||
assert_eq!(Vector2::new(1isize, 2isize).min(), 1isize);
|
||||
assert_eq!(Vector3::new(1isize, 2isize, 3isize).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!(Vector3::new(4.0f64, 5.0f64, 6.0f64).comp_min(), 4.0f64);
|
||||
assert_eq!(Vector4::new(5.0f64, 6.0f64, 7.0f64, 8.0f64).comp_min(), 5.0f64);
|
||||
assert_eq!(Vector2::new(3.0f64, 4.0f64).min(), 3.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).min(), 5.0f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_comp_max() {
|
||||
assert_eq!(Vector2::new(1isize, 2isize).comp_max(), 2isize);
|
||||
assert_eq!(Vector3::new(1isize, 2isize, 3isize).comp_max(), 3isize);
|
||||
assert_eq!(Vector4::new(1isize, 2isize, 3isize, 4isize).comp_max(), 4isize);
|
||||
fn test_max() {
|
||||
assert_eq!(Vector2::new(1isize, 2isize).max(), 2isize);
|
||||
assert_eq!(Vector3::new(1isize, 2isize, 3isize).max(), 3isize);
|
||||
assert_eq!(Vector4::new(1isize, 2isize, 3isize, 4isize).max(), 4isize);
|
||||
|
||||
assert_eq!(Vector2::new(3.0f64, 4.0f64).comp_max(), 4.0f64);
|
||||
assert_eq!(Vector3::new(4.0f64, 5.0f64, 6.0f64).comp_max(), 6.0f64);
|
||||
assert_eq!(Vector4::new(5.0f64, 6.0f64, 7.0f64, 8.0f64).comp_max(), 8.0f64);
|
||||
assert_eq!(Vector2::new(3.0f64, 4.0f64).max(), 4.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).max(), 8.0f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in a new issue