From 6b4b25acd4f557167fddaf8ce15c519b7a0ad83d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Sun, 26 Oct 2014 23:16:44 +0100 Subject: [PATCH] Basis: add a method to compute the i-th element of the canonical basis. --- src/lib.rs | 6 ++++++ src/structs/spec/vec.rs | 41 ++++++++++++++++++++++++++++++++++++++- src/structs/spec/vec0.rs | 5 +++++ src/structs/vec_macros.rs | 24 ++++++++++++++++------- src/traits/structure.rs | 3 +++ 5 files changed, 71 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4a633862..eb76abfb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -915,6 +915,12 @@ pub fn orthonormal_subspace_basis(v: &V, f: |V| -> bool) { Basis::orthonormal_subspace_basis(v, f) } +/// Gets the (0-based) i-th element of the canonical basis of V. +#[inline] +pub fn canonical_basis_element(i: uint) -> Option { + Basis::canonical_basis_element(i) +} + /* * Row */ diff --git a/src/structs/spec/vec.rs b/src/structs/spec/vec.rs index fa2c9220..01da3a2c 100644 --- a/src/structs/spec/vec.rs +++ b/src/structs/spec/vec.rs @@ -75,7 +75,17 @@ impl Basis for Vec1 { } #[inline(always)] - fn orthonormal_subspace_basis(_: &Vec1, _: |Vec1| -> bool ) { } + fn orthonormal_subspace_basis(_: &Vec1, _: |Vec1| -> bool) { } + + #[inline] + fn canonical_basis_element(i: uint) -> Option> { + if i == 0 { + Some(Vec1::new(One::one())) + } + else { + None + } + } } impl> Basis for Vec2 { @@ -89,6 +99,19 @@ impl> Basis for Vec2 { fn orthonormal_subspace_basis(n: &Vec2, f: |Vec2| -> bool) { f(Vec2::new(-n.y, n.x.clone())); } + + #[inline] + fn canonical_basis_element(i: uint) -> Option> { + if i == 0 { + Some(Vec2::new(One::one(), Zero::zero())) + } + else if i == 1 { + Some(Vec2::new(Zero::zero(), One::one())) + } + else { + None + } + } } impl Basis for Vec3 { @@ -112,6 +135,22 @@ impl Basis for Vec3 { if !f(Cross::cross(&a, n)) { return }; f(a); } + + #[inline] + fn canonical_basis_element(i: uint) -> Option> { + if i == 0 { + Some(Vec3::new(One::one(), Zero::zero(), Zero::zero())) + } + else if i == 1 { + Some(Vec3::new(Zero::zero(), One::one(), Zero::zero())) + } + else if i == 2 { + Some(Vec3::new(Zero::zero(), Zero::zero(), One::one())) + } + else { + None + } + } } // FIXME: this bad: this fixes definitly the number of samples… diff --git a/src/structs/spec/vec0.rs b/src/structs/spec/vec0.rs index c4796f68..07008827 100644 --- a/src/structs/spec/vec0.rs +++ b/src/structs/spec/vec0.rs @@ -79,6 +79,11 @@ impl Basis for vec::Vec0 { #[inline(always)] fn orthonormal_subspace_basis(_: &vec::Vec0, _: |vec::Vec0| -> bool) { } + + #[inline(always)] + fn canonical_basis_element(_: uint) -> Option> { + None + } } impl Add> for vec::Vec0 { diff --git a/src/structs/vec_macros.rs b/src/structs/vec_macros.rs index e35fd59d..75c2c8ff 100644 --- a/src/structs/vec_macros.rs +++ b/src/structs/vec_macros.rs @@ -297,13 +297,7 @@ macro_rules! basis_impl( #[inline] fn canonical_basis(f: |$t| -> bool) { for i in range(0u, $dim) { - let mut basis_element : $t = Zero::zero(); - - unsafe { - basis_element.set_fast(i, One::one()); - } - - if !f(basis_element) { return } + if !f(Basis::canonical_basis_element(i).unwrap()) { return } } } @@ -341,6 +335,22 @@ macro_rules! basis_impl( } } } + + #[inline] + fn canonical_basis_element(i: uint) -> Option<$t> { + if i < $dim { + let mut basis_element : $t = Zero::zero(); + + unsafe { + basis_element.set_fast(i, One::one()); + } + + Some(basis_element) + } + else { + None + } + } } ) ) diff --git a/src/traits/structure.rs b/src/traits/structure.rs index ca97ab30..f7b90bff 100644 --- a/src/traits/structure.rs +++ b/src/traits/structure.rs @@ -46,6 +46,9 @@ pub trait Basis { /// Iterates through a basis of the subspace orthogonal to `self`. fn orthonormal_subspace_basis(&Self, |Self| -> bool); + + /// Gets the ith element of the canonical basis. + fn canonical_basis_element(i: uint) -> Option; } /// Trait to access rows of a matrix or a vector.