-
Notifications
You must be signed in to change notification settings - Fork 0
/
convexHull.py
168 lines (127 loc) · 3.26 KB
/
convexHull.py
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# Reads an .obj file and returns/plots the perimeter points
def Left_index(points):
'''
Finding the left most point
'''
minn = 0
for i in range(1,len(points)):
if points[i][0] < points[minn][0]:
minn = i
elif points[i][0] == points[minn][0]:
if points[i][1] > points[minn][1]:
minn = i
return minn
def orientation(p, q, r):
'''
To find orientation of ordered triplet (p, q, r).
The function returns following values
0 --> p, q and r are collinear
1 --> Clockwise
2 --> Counterclockwise
'''
val = (q[1] - p[1]) * (r[0] - q[0]) - \
(q[0] - p[0]) * (r[1] - q[1])
if val == 0:
return 0
elif val > 0:
return 1
else:
return 2
def convexHull(points, n):
result = open("objResult.txt", "w+")
# There must be at least 3 points
if n<3:
return
l = Left_index(points)
hull = []
'''
Start from leftmost point, keep moving counterclockwise
until reach the start point again. This loop runs O(h)
times where h is number of points in result or output.
'''
p = l
q = 0
hullPoints = []
while(True):
# Add current point to result
hull.append(p)
'''
Search for a point 'q' such that orientation(p, q,
x) is counterclockwise for all points 'x'. The idea
is to keep track of last visited most counterclock-
wise point in q. If any point 'i' is more counterclock-
wise than q, then update q.
'''
q = (p + 1) % n
for i in range(n):
# If i is more counterclockwise
# than current q, then update q
if(orientation(points[p],
points[i], points[q]) == 2):
q = i
'''
Now q is the most counterclockwise with respect to p
Set p as q for next iteration, so that q is added to
result 'hull'
'''
p = q
# While we don't come to first point
if(p == l):
break
# Print Result
for each in hull:
hullPoints.append([points[each][0], points[each][1]])
result.close()
return hullPoints
import sys
file = open(sys.argv[1], "r")
readStop = False
# result = open("objResult.txt", "w+")
nodes = []
for line in file:
initialReadStop = readStop
args = line.split()
if (len(args) != 4):
continue
v = args[0]
xPos = args[1]
yPos = args[2]
if (v == "v"):
nodes.append([float(xPos), float(yPos)])
# result.write("x: " + str(xPos) + ", y: " + str(yPos) + "\n")
else:
readStop = False
if initialReadStop and not readStop:
break
# result.close()
file.close()
import time
start = time.time()
hull = convexHull(nodes, len(nodes))
# sort, first by x, then by y
sortedHull = sorted(hull, key=lambda k: [k[0], k[1]])
end = time.time()
print(end - start)
import math
bestHull = []
d = 0.5
for index, p in enumerate(sortedHull):
if index == 0:
bestHull.append(p)
lastBestHull = p
continue
distance = math.dist(lastBestHull, p)
if distance >= d:
bestHull.append(p)
lastBestHull = p
print(len(bestHull))
##################### Show Plot #####################
import matplotlib as mpl
import matplotlib.pyplot as plt
x_values = [h[0] for h in hull]
y_values = [h[1] for h in hull]
plt.plot(x_values, y_values, "bo")
xb_values = [h[0] for h in bestHull]
yb_values = [h[1] for h in bestHull]
plt.plot(xb_values, yb_values, "ro")
plt.show()