From 4008cf81218ce97e521552c745f5d2ae17102edb Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sun, 14 Jul 2013 16:18:25 +1000 Subject: [PATCH] Implement component-wise methods --- src/math/vec.rs | 161 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 158 insertions(+), 3 deletions(-) diff --git a/src/math/vec.rs b/src/math/vec.rs index bbfad58..dcf2126 100644 --- a/src/math/vec.rs +++ b/src/math/vec.rs @@ -27,23 +27,30 @@ pub trait NumVec: Neg { pub fn mul_t(&self, value: T) -> Self; pub fn div_t(&self, value: T) -> Self; pub fn rem_t(&self, value: T) -> Self; + pub fn add_v(&self, other: &Self) -> Self; pub fn sub_v(&self, other: &Self) -> Self; pub fn mul_v(&self, other: &Self) -> Self; pub fn div_v(&self, other: &Self) -> Self; pub fn rem_v(&self, other: &Self) -> Self; + pub fn neg_self(&mut self); pub fn add_self_t(&mut self, value: T); pub fn sub_self_t(&mut self, value: T); pub fn mul_self_t(&mut self, value: T); pub fn div_self_t(&mut self, value: T); pub fn rem_self_t(&mut self, value: T); + pub fn add_self_v(&mut self, other: &Self); pub fn sub_self_v(&mut self, other: &Self); pub fn mul_self_v(&mut self, other: &Self); pub fn div_self_v(&mut self, other: &Self); pub fn rem_self_v(&mut self, other: &Self); + pub fn dot(&self, other: &Self) -> T; + + pub fn comp_add(&self) -> T; + pub fn comp_mul(&self) -> T; } /// Vectors with floating point components @@ -65,10 +72,14 @@ pub trait OrdVec: Vec { pub fn le_t(&self, value: T) -> BV; pub fn ge_t(&self, value: T) -> BV; pub fn gt_t(&self, value: T) -> BV; + pub fn lt_v(&self, other: &Self) -> BV; pub fn le_v(&self, other: &Self) -> BV; pub fn ge_v(&self, other: &Self) -> BV; pub fn gt_v(&self, other: &Self) -> BV; + + pub fn comp_min(&self) -> T; + pub fn comp_max(&self) -> T; } /// Vectors with components that can be tested for equality @@ -328,6 +339,18 @@ impl NumVec for Vec2 { *self.index(0) * *other.index(0) + *self.index(1) * *other.index(1) } + + /// Returns the sum of the vector's components. + #[inline] + pub fn comp_add(&self) -> T { + *self.index(0) + *self.index(1) + } + + /// Returns the product of the vector's components. + #[inline] + pub fn comp_mul(&self) -> T { + *self.index(0) * *self.index(1) + } } impl Neg> for Vec2 { @@ -401,7 +424,7 @@ impl FloatVec for Vec2 { } } -impl OrdVec> for Vec2 { +impl OrdVec> for Vec2 { #[inline] pub fn lt_t(&self, value: T) -> Vec2 { Vec2::new(*self.index(0) < value, @@ -449,6 +472,18 @@ impl OrdVec> for Vec2 { Vec2::new(*self.index(0) > *other.index(0), *self.index(1) > *other.index(1)) } + + /// Returns the smallest component of the vector. + #[inline] + pub fn comp_min(&self) -> T { + self.index(0).min(self.index(1)) + } + + /// Returns the largest component of the vector. + #[inline] + pub fn comp_max(&self) -> T { + self.index(0).max(self.index(1)) + } } impl EqVec> for Vec2 { @@ -561,6 +596,18 @@ mod vec2_tests { assert_eq!(mut_a, A.div_v(&B)); } + #[test] + fn test_comp_add() { + assert_eq!(A.comp_add(), 3.0); + assert_eq!(B.comp_add(), 7.0); + } + + #[test] + fn test_comp_mul() { + assert_eq!(A.comp_mul(), 2.0); + assert_eq!(B.comp_mul(), 12.0); + } + #[test] fn test_approx_eq() { assert!(!Vec2::new::(0.000001, 0.000001).approx_eq(&Vec2::new::(0.0, 0.0))); @@ -604,6 +651,18 @@ mod vec2_tests { assert_eq!(mut_c, c.lerp(&d, 0.75)); } + #[test] + fn test_comp_min() { + assert_eq!(A.comp_min(), 1.0); + assert_eq!(B.comp_min(), 3.0); + } + + #[test] + fn test_comp_max() { + assert_eq!(A.comp_max(), 2.0); + assert_eq!(B.comp_max(), 4.0); + } + #[test] fn test_boolean() { let tf = Vec2::new(true, false); @@ -905,6 +964,18 @@ impl NumVec for Vec3 { *self.index(1) * *other.index(1) + *self.index(2) * *other.index(2) } + + /// Returns the sum of the vector's components. + #[inline] + pub fn comp_add(&self) -> T { + *self.index(0) + *self.index(1) + *self.index(2) + } + + /// Returns the product of the vector's components. + #[inline] + pub fn comp_mul(&self) -> T { + *self.index(0) * *self.index(1) * *self.index(2) + } } impl Neg> for Vec3 { @@ -979,7 +1050,7 @@ impl FloatVec for Vec3 { } } -impl OrdVec> for Vec3 { +impl OrdVec> for Vec3 { #[inline] pub fn lt_t(&self, value: T) -> Vec3 { Vec3::new(*self.index(0) < value, @@ -1035,6 +1106,18 @@ impl OrdVec> for Vec3 { *self.index(1) > *other.index(1), *self.index(2) > *other.index(2)) } + + /// Returns the smallest component of the vector. + #[inline] + pub fn comp_min(&self) -> T { + self.index(0).min(self.index(1)).min(self.index(2)) + } + + /// Returns the largest component of the vector. + #[inline] + pub fn comp_max(&self) -> T { + self.index(0).max(self.index(1)).max(self.index(2)) + } } impl EqVec> for Vec3 { @@ -1167,6 +1250,18 @@ mod vec3_tests{ assert_eq!(mut_a, A.div_v(&B)); } + #[test] + fn test_comp_add() { + assert_eq!(A.comp_add(), 6.0); + assert_eq!(B.comp_add(), 15.0); + } + + #[test] + fn test_comp_mul() { + assert_eq!(A.comp_mul(), 6.0); + assert_eq!(B.comp_mul(), 120.0); + } + #[test] fn test_approx_eq() { assert!(!Vec3::new::(0.000001, 0.000001, 0.000001).approx_eq(&Vec3::new::(0.0, 0.0, 0.0))); @@ -1211,6 +1306,18 @@ mod vec3_tests{ assert_eq!(mut_c, c.lerp(&d, 0.75)); } + #[test] + fn test_comp_min() { + assert_eq!(A.comp_min(), 1.0); + assert_eq!(B.comp_min(), 4.0); + } + + #[test] + fn test_comp_max() { + assert_eq!(A.comp_max(), 3.0); + assert_eq!(B.comp_max(), 6.0); + } + #[test] fn test_boolean() { let tft = Vec3::new(true, false, true); @@ -1512,6 +1619,18 @@ impl NumVec for Vec4 { *self.index(2) * *other.index(2) + *self.index(3) * *other.index(3) } + + /// Returns the sum of the vector's components. + #[inline] + pub fn comp_add(&self) -> T { + *self.index(0) + *self.index(1) + *self.index(2) + *self.index(3) + } + + /// Returns the product of the vector's components. + #[inline] + pub fn comp_mul(&self) -> T { + *self.index(0) * *self.index(1) * *self.index(2) * *self.index(3) + } } impl Neg> for Vec4 { @@ -1587,7 +1706,7 @@ impl FloatVec for Vec4 { } } -impl OrdVec> for Vec4 { +impl OrdVec> for Vec4 { #[inline] pub fn lt_t(&self, value: T) -> Vec4 { Vec4::new(*self.index(0) < value, @@ -1651,6 +1770,18 @@ impl OrdVec> for Vec4 { *self.index(2) > *other.index(2), *self.index(3) > *other.index(3)) } + + /// Returns the smallest component of the vector. + #[inline] + pub fn comp_min(&self) -> T { + self.index(0).min(self.index(1)).min(self.index(2)).min(self.index(3)) + } + + /// Returns the largest component of the vector. + #[inline] + pub fn comp_max(&self) -> T { + self.index(0).max(self.index(1)).max(self.index(2)).max(self.index(3)) + } } impl EqVec> for Vec4 { @@ -1780,6 +1911,18 @@ mod vec4_tests { assert_eq!(mut_a, A.div_v(&B)); } + #[test] + fn test_comp_add() { + assert_eq!(A.comp_add(), 10.0); + assert_eq!(B.comp_add(), 26.0); + } + + #[test] + fn test_comp_mul() { + assert_eq!(A.comp_mul(), 24.0); + assert_eq!(B.comp_mul(), 1680.0); + } + #[test] fn test_approx_eq() { assert!(!Vec4::new::(0.000001, 0.000001, 0.000001, 0.000001).approx_eq(&Vec4::new::(0.0, 0.0, 0.0, 0.0))); @@ -1823,6 +1966,18 @@ mod vec4_tests { assert_eq!(mut_c, c.lerp(&d, 0.75)); } + #[test] + fn test_comp_min() { + assert_eq!(A.comp_min(), 1.0); + assert_eq!(B.comp_min(), 5.0); + } + + #[test] + fn test_comp_max() { + assert_eq!(A.comp_max(), 4.0); + assert_eq!(B.comp_max(), 8.0); + } + #[test] fn test_boolean() { let tftf = Vec4::new(true, false, true, false);