From 6ac1f097501b8f41c0dad08f4b2a6f47e40b0407 Mon Sep 17 00:00:00 2001 From: Risto Saarelma Date: Fri, 31 Jan 2014 20:02:42 +0200 Subject: [PATCH 1/6] Utility methods for AA boxes --- src/cgmath/aabb.rs | 66 +++++++++++++++++++++++++++++++++++++++------- src/test/aabb.rs | 39 ++++++++++++++++++++++----- 2 files changed, 89 insertions(+), 16 deletions(-) diff --git a/src/cgmath/aabb.rs b/src/cgmath/aabb.rs index 5e8ff65..93578c6 100644 --- a/src/cgmath/aabb.rs +++ b/src/cgmath/aabb.rs @@ -15,12 +15,48 @@ //! Axis-aligned bounding boxes -use point::{Point2, Point3}; +use point::{Point, Point2, Point3}; +use vector::{Vector, Vec2, Vec3}; +use array::build; +use std::num::{zero, one}; +use std::iter::Iterator; + +pub trait Aabb +< + S: Primitive, + V: Vector, + P: Point, + Slice +> { + fn new(p1: &P, p2: &P) -> Self; + fn min<'a>(&'a self) -> &'a P; + fn max<'a>(&'a self) -> &'a P; + #[inline] fn dim(&self) -> V { self.max().sub_p(self.min()) } + #[inline] fn volume(&self) -> S { self.dim().comp_mul() } + #[inline] fn center(&self) -> P { + let two = one::() + one::(); + self.min().add_v(&self.dim().div_s(two)) + } + + // Tests whether a point is cointained in the box, inclusive for min corner + // and exclusive for the max corner. + #[inline] fn contains(&self, p: &P) -> bool { + p.sub_p(self.min()).iter().all(|x| *x >= zero::()) && + self.max().sub_p(p).iter().all(|x| *x > zero::()) + } + + // Returns a new AABB that is grown to include the given point. + fn grow(&self, p: &P) -> Self { + let mn : P = build(|i| self.min().i(i).min(p.i(i))); + let mx : P = build(|i| self.max().i(i).max(p.i(i))); + Aabb::new(&mn, &mx) + } +} #[deriving(Clone, Eq)] pub struct Aabb2 { - min: Point2, - max: Point2, + mn: Point2, + mx: Point2, } impl Aabb2 { @@ -28,16 +64,22 @@ impl Aabb2 { #[inline] pub fn new(p1: &Point2, p2: &Point2) -> Aabb2 { Aabb2 { - min: Point2::new(p1.x.min(&p2.x), p1.y.min(&p2.y)), - max: Point2::new(p1.x.max(&p2.x), p1.y.max(&p2.y)), + mn: Point2::new(p1.x.min(&p2.x), p1.y.min(&p2.y)), + mx: Point2::new(p1.x.max(&p2.x), p1.y.max(&p2.y)), } } } +impl Aabb, Point2, [S, ..2]> for Aabb2 { + fn new(p1: &Point2, p2: &Point2) -> Aabb2 { Aabb2::new(p1, p2) } + #[inline] fn min<'a>(&'a self) -> &'a Point2 { &self.mn } + #[inline] fn max<'a>(&'a self) -> &'a Point2 { &self.mx } +} + #[deriving(Clone, Eq)] pub struct Aabb3 { - min: Point3, - max: Point3, + mn: Point3, + mx: Point3, } impl Aabb3 { @@ -45,8 +87,14 @@ impl Aabb3 { #[inline] pub fn new(p1: &Point3, p2: &Point3) -> Aabb3 { Aabb3 { - min: Point3::new(p1.x.min(&p2.x), p1.y.min(&p2.y), p1.z.min(&p2.z)), - max: Point3::new(p1.x.max(&p2.x), p1.y.max(&p2.y), p1.z.max(&p2.z)), + mn: Point3::new(p1.x.min(&p2.x), p1.y.min(&p2.y), p1.z.min(&p2.z)), + mx: Point3::new(p1.x.max(&p2.x), p1.y.max(&p2.y), p1.z.max(&p2.z)), } } } + +impl Aabb, Point3, [S, ..3]> for Aabb3 { + fn new(p1: &Point3, p2: &Point3) -> Aabb3 { Aabb3::new(p1, p2) } + #[inline] fn min<'a>(&'a self) -> &'a Point3 { &self.mn } + #[inline] fn max<'a>(&'a self) -> &'a Point3 { &self.mx } +} diff --git a/src/test/aabb.rs b/src/test/aabb.rs index ccbe832..bf3b926 100644 --- a/src/test/aabb.rs +++ b/src/test/aabb.rs @@ -1,13 +1,38 @@ -use cgmath::aabb::{Aabb2, Aabb3}; +use cgmath::aabb::*; use cgmath::point::{Point2, Point3}; +use cgmath::vector::{Vec2, Vec3}; #[test] fn test_aabb() { - let aabb = Aabb2::new(&Point2::new(-20f64, 30f64), &Point2::new(10f64, -10f64)); - assert_eq!(aabb.min, Point2::new(-20f64, -10f64)); - assert_eq!(aabb.max, Point2::new(10f64, 30f64)); + let aabb = Aabb2::new(&Point2::new(-20, 30), &Point2::new(10, -10)); + assert_eq!(aabb.min(), &Point2::new(-20, -10)); + assert_eq!(aabb.max(), &Point2::new(10, 30)); + assert_eq!(aabb.dim(), Vec2::new(30, 40)); + assert_eq!(aabb.volume(), 30 * 40); + assert_eq!(aabb.center(), Point2::new(-5, 10)); - let aabb = Aabb3::new(&Point3::new(-20f64, 30f64, 0f64), &Point3::new(10f64, -10f64, -5f64)); - assert_eq!(aabb.min, Point3::new(-20f64, -10f64, -5f64)); - assert_eq!(aabb.max, Point3::new(10f64, 30f64, 0f64)); + assert!(aabb.contains(&Point2::new(0, 0))); + assert!(!aabb.contains(&Point2::new(-50, -50))); + assert!(!aabb.contains(&Point2::new(50, 50))); + + assert_eq!(aabb.grow(&Point2::new(0, 0)), aabb); + assert_eq!(aabb.grow(&Point2::new(100, 100)), + Aabb2::new(&Point2::new(-20, -10), &Point2::new(100, 100))); + assert_eq!(aabb.grow(&Point2::new(-100, -100)), + Aabb2::new(&Point2::new(-100, -100), &Point2::new(10, 30))); + + let aabb = Aabb3::new(&Point3::new(-20, 30, 5), &Point3::new(10, -10, -5)); + assert_eq!(aabb.min(), &Point3::new(-20, -10, -5)); + assert_eq!(aabb.max(), &Point3::new(10, 30, 5)); + assert_eq!(aabb.dim(), Vec3::new(30, 40, 10)); + assert_eq!(aabb.volume(), 30 * 40 * 10); + assert_eq!(aabb.center(), Point3::new(-5, 10, 0)); + + assert!(aabb.contains(&Point3::new(0, 0, 0))); + assert!(!aabb.contains(&Point3::new(-100, 0, 0))); + assert!(!aabb.contains(&Point3::new(100, 0, 0))); + assert!(aabb.contains(&Point3::new(9, 29, -1))); + assert!(!aabb.contains(&Point3::new(10, 30, 5))); + assert!(aabb.contains(&Point3::new(-20, -10, -5))); + assert!(!aabb.contains(&Point3::new(-21, -11, -6))); } From ff9fc767d40e8a5d3bb1be7b721cf75f73ddc9b5 Mon Sep 17 00:00:00 2001 From: Risto Saarelma Date: Sat, 1 Feb 2014 10:12:27 +0200 Subject: [PATCH 2/6] Translate method for AABBs --- src/cgmath/aabb.rs | 5 +++++ src/test/aabb.rs | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/cgmath/aabb.rs b/src/cgmath/aabb.rs index 93578c6..57eec39 100644 --- a/src/cgmath/aabb.rs +++ b/src/cgmath/aabb.rs @@ -51,6 +51,11 @@ pub trait Aabb let mx : P = build(|i| self.max().i(i).max(p.i(i))); Aabb::new(&mn, &mx) } + + // Returns a new AABB that has its points translated by the given vector. + fn translate(&self, v: &V) -> Self { + Aabb::new(&self.min().add_v(v), &self.max().add_v(v)) + } } #[deriving(Clone, Eq)] diff --git a/src/test/aabb.rs b/src/test/aabb.rs index bf3b926..f58797e 100644 --- a/src/test/aabb.rs +++ b/src/test/aabb.rs @@ -35,4 +35,7 @@ fn test_aabb() { assert!(!aabb.contains(&Point3::new(10, 30, 5))); assert!(aabb.contains(&Point3::new(-20, -10, -5))); assert!(!aabb.contains(&Point3::new(-21, -11, -6))); + + assert_eq!(aabb.translate(&Vec3::new(1, 2, 3)), + Aabb3::new(&Point3::new(-19, 32, 8), &Point3::new(11, -8, -2))); } From 907165075cdc9a876704930dad579be7b8ebd953 Mon Sep 17 00:00:00 2001 From: Risto Saarelma Date: Sat, 1 Feb 2014 10:29:59 +0200 Subject: [PATCH 3/6] Translate and scale methods for AABB --- src/cgmath/aabb.rs | 12 +++++++++++- src/test/aabb.rs | 8 +++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/cgmath/aabb.rs b/src/cgmath/aabb.rs index 57eec39..f80df23 100644 --- a/src/cgmath/aabb.rs +++ b/src/cgmath/aabb.rs @@ -53,9 +53,19 @@ pub trait Aabb } // Returns a new AABB that has its points translated by the given vector. - fn translate(&self, v: &V) -> Self { + fn add_v(&self, v: &V) -> Self { Aabb::new(&self.min().add_v(v), &self.max().add_v(v)) } + + fn mul_s(&self, s: S) -> Self { + Aabb::new(&self.min().mul_s(s.clone()), &self.max().mul_s(s.clone())) + } + + fn mul_v(&self, v: &V) -> Self { + let mn : P = Point::from_vec(&self.min().to_vec().mul_v(v)); + let mx : P = Point::from_vec(&self.max().to_vec().mul_v(v)); + Aabb::new(&mn, &mx) + } } #[deriving(Clone, Eq)] diff --git a/src/test/aabb.rs b/src/test/aabb.rs index f58797e..2eb2475 100644 --- a/src/test/aabb.rs +++ b/src/test/aabb.rs @@ -36,6 +36,12 @@ fn test_aabb() { assert!(aabb.contains(&Point3::new(-20, -10, -5))); assert!(!aabb.contains(&Point3::new(-21, -11, -6))); - assert_eq!(aabb.translate(&Vec3::new(1, 2, 3)), + assert_eq!(aabb.add_v(&Vec3::new(1, 2, 3)), Aabb3::new(&Point3::new(-19, 32, 8), &Point3::new(11, -8, -2))); + + assert_eq!(aabb.mul_s(2), + Aabb3::new(&Point3::new(-40, -20, -10), &Point3::new(20, 60, 10))); + + assert_eq!(aabb.mul_v(&Vec3::new(1, 2, 3)), + Aabb3::new(&Point3::new(-20, -20, -15), &Point3::new(10, 60, 15))); } From 57ff382cf180eb35b3744a66326b0c805518a327 Mon Sep 17 00:00:00 2001 From: Risto Saarelma Date: Fri, 7 Feb 2014 08:50:10 +0200 Subject: [PATCH 4/6] to_str for Aabbs --- src/cgmath/aabb.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/cgmath/aabb.rs b/src/cgmath/aabb.rs index f80df23..3d3e351 100644 --- a/src/cgmath/aabb.rs +++ b/src/cgmath/aabb.rs @@ -18,6 +18,7 @@ use point::{Point, Point2, Point3}; use vector::{Vector, Vec2, Vec3}; use array::build; +use std::fmt; use std::num::{zero, one}; use std::iter::Iterator; @@ -91,6 +92,12 @@ impl Aabb, Point2, [S, ..2]> for Aabb2 { #[inline] fn max<'a>(&'a self) -> &'a Point2 { &self.mx } } +impl ToStr for Aabb2 { + fn to_str(&self) -> ~str { + format!("[{} - {}]", self.mn.to_str(), self.mx.to_str()) + } +} + #[deriving(Clone, Eq)] pub struct Aabb3 { mn: Point3, @@ -113,3 +120,9 @@ impl Aabb, Point3, [S, ..3]> for Aabb3 { #[inline] fn min<'a>(&'a self) -> &'a Point3 { &self.mn } #[inline] fn max<'a>(&'a self) -> &'a Point3 { &self.mx } } + +impl ToStr for Aabb3 { + fn to_str(&self) -> ~str { + format!("[{} - {}]", self.mn.to_str(), self.mx.to_str()) + } +} From a391d4450bccf6d9bd3b65f2b0bf7ff8014c694e Mon Sep 17 00:00:00 2001 From: Risto Saarelma Date: Sun, 9 Feb 2014 10:28:58 +0200 Subject: [PATCH 5/6] Don't use abbrevations for the Aabb field names --- src/cgmath/aabb.rs | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/cgmath/aabb.rs b/src/cgmath/aabb.rs index 3d3e351..f588ae5 100644 --- a/src/cgmath/aabb.rs +++ b/src/cgmath/aabb.rs @@ -48,9 +48,9 @@ pub trait Aabb // Returns a new AABB that is grown to include the given point. fn grow(&self, p: &P) -> Self { - let mn : P = build(|i| self.min().i(i).min(p.i(i))); - let mx : P = build(|i| self.max().i(i).max(p.i(i))); - Aabb::new(&mn, &mx) + let min : P = build(|i| self.min().i(i).min(p.i(i))); + let max : P = build(|i| self.max().i(i).max(p.i(i))); + Aabb::new(&min, &max) } // Returns a new AABB that has its points translated by the given vector. @@ -63,16 +63,16 @@ pub trait Aabb } fn mul_v(&self, v: &V) -> Self { - let mn : P = Point::from_vec(&self.min().to_vec().mul_v(v)); - let mx : P = Point::from_vec(&self.max().to_vec().mul_v(v)); - Aabb::new(&mn, &mx) + let min : P = Point::from_vec(&self.min().to_vec().mul_v(v)); + let max : P = Point::from_vec(&self.max().to_vec().mul_v(v)); + Aabb::new(&min, &max) } } #[deriving(Clone, Eq)] pub struct Aabb2 { - mn: Point2, - mx: Point2, + min: Point2, + max: Point2, } impl Aabb2 { @@ -80,28 +80,28 @@ impl Aabb2 { #[inline] pub fn new(p1: &Point2, p2: &Point2) -> Aabb2 { Aabb2 { - mn: Point2::new(p1.x.min(&p2.x), p1.y.min(&p2.y)), - mx: Point2::new(p1.x.max(&p2.x), p1.y.max(&p2.y)), + min: Point2::new(p1.x.min(&p2.x), p1.y.min(&p2.y)), + max: Point2::new(p1.x.max(&p2.x), p1.y.max(&p2.y)), } } } impl Aabb, Point2, [S, ..2]> for Aabb2 { fn new(p1: &Point2, p2: &Point2) -> Aabb2 { Aabb2::new(p1, p2) } - #[inline] fn min<'a>(&'a self) -> &'a Point2 { &self.mn } - #[inline] fn max<'a>(&'a self) -> &'a Point2 { &self.mx } + #[inline] fn min<'a>(&'a self) -> &'a Point2 { &self.min } + #[inline] fn max<'a>(&'a self) -> &'a Point2 { &self.max } } impl ToStr for Aabb2 { fn to_str(&self) -> ~str { - format!("[{} - {}]", self.mn.to_str(), self.mx.to_str()) + format!("[{} - {}]", self.min.to_str(), self.max.to_str()) } } #[deriving(Clone, Eq)] pub struct Aabb3 { - mn: Point3, - mx: Point3, + min: Point3, + max: Point3, } impl Aabb3 { @@ -109,20 +109,20 @@ impl Aabb3 { #[inline] pub fn new(p1: &Point3, p2: &Point3) -> Aabb3 { Aabb3 { - mn: Point3::new(p1.x.min(&p2.x), p1.y.min(&p2.y), p1.z.min(&p2.z)), - mx: Point3::new(p1.x.max(&p2.x), p1.y.max(&p2.y), p1.z.max(&p2.z)), + min: Point3::new(p1.x.min(&p2.x), p1.y.min(&p2.y), p1.z.min(&p2.z)), + max: Point3::new(p1.x.max(&p2.x), p1.y.max(&p2.y), p1.z.max(&p2.z)), } } } impl Aabb, Point3, [S, ..3]> for Aabb3 { fn new(p1: &Point3, p2: &Point3) -> Aabb3 { Aabb3::new(p1, p2) } - #[inline] fn min<'a>(&'a self) -> &'a Point3 { &self.mn } - #[inline] fn max<'a>(&'a self) -> &'a Point3 { &self.mx } + #[inline] fn min<'a>(&'a self) -> &'a Point3 { &self.min } + #[inline] fn max<'a>(&'a self) -> &'a Point3 { &self.max } } impl ToStr for Aabb3 { fn to_str(&self) -> ~str { - format!("[{} - {}]", self.mn.to_str(), self.mx.to_str()) + format!("[{} - {}]", self.min.to_str(), self.max.to_str()) } } From fb03e2a66095acbc4070d116a6b65514c247f5ff Mon Sep 17 00:00:00 2001 From: Risto Saarelma Date: Wed, 12 Feb 2014 08:56:39 +0200 Subject: [PATCH 6/6] Arguments directly used to construct AABB passed by value --- src/cgmath/aabb.rs | 18 +++++++++--------- src/test/aabb.rs | 14 +++++++------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/cgmath/aabb.rs b/src/cgmath/aabb.rs index f588ae5..34a4e9b 100644 --- a/src/cgmath/aabb.rs +++ b/src/cgmath/aabb.rs @@ -29,7 +29,7 @@ pub trait Aabb P: Point, Slice > { - fn new(p1: &P, p2: &P) -> Self; + fn new(p1: P, p2: P) -> Self; fn min<'a>(&'a self) -> &'a P; fn max<'a>(&'a self) -> &'a P; #[inline] fn dim(&self) -> V { self.max().sub_p(self.min()) } @@ -50,22 +50,22 @@ pub trait Aabb fn grow(&self, p: &P) -> Self { let min : P = build(|i| self.min().i(i).min(p.i(i))); let max : P = build(|i| self.max().i(i).max(p.i(i))); - Aabb::new(&min, &max) + Aabb::new(min, max) } // Returns a new AABB that has its points translated by the given vector. fn add_v(&self, v: &V) -> Self { - Aabb::new(&self.min().add_v(v), &self.max().add_v(v)) + Aabb::new(self.min().add_v(v), self.max().add_v(v)) } fn mul_s(&self, s: S) -> Self { - Aabb::new(&self.min().mul_s(s.clone()), &self.max().mul_s(s.clone())) + Aabb::new(self.min().mul_s(s.clone()), self.max().mul_s(s.clone())) } fn mul_v(&self, v: &V) -> Self { let min : P = Point::from_vec(&self.min().to_vec().mul_v(v)); let max : P = Point::from_vec(&self.max().to_vec().mul_v(v)); - Aabb::new(&min, &max) + Aabb::new(min, max) } } @@ -78,7 +78,7 @@ pub struct Aabb2 { impl Aabb2 { /// Construct a new axis-aligned bounding box from two points. #[inline] - pub fn new(p1: &Point2, p2: &Point2) -> Aabb2 { + pub fn new(p1: Point2, p2: Point2) -> Aabb2 { Aabb2 { min: Point2::new(p1.x.min(&p2.x), p1.y.min(&p2.y)), max: Point2::new(p1.x.max(&p2.x), p1.y.max(&p2.y)), @@ -87,7 +87,7 @@ impl Aabb2 { } impl Aabb, Point2, [S, ..2]> for Aabb2 { - fn new(p1: &Point2, p2: &Point2) -> Aabb2 { Aabb2::new(p1, p2) } + fn new(p1: Point2, p2: Point2) -> Aabb2 { Aabb2::new(p1, p2) } #[inline] fn min<'a>(&'a self) -> &'a Point2 { &self.min } #[inline] fn max<'a>(&'a self) -> &'a Point2 { &self.max } } @@ -107,7 +107,7 @@ pub struct Aabb3 { impl Aabb3 { /// Construct a new axis-aligned bounding box from two points. #[inline] - pub fn new(p1: &Point3, p2: &Point3) -> Aabb3 { + pub fn new(p1: Point3, p2: Point3) -> Aabb3 { Aabb3 { min: Point3::new(p1.x.min(&p2.x), p1.y.min(&p2.y), p1.z.min(&p2.z)), max: Point3::new(p1.x.max(&p2.x), p1.y.max(&p2.y), p1.z.max(&p2.z)), @@ -116,7 +116,7 @@ impl Aabb3 { } impl Aabb, Point3, [S, ..3]> for Aabb3 { - fn new(p1: &Point3, p2: &Point3) -> Aabb3 { Aabb3::new(p1, p2) } + fn new(p1: Point3, p2: Point3) -> Aabb3 { Aabb3::new(p1, p2) } #[inline] fn min<'a>(&'a self) -> &'a Point3 { &self.min } #[inline] fn max<'a>(&'a self) -> &'a Point3 { &self.max } } diff --git a/src/test/aabb.rs b/src/test/aabb.rs index 2eb2475..189120d 100644 --- a/src/test/aabb.rs +++ b/src/test/aabb.rs @@ -4,7 +4,7 @@ use cgmath::vector::{Vec2, Vec3}; #[test] fn test_aabb() { - let aabb = Aabb2::new(&Point2::new(-20, 30), &Point2::new(10, -10)); + let aabb = Aabb2::new(Point2::new(-20, 30), Point2::new(10, -10)); assert_eq!(aabb.min(), &Point2::new(-20, -10)); assert_eq!(aabb.max(), &Point2::new(10, 30)); assert_eq!(aabb.dim(), Vec2::new(30, 40)); @@ -17,11 +17,11 @@ fn test_aabb() { assert_eq!(aabb.grow(&Point2::new(0, 0)), aabb); assert_eq!(aabb.grow(&Point2::new(100, 100)), - Aabb2::new(&Point2::new(-20, -10), &Point2::new(100, 100))); + Aabb2::new(Point2::new(-20, -10), Point2::new(100, 100))); assert_eq!(aabb.grow(&Point2::new(-100, -100)), - Aabb2::new(&Point2::new(-100, -100), &Point2::new(10, 30))); + Aabb2::new(Point2::new(-100, -100), Point2::new(10, 30))); - let aabb = Aabb3::new(&Point3::new(-20, 30, 5), &Point3::new(10, -10, -5)); + let aabb = Aabb3::new(Point3::new(-20, 30, 5), Point3::new(10, -10, -5)); assert_eq!(aabb.min(), &Point3::new(-20, -10, -5)); assert_eq!(aabb.max(), &Point3::new(10, 30, 5)); assert_eq!(aabb.dim(), Vec3::new(30, 40, 10)); @@ -37,11 +37,11 @@ fn test_aabb() { assert!(!aabb.contains(&Point3::new(-21, -11, -6))); assert_eq!(aabb.add_v(&Vec3::new(1, 2, 3)), - Aabb3::new(&Point3::new(-19, 32, 8), &Point3::new(11, -8, -2))); + Aabb3::new(Point3::new(-19, 32, 8), Point3::new(11, -8, -2))); assert_eq!(aabb.mul_s(2), - Aabb3::new(&Point3::new(-40, -20, -10), &Point3::new(20, 60, 10))); + Aabb3::new(Point3::new(-40, -20, -10), Point3::new(20, 60, 10))); assert_eq!(aabb.mul_v(&Vec3::new(1, 2, 3)), - Aabb3::new(&Point3::new(-20, -20, -15), &Point3::new(10, 60, 15))); + Aabb3::new(Point3::new(-20, -20, -15), Point3::new(10, 60, 15))); }