4
4
import java .util .Comparator ;
5
5
import java .util .Stack ;
6
6
7
- /*
8
- * A Java program that computes the convex hull using the Graham Scan algorithm
7
+ /**
8
+ * A Java program that computes the convex hull using the Graham Scan algorithm.
9
9
* In the best case, time complexity is O(n), while in the worst case, it is O(nlog(n)).
10
- * O(n) space complexity
11
- *
10
+ * O(n) space complexity.
12
11
* This algorithm is only applicable to integral coordinates.
13
- *
12
+ *
14
13
* Reference:
15
14
* https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/geometry/graham_scan_algorithm.cpp
16
15
* https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/geometry/graham_scan_functions.hpp
@@ -20,17 +19,12 @@ public class GrahamScan {
20
19
private final Stack <Point > hull = new Stack <>();
21
20
22
21
public GrahamScan (Point [] points ) {
23
-
24
- /*
25
- * pre-process the points by sorting them with respect to the bottom-most point, then we'll
26
- * push the first point in the array to be our first extreme point.
27
- */
22
+ // Pre-process the points by sorting them with respect to the bottom-most point
28
23
Arrays .sort (points );
29
24
Arrays .sort (points , 1 , points .length , points [0 ].polarOrder ());
30
25
hull .push (points [0 ]);
31
26
32
- // find index of first point not equal to a[0] (indexPoint1) and the first point that's not
33
- // collinear with either (indexPoint2).
27
+ // Find the index of the first point not equal to points[0]
34
28
int indexPoint1 ;
35
29
for (indexPoint1 = 1 ; indexPoint1 < points .length ; indexPoint1 ++) {
36
30
if (!points [0 ].equals (points [indexPoint1 ])) {
@@ -41,6 +35,7 @@ public GrahamScan(Point[] points) {
41
35
return ;
42
36
}
43
37
38
+ // Find the index of the first point that's not collinear with points[0] and points[indexPoint1]
44
39
int indexPoint2 ;
45
40
for (indexPoint2 = indexPoint1 + 1 ; indexPoint2 < points .length ; indexPoint2 ++) {
46
41
if (Point .orientation (points [0 ], points [indexPoint1 ], points [indexPoint2 ]) != 0 ) {
@@ -49,7 +44,7 @@ public GrahamScan(Point[] points) {
49
44
}
50
45
hull .push (points [indexPoint2 - 1 ]);
51
46
52
- // Now we simply add the point to the stack based on the orientation.
47
+ // Add points to the stack based on orientation
53
48
for (int i = indexPoint2 ; i < points .length ; i ++) {
54
49
Point top = hull .pop ();
55
50
while (Point .orientation (hull .peek (), top , points [i ]) <= 0 ) {
@@ -98,12 +93,12 @@ public int y() {
98
93
}
99
94
100
95
/**
101
- * Finds the orientation of ordered triplet.
96
+ * Finds the orientation of an ordered triplet.
102
97
*
103
98
* @param a Co-ordinates of point a <int, int>
104
- * @param b Co-ordinates of point a <int, int>
105
- * @param c Co-ordinates of point a <int, int>
106
- * @return { -1, 0, +1 } if a -→ b -→ c is a { clockwise, collinear; counterclockwise }
99
+ * @param b Co-ordinates of point b <int, int>
100
+ * @param c Co-ordinates of point c <int, int>
101
+ * @return { -1, 0, +1 } if a -> b -> c is a { clockwise, collinear, counterclockwise }
107
102
* turn.
108
103
*/
109
104
public static int orientation (Point a , Point b , Point c ) {
@@ -115,11 +110,11 @@ public static int orientation(Point a, Point b, Point c) {
115
110
}
116
111
117
112
/**
118
- * @param p2 Co-ordinate of point to compare to.
119
- * This function will compare the points and will return a positive integer if the
120
- * point is greater than the argument point and a negative integer if the point is
121
- * less than the argument point.
113
+ * @param p2 Co-ordinate of the point to compare to.
114
+ * @return a positive integer if this point is greater than the argument point,
115
+ * a negative integer if this point is less than the argument point.
122
116
*/
117
+ @ Override
123
118
public int compareTo (Point p2 ) {
124
119
int res = Integer .compare (this .y , p2 .y );
125
120
if (res == 0 ) {
@@ -129,26 +124,26 @@ public int compareTo(Point p2) {
129
124
}
130
125
131
126
/**
132
- * A helper function that will let us sort points by their polar order
133
- * This function will compare the angle between 2 polar Co-ordinates
134
- *
127
+ * A helper function that lets us sort points by their polar order.
128
+ *
135
129
* @return the comparator
136
130
*/
137
131
public Comparator <Point > polarOrder () {
138
132
return new PolarOrder ();
139
133
}
140
134
141
135
private final class PolarOrder implements Comparator <Point > {
136
+ @ Override
142
137
public int compare (Point p1 , Point p2 ) {
143
138
int dx1 = p1 .x - x ;
144
139
int dy1 = p1 .y - y ;
145
140
int dx2 = p2 .x - x ;
146
141
int dy2 = p2 .y - y ;
147
142
148
143
if (dy1 >= 0 && dy2 < 0 ) {
149
- return -1 ; // q1 above; q2 below
144
+ return -1 ; // p1 above; p2 below
150
145
} else if (dy2 >= 0 && dy1 < 0 ) {
151
- return +1 ; // q1 below; q2 above
146
+ return +1 ; // p1 below; p2 above
152
147
} else if (dy1 == 0 && dy2 == 0 ) { // 3-collinear and horizontal
153
148
if (dx1 >= 0 && dx2 < 0 ) {
154
149
return -1 ;
0 commit comments