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
# 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
......
......@@ -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:
......
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