ass_renderer/collision/
mod.rs1mod resolver;
4
5pub use resolver::{CollisionResolver, SmartCollisionResolver};
6
7pub trait CollisionDetector: Send + Sync {
9 fn check_collision(&self, bbox: &BoundingBox, existing: &[BoundingBox]) -> bool;
11
12 fn find_free_position(
14 &self,
15 bbox: &BoundingBox,
16 existing: &[BoundingBox],
17 bounds: &BoundingBox,
18 ) -> Option<(f32, f32)>;
19}
20
21#[derive(Debug, Clone, Copy)]
23pub struct BoundingBox {
24 pub x: f32,
26 pub y: f32,
28 pub width: f32,
30 pub height: f32,
32}
33
34impl BoundingBox {
35 pub fn new(x: f32, y: f32, width: f32, height: f32) -> Self {
37 Self {
38 x,
39 y,
40 width,
41 height,
42 }
43 }
44
45 pub fn intersects(&self, other: &BoundingBox) -> bool {
47 self.x < other.x + other.width
48 && self.x + self.width > other.x
49 && self.y < other.y + other.height
50 && self.y + self.height > other.y
51 }
52
53 pub fn overlap_area(&self, other: &BoundingBox) -> f32 {
55 let x_overlap = (self.x + self.width).min(other.x + other.width) - self.x.max(other.x);
56 let y_overlap = (self.y + self.height).min(other.y + other.height) - self.y.max(other.y);
57
58 if x_overlap > 0.0 && y_overlap > 0.0 {
59 x_overlap * y_overlap
60 } else {
61 0.0
62 }
63 }
64
65 pub fn expand(&self, margin: f32) -> Self {
67 Self {
68 x: self.x - margin,
69 y: self.y - margin,
70 width: self.width + margin * 2.0,
71 height: self.height + margin * 2.0,
72 }
73 }
74
75 pub fn center(&self) -> (f32, f32) {
77 (self.x + self.width / 2.0, self.y + self.height / 2.0)
78 }
79}
80
81#[derive(Debug, Clone)]
83pub struct PositionedEvent {
84 pub bbox: BoundingBox,
86 pub layer: i32,
88 pub margin_v: i32,
90 pub margin_l: i32,
92 pub margin_r: i32,
94 pub alignment: u8,
96 pub priority: i32,
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn test_bounding_box_intersection() {
106 let box1 = BoundingBox::new(0.0, 0.0, 100.0, 50.0);
107 let box2 = BoundingBox::new(50.0, 25.0, 100.0, 50.0);
108 let box3 = BoundingBox::new(200.0, 200.0, 50.0, 50.0);
109
110 assert!(box1.intersects(&box2));
111 assert!(box2.intersects(&box1));
112 assert!(!box1.intersects(&box3));
113 assert!(!box3.intersects(&box1));
114 }
115}