use crate::vec2::Vec2;
use crate::vec3::Vec3;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Aabb2 {
pub min: Vec2,
pub max: Vec2,
}
impl Aabb2 {
#[inline]
pub fn from_points(a: Vec2, b: Vec2) -> Self {
Self {
min: [a[0].min(b[0]), a[1].min(b[1])],
max: [a[0].max(b[0]), a[1].max(b[1])],
}
}
#[inline]
pub fn point(p: Vec2) -> Self {
Self { min: p, max: p }
}
#[inline]
pub fn expand(&mut self, p: Vec2) {
self.min = [self.min[0].min(p[0]), self.min[1].min(p[1])];
self.max = [self.max[0].max(p[0]), self.max[1].max(p[1])];
}
#[inline]
pub fn contains(&self, p: Vec2) -> bool {
p[0] >= self.min[0] && p[0] <= self.max[0] && p[1] >= self.min[1] && p[1] <= self.max[1]
}
#[inline]
pub fn intersects(&self, other: &Aabb2) -> bool {
self.min[0] <= other.max[0]
&& self.max[0] >= other.min[0]
&& self.min[1] <= other.max[1]
&& self.max[1] >= other.min[1]
}
#[inline]
pub fn size(&self) -> Vec2 {
[self.max[0] - self.min[0], self.max[1] - self.min[1]]
}
#[inline]
pub fn center(&self) -> Vec2 {
[
0.5 * (self.min[0] + self.max[0]),
0.5 * (self.min[1] + self.max[1]),
]
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Aabb3 {
pub min: Vec3,
pub max: Vec3,
}
impl Aabb3 {
#[inline]
pub fn from_points(a: Vec3, b: Vec3) -> Self {
Self {
min: [a[0].min(b[0]), a[1].min(b[1]), a[2].min(b[2])],
max: [a[0].max(b[0]), a[1].max(b[1]), a[2].max(b[2])],
}
}
#[inline]
pub fn point(p: Vec3) -> Self {
Self { min: p, max: p }
}
#[inline]
pub fn expand(&mut self, p: Vec3) {
self.min = [
self.min[0].min(p[0]),
self.min[1].min(p[1]),
self.min[2].min(p[2]),
];
self.max = [
self.max[0].max(p[0]),
self.max[1].max(p[1]),
self.max[2].max(p[2]),
];
}
#[inline]
pub fn contains(&self, p: Vec3) -> bool {
p[0] >= self.min[0]
&& p[0] <= self.max[0]
&& p[1] >= self.min[1]
&& p[1] <= self.max[1]
&& p[2] >= self.min[2]
&& p[2] <= self.max[2]
}
#[inline]
pub fn intersects(&self, other: &Aabb3) -> bool {
self.min[0] <= other.max[0]
&& self.max[0] >= other.min[0]
&& self.min[1] <= other.max[1]
&& self.max[1] >= other.min[1]
&& self.min[2] <= other.max[2]
&& self.max[2] >= other.min[2]
}
#[inline]
pub fn size(&self) -> Vec3 {
[
self.max[0] - self.min[0],
self.max[1] - self.min[1],
self.max[2] - self.min[2],
]
}
#[inline]
pub fn center(&self) -> Vec3 {
[
0.5 * (self.min[0] + self.max[0]),
0.5 * (self.min[1] + self.max[1]),
0.5 * (self.min[2] + self.max[2]),
]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn aabb2_contains_and_intersects() {
let a = Aabb2::from_points([0.0, 0.0], [10.0, 10.0]);
assert!(a.contains([5.0, 5.0]));
assert!(!a.contains([11.0, 5.0]));
let b = Aabb2::from_points([5.0, 5.0], [15.0, 15.0]);
let c = Aabb2::from_points([100.0, 100.0], [200.0, 200.0]);
assert!(a.intersects(&b));
assert!(!a.intersects(&c));
}
#[test]
fn aabb3_size_and_center() {
let a = Aabb3::from_points([0.0, 0.0, 0.0], [2.0, 4.0, 8.0]);
assert_eq!(a.size(), [2.0, 4.0, 8.0]);
assert_eq!(a.center(), [1.0, 2.0, 4.0]);
}
}