File tree 2 files changed +59
-0
lines changed
2 files changed +59
-0
lines changed Original file line number Diff line number Diff line change
1
+ from math import atan2
2
+
3
+
4
+ data point(x=0, y=0):
5
+ def angle(self, other):
6
+ """Computes the angle between the two points"""
7
+ match point(x1, y1) in other:
8
+ return atan2(y1 - self.y, x1 - self.x)
9
+ def __str__(self):
10
+ return f'({self.x}, {self.y})'
11
+
12
+ # Is the turn counter-clockwise?
13
+ def counter_clockwise(p1, p2, p3) =
14
+ (p3.y - p1.y) * (p2.x - p1.x) >= (p2.y - p1.y) * (p3.x - p1.x)
15
+
16
+
17
+ def graham_scan(gift):
18
+ gift = list(set(gift)) # Remove the duplicate points if any.
19
+ start = min(gift, key=(p -> (p.x, p.y)))
20
+ gift.remove(start)
21
+
22
+ s = sorted(gift, key=(point -> start.angle(point)))
23
+ hull = [start, s[0], s[1]]
24
+
25
+ # Remove the hull points that make the hull concave
26
+ for point in s[2:]:
27
+ while not counter_clockwise(hull[-2], hull[-1], point):
28
+ del hull[-1]
29
+ hull.append(point)
30
+ return hull
31
+
32
+
33
+ if __name__ == '__main__':
34
+ test_gift = [
35
+ (-5, 2),
36
+ (5, 7),
37
+ (-6, -12),
38
+ (-14, -14),
39
+ (9, 9),
40
+ (-1, -1),
41
+ (-10, 11),
42
+ (-6, 15),
43
+ (-6, -8),
44
+ (15, -9),
45
+ (7, -7),
46
+ (-2, -9),
47
+ (6, -5),
48
+ (0, 14),
49
+ (2, 8),
50
+ ] |> map$(p -> point(*p)) |> list
51
+ hull = graham_scan(test_gift)
52
+ "The points in the hull are:" |> print
53
+ "\n".join(map(str, hull)) |> print
Original file line number Diff line number Diff line change @@ -30,6 +30,8 @@ We can find whether a rotation is counter-clockwise with trigonometric functions
30
30
[ import:5-13, lang:"lisp"] ( code/clisp/graham-scan.lisp )
31
31
{% sample lang="cpp" %}
32
32
[ import:18-20, lang="cpp"] ( code/c++/graham_scan.cpp )
33
+ {% sample lang="coco" %}
34
+ [ import:4-8, lang="coconut"] ( code/coconut/graham_scan.coco )
33
35
{% endmethod %}
34
36
35
37
If the output of this function is 0, the points are collinear.
@@ -62,6 +64,8 @@ In the end, the code should look something like this:
62
64
[ import:15-58, lang:"lisp"] ( code/clisp/graham-scan.lisp )
63
65
{% sample lang="cpp" %}
64
66
[ import:26-62, lang="cpp"] ( code/c++/graham_scan.cpp )
67
+ {% sample lang="coco" %}
68
+ [ import:17-30, lang="coconut"] ( code/coconut/graham_scan.coco )
65
69
{% endmethod %}
66
70
67
71
### Bibliography
@@ -89,6 +93,8 @@ In the end, the code should look something like this:
89
93
[ import, lang:"lisp"] ( code/clisp/graham-scan.lisp )
90
94
{% sample lang="cpp" %}
91
95
[ import, lang="cpp"] ( code/c++/graham_scan.cpp )
96
+ {%sample lang="coco" %}
97
+ [ import, lang="coconut"] ( code/coconut/graham_scan.coco )
92
98
{% endmethod %}
93
99
94
100
<script >
You can’t perform that action at this time.
0 commit comments