added code for Graham's Scan
This commit is contained in:
parent
ac0a977aeb
commit
d25f19e092
|
@ -1,6 +1,7 @@
|
||||||
import random
|
import random
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
Point = namedtuple('Point', ['x', 'y'])
|
Point = namedtuple('Point', ['x', 'y'])
|
||||||
|
|
||||||
|
@ -11,7 +12,8 @@ class Side(Enum):
|
||||||
BELOW = auto()
|
BELOW = auto()
|
||||||
|
|
||||||
|
|
||||||
def sidedness(p1, p2, p3, eps=0.00000001):
|
def sidedness(p1, p2, p3, eps=0.0000001):
|
||||||
|
|
||||||
y = p1.y * (p3.x - p2.x)
|
y = p1.y * (p3.x - p2.x)
|
||||||
x = p1.x
|
x = p1.x
|
||||||
a = (p3.y - p2.y)
|
a = (p3.y - p2.y)
|
||||||
|
@ -36,22 +38,57 @@ p3 = Point(5, 2)
|
||||||
|
|
||||||
|
|
||||||
def genPoint():
|
def genPoint():
|
||||||
a = random.uniform(1, 10)
|
a = random.uniform(1, 5)
|
||||||
b = random.uniform(1, 10)
|
b = random.uniform(1, 5)
|
||||||
|
|
||||||
p = []
|
x_i = random.uniform(1, 5)
|
||||||
for i in range(3):
|
|
||||||
x_i = random.uniform(1, 10)
|
|
||||||
p_i = Point(x_i, a * x_i + b)
|
p_i = Point(x_i, a * x_i + b)
|
||||||
p.append(p_i)
|
|
||||||
return p
|
return p_i
|
||||||
|
|
||||||
|
|
||||||
hej = genPoint()
|
|
||||||
print(hej)
|
|
||||||
|
|
||||||
print(sidedness(*hej))
|
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.
|
||||||
|
|
||||||
|
|
||||||
def graham_scan():
|
sorted_points = sorted(points, key=lambda p: p.x)
|
||||||
3
|
|
||||||
|
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):
|
||||||
|
del UH[-1]
|
||||||
|
UH.append(s)
|
||||||
|
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
|
||||||
|
|
||||||
|
p = [genPoint() for _ in range(30)]
|
||||||
|
UH, LH = graham_scan(p)
|
||||||
|
|
||||||
|
x = [point.x for point in p]
|
||||||
|
y = [point.y for point in p]
|
||||||
|
|
||||||
|
UH_x = [point.x for point in UH]
|
||||||
|
UH_y = [point.y for point in UH]
|
||||||
|
|
||||||
|
LH_x = [point.x for point in LH]
|
||||||
|
LH_y = [point.y for point in LH]
|
||||||
|
|
||||||
|
plt.plot(UH_x, UH_y, 'ro-')
|
||||||
|
plt.plot(LH_x, LH_y, 'ro-')
|
||||||
|
|
||||||
|
plt.scatter(x,y)
|
||||||
|
plt.show()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user