Merge pull request #114 from bjz/array-stuff

Array stuff
This commit is contained in:
Corey Richardson 2014-08-11 08:16:51 -04:00
commit 4a45bf3b53
5 changed files with 407 additions and 168 deletions

View file

@ -28,30 +28,30 @@ pub trait Array1<Element: Copy>: Index<uint, Element> + IndexMut<uint, Element>
&mut (*self)[0]
}
/// Get a shared reference to the `i`th value.
#[deprecated = "Use index operator instead"]
#[inline]
fn i<'a>(&'a self, i: uint) -> &'a Element {
&(*self)[i]
}
/// Get a mutable reference to the `i`th value.
#[deprecated = "Use index operator instead"]
#[inline]
fn mut_i<'a>(&'a mut self, i: uint) -> &'a mut Element {
&mut (*self)[i]
}
#[deprecated = "Use `Array1::swap_elems` instead"]
#[inline]
/// Swap the elements at indices `i` and `j` in-place.
fn swap_i(&mut self, i: uint, j: uint) {
self.swap_i(i, j)
}
/// Swap the elements at indices `i` and `j` in-place.
#[inline]
fn swap_elems(&mut self, i: uint, j: uint) {
// 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.
#[deprecated = "Use `Array1::replace_elem` instead"]
#[inline]
fn replace_i(&mut self, i: uint, src: Element) -> Element {
self.replace_i(i, src)
}
/// Replace an element in the array.
#[inline]
fn replace_elem(&mut self, i: uint, src: Element) -> Element {
mem::replace(&mut (*self)[i], src)
}
@ -72,55 +72,61 @@ pub trait Array2<Column: Array1<Element>, Row: Array1<Element>, Element: Copy>:
&mut (*self)[0][0]
}
/// Get a shared reference to a column of this array.
#[deprecated = "Use index operator instead"]
/// Swap two columns of this array.
#[deprecated = "Use `Array2::swap_cols` instead"]
#[inline]
fn c<'a>(&'a self, c: uint) -> &'a Column {
&(*self)[c]
}
/// Get a mutable reference to a column of this array.
#[deprecated = "Use index operator instead"]
#[inline]
fn mut_c<'a>(&'a mut self, c: uint) -> &'a mut Column {
&mut (*self)[c]
fn swap_c(&mut self, a: uint, b: uint) {
self.swap_cols(a, b)
}
/// Swap two columns of this array.
#[inline]
fn swap_c(&mut self, a: uint, b: uint) {
fn swap_cols(&mut self, a: uint, b: uint) {
unsafe { ptr::swap(&mut (*self)[a], &mut (*self)[b]) };
}
/// Replace a column in the array.
#[deprecated = "Use `Array2::replace_col` instead"]
#[inline]
fn replace_c(&mut self, c: uint, src: Column) -> Column {
self.replace_col(c, src)
}
/// Replace a column in the array.
#[inline]
fn replace_col(&mut self, c: uint, src: Column) -> Column {
mem::replace(&mut (*self)[c], src)
}
/// Get a row from this array by-value.
fn r(&self, r: uint) -> Row;
/// Swap two rows of this array.
fn swap_r(&mut self, a: uint, b: uint);
/// Return a shared reference to the element at column `c` and row `r`.
#[deprecated = "Use index operators instead"]
#[deprecated = "Use `Array2::row` instead"]
#[inline]
fn cr<'a>(&'a self, c: uint, r: uint) -> &'a Element {
&(*self)[c][r]
fn r(&self, r: uint) -> Row {
self.row(r)
}
/// Return a mutable reference to the element at column `c` and row `r`.
#[deprecated = "Use index operators instead"]
/// Get a row from this array by-value.
fn row(&self, r: uint) -> Row;
#[deprecated = "Use `Array2::swap_rows` instead"]
#[inline]
fn mut_cr<'a>(&'a mut self, c: uint, r: uint) -> &'a mut Element {
&mut (*self)[c][r]
fn swap_r(&mut self, a: uint, b: uint) {
self.swap_rows(a, b)
}
/// Swap two rows of this array.
fn swap_rows(&mut self, a: uint, b: uint);
/// Swap the values at index `a` and `b`
#[deprecated = "Use `Array2::swap_elems` instead"]
#[inline]
fn swap_cr(&mut self, a: (uint, uint), b: (uint, uint)) {
self.swap_elems(a, b)
}
/// Swap the values at index `a` and `b`
#[inline]
fn swap_cr(&mut self, a: (uint, uint), b: (uint, uint)) {
fn swap_elems(&mut self, a: (uint, uint), b: (uint, uint)) {
let (ac, ar) = a;
let (bc, br) = b;
unsafe { ptr::swap(&mut (*self)[ac][ar], &mut (*self)[bc][br]) };
@ -129,3 +135,14 @@ pub trait Array2<Column: Array1<Element>, Row: Array1<Element>, Element: Copy>:
/// Apply a function to each column.
fn map(&mut self, op: |&Column| -> Column) -> Self;
}
/// Homogeneous arrays of elements that can be converted to and from `[T, ..N]`
/// arrays.
pub trait FixedArray<V> {
fn into_fixed(self) -> V;
fn as_fixed<'a>(&'a self) -> &'a V;
fn as_mut_fixed<'a>(&'a mut self) -> &'a mut V;
fn from_fixed(v: V) -> Self;
fn from_fixed_ref<'a>(v: &'a V) -> &'a Self;
fn from_fixed_mut<'a>(v: &'a mut V) -> &'a mut Self;
}

