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::transformation::{Transform}; // FIXME: implement Transformation and Transformable
|
||||||
use traits::homogeneous::ToHomogeneous;
|
use traits::homogeneous::ToHomogeneous;
|
||||||
use traits::indexable::Indexable;
|
use traits::indexable::Indexable;
|
||||||
use traits::vector::AlgebraicVec;
|
use traits::norm::Norm;
|
||||||
use vec::Vec1;
|
use vec::Vec1;
|
||||||
use mat::{Mat2, Mat3};
|
use mat::{Mat2, Mat3};
|
||||||
use vec::Vec3;
|
use vec::Vec3;
|
||||||
|
|
|
@ -3,7 +3,6 @@ use std::vec;
|
||||||
use std::vec::{VecIterator, VecMutIterator};
|
use std::vec::{VecIterator, VecMutIterator};
|
||||||
use std::cmp::ApproxEq;
|
use std::cmp::ApproxEq;
|
||||||
use std::iterator::FromIterator;
|
use std::iterator::FromIterator;
|
||||||
use traits::vector::{Vec, AlgebraicVec};
|
|
||||||
use traits::iterable::{Iterable, IterableMut};
|
use traits::iterable::{Iterable, IterableMut};
|
||||||
use traits::translation::Translation;
|
use traits::translation::Translation;
|
||||||
use traits::scalar_op::{ScalarAdd, ScalarSub};
|
use traits::scalar_op::{ScalarAdd, ScalarSub};
|
||||||
|
|
|
@ -59,6 +59,8 @@ pub mod traits
|
||||||
pub mod homogeneous;
|
pub mod homogeneous;
|
||||||
pub mod vec_cast;
|
pub mod vec_cast;
|
||||||
pub mod mat_cast;
|
pub mod mat_cast;
|
||||||
|
pub mod norm;
|
||||||
|
pub mod dot;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -13,7 +13,7 @@ use traits::indexable::Indexable;
|
||||||
#[test]
|
#[test]
|
||||||
use traits::transpose::Transpose;
|
use traits::transpose::Transpose;
|
||||||
#[test]
|
#[test]
|
||||||
use traits::vector::AlgebraicVec;
|
use traits::norm::Norm;
|
||||||
#[test]
|
#[test]
|
||||||
use vec::{Vec1, Vec3};
|
use vec::{Vec1, Vec3};
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -13,7 +13,9 @@ use traits::basis::Basis;
|
||||||
#[test]
|
#[test]
|
||||||
use traits::cross::Cross;
|
use traits::cross::Cross;
|
||||||
#[test]
|
#[test]
|
||||||
use traits::vector::{Vec, AlgebraicVec};
|
use traits::dot::Dot;
|
||||||
|
#[test]
|
||||||
|
use traits::norm::Norm;
|
||||||
#[test]
|
#[test]
|
||||||
use traits::iterable::{Iterable, IterableMut};
|
use traits::iterable::{Iterable, IterableMut};
|
||||||
#[test]
|
#[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::iterable::Iterable;
|
||||||
use traits::sample::UniformSphereSample;
|
use traits::sample::UniformSphereSample;
|
||||||
use traits::scalar_op::{ScalarAdd, ScalarSub};
|
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
|
// NOTE: cant call that `Vector` because it conflicts with std::Vector
|
||||||
/// Trait grouping most common operations on vectors.
|
/// 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>
|
pub trait Vec<N>: Dim + Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Zero + Eq + Mul<N, Self>
|
||||||
+ Div<N, Self>
|
+ Div<N, Self> + 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 {
|
|
||||||
(*self - *b).dot(c)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait of vector with components implementing the `Algebraic` trait.
|
/// Trait of vector with components implementing the `Algebraic` trait.
|
||||||
pub trait AlgebraicVec<N: Algebraic>: Vec<N> {
|
pub trait AlgebraicVec<N: Algebraic>: Vec<N> + Norm<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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait grouping uncommon, low-level and borderline (from the mathematical point of view)
|
/// 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>
|
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,
|
impl<N,
|
||||||
V: Vec<N> + Basis + Indexable<uint, N> + Iterable<N> + Round +
|
V: Vec<N> + Basis + Indexable<uint, N> + Iterable<N> + Round +
|
||||||
UniformSphereSample + ScalarAdd<N> + ScalarSub<N> + Bounded + Orderable>
|
UniformSphereSample + ScalarAdd<N> + ScalarSub<N> + Bounded + Orderable>
|
||||||
VecExt<N> for V;
|
VecExt<N> for V;
|
||||||
|
|
||||||
impl<N: Algebraic, V: AlgebraicVec<N> + VecExt<N>>
|
impl<N: Algebraic, V: AlgebraicVec<N> + VecExt<N>> AlgebraicVecExt<N> for V;
|
||||||
AlgebraicVecExt<N> for V;
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ pub use traits::sample::UniformSphereSample;
|
||||||
pub use traits::scalar_op::{ScalarAdd, ScalarSub};
|
pub use traits::scalar_op::{ScalarAdd, ScalarSub};
|
||||||
pub use traits::cross::{Cross, CrossMatrix};
|
pub use traits::cross::{Cross, CrossMatrix};
|
||||||
pub use traits::outer::Outer;
|
pub use traits::outer::Outer;
|
||||||
|
pub use traits::dot::Dot;
|
||||||
|
pub use traits::norm::Norm;
|
||||||
|
|
||||||
// structs
|
// structs
|
||||||
pub use dvec::DVec;
|
pub use dvec::DVec;
|
||||||
|
|
|
@ -9,7 +9,8 @@ use traits::dim::Dim;
|
||||||
use traits::translation::Translation;
|
use traits::translation::Translation;
|
||||||
use traits::scalar_op::{ScalarAdd, ScalarSub};
|
use traits::scalar_op::{ScalarAdd, ScalarSub};
|
||||||
use traits::indexable::Indexable;
|
use traits::indexable::Indexable;
|
||||||
use traits::vector::{Vec, AlgebraicVec};
|
use traits::dot::Dot;
|
||||||
|
use traits::norm::Norm;
|
||||||
use vec;
|
use vec;
|
||||||
|
|
||||||
impl<N> vec::Vec0<N> {
|
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]
|
#[inline]
|
||||||
fn dot(&self, _: &vec::Vec0<N>) -> N {
|
fn dot(&self, _: &vec::Vec0<N>) -> N {
|
||||||
Zero::zero()
|
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]
|
#[inline]
|
||||||
fn sqnorm(&self) -> N {
|
fn sqnorm(&self) -> N {
|
||||||
self.dot(self)
|
self.dot(self)
|
||||||
|
|
|
@ -277,7 +277,7 @@ macro_rules! neg_impl(
|
||||||
|
|
||||||
macro_rules! dot_impl(
|
macro_rules! dot_impl(
|
||||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
($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]
|
#[inline]
|
||||||
fn dot(&self, other: &$t<N>) -> N {
|
fn dot(&self, other: &$t<N>) -> N {
|
||||||
self.$comp0 * other.$comp0 $(+ self.$compN * other.$compN )*
|
self.$comp0 * other.$comp0 $(+ self.$compN * other.$compN )*
|
||||||
|
@ -380,7 +380,7 @@ macro_rules! translation_impl(
|
||||||
|
|
||||||
macro_rules! norm_impl(
|
macro_rules! norm_impl(
|
||||||
($t: ident) => (
|
($t: ident) => (
|
||||||
impl<N: Clone + Num + Algebraic> AlgebraicVec<N> for $t<N> {
|
impl<N: Clone + Num + Algebraic> Norm<N> for $t<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sqnorm(&self) -> N {
|
fn sqnorm(&self) -> N {
|
||||||
self.dot(self)
|
self.dot(self)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::num::{Zero, One};
|
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};
|
use mat::{Mat3, Row};
|
||||||
|
|
||||||
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec1<N>> for Vec2<N> {
|
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>
|
impl<N: Clone + Ord + Algebraic + Signed> Basis for Vec3<N> {
|
||||||
Basis for Vec3<N> {
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn canonical_basis(f: &fn(Vec3<N>) -> bool) {
|
fn canonical_basis(f: &fn(Vec3<N>) -> bool) {
|
||||||
if !f(Vec3::new(One::one(), Zero::zero(), Zero::zero())) { return };
|
if !f(Vec3::new(One::one(), Zero::zero(), Zero::zero())) { return };
|
||||||
|
|
Loading…
Reference in New Issue