From 7ad637fe35a14083e95f3305d762790932427b39 Mon Sep 17 00:00:00 2001 From: Alexander Munch-Hansen Date: Mon, 17 Sep 2018 17:06:20 +0200 Subject: [PATCH] Added gift_wrapper stuff --- h2/gift_wrapper.py | 64 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 h2/gift_wrapper.py diff --git a/h2/gift_wrapper.py b/h2/gift_wrapper.py new file mode 100644 index 0000000..8064674 --- /dev/null +++ b/h2/gift_wrapper.py @@ -0,0 +1,64 @@ +# Use atan2 instead of acos to calc angle; atan2(x,y) of the point we potentially want to add +import random +from collections import namedtuple +import matplotlib.pyplot as plt +from math import atan2, degrees, tau, pi + +Point = namedtuple('Point', 'x y') +Vector = namedtuple('Vector', 'x y') + + +def gen_point(): + a = random.uniform(1, 5) + b = random.uniform(1, 5) + + x_i = random.uniform(1, 5) + p_i = Point(x_i, a * x_i + b) + + return p_i + + +def calc_angle(v1: Vector) -> float: + # x = atan2(v1.y, v1.x) + + + theta_deg = atan2(-v1.y, -v1.x) / pi * 180 + 180 + + lel = (90 - theta_deg) % 360 + # degrees = (atan2(-v1.y, -v1.x)) + 180 + + return lel + + +def calc_vector(p1: Point, p2: Point) -> Vector: + return Vector((p2.x - p1.x), (p2.y - p1.y)) + +def display(points, hull): + x = [point.x for point in points] + y = [point.y for point in points] + + h_x = [point.x for point in hull] + h_y = [point.y for point in hull] + + plt.plot(h_x, h_y, 'ro-') + + plt.scatter(x, y) + plt.show() + + +def rapper(points: set): + min_pt = min(points) + hull = [min_pt] + + while True: + hull.append(min(points - {hull[-1]}, + key=lambda p: calc_angle(calc_vector(hull[-1], p)))) + display(points, hull) + if hull[-1] == min_pt: + break + + return hull + + +points = {gen_point() for _ in range(10)} +hull = rapper(points)