View file

@ -50,12 +50,12 @@ Frustum<S> {
/// Extracts frustum planes from a projection matrix
pub fn from_matrix4(mat: Matrix4<S>) -> Frustum<S> {
Frustum::new(Plane::from_vector4(mat.r(3).add_v(&mat.r(0)).normalize()),
Plane::from_vector4(mat.r(3).sub_v(&mat.r(0)).normalize()),
Plane::from_vector4(mat.r(3).add_v(&mat.r(1)).normalize()),
Plane::from_vector4(mat.r(3).sub_v(&mat.r(1)).normalize()),
Plane::from_vector4(mat.r(3).add_v(&mat.r(2)).normalize()),
Plane::from_vector4(mat.r(3).sub_v(&mat.r(2)).normalize()))
Frustum::new(Plane::from_vector4(mat.row(3).add_v(&mat.row(0)).normalize()),
Plane::from_vector4(mat.row(3).sub_v(&mat.row(0)).normalize()),
Plane::from_vector4(mat.row(3).add_v(&mat.row(1)).normalize()),
Plane::from_vector4(mat.row(3).sub_v(&mat.row(1)).normalize()),
Plane::from_vector4(mat.row(3).add_v(&mat.row(2)).normalize()),
Plane::from_vector4(mat.row(3).sub_v(&mat.row(2)).normalize()))
}
}

View file

