use vek::Vec2;
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct BBox2D {
pub min: Vec2<f32>, pub max: Vec2<f32>, }
impl BBox2D {
pub fn new(min: Vec2<f32>, max: Vec2<f32>) -> Self {
Self { min, max }
}
pub fn from_pos_size(pos: Vec2<f32>, size: Vec2<f32>) -> Self {
Self {
min: pos,
max: pos + size,
}
}
pub fn size(&self) -> Vec2<f32> {
self.max - self.min
}
pub fn center(&self) -> Vec2<f32> {
(self.min + self.max) * 0.5
}
pub fn contains(&self, point: Vec2<f32>) -> bool {
point.x >= self.min.x
&& point.x <= self.max.x
&& point.y >= self.min.y
&& point.y <= self.max.y
}
pub fn intersects(&self, other: &BBox2D) -> bool {
self.min.x <= other.max.x
&& self.max.x >= other.min.x
&& self.min.y <= other.max.y
&& self.max.y >= other.min.y
}
pub fn expand(&mut self, amount: Vec2<f32>) {
self.min -= amount * 0.5;
self.max += amount * 0.5;
}
pub fn expanded(&self, amount: Vec2<f32>) -> BBox2D {
BBox2D {
min: self.min - amount * 0.5,
max: self.max + amount * 0.5,
}
}
pub fn expand_bbox(&mut self, other: BBox2D) {
self.min.x = self.min.x.min(other.min.x);
self.min.y = self.min.y.min(other.min.y);
self.max.x = self.max.x.max(other.max.x);
self.max.y = self.max.y.max(other.max.y);
}
pub fn line_intersects(&self, a: Vec2<f32>, b: Vec2<f32>) -> bool {
let min = self.min;
let max = self.max;
let dx = b.x - a.x;
let dy = b.y - a.y;
let mut tmin = 0.0;
let mut tmax = 1.0;
let check = |p: f32, q: f32, tmin: &mut f32, tmax: &mut f32| -> bool {
if p == 0.0 {
return q >= 0.0; }
let t = q / p;
if p < 0.0 {
if t > *tmax {
return false;
}
if t > *tmin {
*tmin = t;
}
} else {
if t < *tmin {
return false;
}
if t < *tmax {
*tmax = t;
}
}
true
};
check(-dx, a.x - min.x, &mut tmin, &mut tmax)
&& check(dx, max.x - a.x, &mut tmin, &mut tmax)
&& check(-dy, a.y - min.y, &mut tmin, &mut tmax)
&& check(dy, max.y - a.y, &mut tmin, &mut tmax)
}
}