From abf71658b6a361424e4a0dcbd72f8134b2269a7c Mon Sep 17 00:00:00 2001 From: Matthew Gordon Date: Fri, 10 Jan 2020 17:00:09 -0500 Subject: [PATCH] Add axis_aligned_bounding_box::BoundingBox::union() --- src/raycasting/axis_aligned_bounding_box.rs | 41 +++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/raycasting/axis_aligned_bounding_box.rs b/src/raycasting/axis_aligned_bounding_box.rs index 545c039..e8454eb 100644 --- a/src/raycasting/axis_aligned_bounding_box.rs +++ b/src/raycasting/axis_aligned_bounding_box.rs @@ -74,6 +74,16 @@ impl BoundingBox { .zip(p.iter()) .all(|(interval, &value)| interval.contains_value(value)) } + + pub fn union(&self, other: &BoundingBox) -> BoundingBox { + BoundingBox { + bounds: [ + self.bounds[0].union(other.bounds[0]), + self.bounds[1].union(other.bounds[1]), + self.bounds[2].union(other.bounds[2]), + ], + } + } } impl IntersectP for BoundingBox { @@ -383,5 +393,36 @@ mod tests { let z_ray = Ray::new(Point3::new(0.0, 0.0, 0.0), Vector3::new(0.0, 0.0, 1.0)); assert!(!target.intersect(&z_ray)); } + + #[quickcheck] + fn union_with_self_yields_self(a: Point3, b: Point3) -> bool { + let target = BoundingBox::from_corners(a, b); + let result = target.union(&target); + target + .bounds + .iter() + .zip(result.bounds.iter()) + .all(|(a, b)| a.min == b.min && a.max == b.max) + } + + #[quickcheck] + fn union_yields_full_ranges( + a: Point3, + b: Point3, + c: Point3, + d: Point3, + ) -> bool { + let target1 = BoundingBox::from_corners(a, b); + let target2 = BoundingBox::from_corners(c, d); + let result = target1.union(&target2); + izip!( + result.bounds.iter(), + target1.bounds.iter(), + target2.bounds.iter() + ) + .all(|(r, t1, t2)| { + r.min <= t1.min && r.min <= t2.min && r.max >= t1.max && r.max >= t2.max + }) + } } }