11use crate :: utils:: grid_line:: GridLine ;
22use crate :: utils:: point:: Point ;
33use crate :: utils:: traits:: IsInside ;
4+ use itertools:: Itertools ;
45
56#[ derive( PartialEq , Clone ) ]
67pub struct Polygon {
@@ -26,13 +27,28 @@ impl Polygon {
2627 pub fn rectangle ( first_corner : Point , second_corner : Point ) -> Self {
2728 let points = [
2829 Point :: new ( first_corner. x , first_corner. y ) ,
29- Point :: new ( first_corner. x , second_corner. y ) ,
30- Point :: new ( second_corner. x , second_corner. y ) ,
3130 Point :: new ( second_corner. x , first_corner. y ) ,
31+ Point :: new ( second_corner. x , second_corner. y ) ,
32+ Point :: new ( first_corner. x , second_corner. y ) ,
3233 ] ;
3334
3435 Self :: from_iter ( points)
3536 }
37+
38+ #[ allow( dead_code) ]
39+ pub fn extend ( & self ) -> Self {
40+ let lines = self
41+ . lines
42+ . iter ( )
43+ . map ( |line| {
44+ let direction = line. direction ( ) . ccw ( ) ;
45+
46+ line. extend ( ) . moved ( direction)
47+ } )
48+ . collect_vec ( ) ;
49+
50+ Self { lines }
51+ }
3652}
3753
3854impl FromIterator < Point > for Polygon {
@@ -188,4 +204,78 @@ mod tests {
188204
189205 assert_eq ! ( 24 , polygon. points( ) . len( ) ) ;
190206 }
207+
208+ #[ test]
209+ fn extend_rectangle ( ) {
210+ let rectangle = Polygon :: rectangle ( Point :: new ( 2 , 2 ) , Point :: new ( 5 , 5 ) ) ;
211+ let extended = rectangle. extend ( ) ;
212+
213+ let mut lines = extended. lines . iter ( ) ;
214+
215+ assert_eq ! (
216+ & GridLine :: new( Point :: new( 1 , 1 ) , Point :: new( 6 , 1 ) ) . unwrap( ) ,
217+ lines. next( ) . unwrap( )
218+ ) ;
219+ assert_eq ! (
220+ & GridLine :: new( Point :: new( 6 , 1 ) , Point :: new( 6 , 6 ) ) . unwrap( ) ,
221+ lines. next( ) . unwrap( )
222+ ) ;
223+ assert_eq ! (
224+ & GridLine :: new( Point :: new( 6 , 6 ) , Point :: new( 1 , 6 ) ) . unwrap( ) ,
225+ lines. next( ) . unwrap( )
226+ ) ;
227+ assert_eq ! (
228+ & GridLine :: new( Point :: new( 1 , 6 ) , Point :: new( 1 , 1 ) ) . unwrap( ) ,
229+ lines. next( ) . unwrap( )
230+ ) ;
231+ }
232+
233+ #[ test]
234+ fn extend_complex_l_shape ( ) {
235+ // Create an L-shaped polygon
236+ let points = [
237+ Point :: new ( 2 , 2 ) ,
238+ Point :: new ( 5 , 2 ) ,
239+ Point :: new ( 5 , 4 ) ,
240+ Point :: new ( 4 , 4 ) ,
241+ Point :: new ( 4 , 6 ) ,
242+ Point :: new ( 2 , 6 ) ,
243+ ] ;
244+
245+ let polygon: Polygon = points. into_iter ( ) . collect ( ) ;
246+ let extended = polygon. extend ( ) ;
247+
248+ let mut lines = extended. lines . iter ( ) ;
249+
250+ // Bottom edge: (2,2)->(5,2) extends and moves north
251+ assert_eq ! (
252+ & GridLine :: new( Point :: new( 1 , 1 ) , Point :: new( 6 , 1 ) ) . unwrap( ) ,
253+ lines. next( ) . unwrap( )
254+ ) ;
255+ // Right edge (lower): (5,2)->(5,4) extends and moves east
256+ assert_eq ! (
257+ & GridLine :: new( Point :: new( 6 , 1 ) , Point :: new( 6 , 5 ) ) . unwrap( ) ,
258+ lines. next( ) . unwrap( )
259+ ) ;
260+ // Inner horizontal: (5,4)->(4,4) extends and moves south
261+ assert_eq ! (
262+ & GridLine :: new( Point :: new( 6 , 5 ) , Point :: new( 3 , 5 ) ) . unwrap( ) ,
263+ lines. next( ) . unwrap( )
264+ ) ;
265+ // Right edge (upper): (4,4)->(4,6) extends and moves east
266+ assert_eq ! (
267+ & GridLine :: new( Point :: new( 5 , 3 ) , Point :: new( 5 , 7 ) ) . unwrap( ) ,
268+ lines. next( ) . unwrap( )
269+ ) ;
270+ // Top edge: (4,6)->(2,6) extends and moves south
271+ assert_eq ! (
272+ & GridLine :: new( Point :: new( 5 , 7 ) , Point :: new( 1 , 7 ) ) . unwrap( ) ,
273+ lines. next( ) . unwrap( )
274+ ) ;
275+ // Left edge: (2,6)->(2,2) extends and moves west
276+ assert_eq ! (
277+ & GridLine :: new( Point :: new( 1 , 7 ) , Point :: new( 1 , 1 ) ) . unwrap( ) ,
278+ lines. next( ) . unwrap( )
279+ ) ;
280+ }
191281}
0 commit comments