Skip to content

Commit 87ca7cb

Browse files
wmboylesjiegillet
authored andcommitted
Python implementation for Graham Scan (#238)
* Python implementation of Graham Scan
1 parent 4aa3dd8 commit 87ca7cb

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from math import atan2
2+
3+
4+
#Is the turn counter clockwise?
5+
def counter_clockwise(p1, p2, p3):
6+
return (p3[1]-p1[1])*(p2[0]-p1[0]) >= (p2[1]-p1[1])*(p3[0]-p1[0])
7+
8+
9+
#Find the polar angle of a point relative to a reference point
10+
def polar_angle(ref, point):
11+
return atan2(point[1]-ref[1],point[0]-ref[0])
12+
13+
14+
def graham_scan(gift):
15+
gift = list(set(gift)) #Remove duplicate points
16+
start = min(gift, key=lambda p: (p[1], p[0])) #Must be in hull
17+
gift.remove(start)
18+
19+
s = sorted(gift,key=lambda point: polar_angle(start, point))
20+
hull = [start,s[0],s[1]]
21+
22+
#Remove points from hull that make the hull concave
23+
for pt in s[2:]:
24+
while not counter_clockwise(hull[-2], hull[-1], pt):
25+
del hull[-1]
26+
hull.append(pt)
27+
28+
return hull
29+
30+
31+
def main():
32+
test_gift = [(-5, 2), (5, 7), (-6, -12), (-14, -14), (9, 9),
33+
(-1, -1), (-10, 11), (-6, 15), (-6, -8), (15, -9),
34+
(7, -7), (-2, -9), (6, -5), (0, 14), (2, 8)]
35+
hull = graham_scan(test_gift)
36+
37+
print("The points in the hull are:")
38+
for point in hull:
39+
print(point)
40+
41+
42+
main()

contents/graham_scan/graham_scan.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ We can find whether a rotation is counter-clockwise with trigonometric functions
2020
[import:24-26, lang:"c_cpp"](code/c/graham.c)
2121
{% sample lang="js" %}
2222
[import:36-38, lang:"javascript"](code/javascript/graham-scan.js)
23+
{% sample lang="py" %}
24+
[import:4-6, lang:"python"](code/python/grahamScan.py)
2325
{% endmethod %}
2426

2527
If the output of this function is 0, the points are collinear.
@@ -42,6 +44,8 @@ In the end, the code should look something like this:
4244
[import:65-95, lang:"c_cpp"](code/c/graham.c)
4345
{% sample lang="js" %}
4446
[import:1-30, lang:"javascript"](code/javascript/graham-scan.js)
47+
{% sample lang="py" %}
48+
[import:14-27, lang:"python"](code/python/grahamScan.py)
4549
{% endmethod %}
4650

4751
### Bibliography
@@ -59,6 +63,8 @@ In the end, the code should look something like this:
5963
[import, lang:"c_cpp"](code/c/graham.c)
6064
{% sample lang="js" %}
6165
[import, lang:"javascript"](code/javascript/graham-scan.js)
66+
{% sample lang="py" %}
67+
[import, lang:"python"](code/python/grahamScan.py)
6268
{% endmethod %}
6369

6470
<script>

0 commit comments

Comments
 (0)