use std::num::{Zero, One, abs}; use traits::basis::Basis; use traits::cross::Cross; use traits::division_ring::DivisionRing; use traits::norm::Norm; 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], copy self.at[0]])) } } 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(copy self.at[0]) > abs(copy self.at[1]) { Vec3::new([copy self.at[2], Zero::zero(), -copy self.at[0]]).normalized() } else { Vec3::new([Zero::zero(), -self.at[2], copy self.at[1]]).normalized() }; f(a.cross(self)); f(a); } }