use std::num::{Zero, One}; use traits::basis::Basis; use traits::cross::Cross; use traits::division_ring::DivisionRing; use traits::norm::Norm; use traits::sample::UniformSphereSample; use vec::{Vec1, Vec2, Vec3}; impl + Sub> Cross> for Vec2 { #[inline] fn cross(&self, other : &Vec2) -> Vec1 { Vec1::new(self.x * other.y - self.y * other.x) } } impl + Sub> Cross> for Vec3 { #[inline] fn cross(&self, other : &Vec3) -> Vec3 { Vec3::new(self.y * other.z - self.z * other.y, self.z * other.x - self.x * other.z, self.x * other.y - self.y * other.x ) } } impl Basis for Vec1 { #[inline(always)] fn canonical_basis(f: &fn(Vec1)) { f(Vec1::new(One::one())) } #[inline(always)] fn orthonormal_subspace_basis(&self, _: &fn(Vec1)) { } } impl> Basis for Vec2 { #[inline] fn canonical_basis(f: &fn(Vec2)) { f(Vec2::new(One::one(), Zero::zero())); f(Vec2::new(Zero::zero(), One::one())); } #[inline] fn orthonormal_subspace_basis(&self, f: &fn(Vec2)) { f(Vec2::new(-self.y, self.x.clone())) } } impl Basis for Vec3 { #[inline(always)] fn canonical_basis(f: &fn(Vec3)) { 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())); } #[inline(always)] fn orthonormal_subspace_basis(&self, f: &fn(Vec3)) { let a = if self.x.clone().abs() > self.y.clone().abs() { Vec3::new(self.z.clone(), Zero::zero(), -self.x).normalized() } else { Vec3::new(Zero::zero(), -self.z, self.y.clone()).normalized() }; f(a.cross(self)); f(a); } } // FIXME: this bad: this fixes definitly the number of samples… static SAMPLES_2_F64: [Vec2, ..21] = [ Vec2 { x: 1.0, y: 0.0 }, Vec2 { x: 0.95557281, y: 0.29475517 }, Vec2 { x: 0.82623877, y: 0.56332006 }, Vec2 { x: 0.6234898, y: 0.78183148 }, Vec2 { x: 0.36534102, y: 0.93087375 }, Vec2 { x: 0.07473009, y: 0.9972038 }, Vec2 { x: -0.22252093, y: 0.97492791 }, Vec2 { x: -0.5, y: 0.8660254 }, Vec2 { x: -0.73305187, y: 0.68017274 }, Vec2 { x: -0.90096887, y: 0.43388374 }, Vec2 { x: -0.98883083, y: 0.14904227 }, Vec2 { x: -0.98883083, y: -0.14904227 }, Vec2 { x: -0.90096887, y: -0.43388374 }, Vec2 { x: -0.73305187, y: -0.68017274 }, Vec2 { x: -0.5, y: -0.8660254 }, Vec2 { x: -0.22252093, y: -0.97492791 }, Vec2 { x: 0.07473009, y: -0.9972038 }, Vec2 { x: 0.36534102, y: -0.93087375 }, Vec2 { x: 0.6234898, y: -0.78183148 }, Vec2 { x: 0.82623877, y: -0.56332006 }, Vec2 { x: 0.95557281, y: -0.29475517 }, ]; impl UniformSphereSample for Vec2 { pub fn sample(f: &fn(&'static Vec2)) { for SAMPLES_2_F64.iter().advance |sample| { f(sample) } } } impl UniformSphereSample for Vec3 { pub fn sample(_: &fn(&'static Vec3)) { fail!("UniformSphereSample for Vec3 is not yet implemented.") } }