33import static org .junit .jupiter .api .Assertions .assertEquals ;
44import static org .junit .jupiter .api .Assertions .assertTrue ;
55
6+ import java .util .ArrayList ;
67import java .util .Arrays ;
78import java .util .List ;
89import org .junit .jupiter .api .Test ;
@@ -46,62 +47,35 @@ void testConvexHullRecursive() {
4647 // Test 3: Complex polygon
4748 // Convex hull vertices in CCW order from bottom-most point (2,-4):
4849 // (2,-4) -> (3,0) -> (3,3) -> (0,3) -> (0,0) -> (1,-3) -> back to (2,-4)
49- points = Arrays .asList (
50- new Point (0 , 3 ), new Point (2 , 2 ), new Point (1 , 1 ),
51- new Point (2 , 1 ), new Point (3 , 0 ), new Point (0 , 0 ),
52- new Point (3 , 3 ), new Point (2 , -1 ), new Point (2 , -4 ),
53- new Point (1 , -3 )
54- );
50+ points = Arrays .asList (new Point (0 , 3 ), new Point (2 , 2 ), new Point (1 , 1 ), new Point (2 , 1 ), new Point (3 , 0 ), new Point (0 , 0 ), new Point (3 , 3 ), new Point (2 , -1 ), new Point (2 , -4 ), new Point (1 , -3 ));
5551 result = ConvexHull .convexHullRecursive (points );
56- expected = Arrays .asList (
57- new Point (2 , -4 ), // Bottom-most, left-most (starting point)
58- new Point (3 , 0 ), // Right side going up
59- new Point (3 , 3 ), // Top right corner
60- new Point (0 , 3 ), // Top left corner
61- new Point (0 , 0 ), // Left side coming down
62- new Point (1 , -3 ) // Bottom section, back towards start
63- );
52+ expected = Arrays .asList (new Point (2 , -4 ), new Point (3 , 0 ), new Point (3 , 3 ), new Point (0 , 3 ), new Point (0 , 0 ), new Point (1 , -3 ));
6453 assertEquals (expected , result );
6554 assertTrue (isCounterClockwise (result ), "Points should be in counter-clockwise order" );
6655 }
6756
6857 @ Test
6958 void testConvexHullRecursiveAdditionalCases () {
7059 // Test 4: Square (all corners on hull)
71- List <Point > points = Arrays .asList (
72- new Point (0 , 0 ), new Point (2 , 0 ),
73- new Point (2 , 2 ), new Point (0 , 2 )
74- );
60+ List <Point > points = Arrays .asList (new Point (0 , 0 ), new Point (2 , 0 ), new Point (2 , 2 ), new Point (0 , 2 ));
7561 List <Point > result = ConvexHull .convexHullRecursive (points );
76- List <Point > expected = Arrays .asList (
77- new Point (0 , 0 ), new Point (2 , 0 ),
78- new Point (2 , 2 ), new Point (0 , 2 )
79- );
62+ List <Point > expected = Arrays .asList (new Point (0 , 0 ), new Point (2 , 0 ), new Point (2 , 2 ), new Point (0 , 2 ));
8063 assertEquals (expected , result );
8164 assertTrue (isCounterClockwise (result ), "Square points should be in CCW order" );
8265
8366 // Test 5: Pentagon with interior point
84- points = Arrays .asList (
85- new Point (0 , 0 ), new Point (4 , 0 ), new Point (5 , 3 ),
86- new Point (2 , 5 ), new Point (-1 , 3 ), new Point (2 , 2 ) // (2,2) is interior
67+ points = Arrays .asList (new Point (0 , 0 ), new Point (4 , 0 ), new Point (5 , 3 ), new Point (2 , 5 ), new Point (-1 , 3 ), new Point (2 , 2 ) // (2,2) is interior
8768 );
8869 result = ConvexHull .convexHullRecursive (points );
8970 // CCW from (0,0): (0,0) -> (4,0) -> (5,3) -> (2,5) -> (-1,3)
90- expected = Arrays .asList (
91- new Point (0 , 0 ), new Point (4 , 0 ), new Point (5 , 3 ),
92- new Point (2 , 5 ), new Point (-1 , 3 )
93- );
71+ expected = Arrays .asList (new Point (0 , 0 ), new Point (4 , 0 ), new Point (5 , 3 ), new Point (2 , 5 ), new Point (-1 , 3 ));
9472 assertEquals (expected , result );
9573 assertTrue (isCounterClockwise (result ), "Pentagon points should be in CCW order" );
9674
9775 // Test 6: Simple triangle (clearly convex)
98- points = Arrays .asList (
99- new Point (0 , 0 ), new Point (4 , 0 ), new Point (2 , 3 )
100- );
76+ points = Arrays .asList (new Point (0 , 0 ), new Point (4 , 0 ), new Point (2 , 3 ));
10177 result = ConvexHull .convexHullRecursive (points );
102- expected = Arrays .asList (
103- new Point (0 , 0 ), new Point (4 , 0 ), new Point (2 , 3 )
104- );
78+ expected = Arrays .asList (new Point (0 , 0 ), new Point (4 , 0 ), new Point (2 , 3 ));
10579 assertEquals (expected , result );
10680 assertTrue (isCounterClockwise (result ), "Triangle points should be in CCW order" );
10781 }
@@ -124,4 +98,41 @@ private boolean isCounterClockwise(List<Point> points) {
12498
12599 return signedArea > 0 ; // Positive signed area means counter-clockwise
126100 }
101+
102+ @ Test
103+ void testRecursiveHullForCoverage () {
104+ // 1. Test the base cases of the convexHullRecursive method (covering scenarios with < 3 input points).
105+
106+ // Test Case: 0 points
107+ List <Point > pointsEmpty = new ArrayList <>();
108+ List <Point > resultEmpty = ConvexHull .convexHullRecursive (pointsEmpty );
109+ assertTrue (resultEmpty .isEmpty (), "Should return an empty list for an empty input list" );
110+
111+ // Test Case: 1 point
112+ List <Point > pointsOne = List .of (new Point (5 , 5 ));
113+ // Pass a new ArrayList because the original method modifies the input list.
114+ List <Point > resultOne = ConvexHull .convexHullRecursive (new ArrayList <>(pointsOne ));
115+ List <Point > expectedOne = List .of (new Point (5 , 5 ));
116+ assertEquals (expectedOne , resultOne , "Should return the single point for a single-point input" );
117+
118+ // Test Case: 2 points
119+ List <Point > pointsTwo = Arrays .asList (new Point (10 , 1 ), new Point (0 , 0 ));
120+ List <Point > resultTwo = ConvexHull .convexHullRecursive (new ArrayList <>(pointsTwo ));
121+ List <Point > expectedTwo = Arrays .asList (new Point (0 , 0 ), new Point (10 , 1 )); // Should return the two points, sorted.
122+ assertEquals (expectedTwo , resultTwo , "Should return the two sorted points for a two-point input" );
123+
124+ // 2. Test the logic for handling collinear points in the sortCounterClockwise method.
125+
126+ // Construct a scenario where multiple collinear points lie on an edge of the convex hull.
127+ // The expected convex hull vertices are (0,0), (10,0), and (5,5).
128+ // When (0,0) is used as the pivot for polar angle sorting, (5,0) and (10,0) are collinear.
129+ // This will trigger the crossProduct == 0 branch in the sortCounterClockwise method.
130+ List <Point > pointsWithCollinearOnHull = Arrays .asList (new Point (0 , 0 ), new Point (5 , 0 ), new Point (10 , 0 ), new Point (5 , 5 ), new Point (2 , 2 ));
131+
132+ List <Point > resultCollinear = ConvexHull .convexHullRecursive (new ArrayList <>(pointsWithCollinearOnHull ));
133+ List <Point > expectedCollinear = Arrays .asList (new Point (0 , 0 ), new Point (10 , 0 ), new Point (5 , 5 ));
134+
135+ assertEquals (expectedCollinear , resultCollinear , "Should correctly handle collinear points on the hull edge" );
136+ assertTrue (isCounterClockwise (resultCollinear ), "The result of the collinear test should be in counter-clockwise order" );
137+ }
127138}
0 commit comments