word_cloud/collision/
bb_collider.rs1use quadtree_rs::{area::AreaBuilder, point::Point, Quadtree};
2
3use crate::geometry::{Rectangle, Vector};
4
5use super::CollisionStrategy;
6
7pub struct BoundingBoxCollider {
9 qt: Quadtree<u32, Rectangle>,
10 padding: u32,
11}
12
13impl BoundingBoxCollider {
14 pub fn new(max_width: u32, padding: u32) -> BoundingBoxCollider {
20 BoundingBoxCollider {
21 qt: Quadtree::<u32, Rectangle>::new(f32::sqrt(max_width as f32) as usize),
22 padding,
23 }
24 }
25}
26
27impl CollisionStrategy for BoundingBoxCollider {
28 fn collides(&self, pos: Vector, r: &Rectangle) -> bool {
29 let r = r.grow(2 * self.padding as isize).unwrap();
30
31 let region = AreaBuilder::default()
32 .anchor(Point { x: pos.0, y: pos.1 })
33 .dimensions((r.size().0, r.size().1))
34 .build()
35 .unwrap();
36
37 let query = self.qt.query(region);
38
39 query.count() != 0
40 }
41
42 fn add(&mut self, pos: Vector, r: Rectangle) {
43 let region = AreaBuilder::default()
44 .anchor(Point {
45 x: pos.0 + self.padding,
46 y: pos.1 + self.padding,
47 })
48 .dimensions((r.size().0, r.size().1))
49 .build()
50 .unwrap();
51
52 self.qt.insert(region, r);
53 }
54}
55
56#[cfg(test)]
57mod test {
58 use super::*;
59
60 #[test]
61 fn collide() {
62 let mut bbc = BoundingBoxCollider::new(50, 0);
63 bbc.add((0, 0), Rectangle::new(0, 0, 10, 5));
64 bbc.add((20, 0), Rectangle::new(20, 0, 10, 10));
65
66 assert!(!bbc.collides((15, 5), &Rectangle::new(0, 0, 5, 3)));
67 assert!(!bbc.collides((30, 5), &Rectangle::new(0, 0, 5, 3)));
68
69 assert!(bbc.collides((15, 0), &Rectangle::new(0, 0, 10, 10)));
70 assert!(bbc.collides((0, 0), &Rectangle::new(0, 0, 1, 1)));
71 }
72}