def isThereCrossMovement(cable, dest1, dest2): # I've also included the case where the polygon is not simple cable = getLongCable(cable, dest1, dest2) cable = removeRepeatedVertsOrdered(cable) if len(cable) < 3: return False p = Polygon([convertToPoint(v) for v in cable]) return not p.is_simple()
def _getOriginalBoundary(self) -> None: extendedCable = [self.dest1] + self.cable + [self.dest2] extendedCable = VertexUtils.removeRepeatedVertsOrdered(extendedCable) self.boundaryPts = [ VertexUtils.convertToPoint(vert) for vert in extendedCable ] self.originalPolygon = Polygon(self.boundaryPts)
def isUndoingLastMove(node, v, index): if not node.parent: return False if v.name == "D1" or v.name == "D2": return False if convertToPoint(node.parent.cable[index]) != convertToPoint(v): return False path = node._getPath(index == 0) path = removeRepeatedVertsOrdered(path) if convertToPoint(node.parent.cable[-2]) != convertToPoint(v): return False return True
def preprocessTheCable(cable: VertList, destA: Vertex, destB: Vertex) -> tuple: """ If moves are happening along the current cable """ if convertToPoint(destB) == convertToPoint(cable[-2]) or Geom.isCollinear(cable[-2], cable[-1], destB): cable[-1] = destB if convertToPoint(destA) == convertToPoint(cable[1]) or Geom.isCollinear(cable[1], cable[0], destA): cable[0] = destA cable = removeRepeatedVertsOrdered(cable) return (cable, destA, destB)
def getShortestPath(tri: Triangulation, dest1: Vertex, dest2: Vertex, sleeve: list): # We need to do this because the funnel algorithm assumes that the path lies inside the triangulation if len(sleeve) == 0: raise RuntimeError("Here we are.") funnel = Funnel(dest1, tri, sleeve) pathPt = funnel.getShortestPath(dest2) pathVt = [getClosestVertex(pt) for pt in pathPt] pathVt = removeRepeatedVertsOrdered(pathVt) if len(pathVt) < 2: return [getClosestVertex(dest1), getClosestVertex(dest2)] return pathVt
def _tightenCable(cable: VertList, destA: Vertex, destB: Vertex, isLeft:bool, debugTri=False) -> VertList: """ This is an altered version of "Hershberger, J., & Snoeyink, J. (1994). Computing minimum length paths of a given homotopy class." https://doi.org/10.1016/0925-7721(94)90010-8 """ (cable, destA, destB) = preprocessTheCable(cable, destA, destB) (cable, destA, destB) = pushCableAwayFromObstacles(cable, destA, destB) longCable = getLongCable(cable, destA, destB) if len(longCable) == 2: return [getClosestVertex(pt) for pt in longCable] longCable = removeRepeatedVertsOrdered(longCable) if len(longCable) == 2: return [getClosestVertex(pt) for pt in longCable] tri = Triangulation(cable, destA, destB, debug=debugTri) # Edge case where the two robots go to the same point and cable is not making contact if tri.triangleCount == 1: return [getClosestVertex(pt) for pt in [destA, destB]] allCurrentTries = [] # We represent an edge by a python set to make checks easier currE = getEdge(longCable[0], longCable[1]) currTri = tri.getIncidentTriangles(currE) currTri = chooseTriangleBySide(longCable[0], longCable[1], currTri, isLeft) for i in range(1, len(longCable) - 1): allCurrentTries.append(currTri) e = getEdge(longCable[i], longCable[i + 1]) pivot = e & currE if len(pivot) != 1: raise RuntimeError("The intersection of e and currE must yield only 1 vertex") pivot = next(iter(pivot)) tries = tri.getIncidentTriangles(e) tries = chooseTriangleBySide(longCable[i], longCable[i + 1], tries, isLeft) while not tries & currTri: (flipEdge, currTri) = getFlipEdgeAndCurrentTriangle(tri, pivot, currE, currTri, tries) if flipEdge: currE = flipEdge # FIXME: This happens if the dest1 + cable + dest2 is not a simple polygon else: raise RuntimeError("Deal with this at some point.") allCurrentTries.append(currTri) # Debugging # tri.getCanvasEdge(currE).highlightEdge() currTri = tries & currTri currE = e sleeve = findSleeve(allCurrentTries) return getShortestPath(tri, destA, destB, sleeve)
def _isCorrectSolution(self, paths: list, presetName: str): paths = [removeRepeatedVertsOrdered(p) for p in paths] return repr(paths[0]) == self._tests[presetName][0] and repr( paths[1]) == self._tests[presetName][1]
def polygonAndObstacleIntersection(polyVerts, obstacle) -> List[Point]: result = SHGeom.polygonIntersection(polyVerts, obstacle.polygon.vertices()) result = removeRepeatedVertsOrdered(result) return result