This commit is contained in:
Casper 2018-10-11 14:38:59 +02:00
parent 26dfb6d305
commit 9fee0dac99
No known key found for this signature in database
GPG Key ID: B1156723DB3BDDA8
6 changed files with 60 additions and 33 deletions

View File

@ -11,10 +11,7 @@ def calc_angle(v1: Vector, v2: Vector) -> float:
tmp = dot / (len_1 * len_2) tmp = dot / (len_1 * len_2)
# pls return acos(round(tmp, 6))
hmmmmmmm = round(tmp, 6)
return acos(hmmmmmmm)
def calc_vector(p1: Point, p2: Point) -> Vector: def calc_vector(p1: Point, p2: Point) -> Vector:
@ -27,16 +24,14 @@ def rapper(points: set):
comp_vec = Vector(0, 1) comp_vec = Vector(0, 1)
while True: while True:
hull.append(min(points - {hull[-1]}, 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]) comp_vec = calc_vector(hull[-2], hull[-1])
display(points, hull)
if hull[-1] == min_pt: if hull[-1] == min_pt:
break
return hull return hull
if __name__ == '__main__':
points = {gen_point() for _ in range(30)} points = {gen_point() for _ in range(30)}
hull = rapper(points) hull = rapper(points)

View File

@ -30,14 +30,11 @@ p3 = Point(5, 2)
def graham_scan(points): def graham_scan(points):
# A funky issue where both a and b become negative in the sidedness test causes us to have to use # 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. # Side.ABOVE for both tests, regardless of UH or LH.
sorted_points = sorted(points) sorted_points = sorted(points)
UH = sorted_points[:2] UH = sorted_points[:2]
#del sorted_points[0]
for s in sorted_points[2:]: for s in sorted_points[2:]:
while len(UH) > 1 and (sidedness(UH[-2], UH[-1], s) != Side.ABOVE): 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 = list(reversed(sorted_points))
reversed_list.append(UH[0]) reversed_list.append(UH[0])
LH = reversed_list[:2] LH = reversed_list[:2]
#del reversed_list[0]
for s in reversed_list[2:]: for s in reversed_list[2:]:
while len(LH) > 1 and (sidedness(LH[-2], LH[-1], s) != Side.ABOVE): while len(LH) > 1 and (sidedness(LH[-2], LH[-1], s) != Side.ABOVE):
del LH[-1] del LH[-1]
LH.append(s) LH.append(s)
return UH, LH return UH + LH
if __name__ == '__main__':
p = [gen_point() for _ in range(30)] p = [gen_point() for _ in range(30)]
UH, LH = graham_scan(p) hull = graham_scan(p)
display(p, {*UH, *LH}) display(p, hull)

View File

@ -89,6 +89,11 @@ 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)) return set.union(mbc_ch(pl, linprog_flipper), {left_point, right_point}, mbc_ch(pr, linprog_flipper))
def mbc(points: Set[Point]) -> Set[Point]:
return set.union(mbc_ch(points, lambda x: x), mbc_ch(points, lambda x: -x))
if __name__ == '__main__':
points = {gen_point(1, 10) for _ in range(20)} points = {gen_point(1, 10) for _ in range(20)}
upper_hull_points = mbc_ch(points, lambda x: x) upper_hull_points = mbc_ch(points, lambda x: x)

View File

@ -15,8 +15,6 @@ def is_left(a: Point, b: Point, c: Point):
def quick_hull(points: Set[Point]): def quick_hull(points: Set[Point]):
assert len(points) >= 2
left = min(points) left = min(points)
right = max(points) right = max(points)
@ -55,6 +53,7 @@ def find_hull(points: Set[Point], p: Point, q: Point, hull: Set[Point]):
hull) hull)
if __name__ == '__main__':
points = {gen_point() for _ in range(30)} points = {gen_point() for _ in range(30)}
hull = quick_hull(points) hull = quick_hull(points)

32
h2/tmptest.py Normal file
View File

@ -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,)))

View File

@ -14,10 +14,9 @@ def gen_point(lower: int = 0, upper: int = 10) -> Point:
a = random.uniform(lower, upper) a = random.uniform(lower, upper)
b = random.uniform(lower, upper) b = random.uniform(lower, upper)
x_i = random.uniform(lower, upper) #x_i = random.uniform(lower, upper)
p_i = Point(x_i, a * x_i + b) #p_i = Point(x_i, a * x_i + b)
p_i = Point(a, b) return Point(a, b)
return p_i
def display(points: Set[Point], hull: Set[Point]): def display(points: Set[Point], hull: Set[Point]):