11package com .thealgorithms .geometry ;
22
3- import static org .junit .jupiter .api .Assertions .*;
3+ import static org .junit .jupiter .api .Assertions .assertEquals ;
4+ import static org .junit .jupiter .api .Assertions .assertTrue ;
5+ import static org .junit .jupiter .api .Assertions .assertThrows ;
6+ import static org .junit .jupiter .api .Assertions .assertFalse ;
7+ import static org .junit .jupiter .api .Assertions .assertNotNull ;
48
59import java .awt .geom .Point2D ;
610import java .util .ArrayList ;
@@ -49,10 +53,7 @@ void testNoIntersection() {
4953
5054 @ Test
5155 void testCoincidentSegments () {
52- List <Object > segments = List .of (
53- newSegment (1 , 1 , 5 , 5 ),
54- newSegment (1 , 1 , 5 , 5 )
55- );
56+ List <Object > segments = List .of (newSegment (1 , 1 , 5 , 5 ), newSegment (1 , 1 , 5 , 5 ));
5657
5758 Set <Point2D .Double > intersections = BentleyOttmann .findIntersections (cast (segments ));
5859
@@ -162,15 +163,15 @@ void testGridPattern() {
162163 // Verify all grid points are present
163164 for (int x = 0 ; x <= 2 ; x ++) {
164165 for (int y = 0 ; y <= 2 ; y ++) {
165- assertTrue (containsPoint (intersections , x , y ), String .format ("Grid point (%d, %d) should be present" , x , y )); }
166+ assertTrue (containsPoint (intersections , x , y ), String .format ("Grid point (%d, %d) should be present" , x , y ));
167+ }
166168 }
167169 }
168170
169171 @ Test
170172 void testTriangleIntersections () {
171173 // Three segments forming a triangle
172- List <Object > segments = List .of (
173- newSegment (0 , 0 , 4 , 0 ), // base
174+ List <Object > segments = List .of (newSegment (0 , 0 , 4 , 0 ), // base
174175 newSegment (0 , 0 , 2 , 3 ), // left side
175176 newSegment (4 , 0 , 2 , 3 ) // right side
176177 );
@@ -219,8 +220,7 @@ void testSegmentsShareCommonPoint() {
219220 @ Test
220221 void testSegmentsAtAngles () {
221222 // Segments at 45, 90, 135 degrees
222- List <Object > segments = List .of (
223- newSegment (0 , 2 , 4 , 2 ), // horizontal
223+ List <Object > segments = List .of (newSegment (0 , 2 , 4 , 2 ), // horizontal
224224 newSegment (2 , 0 , 2 , 4 ), // vertical
225225 newSegment (0 , 0 , 4 , 4 ), // 45 degrees
226226 newSegment (0 , 4 , 4 , 0 ) // 135 degrees
@@ -261,8 +261,7 @@ void testPerformanceWithManySegments() {
261261 @ Test
262262 void testIssueExample () {
263263 // Example from the GitHub issue
264- List <Object > segments = List .of (
265- newSegment (1 , 1 , 5 , 5 ), // Segment A
264+ List <Object > segments = List .of (newSegment (1 , 1 , 5 , 5 ), // Segment A
266265 newSegment (1 , 5 , 5 , 1 ), // Segment B
267266 newSegment (3 , 0 , 3 , 6 ) // Segment C
268267 );
@@ -274,13 +273,64 @@ void testIssueExample() {
274273 assertTrue (containsPoint (intersections , 3.0 , 3.0 ), "Intersection should be at (3, 3)" );
275274 }
276275
276+ @ Test
277+ void testEventTypeOrdering () {
278+ // Multiple events at the same point with different types
279+ List <Object > segments = List .of (
280+ newSegment (2 , 2 , 6 , 2 ), // ends at (2,2)
281+ newSegment (0 , 2 , 2 , 2 ), // ends at (2,2)
282+ newSegment (2 , 2 , 2 , 6 ), // starts at (2,2)
283+ newSegment (2 , 0 , 2 , 2 ) // ends at (2,2)
284+ );
285+
286+ Set <Point2D .Double > intersections = BentleyOttmann .findIntersections (cast (segments ));
287+ assertTrue (containsPoint (intersections , 2.0 , 2.0 ));
288+ }
289+
290+ @ Test
291+ void testCollinearOverlapWithInteriorPoint () {
292+ // Test collinear segments where one segment's interior overlaps another
293+ List <Object > segments = List .of (newSegment (0 , 0 , 6 , 6 ), newSegment (2 , 2 , 4 , 4 ));
294+ Set <Point2D .Double > intersections = BentleyOttmann .findIntersections (cast (segments ));
295+
296+ // Should find at least one overlap point (where segments touch/overlap)
297+ assertFalse (intersections .isEmpty (), "Should find overlap points for collinear segments" );
298+ assertTrue (containsPoint (intersections , 2.0 , 2.0 ) || containsPoint (intersections , 4.0 , 4.0 ), "Should contain overlap boundary point" );
299+ }
300+
301+ @ Test
302+ void testCollinearTouchingAtBothEndpoints () {
303+ // Test collinear segments that touch at both endpoints
304+ // This triggers the "endpoint of both" logic (line 354-355)
305+ List <Object > segments = List .of (newSegment (0 , 0 , 4 , 4 ), newSegment (4 , 4 , 8 , 8 ));
306+
307+ Set <Point2D .Double > intersections = BentleyOttmann .findIntersections (cast (segments ));
308+ assertEquals (1 , intersections .size ());
309+ assertTrue (containsPoint (intersections , 4.0 , 4.0 ), "Should find touching point" );
310+ }
311+
312+ @ Test
313+ void testCollinearOverlapPartialInterior () {
314+ // Test case where segments overlap but one point is inside, one is endpoint
315+ List <Object > segments = List .of (newSegment (0 , 0 , 5 , 5 ), newSegment (3 , 3 , 7 , 7 ));
316+
317+ Set <Point2D .Double > intersections = BentleyOttmann .findIntersections (cast (segments ));
318+
319+ // Should detect the overlap region
320+ assertFalse (intersections .isEmpty ());
321+ // The algorithm should return at least one of the boundary points
322+ assertTrue (containsPoint (intersections , 3.0 , 3.0 ) || containsPoint (intersections , 5.0 , 5.0 ));
323+ }
324+
277325 private static Object newSegment (double x1 , double y1 , double x2 , double y2 ) {
278326 return new BentleyOttmann .Segment (new Point2D .Double (x1 , y1 ), new Point2D .Double (x2 , y2 ));
279327 }
280328
281329 private static List <BentleyOttmann .Segment > cast (List <Object > objs ) {
282330 List <BentleyOttmann .Segment > result = new ArrayList <>();
283- for (Object o : objs ) result .add ((BentleyOttmann .Segment ) o );
331+ for (Object o : objs ) {
332+ result .add ((BentleyOttmann .Segment ) o );
333+ }
284334 return result ;
285335 }
286336
0 commit comments