Skip to content
Snippets Groups Projects
Commit f8afede6 authored by tolgayurt's avatar tolgayurt
Browse files

refactored the packing_container function and chaned vertice to vertex

avl_tree.py
parent 1d28871c
No related branches found
No related tags found
No related merge requests found
...@@ -9,10 +9,10 @@ import sys ...@@ -9,10 +9,10 @@ import sys
# Create a tree node # Create a tree node
class TreeNode(object): class TreeNode(object):
def __init__(self, key, vertice, vertice_neighbour): def __init__(self, key, vertex, vertex_neighbour):
self.key = key self.key = key
self.vertice = vertice self.vertex = vertex
self.vertice_neighbour = vertice_neighbour self.vertex_neighbour = vertex_neighbour
self.left = None self.left = None
self.right = None self.right = None
self.height = 1 self.height = 1
...@@ -20,30 +20,30 @@ class TreeNode(object): ...@@ -20,30 +20,30 @@ class TreeNode(object):
class AVLTree(object): class AVLTree(object):
def find_edges(self, root, key, vertice_top): def find_edges(self, root, key, vertex_top):
if not root: if not root:
return vertice_top return vertex_top
elif key < root.key: elif key < root.key:
vertice_top = root vertex_top = root
return self.find_edges(root.left, key, vertice_top) return self.find_edges(root.left, key, vertex_top)
elif key == root.key: elif key == root.key:
return root return root
else: 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 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
vertice_top = TreeNode(key, (0, key), (0, 0)) vertex_top = TreeNode(key, (0, key), (0, 0))
return self.find_edges(root.right, key, vertice_top) return self.find_edges(root.right, key, vertex_top)
# return ("test",vertice_top) # return ("test",vertex_top)
# Function to insert a node # 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 # Find the correct location and insert the node
if not root: if not root:
return TreeNode(key, vertice, vertice_neighbour) return TreeNode(key, vertex, vertex_neighbour)
elif key < root.key: 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: 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), root.height = 1 + max(self.getHeight(root.left),
self.getHeight(root.right)) self.getHeight(root.right))
...@@ -87,8 +87,8 @@ class AVLTree(object): ...@@ -87,8 +87,8 @@ class AVLTree(object):
return temp return temp
temp = self.getMinValueNode(root.right) temp = self.getMinValueNode(root.right)
root.key = temp.key root.key = temp.key
root.vertice = temp.vertice root.vertex = temp.vertex
root.vertice_neighbour = temp.vertice_neighbour root.vertex_neighbour = temp.vertex_neighbour
root.right = self.delete_node(root.right, root.right = self.delete_node(root.right,
temp.key) temp.key)
if root is None: if root is None:
...@@ -168,7 +168,7 @@ class AVLTree(object): ...@@ -168,7 +168,7 @@ class AVLTree(object):
return return
# print("{0} ".format(root.key), end="") # print("{0} ".format(root.key), end="")
if root.key <= key: if root.key <= key:
array.append((root.vertice)) array.append((root.vertex))
self.preOrder_array(root.left, array, key) self.preOrder_array(root.left, array, key)
self.preOrder_array(root.right, array, key) self.preOrder_array(root.right, array, key)
return array return array
......
...@@ -426,30 +426,60 @@ class Container(object): ...@@ -426,30 +426,60 @@ class Container(object):
distance = math.sqrt((intersection_point[0] - point[0]) ** 2 + (intersection_point[1] - point[1]) ** 2) distance = math.sqrt((intersection_point[0] - point[0]) ** 2 + (intersection_point[1] - point[1]) ** 2)
return distance 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): for counter, top_edge_vertex in enumerate(vertices_visible_left):
if top_edge_vertex[1] >= vertex[1]: if top_edge_vertex[1] >= vertex[1]:
bottom_edge_vertex = vertices_visible_left[counter - 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]): def packing_container(self, hc_spine_ordered_polygons: [ConvexPolygon]) -> ([ConvexPolygon], [Figure]):
hc_polygons = copy.deepcopy(hc_spine_ordered_polygons) # n """Packs the spine ordered polygons into the container by translating them to the correct place
sigma_plot_helper = [] # holds the Polygons before their translation to next polygon in sigma
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 step_counter = 0
sigma = [] sigma = []
plot_steps = [] plot_steps = []
for polygon in hc_polygons: for polygon in hc_polygons:
sigma_plot_helper.append(polygon) sigma_plot_helper.append(polygon)
if sigma == []: if not sigma: # first polygon will be packed
transform_x = -polygon.min_x transform_x = -polygon.min_x
transform_y = -polygon.min_y transform_y = -polygon.min_y
polygon.translation(transform_x, transform_y) polygon.translation(transform_x, transform_y)
polygon_vertices = len(polygon.vertices_right_visible) polygon_vertices = len(polygon.vertices_right_visible)
# filling the tree with all vertices visible form right of the first polygon # filling the tree with all vertices visible form right of the first polygon
for count in range(0, polygon_vertices - 1): for count in range(0, polygon_vertices - 1):
vertice = polygon.vertices_right_visible[count] vertex = polygon.vertices_right_visible[count]
vertice_neighbour = polygon.vertices_right_visible[count + 1] vertex_neighbour = polygon.vertices_right_visible[count + 1]
self.root = self.Tree.insert_node(self.root, vertice[1], vertice, vertice_neighbour) self.root = self.Tree.insert_node(self.root, vertex[1], vertex, vertex_neighbour)
sigma.append(polygon) sigma.append(polygon)
self.x_boundary += polygon.width self.x_boundary += polygon.width
plot_steps.append( plot_steps.append(
...@@ -461,32 +491,37 @@ class Container(object): ...@@ -461,32 +491,37 @@ class Container(object):
polygon.translation(transform_x, transform_y) polygon.translation(transform_x, transform_y)
min_horizontal_distance = math.inf min_horizontal_distance = math.inf
distance_rl_plot_helper = [] distance_rl_plot_helper = []
# distanzen von rechts nach links # find the smallest distance from right to left
for vertex in polygon.vertices_left_visible: for vertex in polygon.vertices_left_visible:
vertex_y = vertex[1] 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) 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) distance = self.distance(corresponding_edge_points, vertex)
if distance <= min_horizontal_distance: if distance <= min_horizontal_distance:
min_horizontal_distance = distance min_horizontal_distance = distance
distance_rl_plot_helper.append((vertex, distance)) distance_rl_plot_helper.append((vertex, distance))
key = polygon.spine[1][1] key = polygon.spine[1][1]
tree_array = self.Tree.preOrder_array((self.root), [], tree_array = self.Tree.preOrder_array(self.root, [], key)
key) # alle Ecken bis zum höchsten Punkt von dem neuen Polygon # 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 = [] distance_lr_plot_helper = []
# distanzen von links nach rechts # find the smallest distance from left to right
for vertex in tree_array: 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) distance = self.distance(successor, vertex)
if distance <= min_horizontal_distance: if distance <= min_horizontal_distance:
min_horizontal_distance = 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)) distance_lr_plot_helper.append((vertex, distance))
plot_steps.append( plot_steps.append(
self.plot_container(sigma_plot_helper, distance_rl_plot_helper, distance_lr_plot_helper, self.plot_container(sigma_plot_helper, distance_rl_plot_helper, distance_lr_plot_helper,
min_horizontal_distance, render=False, title="Step {}".format(step_counter))) min_horizontal_distance, render=False, title="Step {}".format(step_counter)))
step_counter += 1 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]): for counter, vertex in enumerate(polygon.vertices_right_visible[0:-1]):
self.root = self.Tree.insert_node(self.root, vertex[1], vertex, self.root = self.Tree.insert_node(self.root, vertex[1], vertex,
(polygon.vertices_right_visible[counter + 1])) (polygon.vertices_right_visible[counter + 1]))
...@@ -494,7 +529,7 @@ class Container(object): ...@@ -494,7 +529,7 @@ class Container(object):
self.x_boundary = x_boundary self.x_boundary = x_boundary
sigma.append(polygon) sigma.append(polygon)
plot_steps.append(self.plot_container(sigma, render=False, title="Finished Container")) 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, 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: title="", box_boundarys_x_values_colors_tuple=None) -> Figure:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment