From 84150a904899957cb32e1c54fa31ad9100937507 Mon Sep 17 00:00:00 2001 From: Michael Nelson Date: Wed, 14 Oct 2015 12:14:38 +0000 Subject: [PATCH] Add support for min and max methods on points. Add some missing tests and modularise tests (better output). Use assert_eq consistently. --- src/point.rs | 222 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 197 insertions(+), 25 deletions(-) diff --git a/src/point.rs b/src/point.rs index ea19b9a..9938282 100644 --- a/src/point.rs +++ b/src/point.rs @@ -12,6 +12,7 @@ use size::Size2D; use num::Zero; use num_lib::NumCast; +use num_lib::traits; use std::fmt::{self, Formatter}; use std::ops::{Add, Neg, Mul, Sub, Div}; @@ -97,6 +98,16 @@ impl > Neg for Point2D { } } +impl Point2D { + pub fn min(self, other: Point2D) -> Point2D { + Point2D::new(self.x.min(other.x), self.y.min(other.y)) + } + + pub fn max(self, other: Point2D) -> Point2D { + Point2D::new(self.x.max(other.x), self.y.max(other.y)) + } +} + impl, T1: Clone> Mul for Point2D { type Output = Point2D; #[inline] @@ -117,7 +128,7 @@ impl, T1: Clone> Div for Point2D = Point2D>; -impl Point2D> { +impl TypedPoint2D { pub fn typed(x: T, y: T) -> TypedPoint2D { Point2D::new(Length::new(x), Length::new(y)) } @@ -235,6 +246,18 @@ impl > Neg for Point3D { } } +impl Point3D { + pub fn min(self, other: Point3D) -> Point3D { + Point3D::new(self.x.min(other.x), self.y.min(other.y), + self.z.min(other.z)) + } + + pub fn max(self, other: Point3D) -> Point3D { + Point3D::new(self.x.max(other.x), self.y.max(other.y), + self.z.max(other.z)) + } +} + #[derive(Clone, Copy, RustcDecodable, RustcEncodable, Eq, Hash, PartialEq)] #[cfg_attr(feature = "heap_size", derive(HeapSizeOf))] pub struct Point4D { @@ -303,34 +326,183 @@ impl > Neg for Point4D { } } -#[test] -pub fn test_dot_2d() { - let p1 = Point2D::new(2.0, 7.0); - let p2 = Point2D::new(13.0, 11.0); - assert!(p1.dot(p2) == 103.0); +impl Point4D { + pub fn min(self, other: Point4D) -> Point4D { + Point4D::new(self.x.min(other.x), self.y.min(other.y), + self.z.min(other.z), self.w.min(other.w)) + } + + pub fn max(self, other: Point4D) -> Point4D { + Point4D::new(self.x.max(other.x), self.y.max(other.y), + self.z.max(other.z), self.w.max(other.w)) + } } -#[test] -pub fn test_dot_3d() { - let p1 = Point3D::new(7.0, 21.0, 32.0); - let p2 = Point3D::new(43.0, 5.0, 16.0); - assert!(p1.dot(p2) == 918.0); + +#[cfg(test)] +mod point2d { + use super::Point2D; + + #[test] + pub fn test_scalar_mul() { + let p1 = Point2D::new(3.0, 5.0); + + let result = p1 * 5.0; + + assert_eq!(result, Point2D::new(15.0, 25.0)); + } + + #[test] + pub fn test_dot() { + let p1 = Point2D::new(2.0, 7.0); + let p2 = Point2D::new(13.0, 11.0); + assert_eq!(p1.dot(p2), 103.0); + } + + #[test] + pub fn test_cross() { + let p1 = Point2D::new(4.0, 7.0); + let p2 = Point2D::new(13.0, 8.0); + let r = p1.cross(p2); + assert_eq!(r, -59.0); + } + + #[test] + pub fn test_min() { + let p1 = Point2D::new(1.0, 3.0); + let p2 = Point2D::new(2.0, 2.0); + + let result = p1.min(p2); + + assert_eq!(result, Point2D::new(1.0, 2.0)); + } + + #[test] + pub fn test_max() { + let p1 = Point2D::new(1.0, 3.0); + let p2 = Point2D::new(2.0, 2.0); + + let result = p1.max(p2); + + assert_eq!(result, Point2D::new(2.0, 3.0)); + } +} + +#[cfg(test)] +mod typedpoint2d { + use super::TypedPoint2D; + use scale_factor::ScaleFactor; + + #[derive(Debug, Copy, Clone)] + enum Mm {} + #[derive(Debug, Copy, Clone)] + enum Cm {} + + pub type Point2DMm = TypedPoint2D; + pub type Point2DCm = TypedPoint2D; + + #[test] + pub fn test_add() { + let p1 = Point2DMm::typed(1.0, 2.0); + let p2 = Point2DMm::typed(3.0, 4.0); + + let result = p1 + p2; + + assert_eq!(result, Point2DMm::typed(4.0, 6.0)); + } + + #[test] + pub fn test_scalar_mul() { + let p1 = Point2DMm::typed(1.0, 2.0); + let cm_per_mm: ScaleFactor = ScaleFactor::new(0.1); + + let result = p1 * cm_per_mm; + + assert_eq!(result, Point2DCm::typed(0.1, 0.2)); + } } -#[test] -pub fn test_cross_2d() { - let p1 = Point2D::new(4.0, 7.0); - let p2 = Point2D::new(13.0, 8.0); - let r = p1.cross(p2); - assert!(r == -59.0); +#[cfg(test)] +mod point3d { + use super::Point3D; + + #[test] + pub fn test_dot() { + let p1 = Point3D::new(7.0, 21.0, 32.0); + let p2 = Point3D::new(43.0, 5.0, 16.0); + assert_eq!(p1.dot(p2), 918.0); + } + + #[test] + pub fn test_cross() { + let p1 = Point3D::new(4.0, 7.0, 9.0); + let p2 = Point3D::new(13.0, 8.0, 3.0); + let p3 = p1.cross(p2); + assert_eq!(p3, Point3D::new(-51.0, 105.0, -59.0)); + } + + #[test] + pub fn test_min() { + let p1 = Point3D::new(1.0, 3.0, 5.0); + let p2 = Point3D::new(2.0, 2.0, -1.0); + + let result = p1.min(p2); + + assert_eq!(result, Point3D::new(1.0, 2.0, -1.0)); + } + + #[test] + pub fn test_max() { + let p1 = Point3D::new(1.0, 3.0, 5.0); + let p2 = Point3D::new(2.0, 2.0, -1.0); + + let result = p1.max(p2); + + assert_eq!(result, Point3D::new(2.0, 3.0, 5.0)); + } } -#[test] -pub fn test_cross_3d() { - let p1 = Point3D::new(4.0, 7.0, 9.0); - let p2 = Point3D::new(13.0, 8.0, 3.0); - let p3 = p1.cross(p2); - assert!(p3.x == -51.0); - assert!(p3.y == 105.0); - assert!(p3.z == -59.0); +#[cfg(test)] +mod point4d { + use super::Point4D; + + #[test] + pub fn test_add() { + let p1 = Point4D::new(7.0, 21.0, 32.0, 1.0); + let p2 = Point4D::new(43.0, 5.0, 16.0, 2.0); + + let result = p1 + p2; + + assert_eq!(result, Point4D::new(50.0, 26.0, 48.0, 3.0)); + } + + #[test] + pub fn test_sub() { + let p1 = Point4D::new(7.0, 21.0, 32.0, 1.0); + let p2 = Point4D::new(43.0, 5.0, 16.0, 2.0); + + let result = p1 - p2; + + assert_eq!(result, Point4D::new(-36.0, 16.0, 16.0, -1.0)); + } + + #[test] + pub fn test_min() { + let p1 = Point4D::new(1.0, 3.0, 5.0, 7.0); + let p2 = Point4D::new(2.0, 2.0, -1.0, 10.0); + + let result = p1.min(p2); + + assert_eq!(result, Point4D::new(1.0, 2.0, -1.0, 7.0)); + } + + #[test] + pub fn test_max() { + let p1 = Point4D::new(1.0, 3.0, 5.0, 7.0); + let p2 = Point4D::new(2.0, 2.0, -1.0, 10.0); + + let result = p1.max(p2); + + assert_eq!(result, Point4D::new(2.0, 3.0, 5.0, 10.0)); + } }