pub trait BBox: Copy {
const DIM: usize;
type Num: Copy + PartialOrd;
fn lo(&self, dim: usize) -> Self::Num;
fn hi(&self, dim: usize) -> Self::Num;
fn contains_in(&self, dim: usize, point: Self::Num) -> bool {
self.lo(dim) <= point && point < self.hi(dim)
}
fn intersects_in(&self, dim: usize, lo: Self::Num, hi: Self::Num) -> bool {
self.lo(dim) < hi && lo < self.hi(dim)
}
fn intersects(&self, other: &Self) -> bool {
for dim in 0..Self::DIM {
if !self.intersects_in(dim, other.lo(dim), other.hi(dim)) {
return false;
}
}
return true;
}
}
#[derive(Clone, Copy, Debug)]
pub struct BoxND<B, const N: usize> {
min: [B; N],
max: [B; N],
}
impl<B: Copy, const N: usize> BoxND<B, N> {
pub fn new(min: [B; N], max: [B; N]) -> Self {
Self { min, max }
}
}
impl<B, const N: usize> BBox for BoxND<B, N>
where
B: Copy + PartialOrd,
{
const DIM: usize = N;
type Num = B;
fn lo(&self, dim: usize) -> Self::Num {
self.min[dim]
}
fn hi(&self, dim: usize) -> Self::Num {
self.max[dim]
}
}
pub type Box2D<B> = BoxND<B, 2>;
pub type Box2Df32 = Box2D<f32>;
pub type Box2Df64 = Box2D<f64>;
pub type Box3D<B> = BoxND<B, 3>;
pub type Box3Df32 = Box3D<f32>;
pub type Box3Df64 = Box3D<f64>;
#[test]
fn intersect() {
let box0 = Box3Df32::new([0.0, 0.0, 0.0], [10.0, 10.0, 10.0]);
let box1 = Box3Df32::new([5.0, 5.0, 5.0], [15.0, 15.0, 15.0]);
let box2 = Box3Df32::new([10.0, 10.0, 10.0], [20.0, 20.0, 20.0]); let box3 = Box3Df32::new([0.0, 0.0, 50.0], [20.0, 20.0, 60.0]);
assert!(box0.intersects(&box0));
assert!(box0.intersects(&box1));
assert!(box1.intersects(&box0));
assert!(!box0.intersects(&box2));
assert!(!box2.intersects(&box0));
assert!(box1.intersects(&box2));
assert!(box2.intersects(&box1));
assert!(!box0.intersects(&box3));
assert!(!box3.intersects(&box0));
}