Example #1
0
def find_intersections(verts, edges):
    """
    Initializing of searching intersection algorithm, read Computational Geometry by Mark de Berg
    :param verts: [(x, y) or (x, y, z), ...]
    :param edges: [(1, 5), ...]
    :return: [(3d dimensional intersection point, [edge1 involved in intersection, edge2, ...]), ...]
    """
    status = AVLTree()
    event_queue = AVLTree()
    for edge in edges:
        upper_vert = get_upper_vert(verts, edge)
        lower_vert = (upper_vert + 1) % 2
        up_node = event_queue.insert(EventPoint(verts[edge[upper_vert]], edge[upper_vert]))
        up_node.key.up_edges += [edge]
        event_queue.insert(EventPoint(verts[edge[lower_vert]], edge[lower_vert]))
    # event_queue = AVLTree([(co[y], co[x]) for co in v])
    # print(event_queue.as_list(0))
    out = []
    while event_queue:
        event_node = event_queue.find_smallest()
        intersection = handle_event_point(status, event_queue, event_node.key, verts)
        if intersection:
            out.append(intersection)
        event_queue.remove_node(event_node)
    return out
Example #2
0
 def get_custom_tree():
     """
          10
         /  \
        5    15
         \
         9
        /
       6
     """
     tree = AVLTree([10])
     root = tree.rootNode
     n5 = Node(5)
     n5.parent = root
     root.leftChild = n5
     n15 = Node(15)
     n15.parent = root
     root.rightChild = n15
     n9 = Node(9)
     n9.parent = n5
     n5.rightChild = n9
     n6 = Node(6)
     n6.parent = n9
     n9.leftChild = n6
     return tree
Example #3
0
def make_monotone(verts, hole_v=None, hole_f=None):
    """
    Splits polygon on monotone pieces optionally with holes
    :param verts: [[x1, y2, z1], [x2, y2, z2], ...]
    :param hole_v: [[x1, y2, z1], [x2, y2, z2], ...]
    :param hole_f: [[index1, index2, ....], [...], ...]
    :return (vertices of main polygon and vertices of holes, faces of new polygons) - in SV format
    """
    #debug_data_clear()
    points, half_edges, faces = create_half_edges(verts)
    if hole_f:
        hole_v, hole_he, hole_f = create_hedges_from_faces(hole_v, hole_f)
        points, half_edges, faces = add_holes((points, half_edges, faces),
                                              hole_f)
    status = AVLTree()
    q = sorted(points)[::-1]
    while q:
        event_point = q.pop()
        EdgeSweepLine.global_event_point = event_point
        #print([(i, p.type) for i, p in enumerate(points)])
        #print_p(event_point, 'event point {} - '.format(event_point.type))
        new_hedges = handle_functions[event_point.type](event_point, status)
        if new_hedges:
            half_edges.extend(new_hedges)
        #print_e(status.as_list(0))
    return to_sv_mesh_from_faces(points, build_face_list(half_edges))
Example #4
0
 def get_huge_random_tree():
     values = [
         1, 14, 27, 31, 45, 55, 77, 103, 141, 175, 230, 231, 239, 251, 267,
         298, 306, 310, 311, 316, 356, 367, 451, 457, 482, 483, 518, 533,
         553, 615, 634, 674, 688, 708, 711, 728, 737, 771, 789, 798, 820,
         833, 862, 864, 919, 928, 985, 994, 997, 999
     ]
     return AVLTree(values)
Example #5
0
 def get_custom2_tree():
     """
     ****************************************55(3)*******************************************
     **************************16(2)**********************86(2)******************************
     ****************7(1)************53(1)***********75(1)***********94(1)*******************
     ********2(0)*****13(0)****26(0)****54(0)****73(0)****78(0)****93(0)****96(0)************
     """
     val = [2, 7, 13, 16, 26, 53, 54, 55, 73, 75, 78, 86, 93, 94, 96]
     return AVLTree(val)
Example #6
0
def make_monotone(face):
    """
    Splits polygon into monotone pieces optionally with holes
    :param face: face of half edge data structure
    :return new half edges
    Probably approach of implemetation of monotone algorithm should be reconsidered according new DCEL data structure
    """
    face.mesh.Point.monotone_current_face = face
    status = AVLTree()
    q = sorted(build_points_list(face))[::-1]
    _ = [p.type for p in q]  # not very cool but this will set type for all points before main algorithm
    while q:
        event_point = q.pop()
        Edge.global_event_point = event_point
        handle_functions[event_point.type](event_point, status, find_hedge(event_point))
