Add algorithm class ConvexHullIncremental
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
108
algorithm.py
108
algorithm.py
@@ -191,3 +191,111 @@ class NearestNeighborsSweep(Algorithm):
|
||||
self._result["points"][0], self._result["points"][1] \
|
||||
).draw(canvas, width, height, max_x, max_y, "#FF0000")
|
||||
|
||||
class ConvexHull(Algorithm):
|
||||
|
||||
"""This algorithm calculates the convex hull for a set of points"""
|
||||
|
||||
def __init__(self, point_set=None):
|
||||
super().__init__()
|
||||
if isinstance(point_set, list):
|
||||
for pnt in point_set:
|
||||
if not isinstance(pnt, point.Point):
|
||||
raise Exception(self, "Inputs have to be of type point.Point!")
|
||||
self._input = copy.deepcopy(point_set)
|
||||
self._ready = True
|
||||
elif point_set is not None:
|
||||
raise Exception(self, "Wrong input type for point_set")
|
||||
self._sss = {} # The sweep state structure
|
||||
self._es = [] # The event queue
|
||||
self._result = {"success": False, \
|
||||
"lt": [], \
|
||||
"lb": [], \
|
||||
"rt": [], \
|
||||
"rb": [], \
|
||||
"hull": []}
|
||||
def start(self):
|
||||
"""Start the performing the algorithm. Return True if it was successful"""
|
||||
if not super().start():
|
||||
return False
|
||||
|
||||
self._result["success"] = False
|
||||
self._sss = {"max": None, \
|
||||
"min": None}
|
||||
# Populate event structure
|
||||
self._es = copy.deepcopy(self._input)
|
||||
# Sort the input elements
|
||||
self._num_steps["sort"] = point.sort_set(self._es)
|
||||
self._section = "sweep-left-to-right"
|
||||
return True
|
||||
def step(self):
|
||||
"""Perform a single step of the algorithm."""
|
||||
if not self._running:
|
||||
return
|
||||
|
||||
if self._section == "sweep-left-to-right":
|
||||
event = self._es.pop(0)
|
||||
if self._sss["min"] is None or self._sss["max"] is None:
|
||||
self._sss["min"] = event
|
||||
self._sss["max"] = event
|
||||
elif event.get_y() < self._sss["min"].get_y():
|
||||
self._result["rb"].append(linesegment.LineSegment(self._sss["min"], event))
|
||||
self._sss["min"] = event
|
||||
elif event.get_y() > self._sss["max"].get_y():
|
||||
self._result["rt"].append(linesegment.LineSegment(self._sss["max"], event))
|
||||
self._sss["max"] = event
|
||||
|
||||
super().step()
|
||||
if len(self._es) == 0:
|
||||
self._sss["min"] = None
|
||||
self._sss["max"] = None
|
||||
self._es = copy.deepcopy(self._input).reverse()
|
||||
self._section = "sweep-right-to-left"
|
||||
|
||||
elif self._section == "sweep-right-to-left":
|
||||
event = self._es.pop(0)
|
||||
if self._sss["min"] is None or self._sss["max"] is None:
|
||||
self._sss["min"] = event
|
||||
self._sss["max"] = event
|
||||
elif event.get_y() < self._sss["min"].get_y():
|
||||
self._result["rb"].append(linesegment.LineSegment(self._sss["min"], event))
|
||||
self._sss["min"] = event
|
||||
elif event.get_y() > self._sss["max"].get_y():
|
||||
self._result["rt"].append(linesegment.LineSegment(self._sss["max"], event))
|
||||
self._sss["max"] = event
|
||||
|
||||
super().step()
|
||||
if len(self._es) == 0:
|
||||
self._section = "sweep-left-to-top"
|
||||
|
||||
elif self._section == "sweep-left-to-top":
|
||||
event = self._es.pop(0)
|
||||
if len(self._es) == 0:
|
||||
self._section = "sweep-left-to-bottom"
|
||||
|
||||
elif self._section == "sweep-left-to-bottom":
|
||||
event = self._es.pop(0)
|
||||
if len(self._es) == 0:
|
||||
self._section = "sweep-right-to-top"
|
||||
|
||||
elif self._section == "sweep-right-to-top":
|
||||
event = self._es.pop(0)
|
||||
if len(self._es) == 0:
|
||||
self._section = "sweep-right-to-bottom"
|
||||
|
||||
elif self._section == "sweep-right-to-bottom":
|
||||
event = self._es.pop(0)
|
||||
if len(self._es) == 0:
|
||||
self._section = "report-hull"
|
||||
elif self._section == "report-hull":
|
||||
for line in self._result["lb"]:
|
||||
self._result["hull"].append(line)
|
||||
for line in self._result["rb"].reverse():
|
||||
self._result["hull"].append(line)
|
||||
for line in self._result["rt"]:
|
||||
self._result["hull"].append(line)
|
||||
for line in self._result["lt"].reverse():
|
||||
self._result["hull"].append(line)
|
||||
self._result["success"] = True
|
||||
self._running = False
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user