Example #1
0
    def intersection_count(self,
                           line_segment: LineSegment) -> Tuple[int, bool]:
        """
        HELPER: Determines number of times that LineSegment object intersects
        with polygon (self)

        Args:
            line_segment: LineSegment object

        Returns:
            tuple consisting of int and bool. int is number of intersections,
            bool is True if point "lies" on one of the edges of the polygon
        """

        intersections_counter, on_edge = 0, False
        points_count = len(self.points)

        for i in range(0, points_count):

            first = self.points[i % points_count]
            second = self.points[(i + 1) % points_count]

            current_line_segment = LineSegment(first=first, second=second)

            if current_line_segment.does_contain(line_segment.first):
                on_edge = True

            if current_line_segment.does_intersect_or_touch(line_segment):
                intersections_counter += 1

        return intersections_counter, on_edge
Example #2
0
def find_pair_edge(triangulation: Triangulation,
                   edge: LineSegment) -> Tuple[LineSegment, List[Triangle]]:
    """
    For edge that is diagonal of a convex quadrilateral in triangulation,
    finds other diagonal of that quadrilateral.

    Args:
        triangulation: Current triangulation
        edge: Some non frontier edge in triangulation.

    Returns: Other diagonal if quadrilateral is convex, edge if it is concave.

    """
    faces = []

    for triangle in triangulation.triangles:
        if edge in triangle.get_sides() or edge.reversed() in \
                triangle.get_sides():
            faces.append(triangle)

    if len(faces) != 2:
        return edge, faces

    endpoints = []
    for triangle in faces:
        for point in triangle.get_points():
            if not edge.does_contain(point):
                endpoints.append(point)

    return LineSegment(endpoints[0], endpoints[1]), faces
Example #3
0
def test_pick_start_segment() -> None:
    """
    Tests if pick_start_segment works correctly. One common and one edge case.
    """

    hex_1 = Polygon([
        Point(0, 0),
        Point(1, -1),
        Point(2, 0),
        Point(2, 1),
        Point(1, 2),
        Point(0, 1)
    ])

    hex_2 = Polygon([
        Point(0, 0),
        Point(1, 0),
        Point(2, 0),
        Point(2, 1),
        Point(1, 2),
        Point(0, 1)
    ])

    assert pick_start_segment(hex_1) == LineSegment(Point(0, 0), Point(1, -1))
    assert pick_start_segment(hex_2) == LineSegment(Point(2, 0), Point(2, 1))
def test_find_pair_edge() -> None:
    """ Tests if find pair edge method works correctly. """

    a, b, c, d = [Point(4, 3), Point(-1, 2), Point(1, 1), Point(2, 1)]
    triangles = [Triangle(b, c, d), Triangle(b, a, d)]
    triangulation = Triangulation(triangles)

    pair = find_pair_edge(triangulation, LineSegment(b, d))

    assert pair == (LineSegment(c, a), triangles)
Example #5
0
    def get_sides(self) -> List[LineSegment]:
        """
        Gets segments of self as a list of three elements.

        Returns: List of three LineSegments.
        """
        return [
            LineSegment(self.first, self.second),
            LineSegment(self.second, self.third),
            LineSegment(self.third, self.first)
        ]
Example #6
0
def line_segs() -> None:
    first = LineSegment(points[0], points[1])
    second = LineSegment(points[2], points[3])
    first.draw(canvas)
    second.draw(canvas)
    if first.does_intersect_or_touch(second):
        messagebox.showinfo("Result", "Segments DO intersect")
    else:
        messagebox.showinfo("Result", "Segments DO NOT intersect")
def test__eq__() -> None:
    """
        Tests if overriden __eq__ method works correctly
    """
    point_1 = Point(1, 2)
    point_2 = Point(-2, -4)
    point_3 = Point(3, 3)
    point_4 = Point(0, 0)
    line_segment_1 = LineSegment(first=point_1, second=point_2)
    line_segment_2 = LineSegment(first=point_1, second=point_2)
    line_segment_3 = LineSegment(first=point_3, second=point_4)

    assert line_segment_1 == line_segment_2
    assert not line_segment_1 == line_segment_3
