Add two traits: `CrossMatrix` and `Row`.
CrossMatrix is a trait for vectors having a cross product representable as a matrix. Row is a trait for Matrixces and Vectors, to access (by index) their rows.
This commit is contained in:
parent
4635d6ebac
commit
7052aa88ee
19
src/mat.rs
19
src/mat.rs
|
@ -13,6 +13,7 @@ use traits::transformation::Transform;
|
|||
use traits::homogeneous::{FromHomogeneous, ToHomogeneous};
|
||||
use traits::indexable::Indexable;
|
||||
use traits::column::Column;
|
||||
use traits::row::Row;
|
||||
use traits::iterable::{Iterable, IterableMut};
|
||||
use traits::outer::Outer;
|
||||
use traits::scalar_op::{ScalarAdd, ScalarSub};
|
||||
|
@ -70,7 +71,8 @@ transform_impl!(Mat1, Vec1)
|
|||
// (specialized) inv_impl!(Mat1, 1)
|
||||
transpose_impl!(Mat1, 1)
|
||||
approx_eq_impl!(Mat1)
|
||||
column_impl!(Mat1, 1)
|
||||
column_impl!(Mat1, Vec1, 1)
|
||||
row_impl!(Mat1, Vec1, 1)
|
||||
to_homogeneous_impl!(Mat1, Mat2, 1, 2)
|
||||
from_homogeneous_impl!(Mat1, Mat2, 1, 2)
|
||||
outer_impl!(Vec1, Mat1)
|
||||
|
@ -111,7 +113,8 @@ transform_impl!(Mat2, Vec2)
|
|||
// (specialized) inv_impl!(Mat2, 2)
|
||||
transpose_impl!(Mat2, 2)
|
||||
approx_eq_impl!(Mat2)
|
||||
column_impl!(Mat2, 2)
|
||||
column_impl!(Mat2, Vec2, 2)
|
||||
row_impl!(Mat2, Vec2, 2)
|
||||
to_homogeneous_impl!(Mat2, Mat3, 2, 3)
|
||||
from_homogeneous_impl!(Mat2, Mat3, 2, 3)
|
||||
outer_impl!(Vec2, Mat2)
|
||||
|
@ -162,7 +165,8 @@ transform_impl!(Mat3, Vec3)
|
|||
// (specialized) inv_impl!(Mat3, 3)
|
||||
transpose_impl!(Mat3, 3)
|
||||
approx_eq_impl!(Mat3)
|
||||
column_impl!(Mat3, 3)
|
||||
column_impl!(Mat3, Vec3, 3)
|
||||
// (specialized) row_impl!(Mat3, Vec3, 3)
|
||||
to_homogeneous_impl!(Mat3, Mat4, 3, 4)
|
||||
from_homogeneous_impl!(Mat3, Mat4, 3, 4)
|
||||
outer_impl!(Vec3, Mat3)
|
||||
|
@ -239,7 +243,8 @@ transform_impl!(Mat4, Vec4)
|
|||
inv_impl!(Mat4, 4)
|
||||
transpose_impl!(Mat4, 4)
|
||||
approx_eq_impl!(Mat4)
|
||||
column_impl!(Mat4, 4)
|
||||
column_impl!(Mat4, Vec4, 4)
|
||||
row_impl!(Mat4, Vec4, 4)
|
||||
to_homogeneous_impl!(Mat4, Mat5, 4, 5)
|
||||
from_homogeneous_impl!(Mat4, Mat5, 4, 5)
|
||||
outer_impl!(Vec4, Mat4)
|
||||
|
@ -328,7 +333,8 @@ transform_impl!(Mat5, Vec5)
|
|||
inv_impl!(Mat5, 5)
|
||||
transpose_impl!(Mat5, 5)
|
||||
approx_eq_impl!(Mat5)
|
||||
column_impl!(Mat5, 5)
|
||||
column_impl!(Mat5, Vec5, 5)
|
||||
row_impl!(Mat5, Vec5, 5)
|
||||
to_homogeneous_impl!(Mat5, Mat6, 5, 6)
|
||||
from_homogeneous_impl!(Mat5, Mat6, 5, 6)
|
||||
outer_impl!(Vec5, Mat5)
|
||||
|
@ -427,5 +433,6 @@ transform_impl!(Mat6, Vec6)
|
|||
inv_impl!(Mat6, 6)
|
||||
transpose_impl!(Mat6, 6)
|
||||
approx_eq_impl!(Mat6)
|
||||
column_impl!(Mat6, 6)
|
||||
column_impl!(Mat6, Vec6, 6)
|
||||
row_impl!(Mat6, Vec6, 6)
|
||||
outer_impl!(Vec6, Mat6)
|
||||
|
|
|
@ -183,29 +183,45 @@ macro_rules! indexable_impl(
|
|||
)
|
||||
|
||||
macro_rules! column_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Clone, V: Zero + Iterable<N> + IterableMut<N>> Column<V> for $t<N> {
|
||||
($t: ident, $tv: ident, $dim: expr) => (
|
||||
impl<N: Clone + Zero> Column<$tv<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn set_column(&mut self, col: uint, v: V) {
|
||||
fn set_column(&mut self, col: uint, v: $tv<N>) {
|
||||
for (i, e) in v.iter().enumerate() {
|
||||
if i == Dim::dim::<$t<N>>() {
|
||||
break
|
||||
}
|
||||
|
||||
self.set((i, col), e.clone());
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn column(&self, col: uint) -> V {
|
||||
let mut res = Zero::zero::<V>();
|
||||
fn column(&self, col: uint) -> $tv<N> {
|
||||
let mut res = Zero::zero::<$tv<N>>();
|
||||
|
||||
for (i, e) in res.mut_iter().enumerate() {
|
||||
if i >= Dim::dim::<$t<N>>() {
|
||||
break
|
||||
*e = self.at((i, col));
|
||||
}
|
||||
|
||||
*e = self.at((i, col));
|
||||
res
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! row_impl(
|
||||
($t: ident, $tv: ident, $dim: expr) => (
|
||||
impl<N: Clone + Zero> Row<$tv<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn set_row(&mut self, row: uint, v: $tv<N>) {
|
||||
for (i, e) in v.iter().enumerate() {
|
||||
self.set((row, i), e.clone());
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn row(&self, row: uint) -> $tv<N> {
|
||||
let mut res = Zero::zero::<$tv<N>>();
|
||||
|
||||
for (i, e) in res.mut_iter().enumerate() {
|
||||
*e = self.at((row, i));
|
||||
}
|
||||
|
||||
res
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use std::num::{Zero, One};
|
||||
use vec::Vec3;
|
||||
use mat::{Mat1, Mat2, Mat3};
|
||||
use traits::inv::Inv;
|
||||
use traits::row::Row;
|
||||
|
||||
// some specializations:
|
||||
impl<N: Num + Clone>
|
||||
|
@ -106,3 +108,38 @@ Inv for Mat3<N> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone> Row<Vec3<N>> for Mat3<N> {
|
||||
#[inline]
|
||||
fn row(&self, i: uint) -> Vec3<N> {
|
||||
match i {
|
||||
0 => Vec3::new(self.m11.clone(), self.m12.clone(), self.m13.clone()),
|
||||
1 => Vec3::new(self.m21.clone(), self.m22.clone(), self.m23.clone()),
|
||||
2 => Vec3::new(self.m31.clone(), self.m32.clone(), self.m33.clone()),
|
||||
_ => fail!("Index out of range: 3d matrices do not have " + i.to_str() + " rows.")
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_row(&mut self, i: uint, r: Vec3<N>) {
|
||||
match i {
|
||||
0 => {
|
||||
self.m11 = r.x.clone();
|
||||
self.m12 = r.y.clone();
|
||||
self.m13 = r.z;
|
||||
},
|
||||
1 => {
|
||||
self.m21 = r.x.clone();
|
||||
self.m22 = r.y.clone();
|
||||
self.m23 = r.z;
|
||||
},
|
||||
2 => {
|
||||
self.m31 = r.x.clone();
|
||||
self.m32 = r.y.clone();
|
||||
self.m33 = r.z;
|
||||
},
|
||||
_ => fail!("Index out of range: 3d matrices do not have " + i.to_str() + " rows.")
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ pub mod traits
|
|||
pub mod sample;
|
||||
pub mod indexable;
|
||||
pub mod column;
|
||||
pub mod row;
|
||||
pub mod iterable;
|
||||
pub mod outer;
|
||||
pub mod cross;
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
/**
|
||||
* Trait of elements having a cross product.
|
||||
*/
|
||||
pub trait Cross<Result>
|
||||
{
|
||||
pub trait Cross<V> {
|
||||
/// Computes the cross product between two elements (usually vectors).
|
||||
fn cross(&self, other : &Self) -> Result;
|
||||
fn cross(&self, other: &Self) -> V;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trait of elements having a cross product operation which can be expressed as a matrix.
|
||||
*/
|
||||
pub trait CrossMatrix<M> {
|
||||
/// The matrix associated to any cross product with this vector. I.e. `v.cross(anything)` =
|
||||
/// `v.cross_matrix().rmul(anything)`.
|
||||
fn cross_matrix(&self) -> M;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
/// Traits to access rows of a matrix or vector.
|
||||
pub trait Row<R> {
|
||||
/// Reads the `i`-th row of `self`.
|
||||
fn row(&self, i: uint) -> R;
|
||||
/// Writes the `i`-th row of `self`.
|
||||
fn set_row(&mut self, i: uint, R);
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
use std::num::{Zero, One};
|
||||
use traits::basis::Basis;
|
||||
use traits::cross::Cross;
|
||||
use traits::cross::{Cross, CrossMatrix};
|
||||
use traits::sample::UniformSphereSample;
|
||||
use traits::vec_cast::VecCast;
|
||||
use traits::vector::{AlgebraicVec};
|
||||
use traits::row::Row;
|
||||
use vec::{Vec1, Vec2, Vec3};
|
||||
use mat::Mat3;
|
||||
|
||||
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec1<N>> for Vec2<N> {
|
||||
#[inline]
|
||||
|
@ -13,6 +15,14 @@ impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec1<N>> for Vec2<N> {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: instead of returning a Vec2, define a Mat2x1 matrix?
|
||||
impl<N: Neg<N> + Clone> CrossMatrix<Vec2<N>> for Vec2<N> {
|
||||
#[inline]
|
||||
fn cross_matrix(&self) -> Vec2<N> {
|
||||
Vec2::new(-self.y, self.x.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec3<N>> for Vec3<N> {
|
||||
#[inline]
|
||||
fn cross(&self, other : &Vec3<N>) -> Vec3<N> {
|
||||
|
@ -24,6 +34,39 @@ impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec3<N>> for Vec3<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Neg<N> + Zero + Clone> CrossMatrix<Mat3<N>> for Vec3<N> {
|
||||
#[inline]
|
||||
fn cross_matrix(&self) -> Mat3<N> {
|
||||
Mat3::new(
|
||||
Zero::zero() , -self.z, self.y.clone(),
|
||||
self.z.clone(), Zero::zero(), -self.x,
|
||||
-self.y , self.x.clone(), Zero::zero()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: iplement this for all other vectors
|
||||
impl<N: Clone> Row<Vec1<N>> for Vec2<N> {
|
||||
#[inline]
|
||||
fn row(&self, i: uint) -> Vec1<N> {
|
||||
match i {
|
||||
0 => Vec1::new(self.x.clone()),
|
||||
1 => Vec1::new(self.y.clone()),
|
||||
_ => fail!("Index out of range: 2d vectors do not have " + i.to_str() + " rows.")
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_row(&mut self, i: uint, r: Vec1<N>) {
|
||||
match i {
|
||||
0 => self.x = r.x,
|
||||
1 => self.y = r.x,
|
||||
_ => fail!("Index out of range: 2d vectors do not have " + i.to_str() + " rows.")
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: One> Basis for Vec1<N> {
|
||||
#[inline(always)]
|
||||
fn canonical_basis(f: &fn(Vec1<N>) -> bool) {
|
||||
|
|
Loading…
Reference in New Issue