diff --git a/h2/gift_wrapper.py b/h2/gift_wrapper.py index e07a2c0..541fd3c 100644 --- a/h2/gift_wrapper.py +++ b/h2/gift_wrapper.py @@ -11,10 +11,7 @@ def calc_angle(v1: Vector, v2: Vector) -> float: tmp = dot / (len_1 * len_2) - # pls - hmmmmmmm = round(tmp, 6) - - return acos(hmmmmmmm) + return acos(round(tmp, 6)) def calc_vector(p1: Point, p2: Point) -> Vector: @@ -27,16 +24,14 @@ def rapper(points: set): 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)))) + key=lambda p: calc_angle(comp_vec, + calc_vector(hull[-1], p)))) comp_vec = calc_vector(hull[-2], hull[-1]) - display(points, hull) - if hull[-1] == min_pt: - break - - return hull + return hull -points = {gen_point() for _ in range(30)} -hull = rapper(points) +if __name__ == '__main__': + points = {gen_point() for _ in range(30)} + hull = rapper(points) diff --git a/h2/graham.py b/h2/graham.py index 41f1f0a..48af38c 100644 --- a/h2/graham.py +++ b/h2/graham.py @@ -30,14 +30,11 @@ p3 = Point(5, 2) def graham_scan(points): - # A funky issue where both a and b become negative in the sidedness test causes us to have to use # Side.ABOVE for both tests, regardless of UH or LH. - sorted_points = sorted(points) UH = sorted_points[:2] - #del sorted_points[0] for s in sorted_points[2:]: while len(UH) > 1 and (sidedness(UH[-2], UH[-1], s) != Side.ABOVE): @@ -47,17 +44,17 @@ def graham_scan(points): reversed_list = list(reversed(sorted_points)) reversed_list.append(UH[0]) LH = reversed_list[:2] - #del reversed_list[0] for s in reversed_list[2:]: while len(LH) > 1 and (sidedness(LH[-2], LH[-1], s) != Side.ABOVE): del LH[-1] LH.append(s) - return UH, LH + return UH + LH -p = [gen_point() for _ in range(30)] -UH, LH = graham_scan(p) +if __name__ == '__main__': + p = [gen_point() for _ in range(30)] + hull = graham_scan(p) -display(p, {*UH, *LH}) + display(p, hull) diff --git a/h2/mbc.py b/h2/mbc.py index 16f2335..4a50ace 100644 --- a/h2/mbc.py +++ b/h2/mbc.py @@ -89,9 +89,14 @@ def mbc_ch(points: Set[Point], linprog_flipper: callable) -> Set[Point]: return set.union(mbc_ch(pl, linprog_flipper), {left_point, right_point}, mbc_ch(pr, linprog_flipper)) -points = {gen_point(1, 10) for _ in range(20)} +def mbc(points: Set[Point]) -> Set[Point]: + return set.union(mbc_ch(points, lambda x: x), mbc_ch(points, lambda x: -x)) -upper_hull_points = mbc_ch(points, lambda x: x) -lower_hull_points = mbc_ch(points, lambda x: -x) -display(points, upper_hull_points.union(lower_hull_points)) +if __name__ == '__main__': + points = {gen_point(1, 10) for _ in range(20)} + + upper_hull_points = mbc_ch(points, lambda x: x) + lower_hull_points = mbc_ch(points, lambda x: -x) + + display(points, upper_hull_points.union(lower_hull_points)) diff --git a/h2/quick_hull.py b/h2/quick_hull.py index 7b1c105..218eeae 100644 --- a/h2/quick_hull.py +++ b/h2/quick_hull.py @@ -15,8 +15,6 @@ def is_left(a: Point, b: Point, c: Point): def quick_hull(points: Set[Point]): - assert len(points) >= 2 - left = min(points) right = max(points) @@ -55,7 +53,8 @@ def find_hull(points: Set[Point], p: Point, q: Point, hull: Set[Point]): hull) -points = {gen_point() for _ in range(30)} -hull = quick_hull(points) +if __name__ == '__main__': + points = {gen_point() for _ in range(30)} + hull = quick_hull(points) -display(points, hull) + display(points, hull) diff --git a/h2/tmptest.py b/h2/tmptest.py new file mode 100644 index 0000000..fecd4ee --- /dev/null +++ b/h2/tmptest.py @@ -0,0 +1,32 @@ +import random +from time import time + +import util +from gift_wrapper import rapper +from graham import graham_scan +from mbc import mbc +from quick_hull import quick_hull + +random.seed(1337_420) + +points = {util.gen_point(-100, 100) for i in range(5_000)} + +# Sanity check +graham = set(graham_scan(points)) +gift = set(rapper(points)) +quick = quick_hull(points) +mbch = set.union(mbc(points)) +assert gift == graham == quick == mbch + + +def time_it(f: callable, args: tuple = (), iterations=20): + start = time() + for i in range(iterations): + f(*args) + return time() - start + + +print("graham:", time_it(graham_scan, args=(points,))) +print("gift:", time_it(rapper, args=(points,))) +print("quick:", time_it(quick_hull, args=(points,))) +print("mbch:", time_it(mbc, args=(points,))) diff --git a/h2/util.py b/h2/util.py index 837d826..ed72b21 100644 --- a/h2/util.py +++ b/h2/util.py @@ -14,10 +14,9 @@ def gen_point(lower: int = 0, upper: int = 10) -> Point: a = random.uniform(lower, upper) b = random.uniform(lower, upper) - x_i = random.uniform(lower, upper) - p_i = Point(x_i, a * x_i + b) - p_i = Point(a, b) - return p_i + #x_i = random.uniform(lower, upper) + #p_i = Point(x_i, a * x_i + b) + return Point(a, b) def display(points: Set[Point], hull: Set[Point]):