telar_geometry_core/
rect.rs1#[derive(Debug, Clone, Copy, PartialEq)]
2pub struct Rect {
3 pub x: f32,
4 pub y: f32,
5 pub width: f32,
6 pub height: f32,
7}
8
9impl Rect {
10 pub fn new(x: f32, y: f32, width: f32, height: f32) -> Self {
11 Self {
12 x,
13 y,
14 width,
15 height,
16 }
17 }
18
19 pub fn contains(&self, x: f32, y: f32) -> bool {
20 x >= self.x && x < self.x + self.width && y >= self.y && y < self.y + self.height
21 }
22
23 pub fn intersect(self, other: Rect) -> Option<Rect> {
24 let x = self.x.max(other.x);
25 let y = self.y.max(other.y);
26 let right = (self.x + self.width).min(other.x + other.width);
27 let bottom = (self.y + self.height).min(other.y + other.height);
28 if right > x && bottom > y {
29 Some(Rect::new(x, y, right - x, bottom - y))
30 } else {
31 None
32 }
33 }
34
35 pub fn union(self, other: Rect) -> Rect {
36 let x = self.x.min(other.x);
37 let y = self.y.min(other.y);
38 let right = (self.x + self.width).max(other.x + other.width);
39 let bottom = (self.y + self.height).max(other.y + other.height);
40 Rect::new(x, y, right - x, bottom - y)
41 }
42
43 pub fn overlaps(self, other: Rect) -> bool {
44 self.x < other.x + other.width
45 && self.x + self.width > other.x
46 && self.y < other.y + other.height
47 && self.y + self.height > other.y
48 }
49}
50
51impl Default for Rect {
52 fn default() -> Self {
53 Self::new(0.0, 0.0, 0.0, 0.0)
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn rect_new_stores_fields() {
63 let r = Rect::new(1.0, 2.0, 10.0, 20.0);
64 assert_eq!(r.x, 1.0);
65 assert_eq!(r.y, 2.0);
66 assert_eq!(r.width, 10.0);
67 assert_eq!(r.height, 20.0);
68 }
69
70 #[test]
71 fn rect_default_is_zero() {
72 let r = Rect::default();
73 assert_eq!(r.x, 0.0);
74 assert_eq!(r.y, 0.0);
75 assert_eq!(r.width, 0.0);
76 assert_eq!(r.height, 0.0);
77 }
78
79 #[test]
80 fn rect_intersect_overlapping() {
81 let a = Rect::new(0.0, 0.0, 10.0, 10.0);
82 let b = Rect::new(5.0, 5.0, 10.0, 10.0);
83 let result = a.intersect(b).unwrap();
84 assert_eq!(result.x, 5.0);
85 assert_eq!(result.y, 5.0);
86 assert_eq!(result.width, 5.0);
87 assert_eq!(result.height, 5.0);
88 }
89
90 #[test]
91 fn rect_intersect_non_overlapping() {
92 let a = Rect::new(0.0, 0.0, 5.0, 5.0);
93 let b = Rect::new(10.0, 10.0, 5.0, 5.0);
94 assert!(a.intersect(b).is_none());
95 }
96}