forked from M-Labs/nalgebra
Add matrix adaptors and addapted to the now rust features.
This commit is contained in:
parent
c7059af99d
commit
d636fdd346
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.swp
|
||||
doc
|
2
Makefile
2
Makefile
@ -1,5 +1,5 @@
|
||||
all:
|
||||
rustpkg install
|
||||
rust build src/nalgebra.rc --out-dir lib # rustpkg install
|
||||
|
||||
doc:
|
||||
rust doc src/nalgebra.rc --output-dir doc
|
||||
|
112
src/adaptors/rotmat.rs
Normal file
112
src/adaptors/rotmat.rs
Normal file
@ -0,0 +1,112 @@
|
||||
use core::num::{One, Zero}; // , Trigonometric};
|
||||
use traits::workarounds::rlmul::{RMul, LMul};
|
||||
use traits::workarounds::trigonometric::Trigonometric;
|
||||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::transpose::Transpose;
|
||||
use dim2::mat2::Mat2;
|
||||
use dim3::mat3::Mat3;
|
||||
use dim3::vec3::Vec3;
|
||||
|
||||
// FIXME: use a newtype here?
|
||||
#[deriving(Eq)]
|
||||
pub struct Rotmat<M>
|
||||
{
|
||||
priv submat: M
|
||||
}
|
||||
|
||||
pub fn Rotmat2<T: Copy + Trigonometric + Neg<T>>(angle: T) -> Rotmat<Mat2<T>>
|
||||
{
|
||||
let coa = Trigonometric::cos(angle);
|
||||
let sia = Trigonometric::sin(angle);
|
||||
|
||||
Rotmat
|
||||
{ submat: Mat2(coa, -sia, sia, coa) }
|
||||
}
|
||||
|
||||
pub fn Rotmat3<T: Copy + Trigonometric + Neg<T> + One + Sub<T, T> + Add<T, T> +
|
||||
Mul<T, T>>
|
||||
(axis: &Vec3<T>, angle: T) -> Rotmat<Mat3<T>>
|
||||
{
|
||||
let _1 = One::one::<T>();
|
||||
let ux = axis.x;
|
||||
let uy = axis.y;
|
||||
let uz = axis.z;
|
||||
let sqx = ux * ux;
|
||||
let sqy = uy * uy;
|
||||
let sqz = uz * uz;
|
||||
let cos = Trigonometric::cos(angle);
|
||||
let one_m_cos = _1 - cos;
|
||||
let sin = Trigonometric::sin(angle);
|
||||
|
||||
Rotmat {
|
||||
submat: Mat3(
|
||||
(sqx + (_1 - sqx) * cos),
|
||||
(ux * uy * one_m_cos - uz * sin),
|
||||
(ux * uz * one_m_cos + uy * sin),
|
||||
|
||||
(ux * uy * one_m_cos + uz * sin),
|
||||
(sqy + (_1 - sqy) * cos),
|
||||
(uy * uz * one_m_cos - ux * sin),
|
||||
|
||||
(ux * uz * one_m_cos - uy * sin),
|
||||
(uy * uz * one_m_cos + ux * sin),
|
||||
(sqz + (_1 - sqz) * cos))
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: Dim> Dim for Rotmat<M>
|
||||
{
|
||||
fn dim() -> uint
|
||||
{ Dim::dim::<M>() }
|
||||
}
|
||||
|
||||
impl<M:Copy + One + Zero> One for Rotmat<M>
|
||||
{
|
||||
fn one() -> Rotmat<M>
|
||||
{ Rotmat { submat: One::one() } }
|
||||
}
|
||||
|
||||
impl<M:Copy + Mul<M, M>> Mul<Rotmat<M>, Rotmat<M>> for Rotmat<M>
|
||||
{
|
||||
fn mul(&self, other: &Rotmat<M>) -> Rotmat<M>
|
||||
{ Rotmat { submat: self.submat.mul(&other.submat) } }
|
||||
}
|
||||
|
||||
impl<V, M: RMul<V>> RMul<V> for Rotmat<M>
|
||||
{
|
||||
fn rmul(&self, other: &V) -> V
|
||||
{ self.submat.rmul(other) }
|
||||
}
|
||||
|
||||
impl<V, M: LMul<V>> LMul<V> for Rotmat<M>
|
||||
{
|
||||
fn lmul(&self, other: &V) -> V
|
||||
{ self.submat.lmul(other) }
|
||||
}
|
||||
|
||||
impl<M:Copy + Transpose>
|
||||
Inv for Rotmat<M>
|
||||
{
|
||||
fn invert(&mut self)
|
||||
{ self.transpose() }
|
||||
|
||||
fn inverse(&self) -> Rotmat<M>
|
||||
{ self.transposed() }
|
||||
}
|
||||
|
||||
impl<M:Copy + Transpose>
|
||||
Transpose for Rotmat<M>
|
||||
{
|
||||
fn transposed(&self) -> Rotmat<M>
|
||||
{ Rotmat { submat: self.submat.transposed() } }
|
||||
|
||||
fn transpose(&mut self)
|
||||
{ self.submat.transpose() }
|
||||
}
|
||||
|
||||
impl<M:ToStr> ToStr for Rotmat<M>
|
||||
{
|
||||
fn to_str(&self) -> ~str
|
||||
{ ~"Rotmat {" + " submat: " + self.submat.to_str() + " }" }
|
||||
}
|
85
src/adaptors/transform.rs
Normal file
85
src/adaptors/transform.rs
Normal file
@ -0,0 +1,85 @@
|
||||
use core::num::{One, Zero};
|
||||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::transpose::Transpose;
|
||||
use traits::workarounds::rlmul::{RMul, LMul};
|
||||
|
||||
pub struct Transform<M, V>
|
||||
{
|
||||
submat : M,
|
||||
subtrans : V
|
||||
}
|
||||
|
||||
pub fn Transform<M: Copy, V: Copy>(mat: &M, trans: &V) -> Transform<M, V>
|
||||
{ Transform { submat: *mat, subtrans: *trans } }
|
||||
|
||||
impl<M:Dim, V> Dim for Transform<M, V>
|
||||
{
|
||||
fn dim() -> uint
|
||||
{ Dim::dim::<M>() }
|
||||
}
|
||||
|
||||
impl<M:Copy + One, V:Copy + Zero> One for Transform<M, V>
|
||||
{
|
||||
fn one() -> Transform<M, V>
|
||||
{ Transform { submat: One::one(), subtrans: Zero::zero() } }
|
||||
}
|
||||
|
||||
impl<M:Copy + Zero, V:Copy + Zero> Zero for Transform<M, V>
|
||||
{
|
||||
fn zero() -> Transform<M, V>
|
||||
{ Transform { submat: Zero::zero(), subtrans: Zero::zero() } }
|
||||
|
||||
fn is_zero(&self) -> bool
|
||||
{ self.submat.is_zero() && self.subtrans.is_zero() }
|
||||
}
|
||||
|
||||
impl<M:Copy + RMul<V> + Mul<M, M>, V:Copy + Add<V, V>>
|
||||
Mul<Transform<M, V>, Transform<M, V>> for Transform<M, V>
|
||||
{
|
||||
fn mul(&self, other: &Transform<M, V>) -> Transform<M, V>
|
||||
{
|
||||
Transform { submat: self.submat * other.submat,
|
||||
subtrans: self.subtrans + self.submat.rmul(&other.subtrans) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: RMul<V>, V> RMul<V> for Transform<M, V>
|
||||
{
|
||||
fn rmul(&self, other: &V) -> V
|
||||
{ self.submat.rmul(other) }
|
||||
}
|
||||
|
||||
impl<M: LMul<V>, V> LMul<V> for Transform<M, V>
|
||||
{
|
||||
fn lmul(&self, other: &V) -> V
|
||||
{ self.submat.lmul(other) }
|
||||
}
|
||||
|
||||
impl<M:Copy + Transpose + Inv + RMul<V>, V:Copy + Neg<V>>
|
||||
Inv for Transform<M, V>
|
||||
{
|
||||
fn invert(&mut self)
|
||||
{
|
||||
self.submat.invert();
|
||||
self.subtrans = self.submat.rmul(&-self.subtrans);
|
||||
}
|
||||
|
||||
fn inverse(&self) -> Transform<M, V>
|
||||
{
|
||||
let mut res = *self;
|
||||
|
||||
res.invert();
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl<M:ToStr, V:ToStr> ToStr for Transform<M, V>
|
||||
{
|
||||
fn to_str(&self) -> ~str
|
||||
{
|
||||
~"Transform {" + " submat: " + self.submat.to_str() +
|
||||
" subtrans: " + self.subtrans.to_str() + " }"
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ use core::num::{One, Zero};
|
||||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::transpose::Transpose;
|
||||
use traits::workarounds::rlmul::{RMul, LMul};
|
||||
use dim2::vec2::Vec2;
|
||||
|
||||
#[deriving(Eq)]
|
||||
@ -45,11 +46,11 @@ impl<T:Copy + Zero> Zero for Mat2<T>
|
||||
_0, _0)
|
||||
}
|
||||
|
||||
// fn is_zero(&self) -> bool
|
||||
// {
|
||||
// self.m11.is_zero() && self.m11.is_zero() && self.m12.is_zero()
|
||||
// && self.m21.is_zero() && self.m21.is_zero() && self.m22.is_zero()
|
||||
// }
|
||||
fn is_zero(&self) -> bool
|
||||
{
|
||||
self.m11.is_zero() && self.m12.is_zero() &&
|
||||
self.m21.is_zero() && self.m22.is_zero()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Mat2<T>, Mat2<T>> for Mat2<T>
|
||||
@ -64,31 +65,47 @@ impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Mat2<T>, Mat2<T>> for Mat2<T>
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: implementation of multiple classes for the same struct fails
|
||||
// with "internal compiler error: Asked to compute kind of a type variable".
|
||||
//
|
||||
// impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Vec2<T>, Vec2<T>> for Mat2<T>
|
||||
// {
|
||||
// fn mul(&self, v: &Vec2<T>) -> Vec2<T>
|
||||
// { Vec2(self.m11 * v.x + self.m12 * v.y, self.m21 * v.x + self.m22 * v.y) }
|
||||
// }
|
||||
|
||||
impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Mat2<T>, Vec2<T>> for Vec2<T>
|
||||
impl<T:Copy + Add<T, T> + Mul<T, T>> RMul<Vec2<T>> for Mat2<T>
|
||||
{
|
||||
fn mul(&self, m: &Mat2<T>) -> Vec2<T>
|
||||
{ Vec2(self.x * m.m11 + self.y * m.m21, self.x * m.m12 + self.y * m.m22) }
|
||||
fn rmul(&self, other: &Vec2<T>) -> Vec2<T>
|
||||
{
|
||||
Vec2(
|
||||
self.m11 * other.x + self.m12 * other.y,
|
||||
self.m21 * other.x + self.m22 * other.y
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Mul<T, T> + Div<T, T> + Sub<T, T> + Neg<T> + Eq + Zero>
|
||||
impl<T:Copy + Add<T, T> + Mul<T, T>> LMul<Vec2<T>> for Mat2<T>
|
||||
{
|
||||
fn lmul(&self, other: &Vec2<T>) -> Vec2<T>
|
||||
{
|
||||
Vec2(
|
||||
self.m11 * other.x + self.m21 * other.y,
|
||||
self.m12 * other.x + self.m22 * other.y
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Mul<T, T> + Quot<T, T> + Sub<T, T> + Neg<T> + Eq + Zero>
|
||||
Inv for Mat2<T>
|
||||
{
|
||||
fn inv(&self) -> Mat2<T>
|
||||
fn inverse(&self) -> Mat2<T>
|
||||
{
|
||||
let mut res : Mat2<T> = *self;
|
||||
|
||||
res.invert();
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn invert(&mut self)
|
||||
{
|
||||
let det = self.m11 * self.m22 - self.m21 * self.m12;
|
||||
|
||||
assert!(det != Zero::zero());
|
||||
|
||||
Mat2(self.m22 / det , -self.m12 / det,
|
||||
*self = Mat2(self.m22 / det , -self.m12 / det,
|
||||
-self.m21 / det, self.m11 / det)
|
||||
}
|
||||
}
|
||||
|
@ -1,92 +0,0 @@
|
||||
use core::num::{One, Zero};
|
||||
use traits::workarounds::trigonometric::Trigonometric;
|
||||
use traits::dim::Dim;
|
||||
use dim2::mat2::Mat2;
|
||||
// use dim2::vec2::Vec2;
|
||||
|
||||
// FIXME: using a newtype did not compile (due a compiler bug)
|
||||
// pub type Rotmat2<T> = (Mat2<T>)
|
||||
#[deriving(Eq)]
|
||||
pub struct Rotmat2<T>
|
||||
{
|
||||
priv submat: Mat2<T>
|
||||
}
|
||||
|
||||
pub fn Rotmat2<T:Copy + Trigonometric + Neg<T>>(angle: T) -> Rotmat2<T>
|
||||
{
|
||||
let coa = angle.cos();
|
||||
let sia = angle.sin();
|
||||
|
||||
Rotmat2
|
||||
{ submat: Mat2(coa, -sia, sia, coa) }
|
||||
}
|
||||
|
||||
impl<T> Dim for Rotmat2<T>
|
||||
{
|
||||
fn dim() -> uint
|
||||
{ 2 }
|
||||
}
|
||||
|
||||
impl<T:Copy + One + Zero> One for Rotmat2<T>
|
||||
{
|
||||
fn one() -> Rotmat2<T>
|
||||
{ Rotmat2 { submat: One::one() } }
|
||||
}
|
||||
|
||||
impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Rotmat2<T>, Rotmat2<T>> for Rotmat2<T>
|
||||
{
|
||||
fn mul(&self, other: &Rotmat2<T>) -> Rotmat2<T>
|
||||
{ Rotmat2 { submat: self.submat.mul(&other.submat) } }
|
||||
}
|
||||
|
||||
// FIXME: implementation of the same classes for the same struct fails
|
||||
// with "internal compiler error: Asked to compute kind of a type variable".
|
||||
//
|
||||
// impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Vec2<T>, Vec2<T>> for Rotmat2<T>
|
||||
// {
|
||||
// fn mul(&self, v: &Vec2<T>) -> Vec2<T>
|
||||
// { Vec2(self.m11 * v.x + self.m12 * v.y, self.m21 * v.x + self.m22 * v.y) }
|
||||
// }
|
||||
|
||||
// FIXME: implementation of the same classes for the same struct (here Vec2<T>)
|
||||
// fails with "internal compiler error: Asked to compute kind of a type
|
||||
// variable".
|
||||
//
|
||||
// impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Rotmat2<T>, Vec2<T>> for Vec2<T>
|
||||
// {
|
||||
// fn mul(&self, m: &Rotmat2<T>) -> Vec2<T>
|
||||
// { self.mult(&m.submat) }
|
||||
// }
|
||||
|
||||
/*
|
||||
impl<T:Copy + Mul<T, T> + Div<T, T> + Sub<T, T> + Neg<T> + Eq + Zero>
|
||||
Inv<T> for Rotmat2<T>
|
||||
{
|
||||
fn inv(&self) -> Rotmat2<T>
|
||||
{
|
||||
// transpose
|
||||
Rotmat2(
|
||||
Mat2(
|
||||
self.submat.m11, self.submat.m21,
|
||||
self.submat.m12, self.submat.m22
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
impl<T:ToStr> ToStr for Rotmat2<T>
|
||||
{
|
||||
fn to_str(&self) -> ~str
|
||||
{
|
||||
~"Rotmat2 {"
|
||||
+ " m11: " + self.m11.to_str()
|
||||
+ " m12: " + self.m12.to_str()
|
||||
|
||||
+ " m21: " + self.m21.to_str()
|
||||
+ " m22: " + self.m22.to_str()
|
||||
+ " }"
|
||||
}
|
||||
}
|
||||
*/
|
@ -1,8 +1,7 @@
|
||||
use core::num::Zero;
|
||||
use core::num::{Zero, Algebraic};
|
||||
use traits::dot::Dot;
|
||||
use traits::dim::Dim;
|
||||
use traits::cross::Cross;
|
||||
use traits::workarounds::sqrt::Sqrt;
|
||||
|
||||
#[deriving(Eq)]
|
||||
pub struct Vec2<T>
|
||||
@ -32,7 +31,7 @@ impl<T:Copy + Sub<T,T>> Sub<Vec2<T>, Vec2<T>> for Vec2<T>
|
||||
{ Vec2(self.x - other.x, self.y - other.y) }
|
||||
}
|
||||
|
||||
impl<T:Copy + Mul<T, T> + Add<T, T> + Sqrt> Dot<T> for Vec2<T>
|
||||
impl<T:Copy + Mul<T, T> + Add<T, T> + Algebraic> Dot<T> for Vec2<T>
|
||||
{
|
||||
fn dot(&self, other : &Vec2<T>) -> T
|
||||
{ self.x * other.x + self.y * other.y }
|
||||
@ -50,6 +49,12 @@ impl<T:Copy + Mul<T, T> + Sub<T, T>> Cross<T> for Vec2<T>
|
||||
{ self.x * other.y - self.y * other.x }
|
||||
}
|
||||
|
||||
impl<T:Copy + Neg<T>> Neg<Vec2<T>> for Vec2<T>
|
||||
{
|
||||
fn neg(&self) -> Vec2<T>
|
||||
{ Vec2(-self.x, -self.y) }
|
||||
}
|
||||
|
||||
impl<T:Copy + Zero> Zero for Vec2<T>
|
||||
{
|
||||
fn zero() -> Vec2<T>
|
||||
@ -57,6 +62,9 @@ impl<T:Copy + Zero> Zero for Vec2<T>
|
||||
let _0 = Zero::zero();
|
||||
Vec2(_0, _0)
|
||||
}
|
||||
|
||||
fn is_zero(&self) -> bool
|
||||
{ self.x.is_zero() && self.y.is_zero() }
|
||||
}
|
||||
|
||||
impl<T:ToStr> ToStr for Vec2<T>
|
||||
|
@ -1,8 +1,8 @@
|
||||
use core::num::{One, Zero};
|
||||
// use core::rand::{Rand, Rng};
|
||||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::transpose::Transpose;
|
||||
use traits::workarounds::rlmul::{RMul, LMul};
|
||||
use dim3::vec3::Vec3;
|
||||
|
||||
#[deriving(Eq)]
|
||||
@ -51,6 +51,13 @@ impl<T:Copy + Zero> Zero for Mat3<T>
|
||||
_0, _0, _0,
|
||||
_0, _0, _0)
|
||||
}
|
||||
|
||||
fn is_zero(&self) -> bool
|
||||
{
|
||||
self.m11.is_zero() && self.m12.is_zero() && self.m13.is_zero() &&
|
||||
self.m21.is_zero() && self.m22.is_zero() && self.m23.is_zero() &&
|
||||
self.m31.is_zero() && self.m32.is_zero() && self.m33.is_zero()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Mat3<T>, Mat3<T>> for Mat3<T>
|
||||
@ -73,34 +80,44 @@ impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Mat3<T>, Mat3<T>> for Mat3<T>
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: implementation of multiple classes for the same struct fails
|
||||
// with "internal compiler error: Asked to compute kind of a type variable".
|
||||
//
|
||||
// impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Vec3<T>, Vec3<T>> for Mat3<T>
|
||||
// {
|
||||
// fn mul(&self, m : &Mat3<T>) -> Vec3<T>
|
||||
// {
|
||||
// Vec3(self.x * m.m11 + self.y * m.m21 + self.z * m.m31,
|
||||
// self.x * m.m12 + self.y * m.m22 + self.z * m.m32,
|
||||
// self.x * m.m13 + self.y * m.m23 + self.z * m.m33)
|
||||
// }
|
||||
// }
|
||||
|
||||
impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Mat3<T>, Vec3<T>> for Vec3<T>
|
||||
impl<T:Copy + Add<T, T> + Mul<T, T>> RMul<Vec3<T>> for Mat3<T>
|
||||
{
|
||||
fn mul(&self, m : &Mat3<T>) -> Vec3<T>
|
||||
fn rmul(&self, other: &Vec3<T>) -> Vec3<T>
|
||||
{
|
||||
Vec3(self.x * m.m11 + self.y * m.m21 + self.z * m.m31,
|
||||
self.x * m.m12 + self.y * m.m22 + self.z * m.m32,
|
||||
self.x * m.m13 + self.y * m.m23 + self.z * m.m33)
|
||||
Vec3(
|
||||
self.m11 * other.x + self.m12 * other.y + self.m13 * other.z,
|
||||
self.m21 * other.x + self.m22 * other.y + self.m33 * other.z,
|
||||
self.m31 * other.x + self.m32 * other.y + self.m33 * other.z
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Mul<T, T> + Div<T, T> + Sub<T, T> + Add<T, T> + Neg<T>
|
||||
impl<T:Copy + Add<T, T> + Mul<T, T>> LMul<Vec3<T>> for Mat3<T>
|
||||
{
|
||||
fn lmul(&self, other: &Vec3<T>) -> Vec3<T>
|
||||
{
|
||||
Vec3(
|
||||
self.m11 * other.x + self.m21 * other.y + self.m31 * other.z,
|
||||
self.m12 * other.x + self.m22 * other.y + self.m32 * other.z,
|
||||
self.m13 * other.x + self.m23 * other.y + self.m33 * other.z
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Copy + Mul<T, T> + Quot<T, T> + Sub<T, T> + Add<T, T> + Neg<T>
|
||||
+ Eq + Zero>
|
||||
Inv for Mat3<T>
|
||||
{
|
||||
fn inv(&self) -> Mat3<T>
|
||||
fn inverse(&self) -> Mat3<T>
|
||||
{
|
||||
let mut res = *self;
|
||||
|
||||
res.invert();
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn invert(&mut self)
|
||||
{
|
||||
let minor_m22_m33 = self.m22 * self.m33 - self.m32 * self.m23;
|
||||
let minor_m21_m33 = self.m21 * self.m33 - self.m31 * self.m23;
|
||||
@ -112,7 +129,7 @@ Inv for Mat3<T>
|
||||
|
||||
assert!(det != Zero::zero());
|
||||
|
||||
Mat3(
|
||||
*self = Mat3(
|
||||
(minor_m22_m33 / det),
|
||||
((self.m13 * self.m32 - self.m33 * self.m12) / det),
|
||||
((self.m12 * self.m23 - self.m22 * self.m13) / det),
|
||||
|
@ -1,8 +1,7 @@
|
||||
use core::num::Zero;
|
||||
use core::num::{Zero, Algebraic};
|
||||
use traits::dim::Dim;
|
||||
use traits::dot::Dot;
|
||||
use traits::cross::Cross;
|
||||
use traits::workarounds::sqrt::Sqrt;
|
||||
|
||||
#[deriving(Eq)]
|
||||
pub struct Vec3<T>
|
||||
@ -33,7 +32,13 @@ impl<T:Copy + Sub<T,T>> Sub<Vec3<T>, Vec3<T>> for Vec3<T>
|
||||
{ Vec3(self.x - other.x, self.y - other.y, self.z - other.z) }
|
||||
}
|
||||
|
||||
impl<T:Copy + Mul<T, T> + Add<T, T> + Sqrt> Dot<T> for Vec3<T>
|
||||
impl<T:Copy + Neg<T>> Neg<Vec3<T>> for Vec3<T>
|
||||
{
|
||||
fn neg(&self) -> Vec3<T>
|
||||
{ Vec3(-self.x, -self.y, -self.z) }
|
||||
}
|
||||
|
||||
impl<T:Copy + Mul<T, T> + Add<T, T> + Algebraic> Dot<T> for Vec3<T>
|
||||
{
|
||||
fn dot(&self, other : &Vec3<T>) -> T
|
||||
{ self.x * other.x + self.y * other.y + self.z * other.z }
|
||||
@ -64,6 +69,9 @@ impl<T:Copy + Zero> Zero for Vec3<T>
|
||||
let _0 = Zero::zero();
|
||||
Vec3(_0, _0, _0)
|
||||
}
|
||||
|
||||
fn is_zero(&self) -> bool
|
||||
{ self.x.is_zero() && self.y.is_zero() && self.z.is_zero() }
|
||||
}
|
||||
|
||||
impl<T:ToStr> ToStr for Vec3<T>
|
||||
|
@ -12,26 +12,26 @@ pub use dim3::mat3::Mat3;
|
||||
|
||||
pub use dim2::vec2::Vec2;
|
||||
pub use dim2::mat2::Mat2;
|
||||
pub use dim2::rotmat2::Rotmat2;
|
||||
|
||||
pub use ndim::nvec::NVec;
|
||||
pub use ndim::nmat::NMat;
|
||||
|
||||
pub use adaptors::rotmat::Rotmat;
|
||||
pub use adaptors::transform::Transform;
|
||||
|
||||
pub use traits::dot::Dot;
|
||||
pub use traits::cross::Cross;
|
||||
pub use traits::dim::Dim;
|
||||
|
||||
pub use traits::workarounds::sqrt::Sqrt;
|
||||
pub use traits::workarounds::trigonometric::Trigonometric;
|
||||
|
||||
pub use traits::inv::Inv;
|
||||
pub use traits::transpose::Transpose;
|
||||
|
||||
pub use traits::workarounds::rlmul::{RMul, LMul};
|
||||
pub use traits::workarounds::trigonometric::Trigonometric;
|
||||
|
||||
mod dim2
|
||||
{
|
||||
mod vec2;
|
||||
mod mat2;
|
||||
mod rotmat2;
|
||||
}
|
||||
|
||||
mod dim3
|
||||
@ -46,6 +46,12 @@ mod ndim
|
||||
mod nmat;
|
||||
}
|
||||
|
||||
mod adaptors
|
||||
{
|
||||
mod rotmat;
|
||||
mod transform;
|
||||
}
|
||||
|
||||
mod traits
|
||||
{
|
||||
mod dot;
|
||||
@ -56,7 +62,7 @@ mod traits
|
||||
|
||||
mod workarounds
|
||||
{
|
||||
mod sqrt;
|
||||
mod rlmul;
|
||||
mod trigonometric;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
use core::num::{One, Zero};
|
||||
use core::vec::{from_elem, swap};
|
||||
use core::vec::{from_elem, swap, all};
|
||||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::transpose::Transpose;
|
||||
// use ndim::nvec::NVec;
|
||||
use traits::workarounds::rlmul::{RMul, LMul};
|
||||
use ndim::nvec::NVec;
|
||||
|
||||
// D is a phantom type parameter, used only as a dimensional token.
|
||||
// Its allows use to encode the vector dimension at the type-level.
|
||||
@ -15,6 +16,12 @@ pub struct NMat<D, T>
|
||||
mij: ~[T]
|
||||
}
|
||||
|
||||
impl<D, T: Clone> Clone for NMat<D, T>
|
||||
{
|
||||
fn clone(&self) -> NMat<D, T>
|
||||
{ NMat{ mij: self.mij.clone() } }
|
||||
}
|
||||
|
||||
impl<D: Dim, T: Copy> NMat<D, T>
|
||||
{
|
||||
fn offset(i: uint, j: uint) -> uint
|
||||
@ -59,6 +66,9 @@ impl<D: Dim, T:Copy + Zero> Zero for NMat<D, T>
|
||||
|
||||
NMat{ mij: from_elem(dim * dim, Zero::zero()) }
|
||||
}
|
||||
|
||||
fn is_zero(&self) -> bool
|
||||
{ all(self.mij, |e| e.is_zero()) }
|
||||
}
|
||||
|
||||
impl<D: Dim, T:Copy + Mul<T, T> + Add<T, T> + Zero>
|
||||
@ -86,13 +96,59 @@ Mul<NMat<D, T>, NMat<D, T>> for NMat<D, T>
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Dim, T:Copy + Add<T, T> + Mul<T, T> + Zero>
|
||||
RMul<NVec<D, T>> for NMat<D, T>
|
||||
{
|
||||
fn rmul(&self, other: &NVec<D, T>) -> NVec<D, T>
|
||||
{
|
||||
let dim = Dim::dim::<D>();
|
||||
let mut res : NVec<D, T> = Zero::zero();
|
||||
|
||||
for uint::range(0u, dim) |i|
|
||||
{
|
||||
for uint::range(0u, dim) |j|
|
||||
{ res.at[i] = res.at[i] + other.at[j] * self[(i, j)]; }
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Dim, T:Copy + Add<T, T> + Mul<T, T> + Zero>
|
||||
LMul<NVec<D, T>> for NMat<D, T>
|
||||
{
|
||||
fn lmul(&self, other: &NVec<D, T>) -> NVec<D, T>
|
||||
{
|
||||
let dim = Dim::dim::<D>();
|
||||
let mut res : NVec<D, T> = Zero::zero();
|
||||
|
||||
for uint::range(0u, dim) |i|
|
||||
{
|
||||
for uint::range(0u, dim) |j|
|
||||
{ res.at[i] = res.at[i] + other.at[j] * self[(j, i)]; }
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Dim,
|
||||
T: Copy + Mul<T, T> + Div<T, T> + Sub<T, T> + Neg<T> + Eq + One + Zero>
|
||||
T: Clone + Copy + Eq + One + Zero +
|
||||
Mul<T, T> + Quot<T, T> + Sub<T, T> + Neg<T>
|
||||
>
|
||||
Inv for NMat<D, T>
|
||||
{
|
||||
fn inv(&self) -> NMat<D, T>
|
||||
fn inverse(&self) -> NMat<D, T>
|
||||
{
|
||||
let mut res : NMat<D, T> = self.clone();
|
||||
|
||||
res.invert();
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn invert(&mut self)
|
||||
{
|
||||
let mut cpy = copy *self;
|
||||
let dim = Dim::dim::<D>();
|
||||
let mut res = One::one::<NMat<D, T>>();
|
||||
let _0T = Zero::zero::<T>();
|
||||
@ -111,7 +167,7 @@ Inv for NMat<D, T>
|
||||
|
||||
while (n0 != dim)
|
||||
{
|
||||
if (cpy[(n0, k)] != _0T)
|
||||
if (self[(n0, k)] != _0T)
|
||||
{ break; }
|
||||
|
||||
n0 += 1;
|
||||
@ -124,7 +180,7 @@ Inv for NMat<D, T>
|
||||
{
|
||||
for uint::range(0u, dim) |j|
|
||||
{
|
||||
swap(cpy.mij,
|
||||
swap(self.mij,
|
||||
NMat::offset::<D, T>(n0, j),
|
||||
NMat::offset::<D, T>(k, j));
|
||||
swap(res.mij,
|
||||
@ -133,11 +189,11 @@ Inv for NMat<D, T>
|
||||
}
|
||||
}
|
||||
|
||||
let pivot = cpy[(k, k)];
|
||||
let pivot = self[(k, k)];
|
||||
|
||||
for uint::range(k, dim) |j|
|
||||
{
|
||||
cpy.set(k, j, &(cpy[(k, j)] / pivot));
|
||||
self.set(k, j, &(self[(k, j)] / pivot));
|
||||
res.set(k, j, &(res[(k, j)] / pivot));
|
||||
}
|
||||
|
||||
@ -145,18 +201,16 @@ Inv for NMat<D, T>
|
||||
{
|
||||
if (l != k)
|
||||
{
|
||||
let normalizer = cpy[(l, k)] / pivot;
|
||||
let normalizer = self[(l, k)] / pivot;
|
||||
|
||||
for uint::range(k, dim) |j|
|
||||
{
|
||||
cpy.set(k, j, &(cpy[(l, j)] - cpy[(k, j)] * normalizer));
|
||||
self.set(k, j, &(self[(l, j)] - self[(k, j)] * normalizer));
|
||||
res.set(k, j, &(res[(l, j)] - res[(k, j)] * normalizer));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
use core::vec::{map2, from_elem};
|
||||
use core::num::Zero;
|
||||
use core::vec::{map_zip, from_elem, map, all};
|
||||
use core::num::{Zero, Algebraic};
|
||||
use traits::dim::Dim;
|
||||
use traits::dot::Dot;
|
||||
use traits::workarounds::sqrt::Sqrt;
|
||||
|
||||
// D is a phantom parameter, used only as a dimensional token.
|
||||
// Its allows use to encode the vector dimension at the type-level.
|
||||
@ -26,16 +25,23 @@ impl<D: Dim, T> Dim for NVec<D, T>
|
||||
impl<D, T:Copy + Add<T,T>> Add<NVec<D, T>, NVec<D, T>> for NVec<D, T>
|
||||
{
|
||||
fn add(&self, other: &NVec<D, T>) -> NVec<D, T>
|
||||
{ NVec { at: map2(self.at, other.at, | a, b | { *a + *b }) } }
|
||||
{ NVec { at: map_zip(self.at, other.at, | a, b | { *a + *b }) } }
|
||||
}
|
||||
|
||||
impl<D, T:Copy + Sub<T,T>> Sub<NVec<D, T>, NVec<D, T>> for NVec<D, T>
|
||||
{
|
||||
fn sub(&self, other: &NVec<D, T>) -> NVec<D, T>
|
||||
{ NVec { at: map2(self.at, other.at, | a, b | *a - *b) } }
|
||||
{ NVec { at: map_zip(self.at, other.at, | a, b | *a - *b) } }
|
||||
}
|
||||
|
||||
impl<D: Dim, T:Copy + Mul<T, T> + Add<T, T> + Sqrt + Zero> Dot<T> for NVec<D, T>
|
||||
impl<D, T:Copy + Neg<T>> Neg<NVec<D, T>> for NVec<D, T>
|
||||
{
|
||||
fn neg(&self) -> NVec<D, T>
|
||||
{ NVec { at: map(self.at, |a| -a) } }
|
||||
}
|
||||
|
||||
impl<D: Dim, T:Copy + Mul<T, T> + Add<T, T> + Algebraic + Zero>
|
||||
Dot<T> for NVec<D, T>
|
||||
{
|
||||
fn dot(&self, other: &NVec<D, T>) -> T
|
||||
{
|
||||
@ -70,6 +76,11 @@ impl<D: Dim, T:Copy + Zero> Zero for NVec<D, T>
|
||||
|
||||
NVec { at: from_elem(Dim::dim::<D>(), _0) }
|
||||
}
|
||||
|
||||
fn is_zero(&self) -> bool
|
||||
{
|
||||
all(self.at, |e| e.is_zero())
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Dim, T:ToStr> ToStr for NVec<D, T>
|
||||
|
@ -1,4 +1,5 @@
|
||||
pub trait Inv
|
||||
{
|
||||
fn inv(&self) -> Self;
|
||||
fn inverse(&self) -> Self;
|
||||
fn invert(&mut self);
|
||||
}
|
||||
|
4
src/traits/workarounds/README
Normal file
4
src/traits/workarounds/README
Normal file
@ -0,0 +1,4 @@
|
||||
This packages contains everything done because current (stable) compiler either
|
||||
bugs or miss features.
|
||||
Therefore, keep in mind anything in there will be inevitably removed some days.
|
||||
So dont rely on them too much.
|
18
src/traits/workarounds/rlmul.rs
Normal file
18
src/traits/workarounds/rlmul.rs
Normal file
@ -0,0 +1,18 @@
|
||||
/** This is a workaround of the fact we cannot implement the same trait
|
||||
* (with different type parameters) twice for the same type:
|
||||
* ~~~
|
||||
* trait Mul<V, V> for M
|
||||
* trait Mul<V2, V2> for M
|
||||
* ~~~
|
||||
*/
|
||||
pub trait RMul<V>
|
||||
{
|
||||
/// Computes self * v
|
||||
fn rmul(&self, v : &V) -> V;
|
||||
}
|
||||
|
||||
pub trait LMul<V>
|
||||
{
|
||||
/// Computes v * self
|
||||
fn lmul(&self, &V) -> V;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
// FIXME: this does not seem to exist already
|
||||
// but it will surely be added someday.
|
||||
|
||||
pub trait Sqrt
|
||||
{
|
||||
fn sqrt(&self) -> Self;
|
||||
}
|
||||
|
||||
impl Sqrt for f64
|
||||
{
|
||||
fn sqrt(&self) -> f64 { f64::sqrt(*self) }
|
||||
}
|
||||
|
||||
impl Sqrt for f32
|
||||
{
|
||||
fn sqrt(&self) -> f32 { f32::sqrt(*self) }
|
||||
}
|
@ -1,5 +1,19 @@
|
||||
// Trigonometric is available in core, but compilation fails with internal
|
||||
// error.
|
||||
|
||||
use core::f64::{cos, sin};
|
||||
|
||||
pub trait Trigonometric
|
||||
{
|
||||
fn sin(&self) -> Self;
|
||||
fn cos(&self) -> Self;
|
||||
fn cos(Self) -> Self;
|
||||
fn sin(Self) -> Self;
|
||||
}
|
||||
|
||||
impl Trigonometric for f64
|
||||
{
|
||||
fn cos(a: f64) -> f64
|
||||
{ cos(a) }
|
||||
|
||||
fn sin(a: f64) -> f64
|
||||
{ sin(a) }
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user