Rework of the traits for Vectors.
The goal is to make traits less fine-grained for vectors, and reduce the amount of `use`. - Scalar{Mul, Div} are removed, replaced by Mul<N, V> and Div<N, V>, - Ring and DivisionRing are removed. Use Num instead. - VectorSpace, Dot, and Norm are removed, replaced by the new, higher-level traits. Add four traits: - Vec: common operations on vectors. Replaces VectorSpace and Dot. - AlgebraicVec: Vec + the old Norm trait. - VecExt: Vec + every other traits vectors implement. - AlgebraicVecExt: AlgebraicVec + VecExt.
This commit is contained in:
parent
cead4f8410
commit
347883caa1
|
@ -1,7 +1,6 @@
|
|||
use std::num::{One, Zero};
|
||||
use std::rand::{Rand, Rng, RngUtil};
|
||||
use std::cmp::ApproxEq;
|
||||
use traits::ring::DivisionRing;
|
||||
use traits::rlmul::{RMul, LMul};
|
||||
use traits::cross::Cross;
|
||||
use traits::dim::Dim;
|
||||
|
@ -11,7 +10,7 @@ use traits::rotation::{Rotation, Rotate, Rotatable};
|
|||
use traits::transformation::{Transform}; // FIXME: implement Transformation and Transformable
|
||||
use traits::homogeneous::ToHomogeneous;
|
||||
use traits::indexable::Indexable;
|
||||
use traits::norm::Norm;
|
||||
use traits::vector::AlgebraicVec;
|
||||
use vec::Vec1;
|
||||
use mat::{Mat2, Mat3};
|
||||
use vec::Vec3;
|
||||
|
@ -42,7 +41,7 @@ impl<N: Clone + Trigonometric + Neg<N>> Rotmat<Mat2<N>> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Trigonometric + DivisionRing + Algebraic> Rotmat<Mat3<N>> {
|
||||
impl<N: Clone + Trigonometric + Num + Algebraic> Rotmat<Mat3<N>> {
|
||||
/// Builds a 3 dimensional rotation matrix from an axis and an angle.
|
||||
///
|
||||
/// # Arguments
|
||||
|
@ -83,7 +82,7 @@ impl<N: Clone + Trigonometric + DivisionRing + Algebraic> Rotmat<Mat3<N>> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + DivisionRing + Algebraic> Rotmat<Mat3<N>> {
|
||||
impl<N: Clone + Num + Algebraic> Rotmat<Mat3<N>> {
|
||||
/// Reorient this matrix such that its local `x` axis points to a given point. Note that the
|
||||
/// usually known `look_at` function does the same thing but with the `z` axis. See `look_at_z`
|
||||
/// for that.
|
||||
|
@ -121,7 +120,7 @@ impl<N: Clone + DivisionRing + Algebraic> Rotmat<Mat3<N>> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Trigonometric + DivisionRing + Clone>
|
||||
impl<N: Trigonometric + Num + Clone>
|
||||
Rotation<Vec1<N>> for Rotmat<Mat2<N>> {
|
||||
#[inline]
|
||||
fn rotation(&self) -> Vec1<N> {
|
||||
|
@ -139,7 +138,7 @@ Rotation<Vec1<N>> for Rotmat<Mat2<N>> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Trigonometric + DivisionRing + Clone>
|
||||
impl<N: Trigonometric + Num + Clone>
|
||||
Rotatable<Vec1<N>, Rotmat<Mat2<N>>> for Rotmat<Mat2<N>> {
|
||||
#[inline]
|
||||
fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>> {
|
||||
|
@ -147,7 +146,7 @@ Rotatable<Vec1<N>, Rotmat<Mat2<N>>> for Rotmat<Mat2<N>> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Trigonometric + DivisionRing + Algebraic>
|
||||
impl<N: Clone + Trigonometric + Num + Algebraic>
|
||||
Rotation<Vec3<N>> for Rotmat<Mat3<N>> {
|
||||
#[inline]
|
||||
fn rotation(&self) -> Vec3<N> {
|
||||
|
@ -166,7 +165,7 @@ Rotation<Vec3<N>> for Rotmat<Mat3<N>> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Trigonometric + DivisionRing + Algebraic>
|
||||
impl<N: Clone + Trigonometric + Num + Algebraic>
|
||||
Rotatable<Vec3<N>, Rotmat<Mat3<N>>> for Rotmat<Mat3<N>> {
|
||||
#[inline]
|
||||
fn rotated(&self, axisangle: &Vec3<N>) -> Rotmat<Mat3<N>> {
|
||||
|
@ -205,7 +204,7 @@ impl<M: RMul<V> + LMul<V>, V> Transform<V> for Rotmat<M> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Rand + Trigonometric + DivisionRing + Algebraic>
|
||||
impl<N: Clone + Rand + Trigonometric + Num + Algebraic>
|
||||
Rand for Rotmat<Mat3<N>> {
|
||||
#[inline]
|
||||
fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat3<N>> {
|
||||
|
|
|
@ -3,7 +3,6 @@ use std::rand::{Rand, Rng, RngUtil};
|
|||
use std::cmp::ApproxEq;
|
||||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::ring::DivisionRing;
|
||||
use traits::rotation::{Rotation, Rotate, Rotatable};
|
||||
use traits::translation::{Translation, Translate, Translatable};
|
||||
use Ts = traits::transformation::Transform;
|
||||
|
@ -53,7 +52,7 @@ impl<M: Clone, V: Clone> Transform<M, V> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + DivisionRing + Algebraic> Transform<Rotmat<Mat3<N>>, Vec3<N>> {
|
||||
impl<N: Clone + Num + Algebraic> Transform<Rotmat<Mat3<N>>, Vec3<N>> {
|
||||
/// Reorient and translate this transformation such that its local `x` axis points to a given
|
||||
/// direction. Note that the usually known `look_at` function does the same thing but with the
|
||||
/// `z` axis. See `look_at_z` for that.
|
||||
|
|
|
@ -2,7 +2,6 @@ use std::num::{One, Zero};
|
|||
use std::vec::from_elem;
|
||||
use std::cmp::ApproxEq;
|
||||
use traits::inv::Inv;
|
||||
use traits::ring::DivisionRing;
|
||||
use traits::transpose::Transpose;
|
||||
use traits::rlmul::{RMul, LMul};
|
||||
use dvec::{DVec, zero_vec_with_dim};
|
||||
|
@ -145,7 +144,7 @@ LMul<DVec<N>> for DMat<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Eq + DivisionRing>
|
||||
impl<N: Clone + Num>
|
||||
Inv for DMat<N> {
|
||||
#[inline]
|
||||
fn inverse(&self) -> Option<DMat<N>> {
|
||||
|
|
41
src/dvec.rs
41
src/dvec.rs
|
@ -3,13 +3,10 @@ use std::vec::{VecIterator, VecMutIterator};
|
|||
use std::vec::from_elem;
|
||||
use std::cmp::ApproxEq;
|
||||
use std::iterator::FromIterator;
|
||||
use traits::vector::{Vec, AlgebraicVec};
|
||||
use traits::iterable::{Iterable, IterableMut};
|
||||
use traits::ring::{Ring, DivisionRing};
|
||||
use traits::dot::Dot;
|
||||
use traits::sub_dot::SubDot;
|
||||
use traits::norm::Norm;
|
||||
use traits::translation::{Translation, Translatable};
|
||||
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
use traits::scalar_op::{ScalarAdd, ScalarSub};
|
||||
|
||||
/// Vector with a dimension unknown at compile-time.
|
||||
#[deriving(Eq, ToStr, Clone)]
|
||||
|
@ -57,7 +54,7 @@ impl<N> FromIterator<N> for DVec<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> DVec<N> {
|
||||
impl<N: Clone + Num + Algebraic + ApproxEq<N>> DVec<N> {
|
||||
/// Computes the canonical basis for the given dimension. A canonical basis is a set of
|
||||
/// vectors, mutually orthogonal, with all its component equal to 0.0 exept one which is equal
|
||||
/// to 1.0.
|
||||
|
@ -94,10 +91,10 @@ impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> DVec<N> {
|
|||
|
||||
let mut elt = basis_element.clone();
|
||||
|
||||
elt = elt - self.scalar_mul(&basis_element.dot(self));
|
||||
elt = elt - self * basis_element.dot(self);
|
||||
|
||||
for v in res.iter() {
|
||||
elt = elt - v.scalar_mul(&elt.dot(v))
|
||||
elt = elt - v * elt.dot(v)
|
||||
};
|
||||
|
||||
if !elt.sqnorm().approx_eq(&Zero::zero()) {
|
||||
|
@ -138,7 +135,7 @@ impl<N: Neg<N>> Neg<DVec<N>> for DVec<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Ring> Dot<N> for DVec<N> {
|
||||
impl<N: Num> DVec<N> {
|
||||
#[inline]
|
||||
fn dot(&self, other: &DVec<N>) -> N {
|
||||
assert!(self.at.len() == other.at.len());
|
||||
|
@ -151,9 +148,7 @@ impl<N: Ring> Dot<N> for DVec<N> {
|
|||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Ring> SubDot<N> for DVec<N> {
|
||||
#[inline]
|
||||
fn sub_dot(&self, a: &DVec<N>, b: &DVec<N>) -> N {
|
||||
let mut res = Zero::zero::<N>();
|
||||
|
@ -166,33 +161,19 @@ impl<N: Ring> SubDot<N> for DVec<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N>> ScalarMul<N> for DVec<N> {
|
||||
impl<N: Mul<N, N>> Mul<N, DVec<N>> for DVec<N> {
|
||||
#[inline]
|
||||
fn scalar_mul(&self, s: &N) -> DVec<N> {
|
||||
fn mul(&self, s: &N) -> DVec<N> {
|
||||
DVec { at: self.at.iter().map(|a| a * *s).collect() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn scalar_mul_inplace(&mut self, s: &N) {
|
||||
for i in range(0u, self.at.len()) {
|
||||
self.at[i] = self.at[i] * *s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<N: Div<N, N>> ScalarDiv<N> for DVec<N> {
|
||||
impl<N: Div<N, N>> Div<N, DVec<N>> for DVec<N> {
|
||||
#[inline]
|
||||
fn scalar_div(&self, s: &N) -> DVec<N> {
|
||||
fn div(&self, s: &N) -> DVec<N> {
|
||||
DVec { at: self.at.iter().map(|a| a / *s).collect() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn scalar_div_inplace(&mut self, s: &N) {
|
||||
for i in range(0u, self.at.len()) {
|
||||
self.at[i] = self.at[i] / *s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Add<N, N>> ScalarAdd<N> for DVec<N> {
|
||||
|
@ -247,7 +228,7 @@ impl<N: Add<N, N> + Neg<N> + Clone> Translatable<DVec<N>, DVec<N>> for DVec<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: DivisionRing + Algebraic + Clone> Norm<N> for DVec<N> {
|
||||
impl<N: Num + Algebraic + Clone> DVec<N> {
|
||||
#[inline]
|
||||
fn sqnorm(&self) -> N {
|
||||
self.dot(self)
|
||||
|
|
|
@ -6,7 +6,6 @@ use std::cmp::ApproxEq;
|
|||
use std::vec::{VecIterator, VecMutIterator};
|
||||
use vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6};
|
||||
use traits::dim::Dim;
|
||||
use traits::ring::{Ring, DivisionRing};
|
||||
use traits::inv::Inv;
|
||||
use traits::transpose::Transpose;
|
||||
use traits::rlmul::{RMul, LMul};
|
||||
|
@ -16,7 +15,7 @@ use traits::indexable::Indexable;
|
|||
use traits::column::Column;
|
||||
use traits::iterable::{Iterable, IterableMut};
|
||||
use traits::outer::Outer;
|
||||
use traits::scalar_op::{ScalarMul, ScalarAdd, ScalarDiv, ScalarSub};
|
||||
use traits::scalar_op::{ScalarAdd, ScalarSub};
|
||||
|
||||
pub use traits::mat_cast::*;
|
||||
pub use traits::column::*;
|
||||
|
|
|
@ -49,34 +49,24 @@ macro_rules! sub_impl(
|
|||
|
||||
macro_rules! scalar_mul_impl(
|
||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||
impl<N: Mul<N, N>> ScalarMul<N> for $t<N> {
|
||||
impl<N: Mul<N, N>> $t<N> {
|
||||
#[inline]
|
||||
fn scalar_mul(&self, other: &N) -> $t<N> {
|
||||
/// Scalar multiplication of each component of this matrix by a scalar.
|
||||
pub fn scalar_mul(&self, other: &N) -> $t<N> {
|
||||
$t::new(self.$comp0 * *other $(, self.$compN * *other )*)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn scalar_mul_inplace(&mut self, other: &N) {
|
||||
self.$comp0 = self.$comp0 * *other;
|
||||
$(self.$compN = self.$compN * *other; )*
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! scalar_div_impl(
|
||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||
impl<N: Div<N, N>> ScalarDiv<N> for $t<N> {
|
||||
impl<N: Div<N, N>> $t<N> {
|
||||
#[inline]
|
||||
fn scalar_div(&self, other: &N) -> $t<N> {
|
||||
/// Scalar division of each component of this matrix by a scalar.
|
||||
pub fn scalar_div(&self, other: &N) -> $t<N> {
|
||||
$t::new(self.$comp0 / *other $(, self.$compN / *other )*)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn scalar_div_inplace(&mut self, other: &N) {
|
||||
self.$comp0 = self.$comp0 / *other;
|
||||
$(self.$compN = self.$compN / *other; )*
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
@ -226,7 +216,7 @@ macro_rules! column_impl(
|
|||
|
||||
macro_rules! mul_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Clone + Ring> Mul<$t<N>, $t<N>> for $t<N> {
|
||||
impl<N: Clone + Num> Mul<$t<N>, $t<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn mul(&self, other: &$t<N>) -> $t<N> {
|
||||
let mut res: $t<N> = Zero::zero();
|
||||
|
@ -251,7 +241,7 @@ macro_rules! mul_impl(
|
|||
|
||||
macro_rules! rmul_impl(
|
||||
($t: ident, $v: ident, $dim: expr) => (
|
||||
impl<N: Clone + Ring> RMul<$v<N>> for $t<N> {
|
||||
impl<N: Clone + Num> RMul<$v<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn rmul(&self, other: &$v<N>) -> $v<N> {
|
||||
let mut res : $v<N> = Zero::zero();
|
||||
|
@ -271,7 +261,7 @@ macro_rules! rmul_impl(
|
|||
|
||||
macro_rules! lmul_impl(
|
||||
($t: ident, $v: ident, $dim: expr) => (
|
||||
impl<N: Clone + Ring> LMul<$v<N>> for $t<N> {
|
||||
impl<N: Clone + Num> LMul<$v<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn lmul(&self, other: &$v<N>) -> $v<N> {
|
||||
let mut res : $v<N> = Zero::zero();
|
||||
|
@ -291,7 +281,7 @@ macro_rules! lmul_impl(
|
|||
|
||||
macro_rules! transform_impl(
|
||||
($t: ident, $v: ident) => (
|
||||
impl<N: Clone + DivisionRing + Eq>
|
||||
impl<N: Clone + Num + Eq>
|
||||
Transform<$v<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn transform(&self, v: &$v<N>) -> $v<N> {
|
||||
|
@ -311,7 +301,7 @@ macro_rules! transform_impl(
|
|||
|
||||
macro_rules! inv_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Clone + Eq + DivisionRing>
|
||||
impl<N: Clone + Eq + Num>
|
||||
Inv for $t<N> {
|
||||
#[inline]
|
||||
fn inverse(&self) -> Option<$t<N>> {
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use std::num::{Zero, One};
|
||||
use mat::{Mat1, Mat2, Mat3};
|
||||
use traits::ring::DivisionRing;
|
||||
use traits::inv::Inv;
|
||||
|
||||
// some specializations:
|
||||
impl<N: DivisionRing + Clone>
|
||||
impl<N: Num + Clone>
|
||||
Inv for Mat1<N> {
|
||||
#[inline]
|
||||
fn inverse(&self) -> Option<Mat1<N>> {
|
||||
|
@ -30,7 +29,7 @@ Inv for Mat1<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: DivisionRing + Clone>
|
||||
impl<N: Num + Clone>
|
||||
Inv for Mat2<N> {
|
||||
#[inline]
|
||||
fn inverse(&self) -> Option<Mat2<N>> {
|
||||
|
@ -61,7 +60,7 @@ Inv for Mat2<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: DivisionRing + Clone>
|
||||
impl<N: Num + Clone>
|
||||
Inv for Mat3<N> {
|
||||
#[inline]
|
||||
fn inverse(&self) -> Option<Mat3<N>> {
|
||||
|
|
|
@ -47,24 +47,20 @@ pub mod types;
|
|||
// FIXME: it would be better to hide all those from the outside!
|
||||
pub mod traits
|
||||
{
|
||||
pub mod vector;
|
||||
pub mod sample;
|
||||
pub mod indexable;
|
||||
pub mod column;
|
||||
pub mod iterable;
|
||||
pub mod dot;
|
||||
pub mod outer;
|
||||
pub mod cross;
|
||||
pub mod inv;
|
||||
pub mod transpose;
|
||||
pub mod dim;
|
||||
pub mod basis;
|
||||
pub mod norm;
|
||||
pub mod rotation;
|
||||
pub mod translation;
|
||||
pub mod transformation;
|
||||
pub mod vector_space;
|
||||
pub mod ring;
|
||||
pub mod sub_dot;
|
||||
pub mod rlmul;
|
||||
pub mod scalar_op;
|
||||
pub mod homogeneous;
|
||||
|
|
|
@ -5,10 +5,6 @@ use std::rand::random;
|
|||
#[test]
|
||||
use std::cmp::ApproxEq;
|
||||
#[test]
|
||||
use traits::norm::Norm;
|
||||
#[test]
|
||||
use traits::scalar_op::ScalarMul;
|
||||
#[test]
|
||||
use traits::inv::Inv;
|
||||
#[test]
|
||||
use traits::rotation::{Rotation, Rotatable};
|
||||
|
@ -17,6 +13,8 @@ use traits::indexable::Indexable;
|
|||
#[test]
|
||||
use traits::transpose::Transpose;
|
||||
#[test]
|
||||
use traits::vector::AlgebraicVec;
|
||||
#[test]
|
||||
use vec::{Vec1, Vec3};
|
||||
#[test]
|
||||
use mat::{Mat1, Mat2, Mat3, Mat4, Mat5, Mat6};
|
||||
|
@ -125,7 +123,7 @@ fn test_inv_rotation3() {
|
|||
do 10000.times {
|
||||
let randmat = One::one::<Rotmat<Mat3<f64>>>();
|
||||
let dir: Vec3<f64> = random();
|
||||
let ang = &dir.normalized().scalar_mul(&(abs::<f64>(random()) % Real::pi()));
|
||||
let ang = &(dir.normalized() * (abs::<f64>(random()) % Real::pi()));
|
||||
let rot = randmat.rotated(ang);
|
||||
|
||||
assert!((rot.transposed() * rot).approx_eq(&One::one()));
|
||||
|
|
|
@ -13,13 +13,11 @@ use traits::basis::Basis;
|
|||
#[test]
|
||||
use traits::cross::Cross;
|
||||
#[test]
|
||||
use traits::dot::Dot;
|
||||
#[test]
|
||||
use traits::norm::Norm;
|
||||
use traits::vector::{Vec, AlgebraicVec};
|
||||
#[test]
|
||||
use traits::iterable::{Iterable, IterableMut};
|
||||
#[test]
|
||||
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
use traits::scalar_op::{ScalarAdd, ScalarSub};
|
||||
#[test]
|
||||
use traits::outer::Outer;
|
||||
|
||||
|
@ -36,7 +34,7 @@ macro_rules! test_iterator_impl(
|
|||
*e = *e * n
|
||||
}
|
||||
|
||||
assert!(nv == mv && nv == v.scalar_mul(&n));
|
||||
assert!(nv == mv && nv == v * n);
|
||||
}
|
||||
)
|
||||
)
|
||||
|
@ -58,8 +56,8 @@ macro_rules! test_scalar_op_impl(
|
|||
let v1 : $t = random();
|
||||
let n : $n = random();
|
||||
|
||||
assert!(v1.scalar_mul(&n).scalar_div(&n).approx_eq(&v1));
|
||||
assert!(v1.scalar_div(&n).scalar_mul(&n).approx_eq(&v1));
|
||||
assert!(((v1 * n) / n).approx_eq(&v1));
|
||||
assert!(((v1 / n) * n).approx_eq(&v1));
|
||||
assert!(v1.scalar_sub(&n).scalar_add(&n).approx_eq(&v1));
|
||||
assert!(v1.scalar_add(&n).scalar_sub(&n).approx_eq(&v1));
|
||||
|
||||
|
@ -67,8 +65,8 @@ macro_rules! test_scalar_op_impl(
|
|||
let v0 : $t = v1.clone();
|
||||
let n : $n = random();
|
||||
|
||||
v1.scalar_mul_inplace(&n);
|
||||
v1.scalar_div_inplace(&n);
|
||||
v1 = v1 * n;
|
||||
v1 = v1 / n;
|
||||
|
||||
assert!(v1.approx_eq(&v0));
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
/**
|
||||
* Trait of objects having a dot product (also called inner product).
|
||||
*/
|
||||
pub trait Dot<N>
|
||||
{
|
||||
/// Computes the dot (inner) product of two objects.
|
||||
fn dot(&self, &Self) -> N;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
/**
|
||||
* Trait of objects having a L² norm and which can be normalized.
|
||||
*/
|
||||
pub trait Norm<N> {
|
||||
/// Computes the norm a an object.
|
||||
fn norm(&self) -> N;
|
||||
|
||||
/**
|
||||
* Computes the squared norm of an object. Usually faster than computing the
|
||||
* norm itself.
|
||||
*/
|
||||
fn sqnorm(&self) -> N;
|
||||
|
||||
/// Gets the normalized version of the argument.
|
||||
fn normalized(&self) -> Self;
|
||||
|
||||
/// In-place version of `normalized`.
|
||||
fn normalize(&mut self) -> N;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
use std::num::{One, Zero};
|
||||
|
||||
/**
|
||||
* Trait of elements of a ring. A rings is an algebraic structure, the
|
||||
* elements of which have all the common numeric operation but the division:
|
||||
* addition, subtraction, multiplication and distinct elements (`One` and
|
||||
* `Zero`) respectively neutral and absorbant wrt the multiplication.
|
||||
*/
|
||||
pub trait Ring :
|
||||
Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Mul<Self, Self> + One + Zero { }
|
||||
|
||||
impl<N: Sub<N, N> + Add<N, N> + Neg<N> + Mul<N, N> + One + Zero>
|
||||
Ring for N;
|
||||
|
||||
/**
|
||||
* Trait of elements of a division ring. A division ring is an algebraic
|
||||
* structure like a ring, but with the division operator.
|
||||
*/
|
||||
pub trait DivisionRing : Ring + Div<Self, Self>
|
||||
{ }
|
||||
|
||||
impl<N: Ring + Div<N, N>> DivisionRing for N;
|
|
@ -2,8 +2,5 @@
|
|||
/// approximate a sphere using support mapping functions.
|
||||
pub trait UniformSphereSample {
|
||||
/// Iterate throught the samples.
|
||||
fn sample(&fn(&'static Self));
|
||||
|
||||
/// Gets the list of all samples.
|
||||
fn sample_list() -> &[Self];
|
||||
fn sample(&fn(Self));
|
||||
}
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
/**
|
||||
* Trait of objects having a multiplication with a scalar.
|
||||
*/
|
||||
pub trait ScalarMul<N> {
|
||||
/// Gets the result of a multiplication by a scalar.
|
||||
fn scalar_mul(&self, &N) -> Self;
|
||||
|
||||
/// In-place version of `scalar_mul`.
|
||||
fn scalar_mul_inplace(&mut self, &N);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trait of objects having a division with a scalar.
|
||||
*/
|
||||
pub trait ScalarDiv<N> {
|
||||
/// Gets the result of a division by a scalar.
|
||||
fn scalar_div(&self, &N) -> Self;
|
||||
|
||||
/// In-place version of `scalar_div`.
|
||||
fn scalar_div_inplace(&mut self, &N);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trait of objects having an addition with a scalar.
|
||||
*/
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
use traits::dot::Dot;
|
||||
|
||||
/// Traits of objects with a subtract and a dot product. Exists only for optimization purpose.
|
||||
pub trait SubDot<N> : Sub<Self, Self> + Dot<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)
|
||||
*
|
||||
*/
|
||||
fn sub_dot(&self, b: &Self, c: &Self) -> N;
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
use std::num::Zero;
|
||||
use traits::dim::Dim;
|
||||
use traits::basis::Basis;
|
||||
use traits::indexable::Indexable;
|
||||
use traits::iterable::Iterable;
|
||||
use traits::sample::UniformSphereSample;
|
||||
use traits::scalar_op::{ScalarAdd, ScalarSub};
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
||||
/// 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
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait grouping uncommon, low-level and borderline (from the mathematical point of view)
|
||||
/// operations on vectors.
|
||||
pub trait VecExt<N>: Vec<N> + Basis + Indexable<uint, N> + Iterable<N> + Round +
|
||||
UniformSphereSample + ScalarAdd<N> + ScalarSub<N> + Bounded + Orderable
|
||||
{ }
|
||||
|
||||
/// Trait grouping uncommon, low-level and borderline (from the mathematical point of view)
|
||||
/// operations on vectors.
|
||||
pub trait AlgebraicVecExt<N: Algebraic>: AlgebraicVec<N> + VecExt<N>
|
||||
{ }
|
||||
|
||||
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;
|
|
@ -1,13 +0,0 @@
|
|||
use std::num::Zero;
|
||||
use traits::ring::DivisionRing;
|
||||
use traits::scalar_op::{ScalarMul, ScalarDiv};
|
||||
|
||||
/// Trait of elements of a vector space. A vector space is an algebraic
|
||||
/// structure, the elements of which have addition, substraction, negation,
|
||||
/// scalar multiplication (the scalar being a element of a `DivisionRing`), and
|
||||
/// has a distinct element (`Zero`) neutral wrt the addition.
|
||||
pub trait VectorSpace<N>
|
||||
: Sub<Self, Self> + Add<Self, Self> + Neg<Self> + Zero + ScalarMul<N> + ScalarDiv<N> { }
|
||||
|
||||
impl<V: Sub<V, V> + Add<V, V> + Neg<V> + Zero + ScalarMul<N> + ScalarDiv<N>,
|
||||
N: DivisionRing> VectorSpace<N> for V;
|
24
src/vec.rs
24
src/vec.rs
|
@ -7,22 +7,12 @@ use std::cmp::ApproxEq;
|
|||
use traits::basis::Basis;
|
||||
use traits::dim::Dim;
|
||||
use traits::translation::{Translation, Translatable};
|
||||
use traits::ring::{Ring, DivisionRing};
|
||||
use traits::homogeneous::{FromHomogeneous, ToHomogeneous};
|
||||
use traits::indexable::Indexable;
|
||||
|
||||
pub use traits::vec_cast::*;
|
||||
pub use traits::basis::*;
|
||||
pub use traits::cross::*;
|
||||
pub use traits::outer::*;
|
||||
pub use traits::dot::*;
|
||||
pub use traits::indexable::*;
|
||||
pub use traits::iterable::*;
|
||||
pub use traits::norm::*;
|
||||
pub use traits::sample::*;
|
||||
pub use traits::sub_dot::*;
|
||||
pub use traits::vector_space::*;
|
||||
pub use traits::scalar_op::*;
|
||||
use traits::scalar_op::{ScalarAdd, ScalarSub};
|
||||
use traits::iterable::{Iterable, IterableMut};
|
||||
use traits::vec_cast::VecCast;
|
||||
use traits::vector::{Vec, AlgebraicVec};
|
||||
|
||||
mod vec_macros;
|
||||
|
||||
|
@ -50,7 +40,6 @@ add_impl!(Vec1, x)
|
|||
sub_impl!(Vec1, x)
|
||||
neg_impl!(Vec1, x)
|
||||
dot_impl!(Vec1, x)
|
||||
sub_dot_impl!(Vec1, x)
|
||||
scalar_mul_impl!(Vec1, x)
|
||||
scalar_div_impl!(Vec1, x)
|
||||
scalar_add_impl!(Vec1, x)
|
||||
|
@ -90,7 +79,6 @@ add_impl!(Vec2, x, y)
|
|||
sub_impl!(Vec2, x, y)
|
||||
neg_impl!(Vec2, x, y)
|
||||
dot_impl!(Vec2, x, y)
|
||||
sub_dot_impl!(Vec2, x, y)
|
||||
scalar_mul_impl!(Vec2, x, y)
|
||||
scalar_div_impl!(Vec2, x, y)
|
||||
scalar_add_impl!(Vec2, x, y)
|
||||
|
@ -132,7 +120,6 @@ add_impl!(Vec3, x, y, z)
|
|||
sub_impl!(Vec3, x, y, z)
|
||||
neg_impl!(Vec3, x, y, z)
|
||||
dot_impl!(Vec3, x, y, z)
|
||||
sub_dot_impl!(Vec3, x, y, z)
|
||||
scalar_mul_impl!(Vec3, x, y, z)
|
||||
scalar_div_impl!(Vec3, x, y, z)
|
||||
scalar_add_impl!(Vec3, x, y, z)
|
||||
|
@ -176,7 +163,6 @@ add_impl!(Vec4, x, y, z, w)
|
|||
sub_impl!(Vec4, x, y, z, w)
|
||||
neg_impl!(Vec4, x, y, z, w)
|
||||
dot_impl!(Vec4, x, y, z, w)
|
||||
sub_dot_impl!(Vec4, x, y, z, w)
|
||||
scalar_mul_impl!(Vec4, x, y, z, w)
|
||||
scalar_div_impl!(Vec4, x, y, z, w)
|
||||
scalar_add_impl!(Vec4, x, y, z, w)
|
||||
|
@ -222,7 +208,6 @@ add_impl!(Vec5, x, y, z, w, a)
|
|||
sub_impl!(Vec5, x, y, z, w, a)
|
||||
neg_impl!(Vec5, x, y, z, w, a)
|
||||
dot_impl!(Vec5, x, y, z, w, a)
|
||||
sub_dot_impl!(Vec5, x, y, z, w, a)
|
||||
scalar_mul_impl!(Vec5, x, y, z, w, a)
|
||||
scalar_div_impl!(Vec5, x, y, z, w, a)
|
||||
scalar_add_impl!(Vec5, x, y, z, w, a)
|
||||
|
@ -270,7 +255,6 @@ add_impl!(Vec6, x, y, z, w, a, b)
|
|||
sub_impl!(Vec6, x, y, z, w, a, b)
|
||||
neg_impl!(Vec6, x, y, z, w, a, b)
|
||||
dot_impl!(Vec6, x, y, z, w, a, b)
|
||||
sub_dot_impl!(Vec6, x, y, z, w, a, b)
|
||||
scalar_mul_impl!(Vec6, x, y, z, w, a, b)
|
||||
scalar_div_impl!(Vec6, x, y, z, w, a, b)
|
||||
scalar_add_impl!(Vec6, x, y, z, w, a, b)
|
||||
|
|
|
@ -6,13 +6,10 @@ use std::cmp::ApproxEq;
|
|||
use traits::iterable::{Iterable, IterableMut};
|
||||
use traits::basis::Basis;
|
||||
use traits::dim::Dim;
|
||||
use traits::dot::Dot;
|
||||
use traits::sub_dot::SubDot;
|
||||
use traits::norm::Norm;
|
||||
use traits::translation::{Translation, Translatable};
|
||||
use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
use traits::ring::{Ring, DivisionRing};
|
||||
use traits::scalar_op::{ScalarAdd, ScalarSub};
|
||||
use traits::indexable::Indexable;
|
||||
use traits::vector::{Vec, AlgebraicVec};
|
||||
use vec;
|
||||
|
||||
impl<N> vec::Vec0<N> {
|
||||
|
@ -69,7 +66,7 @@ impl<N> Dim for vec::Vec0<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> Basis for vec::Vec0<N> {
|
||||
impl<N: Clone + Num + Algebraic + ApproxEq<N>> Basis for vec::Vec0<N> {
|
||||
#[inline(always)]
|
||||
fn canonical_basis(_: &fn(vec::Vec0<N>) -> bool) { }
|
||||
|
||||
|
@ -98,38 +95,30 @@ impl<N: Neg<N>> Neg<vec::Vec0<N>> for vec::Vec0<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Ring> Dot<N> for vec::Vec0<N> {
|
||||
impl<N: Num + Clone> Vec<N> for vec::Vec0<N> {
|
||||
#[inline]
|
||||
fn dot(&self, _: &vec::Vec0<N>) -> N {
|
||||
Zero::zero()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + Ring> SubDot<N> for vec::Vec0<N> {
|
||||
#[inline]
|
||||
fn sub_dot(&self, _: &vec::Vec0<N>, _: &vec::Vec0<N>) -> N {
|
||||
Zero::zero()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Mul<N, N>> ScalarMul<N> for vec::Vec0<N> {
|
||||
impl<N: Mul<N, N>> Mul<N, vec::Vec0<N>> for vec::Vec0<N> {
|
||||
#[inline]
|
||||
fn scalar_mul(&self, _: &N) -> vec::Vec0<N> {
|
||||
fn mul(&self, _: &N) -> vec::Vec0<N> {
|
||||
vec::Vec0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn scalar_mul_inplace(&mut self, _: &N) { }
|
||||
}
|
||||
|
||||
impl<N: Div<N, N>> ScalarDiv<N> for vec::Vec0<N> {
|
||||
impl<N: Div<N, N>> Div<N, vec::Vec0<N>> for vec::Vec0<N> {
|
||||
#[inline]
|
||||
fn scalar_div(&self, _: &N) -> vec::Vec0<N> {
|
||||
fn div(&self, _: &N) -> vec::Vec0<N> {
|
||||
vec::Vec0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn scalar_div_inplace(&mut self, _: &N) { }
|
||||
}
|
||||
|
||||
impl<N: Add<N, N>> ScalarAdd<N> for vec::Vec0<N> {
|
||||
|
@ -176,7 +165,7 @@ impl<N: Add<N, N> + Neg<N> + Clone> Translatable<vec::Vec0<N>, vec::Vec0<N>> for
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + DivisionRing + Algebraic> Norm<N> for vec::Vec0<N> {
|
||||
impl<N: Clone + Num + Algebraic> AlgebraicVec<N> for vec::Vec0<N> {
|
||||
#[inline]
|
||||
fn sqnorm(&self) -> N {
|
||||
self.dot(self)
|
||||
|
@ -200,7 +189,7 @@ impl<N: Clone + DivisionRing + Algebraic> Norm<N> for vec::Vec0<N> {
|
|||
fn normalize(&mut self) -> N {
|
||||
let l = self.norm();
|
||||
|
||||
self.scalar_div_inplace(&l);
|
||||
*self = *self / l;
|
||||
|
||||
l
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@ macro_rules! dim_impl(
|
|||
|
||||
macro_rules! basis_impl(
|
||||
($t: ident, $dim: expr) => (
|
||||
impl<N: Clone + DivisionRing + Algebraic + ApproxEq<N>> Basis for $t<N> {
|
||||
impl<N: Clone + Num + Algebraic + ApproxEq<N>> Basis for $t<N> {
|
||||
#[inline]
|
||||
fn canonical_basis(f: &fn($t<N>) -> bool) {
|
||||
for i in range(0u, $dim) {
|
||||
|
@ -212,10 +212,10 @@ macro_rules! basis_impl(
|
|||
|
||||
let mut elt = basis_element.clone();
|
||||
|
||||
elt = elt - self.scalar_mul(&basis_element.dot(self));
|
||||
elt = elt - *self * basis_element.dot(self);
|
||||
|
||||
for v in basis.iter() {
|
||||
elt = elt - v.scalar_mul(&elt.dot(v))
|
||||
elt = elt - v * elt.dot(v)
|
||||
};
|
||||
|
||||
if !elt.sqnorm().approx_eq(&Zero::zero()) {
|
||||
|
@ -266,18 +266,12 @@ macro_rules! neg_impl(
|
|||
|
||||
macro_rules! dot_impl(
|
||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||
impl<N: Ring> Dot<N> for $t<N> {
|
||||
impl<N: Num + Clone> Vec<N> for $t<N> {
|
||||
#[inline]
|
||||
fn dot(&self, other: &$t<N>) -> N {
|
||||
self.$comp0 * other.$comp0 $(+ self.$compN * other.$compN )*
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! sub_dot_impl(
|
||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||
impl<N: Clone + Ring> SubDot<N> for $t<N> {
|
||||
#[inline]
|
||||
fn sub_dot(&self, a: &$t<N>, b: &$t<N>) -> N {
|
||||
(self.$comp0 - a.$comp0) * b.$comp0 $(+ (self.$compN - a.$compN) * b.$compN )*
|
||||
|
@ -288,34 +282,22 @@ macro_rules! sub_dot_impl(
|
|||
|
||||
macro_rules! scalar_mul_impl(
|
||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||
impl<N: Mul<N, N>> ScalarMul<N> for $t<N> {
|
||||
impl<N: Mul<N, N>> Mul<N, $t<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn scalar_mul(&self, s: &N) -> $t<N> {
|
||||
fn mul(&self, s: &N) -> $t<N> {
|
||||
$t::new(self.$comp0 * *s $(, self.$compN * *s)*)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn scalar_mul_inplace(&mut self, s: &N) {
|
||||
self.$comp0 = self.$comp0 * *s;
|
||||
$(self.$compN = self.$compN * *s;)*
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
macro_rules! scalar_div_impl(
|
||||
($t: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||
impl<N: Div<N, N>> ScalarDiv<N> for $t<N> {
|
||||
impl<N: Div<N, N>> Div<N, $t<N>> for $t<N> {
|
||||
#[inline]
|
||||
fn scalar_div(&self, s: &N) -> $t<N> {
|
||||
fn div(&self, s: &N) -> $t<N> {
|
||||
$t::new(self.$comp0 / *s $(, self.$compN / *s)*)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn scalar_div_inplace(&mut self, s: &N) {
|
||||
self.$comp0 = self.$comp0 / *s;
|
||||
$(self.$compN = self.$compN / *s;)*
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
@ -388,7 +370,7 @@ macro_rules! translatable_impl(
|
|||
|
||||
macro_rules! norm_impl(
|
||||
($t: ident) => (
|
||||
impl<N: Clone + DivisionRing + Algebraic> Norm<N> for $t<N> {
|
||||
impl<N: Clone + Num + Algebraic> AlgebraicVec<N> for $t<N> {
|
||||
#[inline]
|
||||
fn sqnorm(&self) -> N {
|
||||
self.dot(self)
|
||||
|
@ -412,7 +394,7 @@ macro_rules! norm_impl(
|
|||
fn normalize(&mut self) -> N {
|
||||
let l = self.norm();
|
||||
|
||||
self.scalar_div_inplace(&l);
|
||||
*self = *self / l;
|
||||
|
||||
l
|
||||
}
|
||||
|
@ -529,7 +511,7 @@ macro_rules! from_homogeneous_impl(
|
|||
res.$comp0 = v.$comp0.clone();
|
||||
$( res.$compN = v.$compN.clone(); )*
|
||||
|
||||
res.scalar_div(&v.$extra);
|
||||
res = res / v.$extra;
|
||||
|
||||
res
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use std::num::{Zero, One};
|
||||
use traits::basis::Basis;
|
||||
use traits::cross::Cross;
|
||||
use traits::ring::DivisionRing;
|
||||
use traits::norm::Norm;
|
||||
use traits::sample::UniformSphereSample;
|
||||
use traits::vec_cast::VecCast;
|
||||
use traits::vector::{AlgebraicVec};
|
||||
use vec::{Vec1, Vec2, Vec3};
|
||||
|
||||
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec1<N>> for Vec2<N> {
|
||||
|
@ -47,7 +47,7 @@ impl<N: Clone + One + Zero + Neg<N>> Basis for Vec2<N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Clone + DivisionRing + Ord + Algebraic + Signed>
|
||||
impl<N: Clone + Ord + Algebraic + Signed>
|
||||
Basis for Vec3<N> {
|
||||
#[inline(always)]
|
||||
fn canonical_basis(f: &fn(Vec3<N>) -> bool) {
|
||||
|
@ -142,34 +142,20 @@ static SAMPLES_3_F64: [Vec3<f64>, ..42] = [
|
|||
Vec3 { x: 0.162456 , y: 0.499995 , z: 0.850654 }
|
||||
];
|
||||
|
||||
impl UniformSphereSample for Vec2<f64> {
|
||||
impl<N: NumCast> UniformSphereSample for Vec2<N> {
|
||||
#[inline(always)]
|
||||
fn sample(f: &fn(&'static Vec2<f64>)) {
|
||||
fn sample(f: &fn(Vec2<N>)) {
|
||||
for sample in SAMPLES_2_F64.iter() {
|
||||
f(sample)
|
||||
f(VecCast::from(*sample))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sample_list() -> &[Vec2<f64>] {
|
||||
let res: &[Vec2<f64>] = SAMPLES_2_F64;
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl UniformSphereSample for Vec3<f64> {
|
||||
impl<N: NumCast> UniformSphereSample for Vec3<N> {
|
||||
#[inline(always)]
|
||||
fn sample(f: &fn(&'static Vec3<f64>)) {
|
||||
fn sample(f: &fn(Vec3<N>)) {
|
||||
for sample in SAMPLES_3_F64.iter() {
|
||||
f(sample)
|
||||
f(VecCast::from(*sample))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sample_list() -> &[Vec3<f64>] {
|
||||
let res: &[Vec3<f64>] = SAMPLES_3_F64;
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue