Add SubDot trait and basic implementations.

This commit is contained in:
Sébastien Crozet 2013-05-25 13:51:51 +00:00
parent 2b9dc1d2e3
commit 898a87b46c
8 changed files with 61 additions and 8 deletions

View File

@ -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<T: Copy + Add<T, T>> Translation<Vec1<T>> for Vec1<T>
{ *self += *t }
}
impl<T:Copy + Mul<T, T> + Add<T, T> + Algebraic> Dot<T> for Vec1<T>
impl<T:Copy + Mul<T, T>> Dot<T> for Vec1<T>
{
fn dot(&self, other : &Vec1<T>) -> T
{ self.x * other.x }
}
impl<T:Copy + Mul<T, T> + Sub<T, T>> SubDot<T> for Vec1<T>
{
fn sub_dot(&self, a: &Vec1<T>, b: &Vec1<T>) -> T
{ (self.x - a.x) * b.x }
}
impl<T:Copy + Mul<T, T> + Add<T, T> + Div<T, T> + Algebraic>
Norm<T> for Vec1<T>
{

View File

@ -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<T: Copy + Add<T, T>> Translation<Vec2<T>> for Vec2<T>
{ *self += *t; }
}
impl<T:Copy + Mul<T, T> + Add<T, T> + Algebraic> Dot<T> for Vec2<T>
impl<T:Copy + Mul<T, T> + Add<T, T>> Dot<T> for Vec2<T>
{
fn dot(&self, other : &Vec2<T>) -> T
{ self.x * other.x + self.y * other.y }
}
impl<T:Copy + Mul<T, T> + Add<T, T> + Sub<T, T>> SubDot<T> for Vec2<T>
{
fn sub_dot(&self, a: &Vec2<T>, b: &Vec2<T>) -> T
{ (self.x - a.x) * b.x + (self.y - a.y) * b.y }
}
impl<T:Copy + Mul<T, T> + Add<T, T> + Div<T, T> + Algebraic>
Norm<T> for Vec2<T>
{

View File

@ -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<T:Copy + Neg<T>> Neg<Vec3<T>> for Vec3<T>
{ vec3(-self.x, -self.y, -self.z) }
}
impl<T:Copy + Mul<T, T> + Add<T, T> + Algebraic> Dot<T> for Vec3<T>
impl<T:Copy + Mul<T, T> + Add<T, T>> Dot<T> for Vec3<T>
{
fn dot(&self, other : &Vec3<T>) -> T
{ self.x * other.x + self.y * other.y + self.z * other.z }
}
impl<T:Copy + Mul<T, T> + Add<T, T> + Sub<T, T>> SubDot<T> for Vec3<T>
{
fn sub_dot(&self, a: &Vec3<T>, b: &Vec3<T>) -> T
{ (self.x - a.x) * b.x + (self.y - a.y) * b.y + (self.z - a.z) * b.z }
}
impl<T:Copy + Mul<T, T> + Add<T, T> + Div<T, T> + Algebraic>
Norm<T> for Vec3<T>
{

View File

@ -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.

View File

@ -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<D, T: Copy + Neg<T>> Neg<NVec<D, T>> for NVec<D, T>
{ NVec { at: map(self.at, |a| -a) } }
}
impl<D: Dim, T: Copy + Mul<T, T> + Add<T, T> + Algebraic + Zero>
impl<D: Dim, T: Copy + Ring>
Dot<T> for NVec<D, T>
{
fn dot(&self, other: &NVec<D, T>) -> T
@ -66,6 +69,19 @@ Dot<T> for NVec<D, T>
}
}
impl<D: Dim, T: Copy + Ring> SubDot<T> for NVec<D, T>
{
fn sub_dot(&self, a: &NVec<D, T>, b: &NVec<D, T>) -> T
{
let mut res = Zero::zero::<T>();
for uint::range(0u, Dim::dim::<D>()) |i|
{ res += (self.at[i] - a.at[i]) * b.at[i]; }
res
}
}
impl<D: Dim, T: Copy + Mul<T, T>>
ScalarMul<T> for NVec<D, T>
{
@ -131,8 +147,7 @@ impl<D: Dim, T: Clone + Copy + Add<T, T>> Translation<NVec<D, T>> for NVec<D, T>
{ *self = *self + *t; }
}
impl<D: Dim, T: Copy + Mul<T, T> + Add<T, T> + Div<T, T> + Algebraic + Zero +
Clone>
impl<D: Dim, T: Copy + DivisionRing + Algebraic + Clone>
Norm<T> for NVec<D, T>
{
fn sqnorm(&self) -> T
@ -162,8 +177,7 @@ Norm<T> for NVec<D, T>
}
impl<D: Dim,
T: Copy + One + Zero + Neg<T> + Ord + Mul<T, T> + Sub<T, T> + Add<T, T> +
Div<T, T> + Algebraic + Clone + ApproxEq<T>>
T: Copy + DivisionRing + Algebraic + Clone + ApproxEq<T>>
Basis for NVec<D, T>
{
fn canonical_basis() -> ~[NVec<D, T>]

View File

@ -6,3 +6,5 @@ use traits::ring::Ring;
*/
pub trait DivisionRing : Ring + Div<Self, Self>
{ }
impl<T: Ring + Div<T, T>> DivisionRing for T;

View File

@ -9,3 +9,6 @@ use core::num::{One, Zero};
pub trait Ring :
Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Mul<Self, Self> + One + Zero
{ }
impl<T: Sub<T, T> + Add<T, T> + Neg<T> + Mul<T, T> + One + Zero>
Ring for T;

12
src/traits/sub_dot.rs Normal file
View File

@ -0,0 +1,12 @@
pub trait SubDot<T>
{
/**
* 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;
}