Example #7
0
def find_intersections(dcel_mesh, accuracy=1e-6, face_overlapping=False):
    """
    Initializing of searching intersection algorithm, read Computational Geometry by Mark de Berg
    Only half edges have correct data after the algorithm.
    Use build faces from half edges method for updating faces if necessary.
    :param dcel_mesh: inner DCELMesh data structure
    :param accuracy: two floats figures are equal if their difference is lower then accuracy value, float
    :param face_overlapping: if True detect in which faces new face is inside
    """
    status = AVLTree()
    event_queue = AVLTree()
    accuracy = accuracy if isinstance(accuracy, float) else 1 / 10**accuracy
    Edge.set_accuracy(accuracy)
    init_event_queue(event_queue, dcel_mesh)
    while event_queue:
        event_node = event_queue.find_smallest()
        handle_event_point(status, event_queue, event_node.key, dcel_mesh,
                           accuracy, face_overlapping)
        event_queue.remove_node(event_node)
    dcel_mesh.hedges = [hedge for hedge in dcel_mesh.hedges if hedge.edge]
Example #8
0
 def setUp(self):
     self.custom_tree = self.get_custom_tree()
     self.empty_tree = AVLTree()
     self.only_root_tree = AVLTree([10])
     self.huge_tree = self.get_huge_random_tree()
Example #9
0
class AVLTreeTest(SverchokTestCase):
    def setUp(self):
        self.custom_tree = self.get_custom_tree()
        self.empty_tree = AVLTree()
        self.only_root_tree = AVLTree([10])
        self.huge_tree = self.get_huge_random_tree()

    def test_avl_tree_search(self):
        with self.subTest(tree="custom tree"):
            self.assertEqual(self.custom_tree.find(6).key, 6)
        with self.subTest(tree="empty tree"):
            self.assertIsNone(self.empty_tree.find(6))
        with self.subTest(tree="only root tree (10)"):
            self.assertIsNone(self.empty_tree.find(6))
        with self.subTest(tree="huge tree"):
            self.assertIsNone(self.huge_tree.find(500))
            self.assertIsNone(self.huge_tree.find(1000))
            self.assertIsNone(self.huge_tree.find(100))
            self.assertEqual(self.huge_tree.find(533).key, 533)
            self.assertEqual(self.huge_tree.find(367).key, 367)

    def test_avl_tree_find_nearest_left(self):
        values = [6, 5.5, 12, 500]
        expect_custom_tree = [6, 5, 10, 15]
        expect_only_root_tree = [None, None, 10, 10]
        expect_huge_tree = [1, 1, 1, 483]
        for val, ex, ro, hu in zip(values, expect_custom_tree,
                                   expect_only_root_tree, expect_huge_tree):
            with self.subTest(tree="custom tree", value=val, expected=ex):
                node = self.custom_tree.find_nearest_left(val)
                self.assertEqual(node.key, ex)
            with self.subTest(tree="empty tree", value=val):
                self.assertIsNone(self.empty_tree.find_nearest_left(val))
            for tree, expect in zip([self.only_root_tree, self.huge_tree],
                                    [ro, hu]):
                with self.subTest(tree="root tree or huge tree",
                                  value=val,
                                  expected=expect):
                    res = tree.find_nearest_left(val)
                    if isinstance(res, Node):
                        self.assertEqual(res.key, expect)
                    else:
                        self.assertIsNone(res)

    @staticmethod
    def get_custom_tree():
        """
             10
            /  \
           5    15
            \
            9
           /
          6
        """
        tree = AVLTree([10])
        root = tree.rootNode
        n5 = Node(5)
        n5.parent = root
        root.leftChild = n5
        n15 = Node(15)
        n15.parent = root
        root.rightChild = n15
        n9 = Node(9)
        n9.parent = n5
        n5.rightChild = n9
        n6 = Node(6)
        n6.parent = n9
        n9.leftChild = n6
        return tree

    @staticmethod
    def get_huge_random_tree():
        values = [
            1, 14, 27, 31, 45, 55, 77, 103, 141, 175, 230, 231, 239, 251, 267,
            298, 306, 310, 311, 316, 356, 367, 451, 457, 482, 483, 518, 533,
            553, 615, 634, 674, 688, 708, 711, 728, 737, 771, 789, 798, 820,
            833, 862, 864, 919, 928, 985, 994, 997, 999
        ]
        return AVLTree(values)

    @staticmethod
    def get_custom2_tree():
        """
        ****************************************55(3)*******************************************
        **************************16(2)**********************86(2)******************************
        ****************7(1)************53(1)***********75(1)***********94(1)*******************
        ********2(0)*****13(0)****26(0)****54(0)****73(0)****78(0)****93(0)****96(0)************
        """
        val = [2, 7, 13, 16, 26, 53, 54, 55, 73, 75, 78, 86, 93, 94, 96]
        return AVLTree(val)