-
Notifications
You must be signed in to change notification settings - Fork 0
/
minkowskisum.py
77 lines (61 loc) · 2.31 KB
/
minkowskisum.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
import numpy as np
def sort_vertices(polygon):
"""Sorts vertices by polar angles.
Args:
polygon (list[list[float, float]]): list of polygon vertices
Returns:
list[list[float, float]]: list of polygon vertices sorted
"""
cx, cy = polygon.mean(0) # center of mass
x, y = polygon.T
angles = np.arctan2(y-cy, x-cx)
indices = np.argsort(angles)
return polygon[indices]
def crossprod(p1, p2):
"""Cross product of two vectors in 2R space.
Args:
p1 (list[float, float]): first vector
p2 (list[float, float): second vector
Returns:
float: value of cross product
"""
return p1[0] * p2[1] - p1[1] * p2[0]
def minkowskisum(pol1, pol2, var):
"""Calculate Minkowski sum of two convex polygons.
Args:
pol1 (np.ndarray[float, float]): first polygon
pol2 (np.ndarray[float, float]): second polygon
Returns:
np.ndarray[np.ndarray[float, float]]: list of the Minkowski sum vertices
"""
# pol1 = np.array(translate_polygon_to_origin(pol1.tolist()))
pol1 = np.array(pol1.tolist())
# pol2 = np.array(translate_polygon_to_origin(pol2.tolist()))
original_coords = list(pol2)
# # Create a new set of coordinates with negated values
if var==1:
negated_coords = [(-a, -b) for a, b in original_coords]
else:
negated_coords = [(-a, b) for a, b in original_coords]
pol2 = np.array(negated_coords)
msum = []
pol1 = sort_vertices(pol1)
pol2 = sort_vertices(pol2)
# print('pol1: ', pol1)
# print('pol2: ', pol2)
# sort vertices so that is starts with lowest y-value
min1, min2 = np.argmin(pol1[:, 1]), np.argmin(pol2[:, 1]) # index of vertex with min y value
pol1 = np.vstack((pol1[:min1], pol1[min1:]))
pol2 = np.vstack((pol2[:min2], pol2[min2:]))
i, j = 0, 0
l1, l2 = len(pol1), len(pol2)
# iterate through all the vertices
while i < len(pol1) or j < len(pol2):
msum.append(pol1[i % l1] + pol2[j % l2])
cross = crossprod((pol1[(i+1) % l1] - pol1[i % l1]), pol2[(j+1) % l2] - pol2[j % l2])
# using right-hand rule choose the vector with the lower polar angle and iterate this polygon's vertex
if cross >= 0:
i += 1
if cross <= 0:
j += 1
return np.array(msum)