xref: /StarryEngine/starry_server/src/base/rect.rs (revision 49182ea7bc0263215864dd04cd265e345a4af8f5)
1 use std::cmp::{max, min};
2 
3 /// 表示一个矩形区域
4 #[derive(Clone, Copy, Debug, Default)]
5 pub struct Rect {
6     /// 矩形左上角x坐标
7     x: i32,
8     /// 矩形左上角y坐标
9     y: i32,
10     /// 矩形宽度
11     w: i32,
12     /// 矩形高度
13     h: i32,
14 }
15 
16 #[allow(dead_code)]
17 impl Rect {
18     /// 创建矩形
19     pub fn new(x: i32, y: i32, w: i32, h: i32) -> Rect {
20         assert!(w >= 0);
21         assert!(h >= 0);
22 
23         Rect { x, y, w, h }
24     }
25 
26     /// 矩形的面积
27     pub fn area(&self) -> i32 {
28         self.w * self.h
29     }
30 
31     /// 矩形的左边界
32     pub fn left(&self) -> i32 {
33         self.x
34     }
35 
36     /// 矩形的右边界
37     pub fn right(&self) -> i32 {
38         self.x + self.w
39     }
40 
41     /// 矩形的上边界
42     pub fn top(&self) -> i32 {
43         self.y
44     }
45 
46     /// 矩形的下边界
47     pub fn bottom(&self) -> i32 {
48         self.y + self.h
49     }
50 
51     /// 矩形的宽度
52     pub fn width(&self) -> i32 {
53         self.w
54     }
55 
56     /// 矩形的高度
57     pub fn height(&self) -> i32 {
58         self.h
59     }
60 
61     /// 求两矩形的并集
62     pub fn container(&self, other: &Rect) -> Rect {
63         let left = min(self.left(), other.left());
64         let right = max(self.right(), other.right());
65         let top = min(self.top(), other.top());
66         let bottom = max(self.bottom(), other.bottom());
67 
68         assert!(left <= right);
69         assert!(top <= bottom);
70 
71         Rect::new(left, top, right - left, bottom - top)
72     }
73 
74     /// 求两矩形的交集
75     pub fn intersection(&self, other: &Rect) -> Rect {
76         let left = max(self.left(), other.left());
77         let right = min(self.right(), other.right());
78         let top = max(self.top(), other.top());
79         let bottom = min(self.bottom(), other.bottom());
80 
81         Rect::new(left, top, max(0, right - left), max(0, bottom - top))
82     }
83 
84     /// 判断点是否在矩形中
85     pub fn contains(&self, x: i32, y: i32) -> bool {
86         self.left() <= x && self.right() >= x && self.top() <= y && self.bottom() >= y
87     }
88 
89     /// 判断矩形是否为空
90     pub fn is_empty(&self) -> bool {
91         self.w == 0 || self.h == 0
92     }
93 
94     /// # 函数功能
95     /// 偏移矩形的位置
96     /// 可用于矩形绝对和相对位置的转换
97     ///
98     /// ## 参数
99     /// - x: 向右偏移的量
100     /// - y: 向下偏移的量
101     ///
102     /// ## 返回值
103     /// 偏移得到的矩形
104     pub fn offset(&self, x: i32, y: i32) -> Rect {
105         Rect::new(self.x + x, self.y + y, self.w, self.h)
106     }
107 }
108