Example #8
0
    def draw(self, canvas) -> None:
        """
        Draws polygon object onto the canvas.Takes translation into
        consideration.

        Args:
            canvas: Canvas object on which line segment will be drawn to.
        """

        first = self.points[0]

        for i in range(0, len(self.points) - 1):
            LineSegment(self.points[i], self.points[i + 1]).draw(canvas)

        LineSegment(self.points[-1], first).draw(canvas)
def test_contains_point() -> None:
    """
        Tests if contains_point determines relationship between line_segment 
        and point correctly. Tests both common and edge cases.
    """
    point_1 = Point(1, 2)
    point_2 = Point(-2, -4)
    point_3 = Point(3, 3)
    point_4 = Point(0, 0)

    line_segment = LineSegment(first=point_1, second=point_2)

    assert line_segment.does_contain(point_1)
    assert line_segment.does_contain(point_2)
    assert not line_segment.does_contain(point_3)
    assert line_segment.does_contain(point_4)
Example #10
0
def new_edges(t_points: List[Point], t_edges: List[LineSegment],
              point: Point) -> List[LineSegment]:
    """
    Makes valid edges from one point to all points in triangulation so far.
    Args:
        t_points: Points in triangulation
        t_edges: Edges in triangulation
        point: Point that is not yet in triangulation.

    Returns: List of valid LineSegments.

    """
    n_edges = []
    for tri_p in t_points:
        new_edge = LineSegment(point, tri_p)
        valid = True

        for edge in t_edges:
            if edge.strict_intersect(new_edge):
                valid = False
                break

        if valid:
            n_edges.append(new_edge)

    return n_edges
def test_does_intersect() -> None:
    """
        Tests if does_intersect works correctly.
        Tests both common and edge cases.
    """

    line_segment_1 = LineSegment(first=Point(1, 1), second=Point(4, 4))
    reversed_segment = LineSegment(first=Point(4, 4), second=Point(1, 1))
    line_segment_2 = LineSegment(first=Point(1, 1), second=Point(-2, -4))
    line_segment_3 = LineSegment(first=Point(3, 3), second=Point(5, 5))
    line_segment_4 = LineSegment(first=Point(1, 0), second=Point(5, -5))

    assert line_segment_1.does_intersect_or_touch(reversed_segment)
    assert line_segment_1.does_intersect_or_touch(line_segment_2)
    assert line_segment_1.does_intersect_or_touch(line_segment_3)
    assert not line_segment_1.does_intersect_or_touch(line_segment_4)
Example #12
0
def test_number_of_intersections() -> None:
    """
        Tests if Polygon class method number_of_intersections works correctly.
    """
    line_segment_intersect = LineSegment(first=Point(0, 0),
                                         second=Point(10, 10))
    line_segment_no_intersect = LineSegment(first=Point(0, 0),
                                            second=Point(-10, -10))

    polygon = Polygon([
        Point(1, 1),
        Point(5, 6),
        Point(5, 3),
        Point(2, 5),
        Point(4, 8),
        Point(2, 3),
        Point(4, 1),
        Point(3, 4)
    ])

    assert polygon.intersection_count(line_segment_intersect) == (6, False)
    assert polygon.intersection_count(line_segment_no_intersect) == (0, False)
Example #13
0
def test_does_intersect() -> None:
    """
        Tests if Polygon class method does_intersect works correctly.
        Two common and one edge case.
    """
    polygon = Polygon([
        Point(1, 1),
        Point(5, 6),
        Point(5, 3),
        Point(2, 5),
        Point(4, 8),
        Point(2, 3),
        Point(4, 1),
        Point(3, 4)
    ])

    line_segment_intersect = LineSegment(Point(0, 2), Point(2, 2))
    line_segment_no_intersect = LineSegment(Point(0, 0), Point(-5, 2))
    line_segment_match = LineSegment(polygon.points[4], polygon.points[5])

    assert polygon.does_intersect(line_segment_intersect)
    assert not polygon.does_intersect(line_segment_no_intersect)
    assert polygon.does_intersect(line_segment_match)
