use std::num::{Zero, One, abs}; 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.at[0] * other.at[1] - self.at[1] * other.at[0]]) } } impl + Sub> Cross> for Vec3 { #[inline] fn cross(&self, other : &Vec3) -> Vec3 { 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 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.at[1], self.at[0].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 abs(self.at[0].clone()) > abs(self.at[1].clone()) { Vec3::new([self.at[2].clone(), Zero::zero(), -self.at[0]]).normalized() } else { Vec3::new([Zero::zero(), -self.at[2], self.at[1].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 { 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 { 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.") } }