BerGeo/h2/gift_wrapper.py
2018-10-11 14:38:59 +02:00

38 lines
1006 B
Python

# Use atan2 instead of acos to calc angle; atan2(x,y) of the point we potentially want to add
from math import acos, sqrt
from util import Vector, Point, gen_point, display
def calc_angle(v1: Vector, v2: Vector) -> float:
dot = (v1.x * v2.x) + (v1.y * v2.y)
len_1 = sqrt(v1.x**2 + v1.y**2)
len_2 = sqrt(v2.x**2 + v2.y**2)
tmp = dot / (len_1 * len_2)
return acos(round(tmp, 6))
def calc_vector(p1: Point, p2: Point) -> Vector:
return Vector((p2.x - p1.x), (p2.y - p1.y))
def rapper(points: set):
min_pt = min(points)
hull = [min_pt]
comp_vec = Vector(0, 1)
while True:
hull.append(min(points - {hull[-1]},
key=lambda p: calc_angle(comp_vec,
calc_vector(hull[-1], p))))
comp_vec = calc_vector(hull[-2], hull[-1])
if hull[-1] == min_pt:
return hull
if __name__ == '__main__':
points = {gen_point() for _ in range(30)}
hull = rapper(points)