Skip to content

Commit

Permalink
Test Aabb-aabb intersection.
Browse files Browse the repository at this point in the history
  • Loading branch information
finnbear committed Jan 8, 2025
1 parent bb2d0ae commit 11e3aa4
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 11 deletions.
49 changes: 49 additions & 0 deletions src/aabb/aabb_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,29 @@ impl<T: BHValue, const D: usize> Aabb<T, D> {
&& self.approx_contains_eps(&other.max, epsilon)
}

/// Returns true if this [`Aabb`] touches the `other` [`Aabb`].
///
/// # Examples
/// ```
/// use bvh::aabb::Aabb;
/// use nalgebra::Point3;
///
/// let aabb1 = Aabb::with_bounds(Point3::new(-1.0, -1.0, -1.0), Point3::new(1.0, 1.0, 1.0));
/// let aabb2 = Aabb::with_bounds(Point3::new(0.5, -0.1, -0.1), Point3::new(1.5, 0.1, 0.1));
///
/// assert!(aabb1.intersects_aabb(&aabb2));
/// ```
///
/// [`Aabb`]: struct.Aabb.html
pub fn intersects_aabb(&self, aabb: &Aabb<T, D>) -> bool {
for i in 0..D {
if self.max[i] < aabb.min[i] || aabb.max[i] < self.min[i] {
return false;
}
}
true
}

/// Returns true if the `other` [`Aabb`] is approximately equal to this [`Aabb`]
/// with respect to some `epsilon`.
///
Expand Down Expand Up @@ -688,6 +711,32 @@ mod tests {
}

proptest! {
// Test properties of `Aabb` intersection.
#[test]
fn test_intersecting_aabbs(a: TupleVec, b: TupleVec, c: TupleVec, d: TupleVec, p: TupleVec) {
let a = tuple_to_point(&a);
let b = tuple_to_point(&b);
let c = tuple_to_point(&c);
let d = tuple_to_point(&d);
let aabb1 = TAabb3::empty().grow(&a).join_bounded(&b);
let aabb2 = TAabb3::empty().grow(&c).join_bounded(&d);
if aabb1.intersects_aabb(&aabb2) {
// For intersecting Aabb's, at least one point is shared.
let mut closest = aabb1.center();
for i in 0..3 {
closest[i] = closest[i].clamp(aabb2.min[i], aabb2.max[i]);
}
assert!(aabb1.contains(&closest), "closest={closest:?}");
assert!(aabb2.contains(&closest), "closest={closest:?}");
} else {
// For non-intersecting Aabb's, no point can't be in both Aabb's.
let p = tuple_to_point(&p);
for point in [a, b, c, d, p] {
assert!(!aabb1.contains(&point) || !aabb2.contains(&point));
}
}
}

// Test whether an empty `Aabb` does not contains anything.
#[test]
fn test_empty_contains_nothing(tpl: TupleVec) {
Expand Down
7 changes: 1 addition & 6 deletions src/aabb/intersection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,7 @@ pub trait IntersectsAabb<T: BHValue, const D: usize> {

impl<T: BHValue, const D: usize> IntersectsAabb<T, D> for Aabb<T, D> {
fn intersects_aabb(&self, aabb: &Aabb<T, D>) -> bool {
for i in 0..D {
if self.max[i] < aabb.min[i] || aabb.max[i] < self.min[i] {
return false;
}
}
true
self.intersects_aabb(aabb)
}
}

Expand Down
14 changes: 9 additions & 5 deletions src/ball.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,18 @@ impl<T: BHValue, const D: usize> IntersectsAabb<T, D> for Ball<T, D> {

#[cfg(test)]
mod tests {
use nalgebra::Point;

use super::Ball;
use crate::testbase::TPoint3;

#[test]
fn ball_contains() {
let ball = Ball::new(Point::<f32, 3>::new(3.0, 4.0, 5.0), 2.0);
assert!(ball.contains(&Point::<f32, 3>::new(4.0, 4.0, 5.0)));
assert!(!ball.contains(&Point::<f32, 3>::new(-4.0, 4.0, 5.0)));
let ball = Ball::new(TPoint3::new(3.0, 4.0, 5.0), 1.5);

// Ball should contain its own center.
assert!(ball.contains(&ball.center));

// Test some points, selected in 3D software to be just inside/outside the sphere.
assert!(ball.contains(&TPoint3::new(3.04605, 3.23758, 3.81607)));
assert!(!ball.contains(&TPoint3::new(3.06066, 3.15813, 3.70917)));
}
}

0 comments on commit 11e3aa4

Please sign in to comment.