-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjarvis_march.py
More file actions
61 lines (45 loc) · 1.17 KB
/
jarvis_march.py
File metadata and controls
61 lines (45 loc) · 1.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
r"""The Jarvis march (gift wrapping) algorithm.
Computing the convex hull of a set of $n$ points in $O(n \cdot h)$ time where
$h$ is the number of points on the hull.
"""
from dataclasses import dataclass
@dataclass(frozen=True, eq=True)
class Point:
x: float
y: float
idx: float
@property
def tuple(self):
return self.x, self.y
def __lt__(self, other):
return (self.x, self.y) < (other.x, other.y)
def __sub__(self, other):
return Point(self.x - other.x, self.y - other.y, -1)
def leftmost(points):
return sorted(points)[0].idx
def cross(a, b):
return a.x * b.y - a.y * b.x
def orient(a, b, c):
res = cross(b - a, c - a)
if res == 0:
return 0 # on line
elif res > 0:
return 1 # cw
else:
return 2 # ccw
def jarvis(points):
N = len(points)
l = leftmost(points)
hull = []
b = 0
a = None
while a != l:
if a is None:
a = l # start
hull.append(a)
b = (a + 1) % N
for i in range(N):
if orient(points[a], points[i], points[b]) == 2:
b = i
a = b
return [points[i] for i in hull]