Remove dimensional HOFs
This commit is contained in:
parent
c91b0747b3
commit
288afe0898
6 changed files with 998 additions and 404 deletions
|
@ -43,150 +43,6 @@ macro_rules! impl_dimensional(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! impl_dimensional_fns(
|
|
||||||
($Self:ident, $T:ty, 2) => (
|
|
||||||
impl<T> $Self<T> {
|
|
||||||
#[inline]
|
|
||||||
pub fn from_slice<'a>(slice: [$T,..2]) -> $Self<T> {
|
|
||||||
use std::cast::transmute;
|
|
||||||
unsafe { transmute(slice) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn map<U>(&self, f: &fn(&$T) -> U) -> [U,..2] {
|
|
||||||
[f(self.index(0)),
|
|
||||||
f(self.index(1))]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn map_mut(&mut self, f: &fn(&mut $T)) {
|
|
||||||
f(self.index_mut(0));
|
|
||||||
f(self.index_mut(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn zip<U, SU: Dimensional<U,[U,..2]>, V>(&self, other: &SU, f: &fn(&$T, &U) -> V) -> [V,..2] {
|
|
||||||
[f(self.index(0), other.index(0)),
|
|
||||||
f(self.index(1), other.index(1))]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn zip_mut<U, SU: Dimensional<U,[U,..2]>>(&mut self, other: &SU, f: &fn(&mut $T, &U)) {
|
|
||||||
f(self.index_mut(0), other.index(0));
|
|
||||||
f(self.index_mut(1), other.index(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn foldl<U>(&self, init: &U, f: &fn(&$T, &U) -> U) -> U {
|
|
||||||
f(self.index(0), &f(self.index(1), init))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn foldr<U>(&self, init: &U, f: &fn(&$T, &U) -> U) -> U {
|
|
||||||
f(self.index(1), &f(self.index(0), init))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
($Self:ident, $T:ty, 3) => (
|
|
||||||
impl<T> $Self<T> {
|
|
||||||
#[inline]
|
|
||||||
pub fn from_slice<'a>(slice: [$T,..3]) -> $Self<T> {
|
|
||||||
use std::cast::transmute;
|
|
||||||
unsafe { transmute(slice) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn map<U>(&self, f: &fn(&$T) -> U) -> [U,..3] {
|
|
||||||
[f(self.index(0)),
|
|
||||||
f(self.index(1)),
|
|
||||||
f(self.index(2))]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn map_mut(&mut self, f: &fn(&mut $T)) {
|
|
||||||
f(self.index_mut(0));
|
|
||||||
f(self.index_mut(1));
|
|
||||||
f(self.index_mut(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn zip<U, SU: Dimensional<U,[U,..3]>, V>(&self, other: &SU, f: &fn(&$T, &U) -> V) -> [V,..3] {
|
|
||||||
[f(self.index(0), other.index(0)),
|
|
||||||
f(self.index(1), other.index(1)),
|
|
||||||
f(self.index(2), other.index(2))]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn zip_mut<U, SU: Dimensional<U,[U,..3]>>(&mut self, other: &SU, f: &fn(&mut $T, &U)) {
|
|
||||||
f(self.index_mut(0), other.index(0));
|
|
||||||
f(self.index_mut(1), other.index(1));
|
|
||||||
f(self.index_mut(2), other.index(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn foldl<U>(&self, init: &U, f: &fn(&$T, &U) -> U) -> U {
|
|
||||||
f(self.index(0), &f(self.index(1), &f(self.index(2), init)))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn foldr<U>(&self, init: &U, f: &fn(&$T, &U) -> U) -> U {
|
|
||||||
f(self.index(2), &f(self.index(1), &f(self.index(0), init)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
($Self:ident, $T:ty, 4) => (
|
|
||||||
impl<T> $Self<T> {
|
|
||||||
#[inline]
|
|
||||||
pub fn from_slice<'a>(slice: [$T,..4]) -> $Self<T> {
|
|
||||||
use std::cast::transmute;
|
|
||||||
unsafe { transmute(slice) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn map<U>(&self, f: &fn(&$T) -> U) -> [U,..4] {
|
|
||||||
[f(self.index(0)),
|
|
||||||
f(self.index(1)),
|
|
||||||
f(self.index(2)),
|
|
||||||
f(self.index(3))]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn map_mut(&mut self, f: &fn(&mut $T)) {
|
|
||||||
f(self.index_mut(0));
|
|
||||||
f(self.index_mut(1));
|
|
||||||
f(self.index_mut(2));
|
|
||||||
f(self.index_mut(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn zip<U, SU: Dimensional<U,[U,..4]>, V>(&self, other: &SU, f: &fn(&$T, &U) -> V) -> [V,..4] {
|
|
||||||
[f(self.index(0), other.index(0)),
|
|
||||||
f(self.index(1), other.index(1)),
|
|
||||||
f(self.index(2), other.index(2)),
|
|
||||||
f(self.index(3), other.index(3))]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn zip_mut<U, SU: Dimensional<U,[U,..4]>>(&mut self, other: &SU, f: &fn(&mut $T, &U)) {
|
|
||||||
f(self.index_mut(0), other.index(0));
|
|
||||||
f(self.index_mut(1), other.index(1));
|
|
||||||
f(self.index_mut(2), other.index(2));
|
|
||||||
f(self.index_mut(3), other.index(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn foldl<U>(&self, init: &U, f: &fn(&$T, &U) -> U) -> U {
|
|
||||||
f(self.index(0), &f(self.index(1), &f(self.index(2), &f(self.index(3), init))))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn foldr<U>(&self, init: &U, f: &fn(&$T, &U) -> U) -> U {
|
|
||||||
f(self.index(3), &f(self.index(2), &f(self.index(1), &f(self.index(0), init))))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
macro_rules! impl_swap(
|
macro_rules! impl_swap(
|
||||||
($Self:ident) => (
|
($Self:ident) => (
|
||||||
impl<T:Clone> $Self<T> {
|
impl<T:Clone> $Self<T> {
|
||||||
|
@ -201,7 +57,7 @@ macro_rules! impl_swap(
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! impl_approx(
|
macro_rules! impl_approx(
|
||||||
($Self:ident) => (
|
($Self:ident, 2) => (
|
||||||
impl<T:Clone + Eq + ApproxEq<T>> ApproxEq<T> for $Self<T> {
|
impl<T:Clone + Eq + ApproxEq<T>> ApproxEq<T> for $Self<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn approx_epsilon() -> T {
|
pub fn approx_epsilon() -> T {
|
||||||
|
@ -215,8 +71,49 @@ macro_rules! impl_approx(
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn approx_eq_eps(&self, other: &$Self<T>, epsilon: &T) -> bool {
|
pub fn approx_eq_eps(&self, other: &$Self<T>, epsilon: &T) -> bool {
|
||||||
let tmp = self.zip(other, |a, b| a.approx_eq_eps(b, epsilon));
|
self.index(0).approx_eq_eps(other.index(0), epsilon) &&
|
||||||
tmp.iter().all(|&x| x)
|
self.index(1).approx_eq_eps(other.index(1), epsilon)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
($Self:ident, 3) => (
|
||||||
|
impl<T:Clone + Eq + ApproxEq<T>> ApproxEq<T> for $Self<T> {
|
||||||
|
#[inline]
|
||||||
|
pub fn approx_epsilon() -> T {
|
||||||
|
ApproxEq::approx_epsilon::<T,T>()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn approx_eq(&self, other: &$Self<T>) -> bool {
|
||||||
|
self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<T,T>())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn approx_eq_eps(&self, other: &$Self<T>, epsilon: &T) -> bool {
|
||||||
|
self.index(0).approx_eq_eps(other.index(0), epsilon) &&
|
||||||
|
self.index(1).approx_eq_eps(other.index(1), epsilon) &&
|
||||||
|
self.index(2).approx_eq_eps(other.index(2), epsilon)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
($Self:ident, 4) => (
|
||||||
|
impl<T:Clone + Eq + ApproxEq<T>> ApproxEq<T> for $Self<T> {
|
||||||
|
#[inline]
|
||||||
|
pub fn approx_epsilon() -> T {
|
||||||
|
ApproxEq::approx_epsilon::<T,T>()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn approx_eq(&self, other: &$Self<T>) -> bool {
|
||||||
|
self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<T,T>())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn approx_eq_eps(&self, other: &$Self<T>, epsilon: &T) -> bool {
|
||||||
|
self.index(0).approx_eq_eps(other.index(0), epsilon) &&
|
||||||
|
self.index(1).approx_eq_eps(other.index(1), epsilon) &&
|
||||||
|
self.index(2).approx_eq_eps(other.index(2), epsilon) &&
|
||||||
|
self.index(3).approx_eq_eps(other.index(3), epsilon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
207
src/mat.rs
207
src/mat.rs
|
@ -47,14 +47,9 @@ macro_rules! impl_mat(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! impl_mat_clonable(
|
macro_rules! impl_mat_swap(
|
||||||
($Mat:ident, $Vec:ident) => (
|
($Mat:ident, $Vec:ident) => (
|
||||||
impl<T:Clone> $Mat<T> {
|
impl<T:Clone> $Mat<T> {
|
||||||
#[inline]
|
|
||||||
pub fn row(&self, i: uint) -> $Vec<T> {
|
|
||||||
$Vec::from_slice(self.map(|c| c.index(i).clone()))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn swap_cols(&mut self, a: uint, b: uint) {
|
pub fn swap_cols(&mut self, a: uint, b: uint) {
|
||||||
let tmp = self.col(a).clone();
|
let tmp = self.col(a).clone();
|
||||||
|
@ -62,11 +57,6 @@ macro_rules! impl_mat_clonable(
|
||||||
*self.col_mut(b) = tmp;
|
*self.col_mut(b) = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn swap_rows(&mut self, a: uint, b: uint) {
|
|
||||||
self.map_mut(|x| x.swap(a, b))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn swap_elem(&mut self, (col_a, row_a): (uint, uint), (col_b, row_b): (uint, uint)) {
|
pub fn swap_elem(&mut self, (col_a, row_a): (uint, uint), (col_b, row_b): (uint, uint)) {
|
||||||
let tmp = self.elem(col_a, row_a).clone();
|
let tmp = self.elem(col_a, row_a).clone();
|
||||||
|
@ -136,11 +126,10 @@ pub type Mat2f32 = Mat2<f32>;
|
||||||
pub type Mat2f64 = Mat2<f64>;
|
pub type Mat2f64 = Mat2<f64>;
|
||||||
|
|
||||||
impl_dimensional!(Mat2, Vec2<T>, 2)
|
impl_dimensional!(Mat2, Vec2<T>, 2)
|
||||||
impl_dimensional_fns!(Mat2, Vec2<T>, 2)
|
impl_approx!(Mat2, 2)
|
||||||
impl_approx!(Mat2)
|
|
||||||
|
|
||||||
impl_mat!(Mat2, Vec2)
|
impl_mat!(Mat2, Vec2)
|
||||||
impl_mat_clonable!(Mat2, Vec2)
|
impl_mat_swap!(Mat2, Vec2)
|
||||||
|
|
||||||
pub trait ToMat2<T> {
|
pub trait ToMat2<T> {
|
||||||
pub fn to_mat2(&self) -> Mat2<T>;
|
pub fn to_mat2(&self) -> Mat2<T>;
|
||||||
|
@ -161,6 +150,20 @@ impl<T> Mat2<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T:Clone> Mat2<T> {
|
||||||
|
#[inline]
|
||||||
|
pub fn row(&self, i: uint) -> Vec2<T> {
|
||||||
|
Vec2::new(self.col(0).index(i).clone(),
|
||||||
|
self.col(1).index(i).clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn swap_rows(&mut self, a: uint, b: uint) {
|
||||||
|
self.col_mut(0).swap(a, b);
|
||||||
|
self.col_mut(1).swap(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T:Clone + Num> ToMat3<T> for Mat2<T> {
|
impl<T:Clone + Num> ToMat3<T> for Mat2<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_mat3(&self) -> Mat3<T> {
|
pub fn to_mat3(&self) -> Mat3<T> {
|
||||||
|
@ -195,7 +198,8 @@ impl<T:Clone + Num> Mat2<T> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mul_t(&self, value: T) -> Mat2<T> {
|
pub fn mul_t(&self, value: T) -> Mat2<T> {
|
||||||
Mat2::from_slice(self.map(|&c| c.mul_t(value.clone())))
|
Mat2::from_cols(self.col(0).mul_t(value.clone()),
|
||||||
|
self.col(1).mul_t(value.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -204,6 +208,18 @@ impl<T:Clone + Num> Mat2<T> {
|
||||||
self.row(1).dot(vec))
|
self.row(1).dot(vec))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn add_m(&self, other: &Mat2<T>) -> Mat2<T> {
|
||||||
|
Mat2::from_cols(self.col(0).add_v(other.col(0)),
|
||||||
|
self.col(1).add_v(other.col(1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn sub_m(&self, other: &Mat2<T>) -> Mat2<T> {
|
||||||
|
Mat2::from_cols(self.col(0).sub_v(other.col(0)),
|
||||||
|
self.col(1).sub_v(other.col(1)))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mul_m(&self, other: &Mat2<T>) -> Mat2<T> {
|
pub fn mul_m(&self, other: &Mat2<T>) -> Mat2<T> {
|
||||||
Mat2::new(self.row(0).dot(other.col(0)),
|
Mat2::new(self.row(0).dot(other.col(0)),
|
||||||
|
@ -213,29 +229,22 @@ impl<T:Clone + Num> Mat2<T> {
|
||||||
self.row(1).dot(other.col(1)))
|
self.row(1).dot(other.col(1)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn add_m(&self, other: &Mat2<T>) -> Mat2<T> {
|
|
||||||
Mat2::from_slice(self.zip(other, |a, b| a.add_v(b)))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn sub_m(&self, other: &Mat2<T>) -> Mat2<T> {
|
|
||||||
Mat2::from_slice(self.zip(other, |a, b| a.sub_v(b)))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mul_self_t(&mut self, value: T) {
|
pub fn mul_self_t(&mut self, value: T) {
|
||||||
self.map_mut(|x| x.mul_self_t(value.clone()))
|
self.col_mut(0).mul_self_t(value.clone());
|
||||||
|
self.col_mut(1).mul_self_t(value.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn add_self_m(&mut self, other: &Mat2<T>) {
|
pub fn add_self_m(&mut self, other: &Mat2<T>) {
|
||||||
self.zip_mut(other, |a, b| a.add_self_v(b))
|
self.col_mut(0).add_self_v(other.col(0));
|
||||||
|
self.col_mut(1).add_self_v(other.col(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sub_self_m(&mut self, other: &Mat2<T>) {
|
pub fn sub_self_m(&mut self, other: &Mat2<T>) {
|
||||||
self.zip_mut(other, |a, b| a.sub_self_v(b))
|
self.col_mut(0).sub_self_v(other.col(0));
|
||||||
|
self.col_mut(1).sub_self_v(other.col(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dot(&self, other: &Mat2<T>) -> T {
|
pub fn dot(&self, other: &Mat2<T>) -> T {
|
||||||
|
@ -264,7 +273,8 @@ impl<T:Clone + Num> Mat2<T> {
|
||||||
impl<T:Clone + Num> Neg<Mat2<T>> for Mat2<T> {
|
impl<T:Clone + Num> Neg<Mat2<T>> for Mat2<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn neg(&self) -> Mat2<T> {
|
pub fn neg(&self) -> Mat2<T> {
|
||||||
Mat2::from_slice(self.map(|&x| -x))
|
Mat2::from_cols(-*self.col(0),
|
||||||
|
-*self.col(1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,11 +539,10 @@ pub type Mat3f32 = Mat3<f32>;
|
||||||
pub type Mat3f64 = Mat3<f64>;
|
pub type Mat3f64 = Mat3<f64>;
|
||||||
|
|
||||||
impl_dimensional!(Mat3, Vec3<T>, 3)
|
impl_dimensional!(Mat3, Vec3<T>, 3)
|
||||||
impl_dimensional_fns!(Mat3, Vec3<T>, 3)
|
impl_approx!(Mat3, 3)
|
||||||
impl_approx!(Mat3)
|
|
||||||
|
|
||||||
impl_mat!(Mat3, Vec3)
|
impl_mat!(Mat3, Vec3)
|
||||||
impl_mat_clonable!(Mat3, Vec3)
|
impl_mat_swap!(Mat3, Vec3)
|
||||||
|
|
||||||
pub trait ToMat3<T> {
|
pub trait ToMat3<T> {
|
||||||
pub fn to_mat3(&self) -> Mat3<T>;
|
pub fn to_mat3(&self) -> Mat3<T>;
|
||||||
|
@ -557,6 +566,22 @@ impl<T> Mat3<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T:Clone> Mat3<T> {
|
||||||
|
#[inline]
|
||||||
|
pub fn row(&self, i: uint) -> Vec3<T> {
|
||||||
|
Vec3::new(self.col(0).index(i).clone(),
|
||||||
|
self.col(1).index(i).clone(),
|
||||||
|
self.col(2).index(i).clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn swap_rows(&mut self, a: uint, b: uint) {
|
||||||
|
self.col_mut(0).swap(a, b);
|
||||||
|
self.col_mut(1).swap(a, b);
|
||||||
|
self.col_mut(2).swap(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T:Clone + Num> ToMat4<T> for Mat3<T> {
|
impl<T:Clone + Num> ToMat4<T> for Mat3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_mat4(&self) -> Mat4<T> {
|
pub fn to_mat4(&self) -> Mat4<T> {
|
||||||
|
@ -583,7 +608,9 @@ impl<T:Clone + Num> Mat3<T> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mul_t(&self, value: T) -> Mat3<T> {
|
pub fn mul_t(&self, value: T) -> Mat3<T> {
|
||||||
Mat3::from_slice(self.map(|&c| c.mul_t(value.clone())))
|
Mat3::from_cols(self.col(0).mul_t(value.clone()),
|
||||||
|
self.col(1).mul_t(value.clone()),
|
||||||
|
self.col(2).mul_t(value.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -593,6 +620,20 @@ impl<T:Clone + Num> Mat3<T> {
|
||||||
self.row(2).dot(vec))
|
self.row(2).dot(vec))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn add_m(&self, other: &Mat3<T>) -> Mat3<T> {
|
||||||
|
Mat3::from_cols(self.col(0).add_v(other.col(0)),
|
||||||
|
self.col(1).add_v(other.col(1)),
|
||||||
|
self.col(2).add_v(other.col(2)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn sub_m(&self, other: &Mat3<T>) -> Mat3<T> {
|
||||||
|
Mat3::from_cols(self.col(0).sub_v(other.col(0)),
|
||||||
|
self.col(1).sub_v(other.col(1)),
|
||||||
|
self.col(2).sub_v(other.col(2)))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mul_m(&self, other: &Mat3<T>) -> Mat3<T> {
|
pub fn mul_m(&self, other: &Mat3<T>) -> Mat3<T> {
|
||||||
Mat3::new(self.row(0).dot(other.col(0)),
|
Mat3::new(self.row(0).dot(other.col(0)),
|
||||||
|
@ -608,29 +649,25 @@ impl<T:Clone + Num> Mat3<T> {
|
||||||
self.row(2).dot(other.col(2)))
|
self.row(2).dot(other.col(2)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn add_m(&self, other: &Mat3<T>) -> Mat3<T> {
|
|
||||||
Mat3::from_slice(self.zip(other, |a, b| a.add_v(b)))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn sub_m(&self, other: &Mat3<T>) -> Mat3<T> {
|
|
||||||
Mat3::from_slice(self.zip(other, |a, b| a.sub_v(b)))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mul_self_t(&mut self, value: T) {
|
pub fn mul_self_t(&mut self, value: T) {
|
||||||
self.map_mut(|x| x.mul_self_t(value.clone()))
|
self.col_mut(0).mul_self_t(value.clone());
|
||||||
|
self.col_mut(1).mul_self_t(value.clone());
|
||||||
|
self.col_mut(2).mul_self_t(value.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn add_self_m(&mut self, other: &Mat3<T>) {
|
pub fn add_self_m(&mut self, other: &Mat3<T>) {
|
||||||
self.zip_mut(other, |a, b| a.add_self_v(b))
|
self.col_mut(0).add_self_v(other.col(0));
|
||||||
|
self.col_mut(1).add_self_v(other.col(1));
|
||||||
|
self.col_mut(2).add_self_v(other.col(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sub_self_m(&mut self, other: &Mat3<T>) {
|
pub fn sub_self_m(&mut self, other: &Mat3<T>) {
|
||||||
self.zip_mut(other, |a, b| a.sub_self_v(b))
|
self.col_mut(0).sub_self_v(other.col(0));
|
||||||
|
self.col_mut(1).sub_self_v(other.col(1));
|
||||||
|
self.col_mut(2).sub_self_v(other.col(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dot(&self, other: &Mat3<T>) -> T {
|
pub fn dot(&self, other: &Mat3<T>) -> T {
|
||||||
|
@ -661,7 +698,9 @@ impl<T:Clone + Num> Mat3<T> {
|
||||||
impl<T:Clone + Num> Neg<Mat3<T>> for Mat3<T> {
|
impl<T:Clone + Num> Neg<Mat3<T>> for Mat3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn neg(&self) -> Mat3<T> {
|
pub fn neg(&self) -> Mat3<T> {
|
||||||
Mat3::from_slice(self.map(|&x| -x))
|
Mat3::from_cols(-*self.col(0),
|
||||||
|
-*self.col(1),
|
||||||
|
-*self.col(2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1089,11 +1128,10 @@ pub type Mat4f32 = Mat4<f32>;
|
||||||
pub type Mat4f64 = Mat4<f64>;
|
pub type Mat4f64 = Mat4<f64>;
|
||||||
|
|
||||||
impl_dimensional!(Mat4, Vec4<T>, 4)
|
impl_dimensional!(Mat4, Vec4<T>, 4)
|
||||||
impl_dimensional_fns!(Mat4, Vec4<T>, 4)
|
impl_approx!(Mat4, 4)
|
||||||
impl_approx!(Mat4)
|
|
||||||
|
|
||||||
impl_mat!(Mat4, Vec4)
|
impl_mat!(Mat4, Vec4)
|
||||||
impl_mat_clonable!(Mat4, Vec4)
|
impl_mat_swap!(Mat4, Vec4)
|
||||||
|
|
||||||
pub trait ToMat4<T> {
|
pub trait ToMat4<T> {
|
||||||
pub fn to_mat4(&self) -> Mat4<T>;
|
pub fn to_mat4(&self) -> Mat4<T>;
|
||||||
|
@ -1120,6 +1158,24 @@ impl<T> Mat4<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T:Clone> Mat4<T> {
|
||||||
|
#[inline]
|
||||||
|
pub fn row(&self, i: uint) -> Vec4<T> {
|
||||||
|
Vec4::new(self.col(0).index(i).clone(),
|
||||||
|
self.col(1).index(i).clone(),
|
||||||
|
self.col(2).index(i).clone(),
|
||||||
|
self.col(3).index(i).clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn swap_rows(&mut self, a: uint, b: uint) {
|
||||||
|
self.col_mut(0).swap(a, b);
|
||||||
|
self.col_mut(1).swap(a, b);
|
||||||
|
self.col_mut(2).swap(a, b);
|
||||||
|
self.col_mut(3).swap(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T:Clone + Num> Mat4<T> {
|
impl<T:Clone + Num> Mat4<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_value(value: T) -> Mat4<T> {
|
pub fn from_value(value: T) -> Mat4<T> {
|
||||||
|
@ -1137,7 +1193,10 @@ impl<T:Clone + Num> Mat4<T> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mul_t(&self, value: T) -> Mat4<T> {
|
pub fn mul_t(&self, value: T) -> Mat4<T> {
|
||||||
Mat4::from_slice(self.map(|&c| c.mul_t(value.clone())))
|
Mat4::from_cols(self.col(0).mul_t(value.clone()),
|
||||||
|
self.col(1).mul_t(value.clone()),
|
||||||
|
self.col(2).mul_t(value.clone()),
|
||||||
|
self.col(3).mul_t(value.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1148,6 +1207,22 @@ impl<T:Clone + Num> Mat4<T> {
|
||||||
self.row(3).dot(vec))
|
self.row(3).dot(vec))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn add_m(&self, other: &Mat4<T>) -> Mat4<T> {
|
||||||
|
Mat4::from_cols(self.col(0).add_v(other.col(0)),
|
||||||
|
self.col(1).add_v(other.col(1)),
|
||||||
|
self.col(2).add_v(other.col(2)),
|
||||||
|
self.col(3).add_v(other.col(3)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn sub_m(&self, other: &Mat4<T>) -> Mat4<T> {
|
||||||
|
Mat4::from_cols(self.col(0).sub_v(other.col(0)),
|
||||||
|
self.col(1).sub_v(other.col(1)),
|
||||||
|
self.col(2).sub_v(other.col(2)),
|
||||||
|
self.col(3).sub_v(other.col(3)))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mul_m(&self, other: &Mat4<T>) -> Mat4<T> {
|
pub fn mul_m(&self, other: &Mat4<T>) -> Mat4<T> {
|
||||||
Mat4::new(self.row(0).dot(other.col(0)),
|
Mat4::new(self.row(0).dot(other.col(0)),
|
||||||
|
@ -1171,29 +1246,28 @@ impl<T:Clone + Num> Mat4<T> {
|
||||||
self.row(3).dot(other.col(3)))
|
self.row(3).dot(other.col(3)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn add_m(&self, other: &Mat4<T>) -> Mat4<T> {
|
|
||||||
Mat4::from_slice(self.zip(other, |a, b| a.add_v(b)))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn sub_m(&self, other: &Mat4<T>) -> Mat4<T> {
|
|
||||||
Mat4::from_slice(self.zip(other, |a, b| a.sub_v(b)))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mul_self_t(&mut self, value: T) {
|
pub fn mul_self_t(&mut self, value: T) {
|
||||||
self.map_mut(|x| x.mul_self_t(value.clone()))
|
self.col_mut(0).mul_self_t(value.clone());
|
||||||
|
self.col_mut(1).mul_self_t(value.clone());
|
||||||
|
self.col_mut(2).mul_self_t(value.clone());
|
||||||
|
self.col_mut(3).mul_self_t(value.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn add_self_m(&mut self, other: &Mat4<T>) {
|
pub fn add_self_m(&mut self, other: &Mat4<T>) {
|
||||||
self.zip_mut(other, |a, b| a.add_self_v(b))
|
self.col_mut(0).add_self_v(other.col(0));
|
||||||
|
self.col_mut(1).add_self_v(other.col(1));
|
||||||
|
self.col_mut(2).add_self_v(other.col(2));
|
||||||
|
self.col_mut(3).add_self_v(other.col(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sub_self_m(&mut self, other: &Mat4<T>) {
|
pub fn sub_self_m(&mut self, other: &Mat4<T>) {
|
||||||
self.zip_mut(other, |a, b| a.sub_self_v(b))
|
self.col_mut(0).sub_self_v(other.col(0));
|
||||||
|
self.col_mut(1).sub_self_v(other.col(1));
|
||||||
|
self.col_mut(2).sub_self_v(other.col(2));
|
||||||
|
self.col_mut(3).sub_self_v(other.col(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dot(&self, other: &Mat4<T>) -> T {
|
pub fn dot(&self, other: &Mat4<T>) -> T {
|
||||||
|
@ -1238,7 +1312,10 @@ impl<T:Clone + Num> Mat4<T> {
|
||||||
impl<T:Clone + Num> Neg<Mat4<T>> for Mat4<T> {
|
impl<T:Clone + Num> Neg<Mat4<T>> for Mat4<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn neg(&self) -> Mat4<T> {
|
pub fn neg(&self) -> Mat4<T> {
|
||||||
Mat4::from_slice(self.map(|&x| -x))
|
Mat4::from_cols(-*self.col(0),
|
||||||
|
-*self.col(1),
|
||||||
|
-*self.col(2),
|
||||||
|
-*self.col(3))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,8 @@ pub struct Plane<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_dimensional!(Plane, T, 4)
|
impl_dimensional!(Plane, T, 4)
|
||||||
impl_dimensional_fns!(Plane, T, 4)
|
impl_approx!(Plane, 4)
|
||||||
impl_swap!(Plane)
|
impl_swap!(Plane)
|
||||||
impl_approx!(Plane)
|
|
||||||
|
|
||||||
impl<T:Clone + Real> Plane<T> {
|
impl<T:Clone + Real> Plane<T> {
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
|
|
@ -29,8 +29,7 @@ pub trait Point<T,V>: Eq + ApproxEq<T> + ToStr {
|
||||||
pub struct Point2<T>(Vec2<T>);
|
pub struct Point2<T>(Vec2<T>);
|
||||||
|
|
||||||
impl_dimensional!(Point2, T, 2)
|
impl_dimensional!(Point2, T, 2)
|
||||||
impl_dimensional_fns!(Point2, T, 2)
|
impl_approx!(Point2, 2)
|
||||||
impl_approx!(Point2)
|
|
||||||
|
|
||||||
impl<T> Point2<T> {
|
impl<T> Point2<T> {
|
||||||
pub fn new(x: T, y: T) -> Point2<T> {
|
pub fn new(x: T, y: T) -> Point2<T> {
|
||||||
|
@ -59,8 +58,7 @@ impl<T> ToStr for Point2<T> {
|
||||||
pub struct Point3<T>(Vec3<T>);
|
pub struct Point3<T>(Vec3<T>);
|
||||||
|
|
||||||
impl_dimensional!(Point3, T, 3)
|
impl_dimensional!(Point3, T, 3)
|
||||||
impl_dimensional_fns!(Point3, T, 3)
|
impl_approx!(Point3, 3)
|
||||||
impl_approx!(Point3)
|
|
||||||
|
|
||||||
impl<T> Point3<T> {
|
impl<T> Point3<T> {
|
||||||
pub fn new(x: T, y: T, z: T) -> Point3<T> {
|
pub fn new(x: T, y: T, z: T) -> Point3<T> {
|
||||||
|
|
46
src/quat.rs
46
src/quat.rs
|
@ -37,9 +37,8 @@ pub type Quatf64 = Quat<f64>;
|
||||||
pub struct Quat<T> { s: T, v: Vec3<T> }
|
pub struct Quat<T> { s: T, v: Vec3<T> }
|
||||||
|
|
||||||
impl_dimensional!(Quat, T, 4)
|
impl_dimensional!(Quat, T, 4)
|
||||||
impl_dimensional_fns!(Quat, T, 4)
|
impl_approx!(Quat, 4)
|
||||||
impl_swap!(Quat)
|
impl_swap!(Quat)
|
||||||
impl_approx!(Quat)
|
|
||||||
|
|
||||||
pub trait ToQuat<T> {
|
pub trait ToQuat<T> {
|
||||||
pub fn to_quat(&self) -> Quat<T>;
|
pub fn to_quat(&self) -> Quat<T>;
|
||||||
|
@ -124,13 +123,13 @@ impl<T:Clone + Real> Quat<T> {
|
||||||
/// The result of multiplying the quaternion a scalar
|
/// The result of multiplying the quaternion a scalar
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mul_t(&self, value: T) -> Quat<T> {
|
pub fn mul_t(&self, value: T) -> Quat<T> {
|
||||||
Quat::from_slice(self.map(|&x| x * value))
|
Quat::from_sv(self.s * value, self.v.mul_t(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The result of dividing the quaternion a scalar
|
/// The result of dividing the quaternion a scalar
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn div_t(&self, value: T) -> Quat<T> {
|
pub fn div_t(&self, value: T) -> Quat<T> {
|
||||||
Quat::from_slice(self.map(|&x| x / value))
|
Quat::from_sv(self.s / value, self.v.div_t(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The result of multiplying the quaternion by a vector
|
/// The result of multiplying the quaternion by a vector
|
||||||
|
@ -250,7 +249,7 @@ impl<T:Clone + Num> ToMat3<T> for Quat<T> {
|
||||||
impl<T:Clone + Float> Neg<Quat<T>> for Quat<T> {
|
impl<T:Clone + Float> Neg<Quat<T>> for Quat<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn neg(&self) -> Quat<T> {
|
pub fn neg(&self) -> Quat<T> {
|
||||||
Quat::from_slice(self.map(|&x| -x))
|
Quat::from_sv(-self.s, -self.v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,42 +315,21 @@ mod tests {
|
||||||
use vec::*;
|
use vec::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_quat() {
|
fn test_from_angle_axis() {
|
||||||
let a = Quat { s: 1.0, v: Vec3 { x: 2.0, y: 3.0, z: 4.0 } };
|
let v = Vec3::new(1f, 0f, 0f);
|
||||||
|
|
||||||
assert_eq!(a, Quat::from_sv::<float>(1.0, Vec3::new::<float>(2.0, 3.0, 4.0)));
|
let q = Quat::from_angle_axis((-45f).to_radians(), &Vec3::new(0f, 0f, -1f));
|
||||||
assert_eq!(a, Quat::new::<float>(1.0, 2.0, 3.0, 4.0));
|
|
||||||
|
|
||||||
assert_eq!(Quat::zero::<float>(), Quat::new::<float>(0.0, 0.0, 0.0, 0.0));
|
|
||||||
assert_eq!(Quat::identity::<float>(), Quat::new::<float>(1.0, 0.0, 0.0, 0.0));
|
|
||||||
|
|
||||||
assert_eq!(a.s, 1.0);
|
|
||||||
assert_eq!(a.v.x, 2.0);
|
|
||||||
assert_eq!(a.v.y, 3.0);
|
|
||||||
assert_eq!(a.v.z, 4.0);
|
|
||||||
assert_eq!(*a.index(0), 1.0);
|
|
||||||
assert_eq!(*a.index(1), 2.0);
|
|
||||||
assert_eq!(*a.index(2), 3.0);
|
|
||||||
assert_eq!(*a.index(3), 4.0);
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_quat_2() {
|
|
||||||
let v = Vec3::new(1f32, 0f32, 0f32);
|
|
||||||
|
|
||||||
let q = Quat::from_angle_axis((-45f32).to_radians(), &Vec3::new(0f32, 0f32, -1f32));
|
|
||||||
|
|
||||||
// http://www.wolframalpha.com/input/?i={1,0}+rotate+-45+degrees
|
// http://www.wolframalpha.com/input/?i={1,0}+rotate+-45+degrees
|
||||||
assert_approx_eq!(q.mul_v(&v), Vec3::new(1f32/2f32.sqrt(), 1f32/2f32.sqrt(), 0f32));
|
assert_approx_eq!(q.mul_v(&v), Vec3::new(1f/2f.sqrt(), 1f/2f.sqrt(), 0f));
|
||||||
assert_eq!(q.mul_v(&v).length(), v.length());
|
assert_eq!(q.mul_v(&v).length(), v.length());
|
||||||
assert_approx_eq!(q.to_mat3(), Mat3::new( 1f32/2f32.sqrt(), 1f32/2f32.sqrt(), 0f32,
|
assert_approx_eq!(q.to_mat3(), Mat3::new( 1f/2f.sqrt(), 1f/2f.sqrt(), 0f,
|
||||||
-1f32/2f32.sqrt(), 1f32/2f32.sqrt(), 0f32,
|
-1f/2f.sqrt(), 1f/2f.sqrt(), 0f,
|
||||||
0f32, 0f32, 1f32));
|
0f, 0f, 1f));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_quat_approx_eq() {
|
fn test_approx_eq() {
|
||||||
assert!(!Quat::new::<float>(0.000001, 0.000001, 0.000001, 0.000001)
|
assert!(!Quat::new::<float>(0.000001, 0.000001, 0.000001, 0.000001)
|
||||||
.approx_eq(&Quat::new::<float>(0.0, 0.0, 0.0, 0.0)));
|
.approx_eq(&Quat::new::<float>(0.0, 0.0, 0.0, 0.0)));
|
||||||
assert!(Quat::new::<float>(0.0000001, 0.0000001, 0.0000001, 0.0000001)
|
assert!(Quat::new::<float>(0.0000001, 0.0000001, 0.0000001, 0.0000001)
|
||||||
|
|
951
src/vec.rs
951
src/vec.rs
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue