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