snippets/gift_wrapping/wrap.py

60 lines
1.4 KiB
Python
Raw Permalink Normal View History

2024-07-04 21:02:13 +00:00
# Gift wrapping algorithm
# https://en.wikipedia.org/wiki/Gift_wrapping_algorithm
# Date: 2021-11-16
import random
2024-07-04 21:06:36 +00:00
import matplotlib.pyplot as plt
2024-07-04 21:02:13 +00:00
def generate_points(n=100):
X = []
Y = []
2024-07-04 21:06:36 +00:00
for _i in range(n):
2024-07-04 21:02:13 +00:00
X.append(random.random())
Y.append(random.random())
2024-07-04 21:06:36 +00:00
plt.plot(X, Y, ".")
return [(X[i], Y[i]) for i in range(n)]
2024-07-04 21:02:13 +00:00
def cross_product(u, v):
x1, y1 = u
x2, y2 = v
2024-07-04 21:06:36 +00:00
return x1 * y2 - x2 * y1
2024-07-04 21:02:13 +00:00
def gift_wrapping(points):
convex_hull = []
2024-07-04 21:06:36 +00:00
x_sorted = sorted(points, key=lambda point: point[0])
2024-07-04 21:02:13 +00:00
left_most = x_sorted[0]
point_on_hull = left_most
endpoint = None
while endpoint != left_most:
convex_hull.append(point_on_hull)
endpoint = points[0]
for point in points:
2024-07-04 21:06:36 +00:00
cp = cross_product(
(endpoint[0] - point_on_hull[0], endpoint[1] - point_on_hull[1]),
(point[0] - point_on_hull[0], point[1] - point_on_hull[1]),
)
2024-07-04 21:02:13 +00:00
if endpoint == point_on_hull or cp < 0:
endpoint = point
point_on_hull = endpoint
return convex_hull
2024-07-04 21:06:36 +00:00
2024-07-04 21:02:13 +00:00
def draw_points(points, with_edge=False):
X, Y = [], []
for p in points:
X.append(p[0])
Y.append(p[1])
2024-07-04 21:06:36 +00:00
plt.plot(X, Y, "." if not with_edge else "")
2024-07-04 21:02:13 +00:00
pts = generate_points(50)
print(pts)
draw_points(pts)
2024-07-04 21:06:36 +00:00
hull = gift_wrapping(pts)
draw_points(hull + [hull[0]], True)
2024-07-04 21:02:13 +00:00
plt.show()