2013-06-29 08:34:45 +08:00
|
|
|
use std::num::{Zero, One, abs};
|
|
|
|
use traits::basis::Basis;
|
|
|
|
use traits::cross::Cross;
|
|
|
|
use traits::division_ring::DivisionRing;
|
|
|
|
use traits::norm::Norm;
|
2013-07-04 22:23:08 +08:00
|
|
|
use traits::sample::UniformSphereSample;
|
2013-06-29 08:34:45 +08:00
|
|
|
use vec::{Vec1, Vec2, Vec3};
|
|
|
|
|
|
|
|
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec1<N>> for Vec2<N>
|
|
|
|
{
|
|
|
|
#[inline]
|
|
|
|
fn cross(&self, other : &Vec2<N>) -> Vec1<N>
|
|
|
|
{ Vec1::new([self.at[0] * other.at[1] - self.at[1] * other.at[0]]) }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec3<N>> for Vec3<N>
|
|
|
|
{
|
|
|
|
#[inline]
|
|
|
|
fn cross(&self, other : &Vec3<N>) -> Vec3<N>
|
|
|
|
{
|
|
|
|
Vec3::new(
|
|
|
|
[self.at[1] * other.at[2] - self.at[2] * other.at[1],
|
|
|
|
self.at[2] * other.at[0] - self.at[0] * other.at[2],
|
|
|
|
self.at[0] * other.at[1] - self.at[1] * other.at[0]]
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N: One> Basis for Vec1<N>
|
|
|
|
{
|
2013-07-02 00:33:22 +08:00
|
|
|
#[inline(always)]
|
|
|
|
fn canonical_basis(f: &fn(Vec1<N>))
|
|
|
|
{ f(Vec1::new([One::one()])) }
|
2013-06-29 08:34:45 +08:00
|
|
|
|
2013-07-02 00:33:22 +08:00
|
|
|
#[inline(always)]
|
|
|
|
fn orthonormal_subspace_basis(&self, _: &fn(Vec1<N>))
|
|
|
|
{ }
|
2013-06-29 08:34:45 +08:00
|
|
|
}
|
|
|
|
|
2013-07-04 22:23:08 +08:00
|
|
|
impl<N: Clone + One + Zero + Neg<N>> Basis for Vec2<N>
|
2013-06-29 08:34:45 +08:00
|
|
|
{
|
|
|
|
#[inline]
|
2013-07-02 00:33:22 +08:00
|
|
|
fn canonical_basis(f: &fn(Vec2<N>))
|
2013-06-29 08:34:45 +08:00
|
|
|
{
|
2013-07-02 00:33:22 +08:00
|
|
|
f(Vec2::new([One::one(), Zero::zero()]));
|
|
|
|
f(Vec2::new([Zero::zero(), One::one()]));
|
2013-06-29 08:34:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2013-07-02 00:33:22 +08:00
|
|
|
fn orthonormal_subspace_basis(&self, f: &fn(Vec2<N>))
|
2013-07-04 22:23:08 +08:00
|
|
|
{ f(Vec2::new([-self.at[1], self.at[0].clone()])) }
|
2013-06-29 08:34:45 +08:00
|
|
|
}
|
|
|
|
|
2013-07-04 22:23:08 +08:00
|
|
|
impl<N: Clone + Copy + DivisionRing + Ord + Algebraic>
|
2013-06-29 08:34:45 +08:00
|
|
|
Basis for Vec3<N>
|
|
|
|
{
|
2013-07-02 00:33:22 +08:00
|
|
|
#[inline(always)]
|
|
|
|
fn canonical_basis(f: &fn(Vec3<N>))
|
2013-06-29 08:34:45 +08:00
|
|
|
{
|
2013-07-02 00:33:22 +08:00
|
|
|
f(Vec3::new([One::one(), Zero::zero(), Zero::zero()]));
|
|
|
|
f(Vec3::new([Zero::zero(), One::one(), Zero::zero()]));
|
|
|
|
f(Vec3::new([Zero::zero(), Zero::zero(), One::one()]));
|
2013-06-29 08:34:45 +08:00
|
|
|
}
|
|
|
|
|
2013-07-02 00:33:22 +08:00
|
|
|
#[inline(always)]
|
|
|
|
fn orthonormal_subspace_basis(&self, f: &fn(Vec3<N>))
|
2013-06-29 08:34:45 +08:00
|
|
|
{
|
|
|
|
let a =
|
2013-07-04 22:23:08 +08:00
|
|
|
if abs(self.at[0].clone()) > abs(self.at[1].clone())
|
|
|
|
{ Vec3::new([self.at[2].clone(), Zero::zero(), -self.at[0]]).normalized() }
|
2013-06-29 08:34:45 +08:00
|
|
|
else
|
2013-07-04 22:23:08 +08:00
|
|
|
{ Vec3::new([Zero::zero(), -self.at[2], self.at[1].clone()]).normalized() };
|
2013-06-29 08:34:45 +08:00
|
|
|
|
2013-07-02 00:33:22 +08:00
|
|
|
f(a.cross(self));
|
|
|
|
f(a);
|
2013-06-29 08:34:45 +08:00
|
|
|
}
|
|
|
|
}
|
2013-07-04 22:23:08 +08:00
|
|
|
|
|
|
|
// FIXME: this bad: this fixes definitly the number of samples…
|
|
|
|
static SAMPLES_2_F64: [Vec2<f64>, ..21] = [
|
|
|
|
Vec2 { at: [1.0, 0.0] },
|
|
|
|
Vec2 { at: [0.95557281, 0.29475517] },
|
|
|
|
Vec2 { at: [0.82623877, 0.56332006] },
|
|
|
|
Vec2 { at: [0.6234898, 0.78183148] },
|
|
|
|
Vec2 { at: [0.36534102, 0.93087375] },
|
|
|
|
Vec2 { at: [0.07473009, 0.9972038] },
|
|
|
|
Vec2 { at: [-0.22252093, 0.97492791] },
|
|
|
|
Vec2 { at: [-0.5, 0.8660254] },
|
|
|
|
Vec2 { at: [-0.73305187, 0.68017274] },
|
|
|
|
Vec2 { at: [-0.90096887, 0.43388374] },
|
|
|
|
Vec2 { at: [-0.98883083, 0.14904227] },
|
|
|
|
Vec2 { at: [-0.98883083, -0.14904227] },
|
|
|
|
Vec2 { at: [-0.90096887, -0.43388374] },
|
|
|
|
Vec2 { at: [-0.73305187, -0.68017274] },
|
|
|
|
Vec2 { at: [-0.5, -0.8660254] },
|
|
|
|
Vec2 { at: [-0.22252093, -0.97492791] },
|
|
|
|
Vec2 { at: [0.07473009, -0.9972038] },
|
|
|
|
Vec2 { at: [0.36534102, -0.93087375] },
|
|
|
|
Vec2 { at: [0.6234898, -0.78183148] },
|
|
|
|
Vec2 { at: [0.82623877, -0.56332006] },
|
|
|
|
Vec2 { at: [0.95557281, -0.29475517] },
|
|
|
|
];
|
|
|
|
|
|
|
|
impl UniformSphereSample for Vec2<f64>
|
|
|
|
{
|
|
|
|
pub fn sample(f: &fn(&'static Vec2<f64>))
|
|
|
|
{
|
|
|
|
for SAMPLES_2_F64.iter().advance |sample|
|
|
|
|
{ f(sample) }
|
|
|
|
}
|
|
|
|
}
|
2013-07-06 06:54:42 +08:00
|
|
|
|
|
|
|
impl UniformSphereSample for Vec3<f64>
|
|
|
|
{
|
|
|
|
pub fn sample(_: &fn(&'static Vec3<f64>))
|
|
|
|
{
|
|
|
|
fail!("UniformSphereSample for Vec3<f64> is not yet implemented.")
|
|
|
|
}
|
|
|
|
}
|