Basis: add a method to compute the i-th element of the canonical basis.

This commit is contained in:
Sébastien Crozet 2014-10-26 23:16:44 +01:00
parent 171576e2a0
commit 6b4b25acd4
5 changed files with 71 additions and 8 deletions

View File

@ -915,6 +915,12 @@ pub fn orthonormal_subspace_basis<V: 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<V: Basis>(i: uint) -> Option<V> {
Basis::canonical_basis_element(i)
}
/*
* Row<R>
*/

View File

@ -75,7 +75,17 @@ impl<N: One> Basis for Vec1<N> {
}
#[inline(always)]
fn orthonormal_subspace_basis(_: &Vec1<N>, _: |Vec1<N>| -> bool ) { }
fn orthonormal_subspace_basis(_: &Vec1<N>, _: |Vec1<N>| -> bool) { }
#[inline]
fn canonical_basis_element(i: uint) -> Option<Vec1<N>> {
if i == 0 {
Some(Vec1::new(One::one()))
}
else {
None
}
}
}
impl<N: Clone + One + Zero + Neg<N>> Basis for Vec2<N> {
@ -89,6 +99,19 @@ impl<N: Clone + One + Zero + Neg<N>> Basis for Vec2<N> {
fn orthonormal_subspace_basis(n: &Vec2<N>, f: |Vec2<N>| -> bool) {
f(Vec2::new(-n.y, n.x.clone()));
}
#[inline]
fn canonical_basis_element(i: uint) -> Option<Vec2<N>> {
if i == 0 {
Some(Vec2::new(One::one(), Zero::zero()))
}
else if i == 1 {
Some(Vec2::new(Zero::zero(), One::one()))
}
else {
None
}
}
}
impl<N: Float> Basis for Vec3<N> {
@ -112,6 +135,22 @@ impl<N: Float> Basis for Vec3<N> {
if !f(Cross::cross(&a, n)) { return };
f(a);
}
#[inline]
fn canonical_basis_element(i: uint) -> Option<Vec3<N>> {
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…

View File

@ -79,6 +79,11 @@ impl<N> Basis for vec::Vec0<N> {
#[inline(always)]
fn orthonormal_subspace_basis(_: &vec::Vec0<N>, _: |vec::Vec0<N>| -> bool) { }
#[inline(always)]
fn canonical_basis_element(_: uint) -> Option<vec::Vec0<N>> {
None
}
}
impl<N, T> Add<T, vec::Vec0<N>> for vec::Vec0<N> {

View File

@ -297,13 +297,7 @@ macro_rules! basis_impl(
#[inline]
fn canonical_basis(f: |$t<N>| -> bool) {
for i in range(0u, $dim) {
let mut basis_element : $t<N> = 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<N>> {
if i < $dim {
let mut basis_element : $t<N> = Zero::zero();
unsafe {
basis_element.set_fast(i, One::one());
}
Some(basis_element)
}
else {
None
}
}
}
)
)

View File

@ -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<Self>;
}
/// Trait to access rows of a matrix or a vector.