From f8afede624e484f779f5fd6067bb08cddb253baf Mon Sep 17 00:00:00 2001 From: Tolga Yurtseven <tolgayurt02@outlook.de> Date: Sat, 14 Nov 2020 13:10:02 +0100 Subject: [PATCH] refactored the packing_container function and chaned vertice to vertex avl_tree.py --- mysite/plots/avl_tree.py | 36 +++++++++---------- mysite/plots/packing_algo.py | 69 +++++++++++++++++++++++++++--------- 2 files changed, 70 insertions(+), 35 deletions(-) diff --git a/mysite/plots/avl_tree.py b/mysite/plots/avl_tree.py index 90733874..6ff57d8c 100644 --- a/mysite/plots/avl_tree.py +++ b/mysite/plots/avl_tree.py @@ -9,10 +9,10 @@ import sys # Create a tree node class TreeNode(object): - def __init__(self, key, vertice, vertice_neighbour): + def __init__(self, key, vertex, vertex_neighbour): self.key = key - self.vertice = vertice - self.vertice_neighbour = vertice_neighbour + self.vertex = vertex + self.vertex_neighbour = vertex_neighbour self.left = None self.right = None self.height = 1 @@ -20,30 +20,30 @@ class TreeNode(object): class AVLTree(object): - def find_edges(self, root, key, vertice_top): + def find_edges(self, root, key, vertex_top): if not root: - return vertice_top + return vertex_top elif key < root.key: - vertice_top = root - return self.find_edges(root.left, key, vertice_top) + vertex_top = root + return self.find_edges(root.left, key, vertex_top) elif key == root.key: return root else: - if vertice_top.key < key: # falls wir irgendwann im Buam nach links gegangen sind ist dieser Node der Nachfolger, ansonsten gibt es kein Nachfolger und die Ecke berührt den Container rand - vertice_top = TreeNode(key, (0, key), (0, 0)) - return self.find_edges(root.right, key, vertice_top) - # return ("test",vertice_top) + if vertex_top.key < key: # falls wir irgendwann im Buam nach links gegangen sind ist dieser Node der Nachfolger, ansonsten gibt es kein Nachfolger und die Ecke berührt den Container rand + vertex_top = TreeNode(key, (0, key), (0, 0)) + return self.find_edges(root.right, key, vertex_top) + # return ("test",vertex_top) # Function to insert a node - def insert_node(self, root, key, vertice, vertice_neighbour): + def insert_node(self, root, key, vertex, vertex_neighbour): # Find the correct location and insert the node if not root: - return TreeNode(key, vertice, vertice_neighbour) + return TreeNode(key, vertex, vertex_neighbour) elif key < root.key: - root.left = self.insert_node(root.left, key, vertice, vertice_neighbour) + root.left = self.insert_node(root.left, key, vertex, vertex_neighbour) else: - root.right = self.insert_node(root.right, key, vertice, vertice_neighbour) + root.right = self.insert_node(root.right, key, vertex, vertex_neighbour) root.height = 1 + max(self.getHeight(root.left), self.getHeight(root.right)) @@ -87,8 +87,8 @@ class AVLTree(object): return temp temp = self.getMinValueNode(root.right) root.key = temp.key - root.vertice = temp.vertice - root.vertice_neighbour = temp.vertice_neighbour + root.vertex = temp.vertex + root.vertex_neighbour = temp.vertex_neighbour root.right = self.delete_node(root.right, temp.key) if root is None: @@ -168,7 +168,7 @@ class AVLTree(object): return # print("{0} ".format(root.key), end="") if root.key <= key: - array.append((root.vertice)) + array.append((root.vertex)) self.preOrder_array(root.left, array, key) self.preOrder_array(root.right, array, key) return array diff --git a/mysite/plots/packing_algo.py b/mysite/plots/packing_algo.py index 1391494c..62eff063 100644 --- a/mysite/plots/packing_algo.py +++ b/mysite/plots/packing_algo.py @@ -426,30 +426,60 @@ class Container(object): distance = math.sqrt((intersection_point[0] - point[0]) ** 2 + (intersection_point[1] - point[1]) ** 2) return distance - def find_successor(self, vertex: Point_xy, vertices_visible_left: [Point_xy]) -> (Point_xy, Point_xy): + def find_corresponding_edge(self, vertex: Point_xy, vertices_visible_left: [Point_xy]) -> (Point_xy, Point_xy): + """This function finds the corresponding edge for a vertex which is already packed and visible from right. + + To find the corresponding edge the vertices visible from left of the polygon which will be moved to the left + will be checked. Important is that the vertices_visible_left are ordered from smallest y values to bigger ones. + This condition is guaranteed by the splitter function which builds the vertices_visible_left. + The first vertex in the vertices_visible_left list is the bottom_spine element which has the smallest y value + and the next element are ordered because the polygon vertices are convex and where build clockwise. + Args: + vertex (Point_xy): a vertex which is already in the container and visible from the right + vertices_visible_left ([Point_xy]): vertices visible from left of the polygon which will be move to the left + + Returns: + bottom_edge_vertex, top_edge_vertex (Point_xy,Point_xy): the corresponding edge with his two building points + """ for counter, top_edge_vertex in enumerate(vertices_visible_left): if top_edge_vertex[1] >= vertex[1]: bottom_edge_vertex = vertices_visible_left[counter - 1] - return (bottom_edge_vertex, top_edge_vertex) + return bottom_edge_vertex, top_edge_vertex def packing_container(self, hc_spine_ordered_polygons: [ConvexPolygon]) -> ([ConvexPolygon], [Figure]): - hc_polygons = copy.deepcopy(hc_spine_ordered_polygons) # n - sigma_plot_helper = [] # holds the Polygons before their translation to next polygon in sigma + """Packs the spine ordered polygons into the container by translating them to the correct place + + This function will be called by initializing the Container object. + It uses a balanced tree as data structure which helps to pack the polygons efficient into the container. + The tree structure needs be updated while packing and holds all currently packed vertices which are visible + from right. + The function also creates plot objects for almost every packing step. + + Args: + hc_spine_ordered_polygons ([ConvexPolygon]): spine ordered polygons from the HighClass to pack + + Returns: + sigma, plot_steps (([ConvexPolygon], [Figure])): a tuple of the packed polygons and a list of the plot + objects which represent a packing step + """ + # backup for the ordered spine HighClass polygons because they will be translated + hc_polygons = copy.deepcopy(hc_spine_ordered_polygons) + sigma_plot_helper = [] step_counter = 0 sigma = [] plot_steps = [] for polygon in hc_polygons: sigma_plot_helper.append(polygon) - if sigma == []: + if not sigma: # first polygon will be packed transform_x = -polygon.min_x transform_y = -polygon.min_y polygon.translation(transform_x, transform_y) polygon_vertices = len(polygon.vertices_right_visible) # filling the tree with all vertices visible form right of the first polygon for count in range(0, polygon_vertices - 1): - vertice = polygon.vertices_right_visible[count] - vertice_neighbour = polygon.vertices_right_visible[count + 1] - self.root = self.Tree.insert_node(self.root, vertice[1], vertice, vertice_neighbour) + vertex = polygon.vertices_right_visible[count] + vertex_neighbour = polygon.vertices_right_visible[count + 1] + self.root = self.Tree.insert_node(self.root, vertex[1], vertex, vertex_neighbour) sigma.append(polygon) self.x_boundary += polygon.width plot_steps.append( @@ -461,32 +491,37 @@ class Container(object): polygon.translation(transform_x, transform_y) min_horizontal_distance = math.inf distance_rl_plot_helper = [] - # distanzen von rechts nach links + # find the smallest distance from right to left for vertex in polygon.vertices_left_visible: vertex_y = vertex[1] + # finds the next biggest node (vertex) in the tree which holds his smaller neighbour point (vertex) successor_vertex = self.Tree.find_edges(self.root, vertex_y, self.root) - corresponding_edge_points = (successor_vertex.vertice, successor_vertex.vertice_neighbour) + corresponding_edge_points = (successor_vertex.vertex, successor_vertex.vertex_neighbour) distance = self.distance(corresponding_edge_points, vertex) if distance <= min_horizontal_distance: min_horizontal_distance = distance distance_rl_plot_helper.append((vertex, distance)) key = polygon.spine[1][1] - tree_array = self.Tree.preOrder_array((self.root), [], - key) # alle Ecken bis zum höchsten Punkt von dem neuen Polygon + tree_array = self.Tree.preOrder_array(self.root, [], key) + # tree_array holds all vertices which are already packed, visible from right and can hit the new + # polygon which will be packed to the container distance_lr_plot_helper = [] - # distanzen von links nach rechts + # find the smallest distance from left to right for vertex in tree_array: - successor = self.find_successor(vertex, polygon.vertices_left_visible) + successor = self.find_corresponding_edge(vertex, polygon.vertices_left_visible) distance = self.distance(successor, vertex) if distance <= min_horizontal_distance: min_horizontal_distance = distance - self.root = self.Tree.delete_node(self.root, vertex[1]) # deleting vertices from B + # deleting the vertex because the new polygon will cover over it + self.root = self.Tree.delete_node(self.root, vertex[1]) distance_lr_plot_helper.append((vertex, distance)) plot_steps.append( self.plot_container(sigma_plot_helper, distance_rl_plot_helper, distance_lr_plot_helper, min_horizontal_distance, render=False, title="Step {}".format(step_counter))) step_counter += 1 - polygon.translation(-(min_horizontal_distance), 0) + # after the smallest translation distance is found the polygon will be packed and the tree updated + polygon.translation(-min_horizontal_distance, 0) + # add the right_visible vertices from the new packed polygon into the tree for counter, vertex in enumerate(polygon.vertices_right_visible[0:-1]): self.root = self.Tree.insert_node(self.root, vertex[1], vertex, (polygon.vertices_right_visible[counter + 1])) @@ -494,7 +529,7 @@ class Container(object): self.x_boundary = x_boundary sigma.append(polygon) plot_steps.append(self.plot_container(sigma, render=False, title="Finished Container")) - return (sigma, plot_steps) + return sigma, plot_steps def plot_container(self, sigma=None, r_l_distances=None, l_r_distances=None, min_distance=None, render=True, title="", box_boundarys_x_values_colors_tuple=None) -> Figure: -- GitLab