Skip to content

Commit ce3a208

Browse files
committed
Add utilities for fetching various unit points of a Rect
1 parent 2d864cb commit ce3a208

File tree

1 file changed

+81
-2
lines changed
  • lighthouse-protocol/src/utils

1 file changed

+81
-2
lines changed

lighthouse-protocol/src/utils/rect.rs

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use std::{fmt::Debug, ops::{Add, Mul, Range, Sub}};
1+
use std::{fmt::Debug, ops::{Add, Div, Mul, Range, Sub}};
22

33
use rand::{Rng, seq::IteratorRandom, thread_rng};
44

55
use crate::{Vec2, LIGHTHOUSE_COLS};
66

7-
use super::{RemEuclid, Zero};
7+
use super::{RemEuclid, Unity, Zero};
88

99
/// A rectangle on the integer grid.
1010
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
@@ -30,6 +30,62 @@ impl<T> Rect<T> where T: Copy {
3030
pub const fn height(self) -> T {
3131
self.size.y
3232
}
33+
34+
/// Fetches the top-left corner of the rectangle, i.e. the origin.
35+
pub const fn top_left(self) -> Vec2<T> {
36+
self.origin
37+
}
38+
}
39+
40+
impl<T> Rect<T> where T: Add<Output = T> + Copy {
41+
/// Fetches the bottom-right corner of the rectangle.
42+
pub fn bottom_right(self) -> Vec2<T> {
43+
self.origin + self.size
44+
}
45+
}
46+
47+
impl<T> Rect<T> where T: Add<Output = T> + Copy + Zero {
48+
/// Fetches the bottom-left corner of the rectangle.
49+
pub fn bottom_left(self) -> Vec2<T> {
50+
self.origin + Vec2::new(T::ZERO, self.size.y)
51+
}
52+
53+
/// Fetches the top-right corner of the rectangle.
54+
pub fn top_right(self) -> Vec2<T> {
55+
self.origin + Vec2::new(self.size.x, T::ZERO)
56+
}
57+
}
58+
59+
impl<T> Rect<T> where T: Add<Output = T> + Div<Output = T> + Copy + Zero + Unity {
60+
/// The generic constant 2.
61+
fn two() -> T {
62+
T::ONE + T::ONE
63+
}
64+
65+
/// Fetches the top-center position of the rectangle.
66+
pub fn top_center(self) -> Vec2<T> {
67+
self.origin + Vec2::new(self.size.x / Self::two(), T::ZERO)
68+
}
69+
70+
/// Fetches the left-center position of the rectangle.
71+
pub fn center_left(self) -> Vec2<T> {
72+
self.origin + Vec2::new(T::ZERO, self.size.y / Self::two())
73+
}
74+
75+
/// Fetches the right-center position of the rectangle.
76+
pub fn center_right(self) -> Vec2<T> {
77+
self.origin + Vec2::new(self.size.x, self.size.y / Self::two())
78+
}
79+
80+
/// Fetches the bottom-center position of the rectangle.
81+
pub fn bottom_center(self) -> Vec2<T> {
82+
self.origin + Vec2::new(self.size.x / Self::two(), self.size.y)
83+
}
84+
85+
/// Fetches the center position of the rectangle.
86+
pub fn center(self) -> Vec2<T> {
87+
self.origin + self.size.map(|c| c / Self::two())
88+
}
3389
}
3490

3591
impl<T> Rect<T> where T: Mul<Output = T> + Copy {
@@ -98,3 +154,26 @@ impl<T> Rect<T> where T: Add<Output = T> + Sub<Output = T> + TryInto<usize> + Or
98154
relative.y.try_into().unwrap() * LIGHTHOUSE_COLS + relative.x.try_into().unwrap()
99155
}
100156
}
157+
158+
#[cfg(test)]
159+
mod tests {
160+
use crate::Vec2;
161+
162+
use super::Rect;
163+
164+
#[test]
165+
fn unit_points() {
166+
let rect = Rect::new(Vec2::new(-1, -1), Vec2::new(2, 2));
167+
assert_eq!(rect.top_left(), Vec2::new(-1, -1));
168+
assert_eq!(rect.top_center(), Vec2::new(0, -1));
169+
assert_eq!(rect.top_right(), Vec2::new(1, -1));
170+
171+
assert_eq!(rect.center_left(), Vec2::new(-1, 0));
172+
assert_eq!(rect.center(), Vec2::new(0, 0));
173+
assert_eq!(rect.center_right(), Vec2::new(1, 0));
174+
175+
assert_eq!(rect.bottom_left(), Vec2::new(-1, 1));
176+
assert_eq!(rect.bottom_center(), Vec2::new(0, 1));
177+
assert_eq!(rect.bottom_right(), Vec2::new(1, 1));
178+
}
179+
}

0 commit comments

Comments
 (0)