Skip to content

Commit 5df4813

Browse files
committed
Use OGC options and verify input winding order in shared point test
- Switch to Overlay::with_contours_custom with IntOverlayOptions::ogc() - Add test_input_winding_order asserting all rectangles are CCW (negative area_two) - Simplify overlay helper to accept fill_rule and return results directly https://claude.ai/code/session_01UWsUQwhyBYT5ABqevBFmkR
1 parent fc5ec69 commit 5df4813

1 file changed

Lines changed: 39 additions & 37 deletions

File tree

iOverlay/tests/shared_point_tests.rs

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
mod tests {
33
use i_float::int::point::IntPoint;
44
use i_overlay::core::fill_rule::FillRule;
5-
use i_overlay::core::overlay::{Overlay, ShapeType};
5+
use i_overlay::core::overlay::{IntOverlayOptions, Overlay};
66
use i_overlay::core::overlay_rule::OverlayRule;
7+
use i_shape::int::area::Area;
78

89
// Four boxes that form a shape with a hole, where the exterior
910
// contour and hole contour should share a point at (2,2):
@@ -25,16 +26,17 @@ mod tests {
2526
// The hole is at (1,1)-(2,2). The point (2,2) lies on both the
2627
// exterior contour and the hole contour.
2728
//
28-
// Expected exterior contour (6 points):
29+
// Expected exterior contour (6 points, CCW):
2930
// (0,0) → (3,0) → (3,2) → (2,2) → (2,3) → (0,3)
3031
//
31-
// Expected hole contour (4 points):
32+
// Expected hole contour (4 points, CW):
3233
// (1,1) → (2,1) → (2,2) → (1,2)
3334
//
3435
// BUG: The library currently produces a single merged contour that
3536
// visits (2,2) twice in a figure-8 instead of two separate contours:
3637
// (0,0)→(3,0)→(3,2)→(2,2)→(2,1)→(1,1)→(1,2)→(2,2)→(2,3)→(0,3)
3738

39+
/// Create a CCW rectangle contour from (x1,y1) to (x2,y2).
3840
fn rect(x1: i32, y1: i32, x2: i32, y2: i32) -> Vec<IntPoint> {
3941
vec![
4042
IntPoint::new(x1, y1),
@@ -44,29 +46,44 @@ mod tests {
4446
]
4547
}
4648

47-
fn overlay() -> Overlay {
48-
let mut overlay = Overlay::new(16);
49-
50-
overlay.add_contour(&rect(0, 0, 3, 1), ShapeType::Subject);
51-
overlay.add_contour(&rect(0, 1, 1, 2), ShapeType::Subject);
52-
overlay.add_contour(&rect(2, 1, 3, 2), ShapeType::Subject);
53-
overlay.add_contour(&rect(0, 2, 2, 3), ShapeType::Subject);
49+
fn subject_contours() -> Vec<Vec<IntPoint>> {
50+
vec![
51+
rect(0, 0, 3, 1),
52+
rect(0, 1, 1, 2),
53+
rect(2, 1, 3, 2),
54+
rect(0, 2, 2, 3),
55+
]
56+
}
5457

55-
overlay
58+
fn overlay(fill_rule: FillRule) -> Vec<Vec<Vec<IntPoint>>> {
59+
let contours = subject_contours();
60+
let mut overlay = Overlay::with_contours_custom(
61+
&contours,
62+
&[],
63+
IntOverlayOptions::ogc(),
64+
Default::default(),
65+
);
66+
overlay.overlay(OverlayRule::Subject, fill_rule)
5667
}
5768

5869
fn contour_contains(contour: &[IntPoint], point: IntPoint) -> bool {
5970
contour.iter().any(|p| *p == point)
6071
}
6172

6273
#[test]
63-
fn test_shared_point_even_odd() {
64-
let mut buffer = Default::default();
74+
fn test_input_winding_order() {
75+
// All input rectangles must be CCW (negative area_two).
76+
for contour in &subject_contours() {
77+
assert!(
78+
contour.area_two() < 0,
79+
"input contour must be counter-clockwise, got area_two={}", contour.area_two()
80+
);
81+
}
82+
}
6583

66-
let result = overlay()
67-
.build_graph_view(FillRule::EvenOdd)
68-
.unwrap()
69-
.extract_shapes(OverlayRule::Subject, &mut buffer);
84+
#[test]
85+
fn test_shared_point_even_odd() {
86+
let result = overlay(FillRule::EvenOdd);
7087

7188
assert_eq!(result.len(), 1, "expected 1 shape");
7289
assert_eq!(result[0].len(), 2, "expected 2 contours (exterior + hole)");
@@ -84,12 +101,7 @@ mod tests {
84101

85102
#[test]
86103
fn test_shared_point_non_zero() {
87-
let mut buffer = Default::default();
88-
89-
let result = overlay()
90-
.build_graph_view(FillRule::NonZero)
91-
.unwrap()
92-
.extract_shapes(OverlayRule::Subject, &mut buffer);
104+
let result = overlay(FillRule::NonZero);
93105

94106
assert_eq!(result.len(), 1, "expected 1 shape");
95107
assert_eq!(result[0].len(), 2, "expected 2 contours (exterior + hole)");
@@ -107,12 +119,7 @@ mod tests {
107119

108120
#[test]
109121
fn test_shared_point_positive() {
110-
let mut buffer = Default::default();
111-
112-
let result = overlay()
113-
.build_graph_view(FillRule::Positive)
114-
.unwrap()
115-
.extract_shapes(OverlayRule::Subject, &mut buffer);
122+
let result = overlay(FillRule::Positive);
116123

117124
assert_eq!(result.len(), 1, "expected 1 shape");
118125
assert_eq!(result[0].len(), 2, "expected 2 contours (exterior + hole)");
@@ -130,15 +137,10 @@ mod tests {
130137

131138
#[test]
132139
fn test_shared_point_negative() {
133-
let mut buffer = Default::default();
134-
135-
let result = overlay()
136-
.build_graph_view(FillRule::Negative)
137-
.unwrap()
138-
.extract_shapes(OverlayRule::Subject, &mut buffer);
140+
let result = overlay(FillRule::Negative);
139141

140-
// All contours are CCW (positive winding), so Negative fill rule
141-
// produces no filled regions.
142+
// All input contours are CCW (positive winding), so Negative
143+
// fill rule produces no filled regions.
142144
assert_eq!(result.len(), 0, "expected 0 shapes for Negative fill rule");
143145
}
144146
}

0 commit comments

Comments
 (0)