示例#1
0
 def __lt__(self, other: 'SweepLineKey') -> bool:
     """
     Checks if the segment (or at least the point) associated with event
     is lower than other's.
     """
     event, other_event = self.event, other.event
     if event is other_event:
         return False
     start, end = event.start, event.end
     other_start, other_end = other_event.start, other_event.end
     other_start_orientation = orientation(end, start, other_start)
     other_end_orientation = orientation(end, start, other_end)
     if other_start_orientation is other_end_orientation:
         return (other_event.from_left
                 if other_start_orientation is Orientation.COLLINEAR
                 else (other_start_orientation
                       is Orientation.COUNTERCLOCKWISE))
     start_orientation = orientation(other_end, other_start, start)
     end_orientation = orientation(other_end, other_start, end)
     if start_orientation is end_orientation:
         return start_orientation is Orientation.CLOCKWISE
     elif other_start_orientation is Orientation.COLLINEAR:
         return other_end_orientation is Orientation.COUNTERCLOCKWISE
     elif start_orientation is Orientation.COLLINEAR:
         return end_orientation is Orientation.CLOCKWISE
     elif end_orientation is Orientation.COLLINEAR:
         return start_orientation is Orientation.CLOCKWISE
     else:
         return other_start_orientation is Orientation.COUNTERCLOCKWISE
示例#2
0
 def __lt__(self, other: 'SweepLineKey') -> bool:
     """
     Checks if the segment (or at least the point) associated with event
     is lower than other's.
     """
     event, other_event = self.event, other.event
     if event is other_event:
         return False
     start, other_start = event.start, other_event.start
     end, other_end = event.end, other_event.end
     other_start_orientation = orientation(end, start, other_start)
     other_end_orientation = orientation(end, start, other_end)
     if other_start_orientation is other_end_orientation:
         start_x, start_y = event.start
         other_start_x, other_start_y = other_event.start
         if other_start_orientation is not Orientation.COLLINEAR:
             # other segment fully lies on one side
             return other_start_orientation is Orientation.COUNTERCLOCKWISE
         # segments are collinear
         elif start_x == other_start_x:
             end_x, end_y = end
             other_end_x, other_end_y = other_end
             if start_y != other_start_y:
                 # segments are vertical
                 return start_y < other_start_y
             # segments have same start
             elif end_y != other_end_y:
                 return end_y < other_end_y
             elif end_x != other_end_x:
                 # segments are horizontal
                 return end_x < other_end_x
             else:
                 # segments are equal
                 event.segments_ids = other_event.segments_ids = merge_ids(
                     event.segments_ids, other_event.segments_ids)
                 return False
         elif start_y != other_start_y:
             return start_y < other_start_y
         else:
             # segments are horizontal
             return start_x < other_start_x
     start_orientation = orientation(other_end, other_start, start)
     end_orientation = orientation(other_end, other_start, end)
     if start_orientation is end_orientation:
         return start_orientation is Orientation.CLOCKWISE
     elif other_start_orientation is Orientation.COLLINEAR:
         return other_end_orientation is Orientation.COUNTERCLOCKWISE
     elif start_orientation is Orientation.COLLINEAR:
         return end_orientation is Orientation.CLOCKWISE
     elif event.is_vertical:
         return start_orientation is Orientation.CLOCKWISE
     elif other_event.is_vertical:
         return other_start_orientation is Orientation.COUNTERCLOCKWISE
     elif other_end_orientation is Orientation.COLLINEAR:
         return other_start_orientation is Orientation.COUNTERCLOCKWISE
     elif end_orientation is Orientation.COLLINEAR:
         return start_orientation is Orientation.CLOCKWISE
     else:
         current_x = self.sweep_line.current_x
         return event.y_at(current_x) < other_event.y_at(current_x)
示例#3
0
 def __lt__(self, other: 'EventsQueueKey') -> bool:
     event, other_event = self.event, other.event
     start_x, start_y = event.start
     other_start_x, other_start_y = other_event.start
     if start_x != other_start_x:
         # different x-coordinate,
         # the event with lower x-coordinate is processed first
         return start_x < other_start_x
     elif start_y != other_start_y:
         # different points, but same x-coordinate,
         # the event with lower y-coordinate is processed first
         return start_y < other_start_y
     elif event.is_left_endpoint is not other_event.is_left_endpoint:
         # same start, but one is a left endpoint
         # and the other a right endpoint,
         # the right endpoint is processed first
         return other_event.is_left_endpoint
     # same start, both events are left endpoints
     # or both are right endpoints
     else:
         other_end_orientation = orientation(event.end, event.start,
                                             other_event.end)
         # the lowest segment is processed first
         return (other_event.from_left
                 if other_end_orientation is Orientation.COLLINEAR else
                 other_end_orientation is
                 (Orientation.COUNTERCLOCKWISE
                  if event.is_left_endpoint else Orientation.CLOCKWISE))
示例#4
0
def _to_sub_hull(points: Iterable[Point]) -> List[Point]:
    result = []
    for point in points:
        while len(result) >= 2:
            if orientation(result[-1], result[-2],
                           point) is not Orientation.COUNTERCLOCKWISE:
                del result[-1]
            else:
                break
        result.append(point)
    return result
示例#5
0
def _triangulate_three_points(sorted_points: Sequence[Point]) -> Triangulation:
    left_point, mid_point, right_point = sorted_points
    first_edge, second_edge = (QuadEdge.factory(left_point, mid_point),
                               QuadEdge.factory(mid_point, right_point))
    first_edge.opposite.splice(second_edge)
    angle_orientation = orientation(left_point, mid_point, right_point)
    if angle_orientation is Orientation.COUNTERCLOCKWISE:
        third_edge = second_edge.connect(first_edge)
        return Triangulation(third_edge.opposite, third_edge)
    elif angle_orientation is Orientation.CLOCKWISE:
        second_edge.connect(first_edge)
        return Triangulation(first_edge, second_edge.opposite)
    else:
        return Triangulation(first_edge, second_edge.opposite)
示例#6
0
def to_contour_orientation(contour: Contour) -> Orientation:
    index = arg_min(contour)
    return orientation(contour[index], contour[index - 1],
                       contour[(index + 1) % len(contour)])
示例#7
0
def normalize_contour(contour: Contour) -> Contour:
    min_index = arg_min(contour)
    contour = contour[min_index:] + contour[:min_index]
    return (contour[:1] + contour[1:][::-1] if
            (orientation(contour[-1], contour[0], contour[1]) is
             Orientation.COUNTERCLOCKWISE) else contour)
示例#8
0
def _is_inner_segment_point(start: Point, end: Point, point: Point) -> bool:
    return ((start < point < end if start < end else end < point < start)
            and orientation(start, end, point) is Orientation.COLLINEAR)
示例#9
0
def is_convex_contour(contour: Contour) -> bool:
    contour = normalize_contour(contour)
    return all(orientation(contour[index - 2], contour[index - 1],
                           contour[index]) is Orientation.CLOCKWISE
               for index in range(len(contour)))
示例#10
0
def points_do_not_lie_on_the_same_line(points: Sequence[Point]) -> bool:
    return any(orientation(points[index - 1], points[index],
                           points[(index + 1) % len(points)])
               is not Orientation.COLLINEAR
               for index in range(len(points)))
示例#11
0
 def orientation_with(self, point: Point) -> Orientation:
     return orientation(self.end, self._start, point)
示例#12
0
 def orientation_with(self, point: Point) -> Orientation:
     return orientation(self.right, self.left, point)