def concaveHull(dataset, k): assert k >= 3, 'k has to be greater or equal to 3.' points = dataset # todo: remove duplicate points from dataset # todo: check if dataset consists of only 3 or less points # todo: make sure that enough points for a given k can be found firstpoint = GetFirstPoint(points) # init hull as list to easily append stuff hull = [] # add first point to hull hull.append(firstpoint) # and remove it from dataset points = removePoint(points, firstpoint) currentPoint = firstpoint # set prevPoint to a Point righ of currentpoint (angle=0) prevPoint = (currentPoint[0] + 10, currentPoint[1]) step = 2 while ((not np.array_equal(firstpoint, currentPoint) or (step == 2)) and points.size > 0): if (step == 5): # we're far enough to close too early points = np.append(points, [firstpoint], axis=0) kNearestPoints = GetNearestNeighbors(points, currentPoint, k) cPoints = SortByAngle(kNearestPoints, currentPoint, prevPoint) # avoid intersections: select first candidate that does not intersect any # polygon edge its = True i = 0 while ((its == True) and (i < cPoints.shape[0])): i = i + 1 if (np.array_equal(cPoints[i - 1], firstpoint)): lastPoint = 1 else: lastPoint = 0 j = 2 its = False while ((its == False) and (j < np.shape(hull)[0] - lastPoint)): its = li.doLinesIntersect(hull[step - 1 - 1], cPoints[i - 1], hull[step - 1 - j - 1], hull[step - j - 1]) j = j + 1 if (its == True): print "all candidates intersect -- restarting with k = ", k + 1 return concaveHull(dataset, k + 1) prevPoint = currentPoint currentPoint = cPoints[i - 1] # add current point to hull hull.append(currentPoint) points = removePoint(points, currentPoint) step = step + 1 # check if all points are inside the hull p = Path(hull) pContained = p.contains_points(dataset, radius=0.0000000001) if (not pContained.all()): print "not all points of dataset contained in hull -- restarting with k = ", k + 1 return concaveHull(dataset, k + 1) print "finished with k = ", k return hull
def concaveHull(dataset, k, if_optimal=False): #return list of hull [[x,y],[x2,y2]...] assert k >= 3, 'k has to be greater or equal to 3.' points = dataset # todo: remove duplicate points from dataset # todo: check if dataset consists of only 3 or less points # todo: make sure that enough points for a given k can be found firstpoint = GetFirstPoint(points) # init hull as list to easily append stuff hull = [] # add first point to hull hull.append(firstpoint) # and remove it from dataset points = removePoint(points, firstpoint) currentPoint = firstpoint # set prevPoint to a Point right of currentpoint (angle=0) prevPoint = (currentPoint[0] + 10, currentPoint[1]) step = 2 while ((not np.array_equal(firstpoint, currentPoint) or (step == 2)) and points.size > 0): if (step == 5): # we're far enough to close too early points = np.append(points, [firstpoint], axis=0) kNearestPoints = GetNearestNeighbors(points, currentPoint, k) cPoints = SortByAngle(kNearestPoints, currentPoint, prevPoint) # avoid intersections: select first candidate that does not intersect any # polygon edge its = True i = 0 while ((its == True) and (i < cPoints.shape[0])): i = i + 1 if (np.array_equal( cPoints[i - 1], firstpoint)): # if next concave pt is the first pt lastPoint = 1 else: lastPoint = 0 j = 2 its = False while ((its == False) and (j < np.shape(hull)[0] - lastPoint) ): #number of hull pts - lastpoint >2, j its = li.doLinesIntersect(hull[step - 1 - 1], cPoints[i - 1], hull[step - 1 - j - 1], hull[step - j - 1]) j = j + 1 if (its == True): # if k > 100: # print("k exceed max value 100, concavehull fail, return hull k=100") # return hull if if_optimal: # Todo a bug here # [-4.21707002 37.48664473] [-4.61409177 37.06382358] [-4.61262907 37.06245959] [-4.20343005 37.50127181] intersects print("all candidates intersect -- restarting with k = ", k + 1) #print(hull) # return hull return concaveHull(dataset, k + 1, True) prevPoint = currentPoint currentPoint = cPoints[i - 1] # add current point to hull hull.append(currentPoint) points = removePoint(points, currentPoint) step = step + 1 # check if all points are inside the hull p = Path(hull) pContained = p.contains_points(dataset, radius=0.0000000001) if if_optimal: if (not pContained.all()): # if k>100: # print("k exceed max value 100, concavehull fail, return hull k=100") # return hull print( "not all points of dataset contained in hull -- restarting with k = ", k + 1) return concaveHull(dataset, k + 1, True) print("finished with k = ", k) return hull
import sys import polygonarea import lineintersect from lineintersect import Line input = open(sys.argv[1], "r") points = [] # assumes input ends with newline for line in input: points.append(line[:-1]) print polygonarea.calculateArea(points) print lineintersect.doLinesIntersect(Line(points[0], points[1]), Line(points[2], points[3]))