コード例 #1
0
def triangulate(polygon: Polygon, parent: Node) -> Node:
    """
    Performs recursive triangulation of a polygon. Incomplete triangulations
    are put in tree that has parent as root. Complete triangulations are leaf
    nodes of that tree.

    Args:
        polygon: Polygon that will be triangulated.
        parent: Root of tree that will contain triangulations

    Returns: Leaf nodes if polygon is actually triangle.
    """
    if len(polygon.points) == 3:
        child = Node(extend_triangulation(parent, polygon.points[:3]))
        parent.add_child(child)

        return child

    segment = pick_start_segment(polygon)
    polygon.points = rearrange_points(segment, polygon)

    for point in polygon.points[2:]:
        first_triangle = Triangle(segment.first, segment.second, point)

        remainders = polygon_remainders(first_triangle, polygon)
        sub_root = triangulate(Polygon([segment.first, segment.second, point]),
                               parent)
        triangulate(remainders[0], sub_root)

        if remainders[1]:
            second_remainder_root = Node([])
            triangulate(remainders[1], second_remainder_root)

            merge_triangulations(sub_root, second_remainder_root)
コード例 #2
0
def test_depth_first_traversal() -> None:
    """
    Tests if depth_first_traversal works correctly.
    """
    a, b, c, d = Node("a"), Node("b"), Node("c"), Node("d")

    a.add_child(b)
    a.add_child(c)
    c.add_child(d)
    tree = Tree(a)

    assert tree.depth_first_traversal() == [a, b, c, d]
コード例 #3
0
def test_get_leaf_nodes() -> None:
    """
    Tests if get_leaf_nodes works correctly.
    """

    a, b, c, d = Node("a"), Node("b"), Node("c"), Node("d")

    a.add_child(b)
    a.add_child(c)
    c.add_child(d)
    tree = Tree(a)

    assert tree.get_leaf_nodes() == [b, d]
コード例 #4
0
def merge_triangulations(first: Node, second: Node) -> None:
    """
    For nodes whose children contain incomplete triangulations,
    generates all possible complete triangulations and appends them to the
    first tree.

    Args:
        first: Root of the first subtree.
        second: Root of the second subtree.
    """
    first_leaf_nodes = Tree(first).get_leaf_nodes()
    second_leaf_nodes = Tree(second).get_leaf_nodes()
    for leaf_1 in first_leaf_nodes:
        for leaf_2 in second_leaf_nodes:
            leaf_1.add_child(Node(leaf_1.data + leaf_2.data))
コード例 #5
0
def all_triangulations(polygon: Polygon) -> List[List[Triangle]]:
    """
    Wrapper function for recursive "triangulate" function.
    
    Args:
        polygon: Polygon that will be triangulated.

    Returns:
        List of all possible triangulations of this polygon.
    """
    polygon.make_simple()
    tree = Tree(Node([]))
    triangulate(polygon, tree.root)

    return [node.data for node in tree.get_leaf_nodes()]
コード例 #6
0
def test_triangulate() -> None:
    """
    Tests if rearrange_points works correctly.
    """

    quad = Polygon([Point(0, 0), Point(1, -1), Point(2, 0), Point(2, 1)])
    root = Node([])
    triangulate(quad, root)

    triangulation_1 = [
        Triangle(Point(0, 0), Point(1, -1), Point(2, 0)),
        Triangle(Point(0, 0), Point(2, 0), Point(2, 1))
    ]
    triangulation_2 = [
        Triangle(Point(0, 0), Point(1, -1), Point(2, 1)),
        Triangle(Point(1, -1), Point(2, 0), Point(2, 1))
    ]

    assert Tree(root).get_leaf_nodes()[0].data == triangulation_1
    assert Tree(root).get_leaf_nodes()[1].data == triangulation_2