def overUnder(self, point, onThresh=0): """ Arguments: point: [Vector] A point onThresh: [float] The permitted error when testing for being "on" a line Returns: 1 if this point lies on or vertically over segment, -1 if lies vertically under, 0 if out of range over x """ rx = Region(self.p1.x, self.p2.x) ry = Region(self.p1.y, self.p2.y) if (not rx.contains(point.x)) or self.p1.x == self.p2.x: # Point is out of range over x return 0 # y at the point where point is yThresh = self.p1.y + \ (self.p2.y - self.p1.y) * \ (point.x - self.p1.x) / (self.p2.x - self.p1.x) if abs(point.y - yThresh) < onThresh: # On segment return 1 if point.y >= yThresh: # Over segment return 1 else: # Under segment return -1
def overUnder(self, point, onThresh=0): """ Arguments: point: [Vector] A point onThresh: [float] The permitted error when testing for being "on" a line Returns: 1 if this point lies on or vertically over segment, -1 if lies vertically under, 0 if out of range over x """ rx = Region(self.p1.x, self.p2.x) ry = Region(self.p1.y, self.p2.y) if (not rx.contains(point.x)) or self.p1.x == self.p2.x: # Point is out of range over x return 0 # y at the point where point is yThresh = self.p1.y + \ (self.p2.y - self.p1.y) * \ (point.x - self.p1.x) / (self.p2.x - self.p1.x) if abs(point.y - yThresh) < onThresh: # On segment return 1 if point.y >= yThresh: # Over segment return 1 else: # Under segment return -1
def _polygonCircle(sp): sp.order("polygon") p = sp.shapes[0] c0 = sp.shapes[1] intersectList = [] for segment in p.segments(): c = c0.copy() s = segment.copy() # Maps circle's center to origin, line to horizontal toMove = c.center.mul(-1) toRotate = -s.angle() c.move(toMove) s.move(toMove) s.rotate(toRotate) # Calculates intersects segmentHeight = s.p1.y segmentSpan = Region(s.p1.x, s.p2.x) segmentPoints = [] if abs(segmentHeight) >= abs(c.radius): continue else: xMaxPt = math.sqrt(c.radius**2 - segmentHeight**2) xMinPt = -xMaxPt if segmentSpan.contains(xMinPt): segmentPoints.append(Vector(xMinPt, segmentHeight)) if segmentSpan.contains(xMaxPt): segmentPoints.append(Vector(xMaxPt, segmentHeight)) # Translates solutions back to original coordinates for spt in segmentPoints: spt = spt.rotate(-toRotate) spt = spt.sub(toMove) intersectList.append(spt) return intersectList
def _polygonCircle(sp): sp.order("polygon") p = sp.shapes[0] c0 = sp.shapes[1] intersectList = [] for segment in p.segments(): c = c0.copy() s = segment.copy() # Maps circle's center to origin, line to horizontal toMove = c.center.mul(-1) toRotate = -s.angle() c.move(toMove) s.move(toMove) s.rotate(toRotate) # Calculates intersects segmentHeight = s.p1.y segmentSpan = Region(s.p1.x, s.p2.x) segmentPoints = [] if abs(segmentHeight) >= abs(c.radius): continue else: xMaxPt = math.sqrt(c.radius ** 2 - segmentHeight ** 2) xMinPt = -xMaxPt if segmentSpan.contains(xMinPt): segmentPoints.append(Vector(xMinPt, segmentHeight)) if segmentSpan.contains(xMaxPt): segmentPoints.append(Vector(xMaxPt, segmentHeight)) # Translates solutions back to original coordinates for spt in segmentPoints: spt = spt.rotate(-toRotate) spt = spt.sub(toMove) intersectList.append(spt) return intersectList
def reset(self, region=None, exemptions=None): ''' Method: reset Description: Reset cells inside the provided region whose coordinates do not also fall within any of the provided exemption ranges. Parameters: region=None, exemptions=None region: Region - A region for maze reset to span exemptions: Regions - A collection of regions for maze reset to avoid Return: None ''' # Ensure that valid boundaries are set. if region is None: region = Region((0, 0), (self.get_width(), self.get_height())) # Reset all cells that do not fall inside any of the provided exempt ranges. for row in self.m_cells: # If the current row is inside the reset boundary, check for cells to reset inside that row. for cell in row: exempt = False # If the current cell is outside the reset boundary, move on to the next cell. if not region.contains(cell.m_position): continue # Check for the inclusion of each cell in each provided exempt range. if exemptions is not None: for exemption in exemptions: # Reset the boundary walls of the provided exempt ranges. border_directions = exemption.on_border(cell.m_position) for border_direction in border_directions: self.set_wall(cell, border_direction, True) # If the cell falls inside any of the provided exempt ranges, do not reset it. if exemption.contains(cell.m_position): exempt = True break # Do not reset exempt cells. if exempt: continue # Completely reset non-exempt cells. self.unvisit(cell) for direction in list(Direction): self.set_wall(cell, direction, True)
def trailblaze(self, source_cell, direction=None, region=None, exemptions=None): ''' Method: trailblaze Description: Trailblaze from the source cell in the specified direction, knocking down both sides of the wall between the source and the target. Parameters: source_cell, direction=None, region=None, exemptions=None source_cell: Cell - The cell to trailblaze from direction: Direction - The direction to trailblaze in (None simply visits the source cell) region: Region - A region for trailblazing to span exemptions: Regions - A collection of regions for trailblazing to avoid Return: Cell - The target cell is trailblazing was successful, and None otherwise ''' # If the direction is None, "trailblaze" to the source cell by marking it as visited. if direction is None: self.visit(source_cell) return source_cell # Ensure that valid boundaries are set. if region is None: region = Region((0, 0), (self.get_width(), self.get_height())) # Grab the target cell. target_cell = self.get_neighbor_cell(source_cell, direction) # If the target cell is invalid, return without trailblazing. if target_cell is None: return None # If the target cell is exempt, return without trailblazing. if exemptions is not None: for exemption in exemptions: if exemption.contains(target_cell.m_position): return None # If non-exempt target cell is valid, trailblaze to it. if not target_cell.is_visited() and region.contains(target_cell.m_position): # Remove wall between source and target cells. self.set_wall(source_cell, direction, False) # Visit the target cell. self.visit(target_cell) return target_cell