pierro/core/math/
rect.rs

1
2use core::f32;
3use std::fmt::Display;
4
5use crate::Animatable;
6
7use super::{vec2, Axis, Margin, Range, Vec2};
8
9#[derive(Clone, Copy)]
10pub struct Rect {
11    min: Vec2,
12    max: Vec2
13}
14
15impl Rect {
16
17    pub const fn min_max(min: Vec2, max: Vec2) -> Self {
18        Self {
19            min,
20            max
21        }
22    }
23
24    pub fn min_size(min: Vec2, size: Vec2) -> Self {
25        Self {
26            min,
27            max: min + size
28        }
29    }
30
31    pub const fn from_ranges(x_range: Range, y_range: Range) -> Self {
32        Self {
33            min: vec2(x_range.min, y_range.min),
34            max: vec2(x_range.max, y_range.max)
35        }
36    }
37
38    pub const fn to_infinity(from: Vec2) -> Self {
39        Self {
40            min: from,
41            max: Vec2::INFINITY 
42        }
43    }
44
45    pub const ZERO: Self = Self::min_max(Vec2::ZERO, Vec2::ZERO);
46
47    pub const fn tl(&self) -> Vec2 {
48        self.min
49    }
50
51    pub const fn tr(&self) -> Vec2 {
52        vec2(self.max.x, self.min.y)
53    }
54
55    pub const fn bl(&self) -> Vec2 {
56        vec2(self.min.x, self.max.y)
57    }
58
59    pub const fn br(&self) -> Vec2 {
60        self.max
61    }
62    
63    pub const fn left(&self) -> f32 {
64        self.min.x
65    }
66
67    pub const fn right(&self) -> f32 {
68        self.max.x
69    }
70
71    pub const fn top(&self) -> f32 {
72        self.min.y
73    }
74
75    pub const fn bottom(&self) -> f32 {
76        self.max.y
77    }
78
79    pub fn center(&self) -> Vec2 {
80        (self.min + self.max) * 0.5
81    }
82
83    pub fn size(&self) -> Vec2 {
84        self.max - self.min
85    }
86
87    pub fn width(&self) -> f32 {
88        self.size().x
89    }
90    
91    pub fn height(&self) -> f32 {
92        self.size().y
93    }
94
95    pub const fn x_range(&self) -> Range {
96        Range::new(self.min.x, self.max.x)
97    }
98
99    pub fn set_x_range(&mut self, range: Range) {
100        self.min.x = range.min;
101        self.max.x = range.max;
102    } 
103
104    pub const fn y_range(&self) -> Range {
105        Range::new(self.min.y, self.max.y)
106    }
107
108    pub fn set_y_range(&mut self, range: Range) {
109        self.min.y = range.min;
110        self.max.y = range.max;
111    } 
112
113    pub const fn axis_range(&self, axis: Axis) -> Range {
114        Range::new(self.min.on_axis(axis), self.max.on_axis(axis))
115    }
116
117    pub fn set_axis_range(&mut self, axis: Axis, range: Range) {
118        *self.min.on_axis_mut(axis) = range.min; 
119        *self.max.on_axis_mut(axis) = range.max; 
120    }
121
122    pub fn contains(&self, pt: Vec2) -> bool {
123        self.x_range().contains(pt.x) && self.y_range().contains(pt.y)
124    }
125
126    pub fn intersect(&self, other: Rect) -> Rect {
127        Self::from_ranges(
128            self.x_range().intersect(other.x_range()),
129            self.y_range().intersect(other.y_range()) 
130        )
131    }
132
133    pub fn shift(&self, offset: Vec2) -> Rect {
134        Self::min_max(self.min + offset, self.max + offset)
135    }
136
137    pub fn grow(&self, margin: Margin) -> Rect {
138        Self::min_max(self.min - margin.min, self.max + margin.max)
139    }
140
141    pub fn map(&self, from: Rect, to: Rect) -> Self {
142        Self::min_max(
143            self.min.map(from, to),
144           self.max.map(from, to) 
145        )
146    }
147
148    pub fn area(&self) -> f32 {
149        self.width() * self.height()
150    }
151
152    pub fn left_frac(&self, frac: f32) -> Rect {
153        Self::min_max(self.tl(), self.bl().lerp(self.br(), frac))
154    }
155    
156    pub fn right_frac(&self, frac: f32) -> Rect {
157        Self::min_max(self.tl().lerp(self.tr(), frac), self.br())
158    }
159
160    pub fn top_frac(&self, frac: f32) -> Rect {
161        Self::min_max(self.tl(), self.tr().lerp(self.br(), frac))
162    }
163
164    pub fn bottom_frac(&self, frac: f32) -> Rect {
165        Self::min_max(self.bl().lerp(self.tl(), frac), self.br())
166    }
167
168    pub fn left_half(&self) -> Rect {
169        self.left_frac(0.5)
170    }
171
172    pub fn right_half(&self) -> Rect {
173        self.right_frac(0.5)
174    }
175
176    pub fn top_half(&self) -> Rect {
177        self.top_frac(0.5)
178    }
179
180    pub fn bottom_half(&self) -> Rect {
181        self.bottom_frac(0.5)
182    }
183
184}
185
186impl Display for Rect {
187
188    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
189        self.tl().fmt(f)?;
190        f.write_str(" -> ")?;
191        self.br().fmt(f)
192    }
193
194}
195