quadtree/
collision_detection.rs1use crate::error::QuadtreeResult;
2use crate::quadtree::{validate_circle_radius, validate_rect_dims};
3use crate::shapes::{Circle, Rectangle, ShapeEnum};
4
5pub fn rectangle_contains_rectangle(outer: &Rectangle, inner: &Rectangle) -> QuadtreeResult<bool> {
7 validate_rect_dims(outer.width, outer.height)?;
8 validate_rect_dims(inner.width, inner.height)?;
9 Ok(outer.left() <= inner.left()
10 && outer.right() >= inner.right()
11 && outer.top() <= inner.top()
12 && outer.bottom() >= inner.bottom())
13}
14
15pub fn rectangle_rectangle(a: &Rectangle, b: &Rectangle) -> QuadtreeResult<bool> {
17 validate_rect_dims(a.width, a.height)?;
18 validate_rect_dims(b.width, b.height)?;
19 Ok(
20 a.left() < b.right()
21 && a.right() > b.left()
22 && a.top() < b.bottom()
23 && a.bottom() > b.top(),
24 )
25}
26
27pub fn circle_circle(a: &Circle, b: &Circle) -> QuadtreeResult<bool> {
29 validate_circle_radius(a.radius)?;
30 validate_circle_radius(b.radius)?;
31 let dx = a.x - b.x;
32 let dy = a.y - b.y;
33 let distance_sq = dx * dx + dy * dy;
34 let radius_sum = a.radius + b.radius;
35 Ok(distance_sq < radius_sum * radius_sum)
36}
37
38pub fn circle_rectangle(circle: &Circle, rectangle: &Rectangle) -> QuadtreeResult<bool> {
40 validate_circle_radius(circle.radius)?;
41 validate_rect_dims(rectangle.width, rectangle.height)?;
42 let dx = (circle.x - rectangle.x).abs();
43 let dy = (circle.y - rectangle.y).abs();
44
45 let half_rect_width = rectangle.width / 2.0;
46 let half_rect_height = rectangle.height / 2.0;
47
48 if dx >= half_rect_width + circle.radius || dy >= half_rect_height + circle.radius {
50 return Ok(false);
51 }
52
53 if dx < half_rect_width || dy < half_rect_height {
55 return Ok(true);
56 }
57
58 let corner_dx = dx - half_rect_width;
60 let corner_dy = dy - half_rect_height;
61 let corner_distance_sq = corner_dx * corner_dx + corner_dy * corner_dy;
62
63 Ok(corner_distance_sq < circle.radius * circle.radius)
64}
65
66pub fn shape_shape(a: &ShapeEnum, b: &ShapeEnum) -> QuadtreeResult<bool> {
68 match (a, b) {
69 (ShapeEnum::Circle(circle_a), ShapeEnum::Circle(circle_b)) => {
70 circle_circle(circle_a, circle_b)
71 }
72 (ShapeEnum::Circle(circle), ShapeEnum::Rectangle(rectangle))
73 | (ShapeEnum::Rectangle(rectangle), ShapeEnum::Circle(circle)) => {
74 circle_rectangle(circle, rectangle)
75 }
76 (ShapeEnum::Rectangle(rectangle_a), ShapeEnum::Rectangle(rectangle_b)) => {
77 rectangle_rectangle(rectangle_a, rectangle_b)
78 }
79 }
80}