hui_shared/rect/
rect.rs

1use glam::Vec2;
2use super::Corners;
3
4/// Represents a rectangle/AABB with specified position and size
5#[derive(Clone, Copy, Debug, PartialEq, Default)]
6pub struct Rect {
7  /// Position of the top-left corner of the rect.
8  pub position: Vec2,
9  /// Size of the rect, should not be negative.
10  pub size: Vec2,
11}
12
13impl Rect {
14  pub const fn new(position: Vec2, size: Vec2) -> Self {
15    Self { position, size }
16  }
17
18  pub const fn from_position(position: Vec2) -> Self {
19    Self {
20      position,
21      size: Vec2::ZERO,
22    }
23  }
24
25  pub const fn from_size(size: Vec2) -> Self {
26    Self {
27      position: Vec2::ZERO,
28      size,
29    }
30  }
31
32  /// Check if the rect contains a point.
33  pub fn contains_point(&self, point: Vec2) -> bool {
34    point.cmpge(self.position).all() && point.cmple(self.position + self.size).all()
35  }
36
37  //TODO: return intersect rect
38  /// Check if the rect intersects with another rect.
39  pub fn intersects_rect(&self, other: Rect) -> bool {
40    self.position.x < other.position.x + other.size.x
41      && self.position.x + self.size.x > other.position.x
42      && self.position.y < other.position.y + other.size.y
43      && self.position.y + self.size.y > other.position.y
44  }
45
46  /// Get width of the rectangle.
47  ///
48  /// To get both width and height, use the `size` property instead.
49  pub fn width(&self) -> f32 {
50    self.size.x
51  }
52
53  /// Get height of the rectangle.
54  ///
55  /// To get both width and height, use the `size` property instead.
56  pub fn height(&self) -> f32 {
57    self.size.y
58  }
59
60  /// Get position of the top-left corner of the rectangle on the x-axis.
61  ///
62  /// To get both x and y, use the `position` property instead.
63  pub fn x(&self) -> f32 {
64    self.position.x
65  }
66
67  /// Get position of the top-left corner of the rectangle on the y-axis.
68  ///
69  /// To get both x and y, use the `position` property instead.
70  pub fn y(&self) -> f32 {
71    self.position.y
72  }
73
74  /// Get positions of all 4 corners of the rectangle.
75  pub fn corners(&self) -> Corners<Vec2> {
76    Corners {
77      top_left: self.position,
78      top_right: self.position + Vec2::new(self.size.x, 0.0),
79      bottom_left: self.position + Vec2::new(0.0, self.size.y),
80      bottom_right: self.position + self.size,
81    }
82  }
83}
84
85impl From<Vec2> for Rect {
86  /// Create a new `Rect` from a `Vec2`, where x and y are the width and height of the rect respectively.
87  fn from(size: Vec2) -> Self {
88    Self::from_size(size)
89  }
90}
91
92impl From<(Vec2, Vec2)> for Rect {
93  /// Create a new `Rect` from a tuple of two `Vec2`s, where the first `Vec2` is the position and the second `Vec2` is the size.
94  fn from((position, size): (Vec2, Vec2)) -> Self {
95    Self { position, size }
96  }
97}
98
99impl From<(f32, f32, f32, f32)> for Rect {
100  /// Create a new `Rect` from a tuple of 4 `f32`s, where the first two `f32`s are the x and y positions of the top-left corner and the last two `f32`s are the width and height of the rect respectively.
101  fn from((x, y, width, height): (f32, f32, f32, f32)) -> Self {
102    Self {
103      position: Vec2::new(x, y),
104      size: Vec2::new(width, height),
105    }
106  }
107}
108
109impl From<[f32; 4]> for Rect {
110  /// Create a new `Rect` from an array of 4 `f32`s, where the first two `f32`s are the x and y positions of the top-left corner and the last two `f32`s are the width and height of the rect respectively.
111  fn from([x, y, width, height]: [f32; 4]) -> Self {
112    Self {
113      position: Vec2::new(x, y),
114      size: Vec2::new(width, height),
115    }
116  }
117}
118
119impl From<Rect> for (Vec2, Vec2) {
120  /// Convert a `Rect` into a tuple of two `Vec2`s, where the first `Vec2` is the position and the second `Vec2` is the size.
121  fn from(rect: Rect) -> Self {
122    (rect.position, rect.size)
123  }
124}
125
126impl From<Rect> for (f32, f32, f32, f32) {
127  /// Convert a `Rect` into a tuple of 4 `f32`s, where the first two `f32`s are the x and y positions of the top-left corner and the last two `f32`s are the width and height of the rect respectively.
128  fn from(rect: Rect) -> Self {
129    (rect.position.x, rect.position.y, rect.size.x, rect.size.y)
130  }
131}
132
133impl From<Rect> for [f32; 4] {
134  /// Convert a `Rect` into an array of 4 `f32`s, where the first two `f32`s are the x and y positions of the top-left corner and the last two `f32`s are the width and height of the rect respectively.
135  fn from(rect: Rect) -> Self {
136    [rect.position.x, rect.position.y, rect.size.x, rect.size.y]
137  }
138}