Basis: add a method to compute the i-th element of the canonical basis.
This commit is contained in:
parent
171576e2a0
commit
6b4b25acd4
|
@ -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>
|
||||
*/
|
||||
|
|
|
@ -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…
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue