Add a `Dot` and a `Norm` trait for vectors having a dot product and a norm.
Those methods are not part of the `Vec` and `AlgebraicVec` traits any more.
This commit is contained in:
parent
37f0b123e0
commit
bdf82748dc
|
@ -10,7 +10,7 @@ use traits::rotation::{Rotation, Rotate};
|
|||
use traits::transformation::{Transform}; // FIXME: implement Transformation and Transformable
|
||||
use traits::homogeneous::ToHomogeneous;
|
||||
use traits::indexable::Indexable;
|
||||
use traits::vector::AlgebraicVec;
|
||||
use traits::norm::Norm;
|
||||
use vec::Vec1;
|
||||
use mat::{Mat2, Mat3};
|
||||
use vec::Vec3;
|
||||
|
|
|
@ -3,7 +3,6 @@ use std::vec;
|
|||
use std::vec::{VecIterator, VecMutIterator};
|
||||
use std::cmp::ApproxEq;
|
||||
use std::iterator::FromIterator;
|
||||
use traits::vector::{Vec, AlgebraicVec};
|
||||
use traits::iterable::{Iterable, IterableMut};
|
||||
use traits::translation::Translation;
|
||||
use traits::scalar_op::{ScalarAdd, ScalarSub};
|
||||
|
|
|
@ -59,6 +59,8 @@ pub mod traits
|
|||
pub mod homogeneous;
|
||||
pub mod vec_cast;
|
||||
pub mod mat_cast;
|
||||
pub mod norm;
|
||||
pub mod dot;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -13,7 +13,7 @@ use traits::indexable::Indexable;
|
|||
#[test]
|
||||
use traits::transpose::Transpose;
|
||||
#[test]
|
||||
use traits::vector::AlgebraicVec;
|
||||
use traits::norm::Norm;
|
||||
#[test]
|
||||
use vec::{Vec1, Vec3};
|
||||
#[test]
|
||||
|
|
|
@ -13,7 +13,9 @@ use traits::basis::Basis;
|
|||
#[test]
|
||||
use traits::cross::Cross;
|
||||
#[test]
|
||||
use traits::vector::{Vec, AlgebraicVec};
|
||||
use traits::dot::Dot;
|
||||
#[test]
|
||||
use traits::norm::Norm;
|
||||
#[test]
|
||||
use traits::iterable::{Iterable, IterableMut};
|
||||
#[test]
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/// Traits of objects having a dot product.
|
||||
pub trait Dot<N> {
|
||||
/// Computes the dot (inner) product of two vectors.
|
||||
#[inline]
|
||||
fn dot(&self, &Self) -> N;
|
||||
|
||||
/**
|
||||
* Short-cut to compute the projection of a point on a vector, but without
|
||||
* computing intermediate vectors.
|
||||
* This must be equivalent to:
|
||||
*
|
||||
* (a - b).dot(c)
|
||||
*
|
||||
*/
|
||||
#[inline]
|
||||
fn sub_dot(&self, b: &Self, c: &Self) -> N;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/// Traits of objects having an euclidian norm.
|
||||
pub trait Norm<N: Algebraic> {
|
||||
/// Computes the norm a an object.
|
||||
#[inline]
|
||||
fn norm(&self) -> N {
|
||||
self.sqnorm().sqrt()
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the squared norm of an object. Usually faster than computing the
|
||||
* norm itself.
|
||||
*/
|
||||
#[inline]
|
||||
fn sqnorm(&self) -> N;
|
||||
|
||||
/// Gets the normalized version of the argument.
|
||||
#[inline]
|
||||
fn normalized(&self) -> Self;
|
||||
|
||||
/// In-place version of `normalized`.
|
||||
#[inline]
|
||||
fn normalize(&mut self) -> N;
|
||||
}
|
|
@ -5,62 +5,17 @@ use traits::indexable::Indexable;
|
|||
use traits::iterable::Iterable;
|
||||
use traits::sample::UniformSphereSample;
|
||||
use traits::scalar_op::{ScalarAdd, ScalarSub};
|
||||
use traits::dot::Dot;
|
||||
use traits::norm::Norm;
|
||||
|
||||
// NOTE: cant call that `Vector` because it conflicts with std::Vector
|
||||
/// Trait grouping most common operations on vectors.
|
||||
pub trait Vec<N>: Dim + Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Zero + Eq + Mul<N, Self>
|
||||
+ Div<N, Self>
|
||||
{
|
||||
/// Computes the dot (inner) product of two vectors.
|
||||
#[inline]
|
||||
fn dot(&self, &Self) -> N;
|
||||
|
||||
/**
|
||||
* Short-cut to compute the projection of a point on a vector, but without
|
||||
* computing intermediate vectors.
|
||||
* This must be equivalent to:
|
||||
*
|
||||
* (a - b).dot(c)
|
||||
*
|
||||
*/
|
||||
#[inline]
|
||||
fn sub_dot(&self, b: &Self, c: &Self) -> N {
|
||||
(*self - *b).dot(c)
|
||||
}
|
||||
+ Div<N, Self> + Dot<N> {
|
||||
}
|
||||
|
||||
/// Trait of vector with components implementing the `Algebraic` trait.
|
||||
pub trait AlgebraicVec<N: Algebraic>: Vec<N> {
|
||||
/// Computes the norm a an object.
|
||||
#[inline]
|
||||
fn norm(&self) -> N {
|
||||
self.sqnorm().sqrt()
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the squared norm of an object. Usually faster than computing the
|
||||
* norm itself.
|
||||
*/
|
||||
#[inline]
|
||||
fn sqnorm(&self) -> N {
|
||||
self.dot(self)
|
||||
}
|
||||
|
||||
/// Gets the normalized version of the argument.
|
||||
#[inline]
|
||||
fn normalized(&self) -> Self {
|
||||
self / self.norm()
|
||||
}
|
||||
|
||||
/// In-place version of `normalized`.
|
||||
#[inline]
|
||||
fn normalize(&mut self) -> N {
|
||||
let norm = self.norm();
|
||||
|
||||
*self = *self / norm;
|
||||
|
||||
norm
|
||||
}
|
||||
pub trait AlgebraicVec<N: Algebraic>: Vec<N> + Norm<N> {
|
||||
}
|
||||
|
||||
/// Trait grouping uncommon, low-level and borderline (from the mathematical point of view)
|
||||
|
@ -74,10 +29,14 @@ pub trait VecExt<N>: Vec<N> + Basis + Indexable<uint, N> + Iterable<N> + Round +
|
|||
pub trait AlgebraicVecExt<N: Algebraic>: AlgebraicVec<N> + VecExt<N>
|
||||
{ }
|
||||
|
||||
impl<N, V: Dim + Sub<V, V> + Add<V, V> + Neg<V> + Zero + Eq + Mul<N, V> + Div<N, V> + Dot<N>>
|
||||
Vec<N> for V;
|
||||
|
||||
impl<N: Algebraic, V: Vec<N> + Norm<N>> AlgebraicVec<N> for V;
|
||||
|
||||
impl<N,
|
||||
V: Vec<N> + Basis + Indexable<uint, N> + Iterable<N> + Round +
|
||||
UniformSphereSample + ScalarAdd<N> + ScalarSub<N> + Bounded + Orderable>
|
||||
VecExt<N> for V;
|
||||
|
||||
impl<N: Algebraic, V: AlgebraicVec<N> + VecExt<N>>
|
||||
AlgebraicVecExt<N> for V;
|
||||
impl<N: Algebraic, V: AlgebraicVec<N> + VecExt<N>> AlgebraicVecExt<N> for V;
|
||||
|
|
|
@ -20,6 +20,8 @@ pub use traits::sample::UniformSphereSample;
|
|||
pub use traits::scalar_op::{ScalarAdd, ScalarSub};
|
||||
pub use traits::cross::{Cross, CrossMatrix};
|
||||
pub use traits::outer::Outer;
|
||||
pub use traits::dot::Dot;
|
||||
pub use traits::norm::Norm;
|
||||
|
||||
// structs
|
||||
pub use dvec::DVec;
|
||||
|
|
|
@ -9,7 +9,8 @@ use traits::dim::Dim;
|
|||
use traits::translation::Translation;
|
||||
use traits::scalar_op::{ScalarAdd, ScalarSub};
|
||||
use traits::indexable::Indexable;
|
||||
use traits::vector::{Vec, AlgebraicVec};
|
||||
use traits::dot::Dot;
|
||||
use traits::norm::Norm;
|
||||
use vec;
|
||||
|
||||
impl<N> vec::Vec0<N> {
|
||||
|
@ -95,7 +96,7 @@ impl<N: Neg<N>> Neg<vec::Vec0<N>> for vec::Vec0<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Num + Clone> Vec<N> for vec::Vec0<N> {
|
||||
impl<N: Num + Clone> Dot<N> for vec::Vec0<N> {
|
||||
#[inline]
|
||||
fn dot(&self, _: &vec::Vec0<N>) -> N {
|
||||
Zero::zero()
|
||||
|
@ -167,7 +168,7 @@ impl<N: Clone + Add<N, N> + Neg<N>> Translation<vec::Vec0<N>> for vec::Vec0<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Num + Algebraic> AlgebraicVec<N> for vec::Vec0<N> {
|
||||
impl<N: Clone + Num + Algebraic> Norm<N> for vec::Vec0<N> {
|
||||
#[inline]
|
||||
fn sqnorm(&self) -> N {
|
||||
self.dot(self)
|
||||
|
|
|
@ -277,7 +277,7 @@ macro_rules! neg_impl(
|
|||
|
||||
macro_rules! dot_impl(
|
||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||
impl<N: Num + Clone> Vec<N> for $t<N> {
|
||||
impl<N: Num + Clone> Dot<N> for $t<N> {
|
||||
#[inline]
|
||||
fn dot(&self, other: &$t<N>) -> N {
|
||||
self.$comp0 * other.$comp0 $(+ self.$compN * other.$compN )*
|
||||
|
@ -380,7 +380,7 @@ macro_rules! translation_impl(
|
|||
|
||||
macro_rules! norm_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Clone + Num + Algebraic> AlgebraicVec<N> for $t<N> {
|
||||
impl<N: Clone + Num + Algebraic> Norm<N> for $t<N> {
|
||||
#[inline]
|
||||
fn sqnorm(&self) -> N {
|
||||
self.dot(self)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::num::{Zero, One};
|
||||
use vec::{Vec1, Vec2, Vec3, AlgebraicVec, VecCast, UniformSphereSample, Cross, CrossMatrix, Basis};
|
||||
use vec::{Vec1, Vec2, Vec3, Norm, VecCast, UniformSphereSample, Cross, CrossMatrix, Basis};
|
||||
use mat::{Mat3, Row};
|
||||
|
||||
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec1<N>> for Vec2<N> {
|
||||
|
@ -84,8 +84,7 @@ impl<N: Clone + One + Zero + Neg<N>> Basis for Vec2<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Ord + Algebraic + Signed>
|
||||
Basis for Vec3<N> {
|
||||
impl<N: Clone + Ord + Algebraic + Signed> Basis for Vec3<N> {
|
||||
#[inline(always)]
|
||||
fn canonical_basis(f: &fn(Vec3<N>) -> bool) {
|
||||
if !f(Vec3::new(One::one(), Zero::zero(), Zero::zero())) { return };
|
||||
|
|
Loading…
Reference in New Issue