@ -21,7 +21,7 @@ use std::num::{Zero, zero, One, one, cast};
use angle::{Rad, sin, cos, sin_cos};
use approx::ApproxEq;
use array::{Array1, Array2};
use array::{Array1, Array2, FixedArray};
use num::{BaseFloat, BaseNum};
use point::{Point, Point3};
use quaternion::{Quaternion, ToQuaternion};
@ -209,7 +209,7 @@ Matrix3<S> {
_1subc * axis.z * axis.z + c)
}
/// Create a matrix from a non-uniform scale
/// 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(),
@ -377,9 +377,9 @@ impl<S: BaseFloat> Sub<Matrix2<S>, Matrix2<S>> for Matrix2<S> { #[inline] fn sub
impl<S: BaseFloat> Sub<Matrix3<S>, Matrix3<S>> for Matrix3<S> { #[inline] fn sub(&self, other: &Matrix3<S>) -> Matrix3<S> { self.sub_m(other) } }
impl<S: BaseFloat> Sub<Matrix4<S>, Matrix4<S>> for Matrix4<S> { #[inline] fn sub(&self, other: &Matrix4<S>) -> Matrix4<S> { self.sub_m(other) } }
impl<S: BaseFloat> Neg<Matrix2<S>> for Matrix2<S> { #[inline] fn neg(&self) -> Matrix2<S> { Matrix2::from_cols(self.c(0).neg(), self.c(1).neg()) } }
impl<S: BaseFloat> Neg<Matrix3<S>> for Matrix3<S> { #[inline] fn neg(&self) -> Matrix3<S> { Matrix3::from_cols(self.c(0).neg(), self.c(1).neg(), self.c(2).neg()) } }
impl<S: BaseFloat> Neg<Matrix4<S>> for Matrix4<S> { #[inline] fn neg(&self) -> Matrix4<S> { Matrix4::from_cols(self.c(0).neg(), self.c(1).neg(), self.c(2).neg(), self.c(3).neg()) } }
impl<S: BaseFloat> Neg<Matrix2<S>> for Matrix2<S> { #[inline] fn neg(&self) -> Matrix2<S> { Matrix2::from_cols(self[0].neg(), self[1].neg()) } }
impl<S: BaseFloat> Neg<Matrix3<S>> for Matrix3<S> { #[inline] fn neg(&self) -> Matrix3<S> { Matrix3::from_cols(self[0].neg(), self[1].neg(), self[2].neg()) } }
impl<S: BaseFloat> Neg<Matrix4<S>> for Matrix4<S> { #[inline] fn neg(&self) -> Matrix4<S> { Matrix4::from_cols(self[0].neg(), self[1].neg(), self[2].neg(), self[3].neg()) } }
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() } }
@ -393,17 +393,74 @@ impl<S: BaseFloat> One for Matrix2<S> { #[inline] fn one() -> Matrix2<S> { Matri
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> FixedArray<[[S, ..2], ..2]> for Matrix2<S> {
#[inline]
fn into_fixed(self) -> [[S, ..2], ..2] {
match self {
Matrix2 { x, y } => [
x.into_fixed(),
y.into_fixed(),
],
}
}
#[inline]
fn as_fixed<'a>(&'a self) -> &'a [[S, ..2], ..2] {
unsafe { mem::transmute(self) }
}
#[inline]
fn as_mut_fixed<'a>(&'a mut self) -> &'a mut [[S, ..2], ..2] {
unsafe { mem::transmute(self) }
}
#[inline]
fn from_fixed(_v: [[S, ..2], ..2]) -> Matrix2<S> {
// match v {
// [x, y] => Matrix2 {
// x: FixedArray::from_fixed(x),
// y: FixedArray::from_fixed(y),
// },
// }
fail!("Unimplemented, pending a fix for rust-lang/rust#16418")
}
#[inline]
fn from_fixed_ref<'a>(v: &'a [[S, ..2], ..2]) -> &'a Matrix2<S> {
unsafe { mem::transmute(v) }
}
#[inline]
fn from_fixed_mut<'a>(v: &'a mut [[S, ..2], ..2]) -> &'a mut Matrix2<S> {
unsafe { mem::transmute(v) }
}
}
impl<S> Index<uint, Vector2<S>> for Matrix2<S> {
#[inline]
fn index<'a>(&'a self, i: &uint) -> &'a Vector2<S> {
FixedArray::from_fixed_ref(&self.as_fixed()[*i])
}
}
impl<S> IndexMut<uint, Vector2<S>> for Matrix2<S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut Vector2<S> {
FixedArray::from_fixed_mut(&mut self.as_mut_fixed()[*i])
}
}
impl<S: Copy> Array2<Vector2<S>, Vector2<S>, S> for Matrix2<S> {
#[inline]
fn r(&self, r: uint) -> Vector2<S> {
fn row(&self, r: uint) -> Vector2<S> {
Vector2::new(self[0][r],
self[1][r])
}
#[inline]
fn swap_r(&mut self, a: uint, b: uint) {
(&mut self[0]).swap_i(a, b);
(&mut self[1]).swap_i(a, b);
fn swap_rows(&mut self, a: uint, b: uint) {
(&mut self[0]).swap_elems(a, b);
(&mut self[1]).swap_elems(a, b);
}
#[inline]
@ -414,35 +471,78 @@ impl<S: Copy> Array2<Vector2<S>, Vector2<S>, S> for Matrix2<S> {
}
}
impl<S: Copy> Index<uint, Vector2<S>> for Matrix2<S> {
impl<S> FixedArray<[[S, ..3], ..3]> for Matrix3<S> {
#[inline]
fn index<'a>(&'a self, c: &uint) -> &'a Vector2<S> {
let slice: &'a [Vector2<S>, ..2] = unsafe { mem::transmute(self) };
&slice[*c]
fn into_fixed(self) -> [[S, ..3], ..3] {
match self {
Matrix3 { x, y, z } => [
x.into_fixed(),
y.into_fixed(),
z.into_fixed(),
],
}
}
#[inline]
fn as_fixed<'a>(&'a self) -> &'a [[S, ..3], ..3] {
unsafe { mem::transmute(self) }
}
#[inline]
fn as_mut_fixed<'a>(&'a mut self) -> &'a mut [[S, ..3], ..3] {
unsafe { mem::transmute(self) }
}
#[inline]
fn from_fixed(_v: [[S, ..3], ..3]) -> Matrix3<S> {
// match v {
// [x, y, z] => Matrix3 {
// x: FixedArray::from_fixed(x),
// y: FixedArray::from_fixed(y),
// z: FixedArray::from_fixed(z),
// },
// }
fail!("Unimplemented, pending a fix for rust-lang/rust#16418")
}
#[inline]
fn from_fixed_ref<'a>(v: &'a [[S, ..3], ..3]) -> &'a Matrix3<S> {
unsafe { mem::transmute(v) }
}
#[inline]
fn from_fixed_mut<'a>(v: &'a mut [[S, ..3], ..3]) -> &'a mut Matrix3<S> {
unsafe { mem::transmute(v) }
}
}
impl<S: Copy> IndexMut<uint, Vector2<S>> for Matrix2<S> {
impl<S> Index<uint, Vector3<S>> for Matrix3<S> {
#[inline]
fn index_mut<'a>(&'a mut self, c: &uint) -> &'a mut Vector2<S> {
let slice: &'a mut [Vector2<S>, ..2] = unsafe { mem::transmute(self) };
&mut slice[*c]
fn index<'a>(&'a self, i: &uint) -> &'a Vector3<S> {
FixedArray::from_fixed_ref(&self.as_fixed()[*i])
}
}
impl<S> IndexMut<uint, Vector3<S>> for Matrix3<S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut Vector3<S> {
FixedArray::from_fixed_mut(&mut self.as_mut_fixed()[*i])
}
}
impl<S: Copy> Array2<Vector3<S>, Vector3<S>, S> for Matrix3<S> {
#[inline]
fn r(&self, r: uint) -> Vector3<S> {
fn row(&self, r: uint) -> Vector3<S> {
Vector3::new(self[0][r],
self[1][r],
self[2][r])
}
#[inline]
fn swap_r(&mut self, a: uint, b: uint) {
(&mut self[0]).swap_i(a, b);
(&mut self[1]).swap_i(a, b);
(&mut self[2]).swap_i(a, b);
fn swap_rows(&mut self, a: uint, b: uint) {
(&mut self[0]).swap_elems(a, b);
(&mut self[1]).swap_elems(a, b);
(&mut self[2]).swap_elems(a, b);
}
#[inline]
@ -454,25 +554,70 @@ impl<S: Copy> Array2<Vector3<S>, Vector3<S>, S> for Matrix3<S> {
}
}
impl<S: Copy> Index<uint, Vector3<S>> for Matrix3<S> {
impl<S> FixedArray<[[S, ..4], ..4]> for Matrix4<S> {
#[inline]
fn index<'a>(&'a self, c: &uint) -> &'a Vector3<S> {
let slice: &'a [Vector3<S>, ..3] = unsafe { mem::transmute(self) };
&slice[*c]
fn into_fixed(self) -> [[S, ..4], ..4] {
match self {
Matrix4 { x, y, z, w } => [
x.into_fixed(),
y.into_fixed(),
z.into_fixed(),
w.into_fixed(),
],
}
}
#[inline]
fn as_fixed<'a>(&'a self) -> &'a [[S, ..4], ..4] {
unsafe { mem::transmute(self) }
}
#[inline]
fn as_mut_fixed<'a>(&'a mut self) -> &'a mut [[S, ..4], ..4] {
unsafe { mem::transmute(self) }
}
#[inline]
fn from_fixed(_v: [[S, ..4], ..4]) -> Matrix4<S> {
// match v {
// [x, y, z, w] => Matrix4 {
// x: FixedArray::from_fixed(x),
// y: FixedArray::from_fixed(y),
// z: FixedArray::from_fixed(z),
// w: FixedArray::from_fixed(w),
// },
// }
fail!("Unimplemented, pending a fix for rust-lang/rust#16418")
}
#[inline]
fn from_fixed_ref<'a>(v: &'a [[S, ..4], ..4]) -> &'a Matrix4<S> {
unsafe { mem::transmute(v) }
}
#[inline]
fn from_fixed_mut<'a>(v: &'a mut [[S, ..4], ..4]) -> &'a mut Matrix4<S> {
unsafe { mem::transmute(v) }
}
}
impl<S: Copy> IndexMut<uint, Vector3<S>> for Matrix3<S> {
impl<S> Index<uint, Vector4<S>> for Matrix4<S> {
#[inline]
fn index_mut<'a>(&'a mut self, c: &uint) -> &'a mut Vector3<S> {
let slice: &'a mut [Vector3<S>, ..3] = unsafe { mem::transmute(self) };
&mut slice[*c]
fn index<'a>(&'a self, i: &uint) -> &'a Vector4<S> {
FixedArray::from_fixed_ref(&self.as_fixed()[*i])
}
}
impl<S> IndexMut<uint, Vector4<S>> for Matrix4<S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut Vector4<S> {
FixedArray::from_fixed_mut(&mut self.as_mut_fixed()[*i])
}
}
impl<S: Copy> Array2<Vector4<S>, Vector4<S>, S> for Matrix4<S> {
#[inline]
fn r(&self, r: uint) -> Vector4<S> {
fn row(&self, r: uint) -> Vector4<S> {
Vector4::new(self[0][r],
self[1][r],
self[2][r],
@ -480,11 +625,11 @@ impl<S: Copy> Array2<Vector4<S>, Vector4<S>, S> for Matrix4<S> {
}
#[inline]
fn swap_r(&mut self, a: uint, b: uint) {
(&mut self[0]).swap_i(a, b);
(&mut self[1]).swap_i(a, b);
(&mut self[2]).swap_i(a, b);
(&mut self[3]).swap_i(a, b);
fn swap_rows(&mut self, a: uint, b: uint) {
(&mut self[0]).swap_elems(a, b);
(&mut self[1]).swap_elems(a, b);
(&mut self[2]).swap_elems(a, b);
(&mut self[3]).swap_elems(a, b);
}
#[inline]
@ -497,22 +642,6 @@ impl<S: Copy> Array2<Vector4<S>, Vector4<S>, S> for Matrix4<S> {
}
}
impl<S: Copy> Index<uint, Vector4<S>> for Matrix4<S> {
#[inline]
fn index<'a>(&'a self, c: &uint) -> &'a Vector4<S> {
let slice: &'a [Vector4<S>, ..4] = unsafe { mem::transmute(self) };
&slice[*c]
}
}
impl<S: Copy> IndexMut<uint, Vector4<S>> for Matrix4<S> {
#[inline]
fn index_mut<'a>(&'a mut self, c: &uint) -> &'a mut Vector4<S> {
let slice: &'a mut [Vector4<S>, ..4] = unsafe { mem::transmute(self) };
&mut slice[*c]
}
}
impl<S: BaseFloat> Matrix<S, Vector2<S>> for Matrix2<S> {
#[inline]
fn mul_s(&self, s: S) -> Matrix2<S> {
@ -546,13 +675,13 @@ impl<S: BaseFloat> Matrix<S, Vector2<S>> for Matrix2<S> {
#[inline]
fn mul_v(&self, v: &Vector2<S>) -> Vector2<S> {
Vector2::new(self.r(0).dot(v),
self.r(1).dot(v))
Vector2::new(self.row(0).dot(v),
self.row(1).dot(v))
}
fn mul_m(&self, other: &Matrix2<S>) -> Matrix2<S> {
Matrix2::new(self.r(0).dot(&other[0]), self.r(1).dot(&other[0]),
self.r(0).dot(&other[1]), self.r(1).dot(&other[1]))
Matrix2::new(self.row(0).dot(&other[0]), self.row(1).dot(&other[0]),
self.row(0).dot(&other[1]), self.row(1).dot(&other[1]))
}
#[inline]
@ -598,7 +727,7 @@ impl<S: BaseFloat> Matrix<S, Vector2<S>> for Matrix2<S> {
#[inline]
fn transpose_self(&mut self) {
self.swap_cr((0, 1), (1, 0));
self.swap_elems((0, 1), (1, 0));
}
#[inline]
@ -675,15 +804,15 @@ impl<S: BaseFloat> Matrix<S, Vector3<S>> for Matrix3<S> {
#[inline]
fn mul_v(&self, v: &Vector3<S>) -> Vector3<S> {
Vector3::new(self.r(0).dot(v),
self.r(1).dot(v),
self.r(2).dot(v))
Vector3::new(self.row(0).dot(v),
self.row(1).dot(v),
self.row(2).dot(v))
}
fn mul_m(&self, other: &Matrix3<S>) -> Matrix3<S> {
Matrix3::new(self.r(0).dot(&other[0]),self.r(1).dot(&other[0]),self.r(2).dot(&other[0]),
self.r(0).dot(&other[1]),self.r(1).dot(&other[1]),self.r(2).dot(&other[1]),
self.r(0).dot(&other[2]),self.r(1).dot(&other[2]),self.r(2).dot(&other[2]))
Matrix3::new(self.row(0).dot(&other[0]),self.row(1).dot(&other[0]),self.row(2).dot(&other[0]),
self.row(0).dot(&other[1]),self.row(1).dot(&other[1]),self.row(2).dot(&other[1]),
self.row(0).dot(&other[2]),self.row(1).dot(&other[2]),self.row(2).dot(&other[2]))
}
#[inline]
@ -736,9 +865,9 @@ impl<S: BaseFloat> Matrix<S, Vector3<S>> for Matrix3<S> {
#[inline]
fn transpose_self(&mut self) {
self.swap_cr((0, 1), (1, 0));
self.swap_cr((0, 2), (2, 0));
self.swap_cr((1, 2), (2, 1));
self.swap_elems((0, 1), (1, 0));
self.swap_elems((0, 2), (2, 0));
self.swap_elems((1, 2), (2, 1));
}
fn determinant(&self) -> S {
@ -786,7 +915,7 @@ impl<S: BaseFloat> Matrix<S, Vector3<S>> for Matrix3<S> {
}
}
// Using self.r(0).dot(other.c(0)) like the other matrix multiplies
// Using self.row(0).dot(other[0]) like the other matrix multiplies
// causes the LLVM to miss identical loads and multiplies. This optimization
// causes the code to be auto vectorized properly increasing the performance
// around ~4 times.
@ -841,10 +970,10 @@ impl<S: BaseFloat> Matrix<S, Vector4<S>> for Matrix4<S> {
#[inline]
fn mul_v(&self, v: &Vector4<S>) -> Vector4<S> {
Vector4::new(self.r(0).dot(v),
self.r(1).dot(v),
self.r(2).dot(v),
self.r(3).dot(v))
Vector4::new(self.row(0).dot(v),
self.row(1).dot(v),
self.row(2).dot(v),
self.row(3).dot(v))
}
fn mul_m(&self, other: &Matrix4<S>) -> Matrix4<S> {
@ -910,12 +1039,12 @@ impl<S: BaseFloat> Matrix<S, Vector4<S>> for Matrix4<S> {
}
fn transpose_self(&mut self) {
self.swap_cr((0, 1), (1, 0));
self.swap_cr((0, 2), (2, 0));
self.swap_cr((0, 3), (3, 0));
self.swap_cr((1, 2), (2, 1));
self.swap_cr((1, 3), (3, 1));
self.swap_cr((2, 3), (3, 2));
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));
}
fn determinant(&self) -> S {

View file

@ -22,7 +22,7 @@ use std::mem;
use std::num::{one, zero};
use approx::ApproxEq;
use array::Array1;
use array::{Array1, FixedArray};
use num::{BaseNum, BaseFloat};
use vector::*;
@ -102,28 +102,59 @@ pub trait Point<S: BaseNum, V: Vector<S>>: Array1<S> + Clone {
fn max(&self, p: &Self) -> Self;
}
impl<S: BaseNum> Array1<S> for Point2<S> {
impl<S> FixedArray<[S, ..2]> for Point2<S> {
#[inline]
fn map(&mut self, op: |S| -> S) -> Point2<S> {
self.x = op(self.x);
self.y = op(self.y);
*self
fn into_fixed(self) -> [S, ..2] {
match self { Point2 { x, y } => [x, y] }
}
#[inline]
fn as_fixed<'a>(&'a self) -> &'a [S, ..2] {
unsafe { mem::transmute(self) }
}
#[inline]
fn as_mut_fixed<'a>(&'a mut self) -> &'a mut [S, ..2] {
unsafe { mem::transmute(self) }
}
#[inline]
fn from_fixed(_v: [S, ..2]) -> Point2<S> {
// match v { [x, y] => Point2 { x: x, y: y } }
fail!("Unimplemented, pending a fix for rust-lang/rust#16418")
}
#[inline]
fn from_fixed_ref<'a>(v: &'a [S, ..2]) -> &'a Point2<S> {
unsafe { mem::transmute(v) }
}
#[inline]
fn from_fixed_mut<'a>(v: &'a mut [S, ..2]) -> &'a mut Point2<S> {
unsafe { mem::transmute(v) }
}
}
impl<S: BaseNum> Index<uint, S> for Point2<S> {
#[inline]
fn index<'a>(&'a self, i: &uint) -> &'a S {
let slice: &[S, ..2] = unsafe { mem::transmute(self) };
&slice[*i]
&self.as_fixed()[*i]
}
}
impl<S: BaseNum> IndexMut<uint, S> for Point2<S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut S {
let slice: &'a mut [S, ..2] = unsafe { mem::transmute(self) };
&mut slice[*i]
&mut self.as_mut_fixed()[*i]
}
}
impl<S: BaseNum> Array1<S> for Point2<S> {
#[inline]
fn map(&mut self, op: |S| -> S) -> Point2<S> {
self.x = op(self.x);
self.y = op(self.y);
*self
}
}
@ -225,6 +256,53 @@ impl<S: BaseFloat> ApproxEq<S> for Point2<S> {
}
}
impl<S> FixedArray<[S, ..3]> for Point3<S> {
#[inline]
fn into_fixed(self) -> [S, ..3] {
match self { Point3 { x, y, z } => [x, y, z] }
}
#[inline]
fn as_fixed<'a>(&'a self) -> &'a [S, ..3] {
unsafe { mem::transmute(self) }
}
#[inline]
fn as_mut_fixed<'a>(&'a mut self) -> &'a mut [S, ..3] {
unsafe { mem::transmute(self) }
}
#[inline]
fn from_fixed(_v: [S, ..3]) -> Point3<S> {
// match v { [x, y, z] => Point3 { x: x, y: y, z: z } }
fail!("Unimplemented, pending a fix for rust-lang/rust#16418")
}
#[inline]
fn from_fixed_ref<'a>(v: &'a [S, ..3]) -> &'a Point3<S> {
unsafe { mem::transmute(v) }
}
#[inline]
fn from_fixed_mut<'a>(v: &'a mut [S, ..3]) -> &'a mut Point3<S> {
unsafe { mem::transmute(v) }
}
}
impl<S: BaseNum> Index<uint, S> for Point3<S> {
#[inline]
fn index<'a>(&'a self, i: &uint) -> &'a S {
&self.as_fixed()[*i]
}
}
impl<S: BaseNum> IndexMut<uint, S> for Point3<S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut S {
&mut self.as_mut_fixed()[*i]
}
}
impl<S: BaseNum> Array1<S> for Point3<S> {
#[inline]
fn map(&mut self, op: |S| -> S) -> Point3<S> {
@ -235,22 +313,6 @@ impl<S: BaseNum> Array1<S> for Point3<S> {
}
}
impl<S: BaseNum> Index<uint, S> for Point3<S> {
#[inline]
fn index<'a>(&'a self, i: &uint) -> &'a S {
let slice: &[S, ..3] = unsafe { mem::transmute(self) };
&slice[*i]
}
}
impl<S: BaseNum> IndexMut<uint, S> for Point3<S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut S {
let slice: &'a mut [S, ..3] = unsafe { mem::transmute(self) };
&mut slice[*i]
}
}
impl<S: BaseNum> Point<S, Vector3<S>> for Point3<S> {
#[inline]
fn origin() -> Point3<S> {

View file

@ -105,7 +105,7 @@ use std::num::{Zero, zero, One, one};
use angle::{Rad, atan2, acos};
use approx::ApproxEq;
use array::Array1;
use array::{Array1, FixedArray};
use num::{BaseNum, BaseFloat};
/// A trait that specifies a range of numeric operations for vectors. Not all
@ -212,9 +212,56 @@ macro_rules! vec(
pub fn ident() -> $Self<$S> { $Self::from_value(one()) }
}
impl<S: Copy> Array1<S> for $Self<S> {
impl<$S> FixedArray<[$S, ..$n]> for $Self<$S> {
#[inline]
fn map(&mut self, op: |S| -> S) -> $Self<S> {
fn into_fixed(self) -> [$S, ..$n] {
match self { $Self { $($field),+ } => [$($field),+] }
}
#[inline]
fn as_fixed<'a>(&'a self) -> &'a [$S, ..$n] {
unsafe { mem::transmute(self) }
}
#[inline]
fn as_mut_fixed<'a>(&'a mut self) -> &'a mut [$S, ..$n] {
unsafe { mem::transmute(self) }
}
#[inline]
fn from_fixed(_v: [$S, ..$n]) -> $Self<$S> {
// match v { [$($field),+] => $Self { $($field: $field),+ } }
fail!("Unimplemented, pending a fix for rust-lang/rust#16418")
}
#[inline]
fn from_fixed_ref<'a>(v: &'a [$S, ..$n]) -> &'a $Self<$S> {
unsafe { mem::transmute(v) }
}
#[inline]
fn from_fixed_mut<'a>(v: &'a mut [$S, ..$n]) -> &'a mut $Self<$S> {
unsafe { mem::transmute(v) }
}
}
impl<$S: Copy> Index<uint, S> for $Self<$S> {
#[inline]
fn index<'a>(&'a self, i: &uint) -> &'a $S {
&self.as_fixed()[*i]
}
}
impl<$S: Copy> IndexMut<uint, S> for $Self<$S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut $S {
&mut self.as_mut_fixed()[*i]
}
}
impl<$S: Copy> Array1<$S> for $Self<$S> {
#[inline]
fn map(&mut self, op: |$S| -> $S) -> $Self<$S> {
$(self.$field = op(self.$field);)+ *self
}
}
@ -285,22 +332,6 @@ macro_rules! vec(
#[inline] fn one() -> $Self<S> { $Self::from_value(one()) }
}
impl<S: Copy> Index<uint, S> for $Self<S> {
#[inline]
fn index<'a>(&'a self, i: &uint) -> &'a S {
let slice: &[S, ..$n] = unsafe { mem::transmute(self) };
&slice[*i]
}
}
impl<S: Copy> IndexMut<uint, S> for $Self<S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut S {
let slice: &'a mut [S, ..$n] = unsafe { mem::transmute(self) };
&mut slice[*i]
}
}
impl<S: BaseFloat> ApproxEq<S> for $Self<S> {
#[inline]
fn approx_eq_eps(&self, other: &$Self<S>, epsilon: &S) -> bool {