diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..c2a48074 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +all: + rustpkg install + +doc: + rust doc src/nalgebra.rc --output-dir doc + +.PHONY:doc diff --git a/pkg.rs b/pkg.rs new file mode 100644 index 00000000..8bd591f5 --- /dev/null +++ b/pkg.rs @@ -0,0 +1,3 @@ +#[pkg(id = "re.crozet.nalgebra", vers = "0.0.0")]; + +#[pkg_crate(file = "src/nalgebra.rc")]; diff --git a/src/dim2/mat2.rs b/src/dim2/mat2.rs new file mode 100644 index 00000000..831f99fa --- /dev/null +++ b/src/dim2/mat2.rs @@ -0,0 +1,99 @@ +use core::num::{One, Zero}; +use traits::inv::Inv; +use dim2::vec2::Vec2; + +pub struct Mat2 +{ + m11: T, m12: T, + m21: T, m22: T +} + +pub fn Mat2(m11: T, m12: T, m21: T, m22: T) -> Mat2 +{ + Mat2 + { + m11: m11, m12: m12, + m21: m21, m22: m22, + } +} + +impl One for Mat2 +{ + fn one() -> Mat2 + { + let (_0, _1) = (Zero::zero(), One::one()); + return Mat2(_1, _0, + _0, _1) + } +} + +impl Zero for Mat2 +{ + fn zero() -> Mat2 + { + let _0 = Zero::zero(); + return Mat2(_0, _0, + _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() + // } +} + +impl + Add> Mul, Mat2> for Mat2 +{ + fn mul(&self, other : &Mat2) -> Mat2 + { + Mat2 + (self.m11 * other.m11 + self.m12 * other.m21, + self.m11 * other.m12 + self.m12 * other.m22, + self.m21 * other.m11 + self.m22 * other.m21, + self.m21 * other.m22 + self.m22 * other.m22) + } +} + +// FIXME: implementation of multiple classes for the same struct fails +// with "internal compiler error: Asked to compute kind of a type variable". +// +// impl + Add> Mul, Vec2> for Mat2 +// { +// fn mul(&self, v : &Vec2) -> Vec2 +// { Vec2(self.m11 * v.x + self.m12 * v.y, self.m21 * v.x + self.m22 * v.y) } +// } + +impl + Add> Mul, Vec2> for Vec2 +{ + fn mul(&self, m : &Mat2) -> Vec2 + { Vec2(self.x * m.m11 + self.y * m.m21, self.x * m.m12 + self.y * m.m22) } +} + +impl + Div + Sub + Neg + Eq + Zero> +Inv for Mat2 +{ + fn inv(&self) -> Mat2 + { + let det = self.m11 * self.m22 - self.m21 * self.m12; + + assert!(det != Zero::zero()); + + Mat2(self.m22 / det , -self.m12 / det, + -self.m21 / det, self.m11 / det) + } +} + +impl ToStr for Mat2 +{ + fn to_str(&self) -> ~str + { + ~"Mat2 {" + + " m11: " + self.m11.to_str() + + " m12: " + self.m12.to_str() + + + " m21: " + self.m21.to_str() + + " m22: " + self.m22.to_str() + + " }" + } +} diff --git a/src/dim2/vec2.rs b/src/dim2/vec2.rs new file mode 100644 index 00000000..bb4b4f8a --- /dev/null +++ b/src/dim2/vec2.rs @@ -0,0 +1,43 @@ +use traits::dot::Dot; +use traits::sqrt::Sqrt; + +#[deriving(Eq)] +pub struct Vec2 +{ + x : T, + y : T +} + +pub fn Vec2(x: T, y: T) -> Vec2 +{ Vec2 {x: x, y: y} } + + +impl> Add, Vec2> for Vec2 +{ + fn add(&self, other: &Vec2) -> Vec2 + { Vec2(self.x + other.x, self.y + other.y) } +} + +impl> Sub, Vec2> for Vec2 +{ + fn sub(&self, other: &Vec2) -> Vec2 + { Vec2(self.x - other.x, self.y - other.y) } +} + +impl + Add + Sqrt> Dot for Vec2 +{ + fn dot(&self, other : &Vec2) -> T + { self.x * other.x + self.y * other.y } + + fn sqnorm(&self) -> T + { self.dot(self) } + + fn norm(&self) -> T + { self.sqnorm().sqrt() } +} + +impl ToStr for Vec2 +{ + fn to_str(&self) -> ~str + { ~"Vec2 { x : " + self.x.to_str() + ", y : " + self.y.to_str() + " }" } +} diff --git a/src/dim3/mat3.rs b/src/dim3/mat3.rs new file mode 100644 index 00000000..2df20705 --- /dev/null +++ b/src/dim3/mat3.rs @@ -0,0 +1,146 @@ +use core::num::{One, Zero}; +use traits::inv::Inv; +use dim3::vec3::Vec3; + +pub struct Mat3 +{ + m11: T, m12: T, m13: T, + m21: T, m22: T, m23: T, + m31: T, m32: T, m33: T +} + +pub fn Mat3(m11: T, m12: T, m13: T, + m21: T, m22: T, m23: T, + m31: T, m32: T, m33: T) -> Mat3 +{ + Mat3 + { + m11: m11, m12: m12, m13: m13, + m21: m21, m22: m22, m23: m23, + m31: m31, m32: m32, m33: m33 + } +} + +impl One for Mat3 +{ + fn one() -> Mat3 + { + let (_0, _1) = (Zero::zero(), One::one()); + return Mat3(_1, _0, _0, + _0, _1, _0, + _0, _0, _1) + } +} + +impl Zero for Mat3 +{ + fn zero() -> Mat3 + { + let _0 = Zero::zero(); + return Mat3(_0, _0, _0, + _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 + Add> Mul, Mat3> for Mat3 +{ + fn mul(&self, other : &Mat3) -> Mat3 + { + Mat3( + self.m11 * other.m11 + self.m12 * other.m21 + self.m13 * other.m31, + self.m11 * other.m12 + self.m12 * other.m22 + self.m13 * other.m32, + self.m11 * other.m13 + self.m12 * other.m23 + self.m13 * other.m33, + + self.m21 * other.m11 + self.m22 * other.m21 + self.m23 * other.m31, + self.m21 * other.m12 + self.m22 * other.m22 + self.m23 * other.m32, + self.m21 * other.m13 + self.m22 * other.m23 + self.m23 * other.m33, + + self.m31 * other.m11 + self.m32 * other.m21 + self.m33 * other.m31, + self.m31 * other.m12 + self.m32 * other.m22 + self.m33 * other.m32, + self.m31 * other.m13 + self.m32 * other.m23 + self.m33 * other.m33 + ) + } +} + +// FIXME: implementation of multiple classes for the same struct fails +// with "internal compiler error: Asked to compute kind of a type variable". +// +// impl + Add> Mul, Vec3> for Mat3 +// { +// fn mul(&self, m : &Mat3) -> Vec3 +// { +// 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 + Add> Mul, Vec3> for Vec3 +{ + fn mul(&self, m : &Mat3) -> Vec3 + { + 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 + Div + Sub + Add + Neg + + Eq + Zero> +Inv for Mat3 +{ + fn inv(&self) -> Mat3 + { + let minor_m22_m33 = self.m22 * self.m33 - self.m32 * self.m23; + let minor_m21_m33 = self.m21 * self.m33 - self.m31 * self.m23; + let minor_m21_m32 = self.m21 * self.m32 - self.m31 * self.m22; + + let det = self.m11 * minor_m22_m33 + - self.m12 * minor_m21_m33 + + self.m13 * minor_m21_m32; + + assert!(det != Zero::zero()); + + Mat3( + (minor_m22_m33 / det), + ((self.m13 * self.m32 - self.m33 * self.m12) / det), + ((self.m12 * self.m23 - self.m22 * self.m13) / det), + + (-minor_m21_m33 / det), + ((self.m11 * self.m33 - self.m31 * self.m13) / det), + ((self.m13 * self.m21 - self.m23 * self.m11) / det), + + (minor_m21_m32 / det), + ((self.m12 * self.m31 - self.m31 * self.m11) / det), + ((self.m11 * self.m22 - self.m21 * self.m12) / det) + ) + } +} + +impl ToStr for Mat3 +{ + fn to_str(&self) -> ~str + { + ~"Mat3 {" + + " m11: " + self.m11.to_str() + + " m12: " + self.m12.to_str() + + " m13: " + self.m13.to_str() + + + " m21: " + self.m21.to_str() + + " m22: " + self.m22.to_str() + + " m23: " + self.m23.to_str() + + + " m31: " + self.m31.to_str() + + " m32: " + self.m32.to_str() + + " m33: " + self.m33.to_str() + + " }" + } +} diff --git a/src/dim3/vec3.rs b/src/dim3/vec3.rs new file mode 100644 index 00000000..9f210c93 --- /dev/null +++ b/src/dim3/vec3.rs @@ -0,0 +1,50 @@ +use traits::dot::Dot; +use traits::sqrt::Sqrt; + +#[deriving(Eq)] +pub struct Vec3 +{ + x : T, + y : T, + z : T +} + +pub fn Vec3(x: T, y: T, z: T) -> Vec3 +{ Vec3 {x: x, y: y, z: z} } + + +impl> Add, Vec3> for Vec3 +{ + fn add(&self, other: &Vec3) -> Vec3 + { Vec3(self.x + other.x, self.y + other.y, self.z + other.z) } +} + +impl> Sub, Vec3> for Vec3 +{ + fn sub(&self, other: &Vec3) -> Vec3 + { Vec3(self.x - other.x, self.y - other.y, self.z - other.z) } +} + +impl ToStr for Vec3 +{ + fn to_str(&self) -> ~str + { + ~"Vec3 " + + "{ x : " + self.x.to_str() + + ", y : " + self.y.to_str() + + ", z : " + self.z.to_str() + + " }" + } +} + +impl + Add + Sqrt> Dot for Vec3 +{ + fn dot(&self, other : &Vec3) -> T + { self.x * other.x + self.y * other.y + self.z * other.z } + + fn sqnorm(&self) -> T + { self.dot(self) } + + fn norm(&self) -> T + { self.sqnorm().sqrt() } +} diff --git a/src/traits/dot.rs b/src/traits/dot.rs new file mode 100644 index 00000000..4d57eeff --- /dev/null +++ b/src/traits/dot.rs @@ -0,0 +1,6 @@ +pub trait Dot +{ + fn dot(&self, &Self) -> T; + fn norm(&self) -> T; + fn sqnorm(&self) -> T; // { self.dot(self); } +} diff --git a/src/traits/inv.rs b/src/traits/inv.rs new file mode 100644 index 00000000..0ce3ffe8 --- /dev/null +++ b/src/traits/inv.rs @@ -0,0 +1,4 @@ +pub trait Inv +{ + fn inv(&self) -> Self; +} diff --git a/src/traits/sqrt.rs b/src/traits/sqrt.rs new file mode 100644 index 00000000..9da09ca6 --- /dev/null +++ b/src/traits/sqrt.rs @@ -0,0 +1,17 @@ +// 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) } +}