Example #14
0
def add_triangles(triangulation: Triangulation, point: Point,
                  t_points: List[Point]) -> None:
    """
    Adds triangles from new point to triangulation.

    Args:
        triangulation: Current triangulation.
        point: New point that is not yet in triangulation.
        t_points: Points in triangulation.

    """
    t_edges = triangulation.get_edges()
    n_edges = new_edges(t_points, t_edges, point)
    edges_to_flip = []

    for edge_1 in n_edges:
        for edge_2 in n_edges:

            if edge_1 == edge_2:
                break

            tri_edge = LineSegment(edge_1.second, edge_2.second)

            if tri_edge in t_edges:
                tri_edge = t_edges[t_edges.index(tri_edge)]
            elif tri_edge.reversed() in t_edges:
                tri_edge = t_edges[t_edges.index(tri_edge.reversed())]
            else:
                continue

            tri_edge.frontier = False

            edges_to_flip.append(tri_edge)
            tri_1 = Triangle(edge_1.second, edge_2.second, point)
            triangulation.add(tri_1)

    flip_edges(triangulation, edges_to_flip)
Example #15
0
    def does_contain(self, point: Point) -> bool:
        """
        Determines if point "lies" in polygon (self)

        Args:
            point: Point object to be tested

        Returns:
            True if point is in polygon, False otherwise
        """
        # NOTE: PSEUDO_INF used instead of float("inf") of numpy.inf because
        # usage of these methods gave incorrect results. Float comparison error?
        ray = LineSegment(first=point, second=Point(PSEUDO_INF, point.y))
        num_of_int, on_edge = self.intersection_count(ray)
        return num_of_int % 2 != 0 or on_edge
Example #16
0
def test_new_edges() -> None:
    """ Tests if new_edges method works correctly. """

    a, b, c, d = [Point(4, 3), Point(-1, 2), Point(1, 1), Point(2, 1)]
    t_points = [a, b, c, d]
    t_edges = [
        LineSegment(b, c),
        LineSegment(c, d),
        LineSegment(b, d),
        LineSegment(b, a),
        LineSegment(a, d)
    ]

    point = Point(1, 3)
    assert new_edges(t_points, t_edges,
                     point) == [LineSegment(point, a),
                                LineSegment(point, b)]
def pick_start_segment(polygon: Polygon) -> LineSegment:
    points_count = len(polygon.points)

    if points_count > 3:

        for i in range(points_count):
            ref_points = (polygon.points[(i - 1) % points_count],
                          polygon.points[i % points_count],
                          polygon.points[(i + 1) % points_count],
                          polygon.points[(i + 2) % points_count])

            or_1 = orientation(ref_points[0], ref_points[1], ref_points[2])
            or_2 = orientation(ref_points[1], ref_points[2], ref_points[3])

            if or_1 != 0 and or_2 != 0:
                return LineSegment(ref_points[1], ref_points[2])
        raise ValueError("Polygon consists only out of collinear points!")
    else:
        raise ValueError("Polygon size is less than 3!")
Example #18
0
    def diagonals_from_point(self, start_point: Point) -> List[LineSegment]:
        """
        For a given polygon points, creates all diagonals that start in
        that point.

        Args:
            start_point: One of the points of the polygon

        Returns: List of LineSegments (diagonals)

        """
        self.make_simple()
        diagonals = []

        for index, point in enumerate(self.points):

            if not neighbors(start_point, point, self.points):
                diagonals.append(LineSegment(start_point, point))

        return diagonals
Example #19
0
def test_rearrange_points() -> None:
    """
    Tests if rearrange_points works correctly.
    """

    hexagon = Polygon([
        Point(0, 0),
        Point(1, -1),
        Point(2, 0),
        Point(2, 1),
        Point(1, 2),
        Point(0, 1)
    ])

    segment = LineSegment(Point(1, -1), Point(2, 0))

    assert rearrange_points(segment, hexagon) == [
        Point(1, -1),
        Point(2, 0),
        Point(2, 1),
        Point(1, 2),
        Point(0, 1),
        Point(0, 0)
    ]