Skip to content

Commit 8b50c0a

Browse files
PaddyKezsparal
authored andcommitted
Add Graham Scan in Java (#459)
* Add Graham Scan in Java * refactoring * reworked code and added point.equals
1 parent e24b5bf commit 8b50c0a

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import java.util.ArrayList;
2+
import java.util.Comparator;
3+
import java.util.List;
4+
import java.util.stream.Collectors;
5+
6+
public class GrahamScan {
7+
8+
static class Point {
9+
public double x;
10+
public double y;
11+
12+
public Point(double x, double y) {
13+
this.x = x;
14+
this.y = y;
15+
}
16+
17+
@Override
18+
public boolean equals(Object o) {
19+
if (o == null) return false;
20+
if (o == this) return true;
21+
if (!(o instanceof Point)) return false;
22+
Point p = (Point)o;
23+
return p.x == this.x && p.y == this.y;
24+
}
25+
}
26+
27+
static double ccw(Point a, Point b, Point c) {
28+
return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
29+
}
30+
31+
static double polarAngle(Point origin, Point p) {
32+
return Math.atan2(p.y - origin.y, p.x - origin.x);
33+
}
34+
35+
static List<Point> grahamScan(List<Point> gift) {
36+
gift = gift.stream()
37+
.distinct()
38+
.sorted(Comparator.comparingDouble(point -> -point.y))
39+
.collect(Collectors.toList());
40+
41+
Point pivot = gift.get(0);
42+
43+
// Sort the remaining Points based on the angle between the pivot and itself
44+
List<Point> hull = gift.subList(1, gift.size());
45+
hull.sort(Comparator.comparingDouble(point -> polarAngle(point, pivot)));
46+
47+
// The pivot is always on the hull
48+
hull.add(0, pivot);
49+
50+
int n = hull.size();
51+
int m = 1;
52+
53+
for (int i = 2; i < n; i++) {
54+
while (ccw(hull.get(m - 1), hull.get(m), hull.get(i)) <= 0) {
55+
if (m > 1) {
56+
m--;
57+
} else if (m == 1) {
58+
break;
59+
} else {
60+
i++;
61+
}
62+
}
63+
m++;
64+
65+
Point temp = hull.get(i);
66+
hull.set(i, hull.get(m));
67+
hull.set(m, temp);
68+
}
69+
return hull.subList(0, m + 1);
70+
}
71+
72+
public static void main(String[] args) {
73+
ArrayList<Point> points = new ArrayList<>();
74+
75+
points.add(new Point(-5, 2));
76+
points.add(new Point(5, 7));
77+
points.add(new Point(-6, -12));
78+
points.add(new Point(-14, -14));
79+
points.add(new Point(9, 9));
80+
points.add(new Point(-1, -1));
81+
points.add(new Point(-10, 11));
82+
points.add(new Point(-6, 15));
83+
points.add(new Point(-6, -8));
84+
points.add(new Point(15, -9));
85+
points.add(new Point(7, -7));
86+
points.add(new Point(-2, -9));
87+
points.add(new Point(6, -5));
88+
points.add(new Point(0, 14));
89+
points.add(new Point(2, 8));
90+
91+
List<Point> convexHull = grahamScan(points);
92+
93+
convexHull.forEach(p -> System.out.printf("% 1.0f, % 1.0f\n", p.x, p.y));
94+
}
95+
}

contents/graham_scan/graham_scan.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ We can find whether a rotation is counter-clockwise with trigonometric functions
2222
[import:36-38, lang:"javascript"](code/javascript/graham-scan.js)
2323
{% sample lang="py" %}
2424
[import:4-6, lang:"python"](code/python/grahamScan.py)
25+
{% sample lang="java" %}
26+
[import:27-29, lang:"java"](code/java/GrahamScan.java)
2527
{% endmethod %}
2628

2729
If the output of this function is 0, the points are collinear.
@@ -46,6 +48,8 @@ In the end, the code should look something like this:
4648
[import:1-30, lang:"javascript"](code/javascript/graham-scan.js)
4749
{% sample lang="py" %}
4850
[import:14-27, lang:"python"](code/python/grahamScan.py)
51+
{% sample lang="java" %}
52+
[import:35-70, lang:"java"](code/java/GrahamScan.java)
4953
{% endmethod %}
5054

5155
### Bibliography
@@ -65,6 +69,8 @@ In the end, the code should look something like this:
6569
[import, lang:"javascript"](code/javascript/graham-scan.js)
6670
{% sample lang="py" %}
6771
[import, lang:"python"](code/python/grahamScan.py)
72+
{% sample lang="java" %}
73+
[import, lang:"java"](code/java/GrahamScan.java)
6874
{% endmethod %}
6975

7076
<script>

0 commit comments

Comments
 (0)