diff --git a/src/dim1/vec1.rs b/src/dim1/vec1.rs index c0f19908..fbb26af0 100644 --- a/src/dim1/vec1.rs +++ b/src/dim1/vec1.rs @@ -6,6 +6,7 @@ use traits::dim::Dim; use traits::dot::Dot; use traits::norm::Norm; use traits::translation::Translation; +use traits::sub_dot::SubDot; use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub}; #[deriving(Eq)] @@ -86,12 +87,18 @@ impl> Translation> for Vec1 { *self += *t } } -impl + Add + Algebraic> Dot for Vec1 +impl> Dot for Vec1 { fn dot(&self, other : &Vec1) -> T { self.x * other.x } } +impl + Sub> SubDot for Vec1 +{ + fn sub_dot(&self, a: &Vec1, b: &Vec1) -> T + { (self.x - a.x) * b.x } +} + impl + Add + Div + Algebraic> Norm for Vec1 { diff --git a/src/dim2/vec2.rs b/src/dim2/vec2.rs index bde7270c..aaf01032 100644 --- a/src/dim2/vec2.rs +++ b/src/dim2/vec2.rs @@ -6,6 +6,7 @@ use traits::basis::Basis; use traits::cross::Cross; use traits::dim::Dim; use traits::dot::Dot; +use traits::sub_dot::SubDot; use traits::norm::Norm; use traits::translation::Translation; use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub}; @@ -103,12 +104,18 @@ impl> Translation> for Vec2 { *self += *t; } } -impl + Add + Algebraic> Dot for Vec2 +impl + Add> Dot for Vec2 { fn dot(&self, other : &Vec2) -> T { self.x * other.x + self.y * other.y } } +impl + Add + Sub> SubDot for Vec2 +{ + fn sub_dot(&self, a: &Vec2, b: &Vec2) -> T + { (self.x - a.x) * b.x + (self.y - a.y) * b.y } +} + impl + Add + Div + Algebraic> Norm for Vec2 { diff --git a/src/dim3/vec3.rs b/src/dim3/vec3.rs index 103aeeb3..96dc17a0 100644 --- a/src/dim3/vec3.rs +++ b/src/dim3/vec3.rs @@ -5,6 +5,7 @@ use traits::basis::Basis; use traits::cross::Cross; use traits::dim::Dim; use traits::dot::Dot; +use traits::sub_dot::SubDot; use traits::norm::Norm; use traits::translation::Translation; use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub}; @@ -115,12 +116,18 @@ impl> Neg> for Vec3 { vec3(-self.x, -self.y, -self.z) } } -impl + Add + Algebraic> Dot for Vec3 +impl + Add> Dot for Vec3 { fn dot(&self, other : &Vec3) -> T { self.x * other.x + self.y * other.y + self.z * other.z } } +impl + Add + Sub> SubDot for Vec3 +{ + fn sub_dot(&self, a: &Vec3, b: &Vec3) -> T + { (self.x - a.x) * b.x + (self.y - a.y) * b.y + (self.z - a.z) * b.z } +} + impl + Add + Div + Algebraic> Norm for Vec3 { diff --git a/src/nalgebra.rc b/src/nalgebra.rc index b79749e2..01e71d42 100644 --- a/src/nalgebra.rc +++ b/src/nalgebra.rc @@ -66,6 +66,7 @@ pub mod traits pub mod vector_space; pub mod ring; pub mod division_ring; + pub mod sub_dot; /// This package contains everything done because the current compiler either /// crashes or miss features. diff --git a/src/ndim/nvec.rs b/src/ndim/nvec.rs index eb20aeea..ae9467ab 100644 --- a/src/ndim/nvec.rs +++ b/src/ndim/nvec.rs @@ -3,8 +3,11 @@ use core::rand::{Rand, Rng, RngUtil}; use core::vec::{map_zip, from_elem, map, all, all2}; use core::cmp::ApproxEq; use traits::basis::Basis; +use traits::ring::Ring; +use traits::division_ring::DivisionRing; use traits::dim::Dim; use traits::dot::Dot; +use traits::sub_dot::SubDot; use traits::norm::Norm; use traits::translation::Translation; use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub}; @@ -52,7 +55,7 @@ impl> Neg> for NVec { NVec { at: map(self.at, |a| -a) } } } -impl + Add + Algebraic + Zero> +impl Dot for NVec { fn dot(&self, other: &NVec) -> T @@ -66,6 +69,19 @@ Dot for NVec } } +impl SubDot for NVec +{ + fn sub_dot(&self, a: &NVec, b: &NVec) -> T + { + let mut res = Zero::zero::(); + + for uint::range(0u, Dim::dim::()) |i| + { res += (self.at[i] - a.at[i]) * b.at[i]; } + + res + } +} + impl> ScalarMul for NVec { @@ -131,8 +147,7 @@ impl> Translation> for NVec { *self = *self + *t; } } -impl + Add + Div + Algebraic + Zero + - Clone> +impl Norm for NVec { fn sqnorm(&self) -> T @@ -162,8 +177,7 @@ Norm for NVec } impl + Ord + Mul + Sub + Add + - Div + Algebraic + Clone + ApproxEq> + T: Copy + DivisionRing + Algebraic + Clone + ApproxEq> Basis for NVec { fn canonical_basis() -> ~[NVec] diff --git a/src/traits/division_ring.rs b/src/traits/division_ring.rs index 69394c6e..cf50f689 100644 --- a/src/traits/division_ring.rs +++ b/src/traits/division_ring.rs @@ -6,3 +6,5 @@ use traits::ring::Ring; */ pub trait DivisionRing : Ring + Div { } + +impl> DivisionRing for T; diff --git a/src/traits/ring.rs b/src/traits/ring.rs index fbc49e91..d09661d0 100644 --- a/src/traits/ring.rs +++ b/src/traits/ring.rs @@ -9,3 +9,6 @@ use core::num::{One, Zero}; pub trait Ring : Sub + Add + Neg + Mul + One + Zero { } + +impl + Add + Neg + Mul + One + Zero> +Ring for T; diff --git a/src/traits/sub_dot.rs b/src/traits/sub_dot.rs new file mode 100644 index 00000000..e0b8b42c --- /dev/null +++ b/src/traits/sub_dot.rs @@ -0,0 +1,12 @@ +pub trait SubDot +{ + /** + * Short-cut to compute the projecton of a point on a vector, but without + * computing intermediate vectors. + * This must be equivalent to: + * + * (a - b).dot(c) + * + */ + fn sub_dot(&self, b: &Self, c: &Self) -> T; +}