1- use std:: { fmt:: Debug , ops:: { Add , Mul , Range , Sub } } ;
1+ use std:: { fmt:: Debug , ops:: { Add , Div , Mul , Range , Sub } } ;
22
33use rand:: { Rng , seq:: IteratorRandom , thread_rng} ;
44
55use 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
3591impl < 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