Skip to content

Commit f222858

Browse files
committed
feat: implement extend for polygon
1 parent 812b3e0 commit f222858

File tree

5 files changed

+107
-26
lines changed

5 files changed

+107
-26
lines changed

src/utils/grid.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ where
4646
Self::new(cells)
4747
}
4848

49-
#[expect(dead_code)]
49+
#[allow(dead_code)]
5050
pub fn filled(surface_range: SurfaceRange, element: T) -> Self
5151
where
5252
T: Clone,
@@ -178,7 +178,7 @@ where
178178
*self.cells.get_mut(&point).unwrap() = new_value;
179179
}
180180

181-
#[expect(dead_code)]
181+
#[allow(dead_code)]
182182
pub fn modify_many(&mut self, points: Vec<Point>, new_value: T)
183183
where
184184
T: Clone,

src/utils/grid_line.rs

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ impl GridLine {
5454
matches!(self, Self::Vertical { .. })
5555
}
5656

57-
#[expect(dead_code)]
57+
#[allow(dead_code)]
5858
pub fn is_horizontal(&self) -> bool {
5959
matches!(self, Self::Horizontal { .. })
6060
}
@@ -90,7 +90,6 @@ impl GridLine {
9090
}
9191

9292
/// It extends its size by 1 in the direction of orientation
93-
#[expect(dead_code)]
9493
pub fn extend(&self) -> Self {
9594
match self {
9695
GridLine::Horizontal {
@@ -119,21 +118,19 @@ impl GridLine {
119118
}
120119

121120
/// Move line in direction by 1
122-
#[expect(dead_code)]
123-
pub fn moved(&self, direction: Direction) -> Option<Self> {
121+
pub fn moved(&self, direction: Direction) -> Self {
124122
let start = self.start();
125123
let end = self.end();
126124

127125
match direction {
128-
Direction::North => Self::new(start.north(), end.north()),
129-
Direction::East => Self::new(start.east(), end.east()),
130-
Direction::South => Self::new(start.south(), end.south()),
131-
Direction::West => Self::new(start.west(), end.west()),
126+
Direction::North => Self::new(start.north(), end.north()).unwrap(),
127+
Direction::East => Self::new(start.east(), end.east()).unwrap(),
128+
Direction::South => Self::new(start.south(), end.south()).unwrap(),
129+
Direction::West => Self::new(start.west(), end.west()).unwrap(),
132130
_ => unimplemented!("Direction {} unimplemented to move grid line", direction),
133131
}
134132
}
135133

136-
#[expect(dead_code)]
137134
pub fn direction(&self) -> Direction {
138135
self.start().direction(&self.end())
139136
}
@@ -274,20 +271,17 @@ mod tests {
274271
#[test]
275272
fn moved_horizontal() {
276273
let line = GridLine::new(Point::new(3, 8), Point::new(3, 2)).unwrap();
277-
let east = line.moved(Direction::East);
278274

279-
assert!(east.is_some());
275+
let east = line.moved(Direction::East);
280276
assert_eq!(
281277
GridLine::new(Point::new(4, 8), Point::new(4, 2)).unwrap(),
282-
east.unwrap()
278+
east
283279
);
284280

285281
let west = line.moved(Direction::West);
286-
287-
assert!(west.is_some());
288282
assert_eq!(
289283
GridLine::new(Point::new(2, 8), Point::new(2, 2)).unwrap(),
290-
west.unwrap()
284+
west
291285
);
292286
}
293287

@@ -296,18 +290,15 @@ mod tests {
296290
let line = GridLine::new(Point::new(2, 7), Point::new(7, 7)).unwrap();
297291
let north = line.moved(Direction::North);
298292

299-
assert!(north.is_some());
300293
assert_eq!(
301294
GridLine::new(Point::new(2, 6), Point::new(7, 6)).unwrap(),
302-
north.unwrap()
295+
north
303296
);
304297

305298
let south = line.moved(Direction::South);
306-
307-
assert!(south.is_some());
308299
assert_eq!(
309300
GridLine::new(Point::new(2, 8), Point::new(7, 8)).unwrap(),
310-
south.unwrap()
301+
south
311302
);
312303
}
313304

src/utils/line.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ impl Line {
4646
Some(Point::new(x as isize, y as isize))
4747
}
4848

49-
#[expect(dead_code)]
49+
#[allow(dead_code)]
5050
pub fn is_on(&self, point: &Point) -> bool {
5151
let a = self.start;
5252
let b = self.end;

src/utils/point.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ impl Point {
129129
unimplemented!("Diagonal directions are not implemented");
130130
}
131131

132-
#[expect(dead_code)]
132+
#[allow(dead_code)]
133133
fn is_neighbour(&self, other: &Self) -> bool {
134134
let distance = self.distance(other);
135135

src/utils/polygon.rs

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::utils::grid_line::GridLine;
22
use crate::utils::point::Point;
33
use crate::utils::traits::IsInside;
4+
use itertools::Itertools;
45

56
#[derive(PartialEq, Clone)]
67
pub 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

3854
impl 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

Comments
 (0)