diff --git a/mysite/plots/packing_algo.py b/mysite/plots/packing_algo.py index 4c05687e50f5de8c1a5881b1492dab786a7fbfc2..d791ef49409772fdd77ed6e009f4f631e1ba9dd6 100644 --- a/mysite/plots/packing_algo.py +++ b/mysite/plots/packing_algo.py @@ -13,7 +13,7 @@ from shapely import affinity # plotting packages from bokeh.plotting import figure, Figure from bokeh.io import output_notebook, show -from bokeh.layouts import gridplot, layout, column, Column +from bokeh.layouts import gridplot, layout, column, Column, Row from bokeh.models import Div from bokeh.models import Legend from bokeh.models import BoxAnnotation @@ -535,7 +535,7 @@ class Container(object): 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: + title="", box_boundaries_x_values_colors_tuple=None) -> Figure: """Creates a plot object of the actual container Args: @@ -547,7 +547,7 @@ class Container(object): min_distance (float): the minimal distance from all distances right to left and left to right render (bool): if True the plot will be also rendered else not title (str): the title of the plot default "" - box_boundarys_x_values_colors_tuple (([float],[color])): the boundary x values for the boxes and their + box_boundaries_x_values_colors_tuple (([float],[color])): the boundary x values for the boxes and their background color, the boxes will later be extended to the mini-containers Returns: @@ -580,12 +580,12 @@ class Container(object): # mark the boxes with their background color, these boxes will later be extend to mini-containers if title == "": fig.title.text = 'Hc_{}-Container height: {} '.format(self.hc.i, truncate(self.y_boundary, 1)) - if box_boundarys_x_values_colors_tuple is not None: - box_boundarys_x_values = box_boundarys_x_values_colors_tuple[0] - background_c_list = box_boundarys_x_values_colors_tuple[1] - for counter, boundary in enumerate(box_boundarys_x_values[0:-1]): - next_boundary = box_boundarys_x_values[counter + 1] - color_box = BoxAnnotation(bottom=0, top=self.y_boundary, left=box_boundarys_x_values[counter], + if box_boundaries_x_values_colors_tuple is not None: + box_boundaries_x_values = box_boundaries_x_values_colors_tuple[0] + background_c_list = box_boundaries_x_values_colors_tuple[1] + for counter, boundary in enumerate(box_boundaries_x_values[0:-1]): + next_boundary = box_boundaries_x_values[counter + 1] + color_box = BoxAnnotation(bottom=0, top=self.y_boundary, left=box_boundaries_x_values[counter], right=next_boundary, fill_color=background_c_list[counter], fill_alpha=0.1) fig.add_layout(color_box) fig.line([next_boundary, next_boundary], [0, self.y_boundary], line_dash="dotted") @@ -960,70 +960,104 @@ class RectangularContainer(object): class ConvexContainer(object): + """Convex Container which holds the packed polygons + + To build the convex container the convex input polygons will be rotated with an negative angle = -gamma and packed + to a RectangularContainer. + After packing the RectangularContainer its border and all polygons from it will be rotated back with the angle + positive gamma. These rotation, packing and back rotation steps will be done several times by incrementing the angle + to find the smallest ConvexContainer. The angle should be between 0 <= |gamma| < 360 to prevent repetition of the + ConvexContainers. Smaller gamma increments means more repetitions to find the ConvexContainer but the chance to + skip the smallest ConvexContainer is lower. + + Example: + gamma=10° increments:=0°,10°,20° ...350° -> 36 times doing the 3 steps rotating ( with -gamma), packing to Rect- + angularContainer and back rotating (with gamma) of the convex input polygons, + between the increments could be some angle like 8° where we miss the smallest ConvexContainer. + + Args: + polygons ([ConvexPolygon]): convex input polygons to pack into the smallest ConvexContainer + steps (int): the angle for the rotation and backrotation increments + Attributes: + angle_0_rectangular_container (ConvexContainer): the input polygons packed to a not rotated RectangularContainer + angle_0_rectangular_container_polygons ([ConvexPolygon]): the polygons of the 0° RectangularContainer + rotate_center (float): the center for rotating the polygons, the center of the 0° RectangularContainer + rotated_rectangular_container_list ([EndContainer]): the list of all packed RectangularContainers + rotated_container_plots (Column): plot object which include all packed RectangularContainers + back_rotated_polygons_plots (Column): plot object which include all back rotated RectangularContainers + smallest_rectangular_container (EndContainer): smallest RectangularContainer (ConvexContainer) + polygons ([ConvexPolygon]): the polygon of the smallest RectangularContainer (ConvexContainer) + angle (int): the angle of the smallest RectangularContainer (ConvexContainer) + area (float): the area of the smallest RectangularContainer (ConvexContainer) + polygon_shells ([[Point_xy]]): the shells of the polygons in the smallest RectangularContainer (ConvexContainer) + width (float): the width of the ConvexContainer + height (float): the height of the ConvexContainer + boundary_x_values ([float]): the x values of the ConvexContainer boundary + boundary_y_values ([float]): the y values of the ConvexContainer boundary + plot_steps_all (Tabs): all steps of building the smallest RectangularContainer (ConvexContainer) and + including all rotated and back rotated RectangularContainers + """ def __init__(self, polygons: [ConvexPolygon], steps=90, build_plots=True) -> None: - self.angle_0_end_container = pack_polygons(polygons) - self.angle_0_end_container_polygons = self.angle_0_end_container.polygons - self.rotate_center = (self.angle_0_end_container.x_boundary / 2, self.angle_0_end_container.y_boundary / 2) - self.rotated_end_container_list = [] # Liste aller RectangularContainer + self.angle_0_rectangular_container = pack_polygons(polygons) + self.angle_0_rectangular_container_polygons = self.angle_0_rectangular_container.polygons + self.rotate_center = (self.angle_0_rectangular_container.x_boundary / 2, + self.angle_0_rectangular_container.y_boundary / 2) + self.rotated_rectangular_container_list = [] # Liste aller RectangularContainer self.rotated_container_plots = [] self.back_rotated_polygons_plots = [] - self.smallest_end_container, self.polygons, self.angle, self.area = self.find_convex_container(steps, - build_plots) + self.smallest_rectangular_container, self.polygons, self.angle, self.area = self.find_convex_container(steps,build_plots) self.polygon_shells = self.collect_polygon_shells() - self.width = self.smallest_end_container.x_boundary - self.height = self.smallest_end_container.y_boundary - self.boundarys_x_values, self.boundarys_y_values = self.set_boundarys() + self.width = self.smallest_rectangular_container.x_boundary + self.height = self.smallest_rectangular_container.y_boundary + self.boundary_x_values, self.boundary_y_values = self.set_boundaries() self.plot_steps_all = self.build_plot_steps() - def build_plot_steps(self): - convex_c_panels = [] - smallest_c = self.plot_container(render=False, plot_width=800, plot_height=700) - smallest_c_tab = Panel(child=smallest_c, title="Smallest-Convex-Container") - convex_c_panels.append(smallest_c_tab) - - rotated_c = self.plot_rotated_containers(render=False, plot_width=800, plot_height=700) - rotated_c_tab = Panel(child=rotated_c, title="Rotated-Rectangular-Containers") - convex_c_panels.append(rotated_c_tab) - - back_rotated_c = self.plot_back_rotated_polygons(render=False, plot_width=800, plot_height=700) - back_rotated_c_tab = Panel(child=back_rotated_c, title="Convex-Containers (back rotated)") - convex_c_panels.append(back_rotated_c_tab) - - tabs = Tabs(tabs=convex_c_panels) - t_header = Panel(child=tabs, title="Convex-Container") # - tab_header = self.smallest_end_container.plot_steps(render=False) - tab_header.tabs.append(t_header) - return tab_header + def find_convex_container(self, steps: int, build_plots=True) -> (RectangularContainer, [ConvexPolygon], int, + float): + """Finds the ConvexContainer and collects the steps as plot objects - def plot_steps(self, render=True): - if render: - show(self.plot_steps_all) - return self.plot_steps_all + To find the convex container the convex input polygons will be rotated with an negative angle=-gamma and packed + to a RectangularContainer. + After packing the RectangularContainer its border and all polygons from it will be rotated back with the angle + positive gamma. The RectangularContainer with the smallest area is the ConvexContainer result. - def find_convex_container(self, steps: int, build_plots=True) -> (RectangularContainer, [ConvexPolygon], int, float): + Args: + steps (int): the increment steps (degree) for rotating the polygons + build_plots (bool): if True all the RectangularContainer plot steps which will be done to find the Convex- + Container will be collected that means even the RectangularContainers which are not the + smallest will be back rotated and a plot object will created + -> more redundant steps and worse performance but winning more information + else no plot objects for the steps are build -> just the end ConvexContainer and his + polygons can be plotted + Returns: + smallest_container (RectangularContainer): the smallest RectangularContainer not back rotated + smallest_back_rotated_polygons: the polygons of the smallest RectangularContainer back rotated which are + building the ConvexContainer by adding the boundary + abs_angle (int): the rotation angle of the smallest RectangularContainer (ConvexContainer) + smallest_area (float): the area of the smallest RectangularContainer (ConvexContainer) + """ list_of_area = [] - polygons = [] for angle in range(0, 360, steps): - polygons = rotate_polygons(self.angle_0_end_container_polygons, -angle, origin=self.rotate_center) - rotated_end_container = pack_polygons(polygons, -angle) - # rotated_end_container.angle=angle - self.rotated_end_container_list.append(rotated_end_container) - list_of_area.append(rotated_end_container) - if build_plots: # das Flag ist aus Performance gründen da sonst wird jeder Rectangular-Container zurück rotiert + polygons = rotate_polygons(self.angle_0_rectangular_container_polygons, -angle, origin=self.rotate_center) + rotated_rectangular_container = pack_polygons(polygons, -angle) + self.rotated_rectangular_container_list.append(rotated_rectangular_container) + list_of_area.append(rotated_rectangular_container) + if build_plots: title = 'Rectangular-Container area: {} not-clipped-area: {} angle: {}'.format( - truncate(rotated_end_container.container_area, 1), - truncate(rotated_end_container.container_not_clipped_area, 1), rotated_end_container.angle) - self.rotated_container_plots.append(rotated_end_container.plot_container(render=False, title=title)) - back_rotated_polygons = rotate_polygons(rotated_end_container.polygons, angle, + truncate(rotated_rectangular_container.container_area, 1), + truncate(rotated_rectangular_container.container_not_clipped_area, 1), + rotated_rectangular_container.angle) + self.rotated_container_plots.append(rotated_rectangular_container.plot_container(render=False, title=title)) + back_rotated_polygons = rotate_polygons(rotated_rectangular_container.polygons, angle, origin=self.rotate_center) # kreiert neue Polygone - box_x_v = rotated_end_container.x_values_border - box_y_v = rotated_end_container.y_values_border - boundarys = list(zip(box_x_v, box_y_v)) - rotated_x_values, rotated_y_values = rotate_points_and_split(boundarys, angle, + box_x_v = rotated_rectangular_container.x_values_border + box_y_v = rotated_rectangular_container.y_values_border + boundaries = list(zip(box_x_v, box_y_v)) + rotated_x_values, rotated_y_values = rotate_points_and_split(boundaries, angle, origin=self.rotate_center) title2 = 'Convex-Container area: {} not-clipped-area: {} angle: {}'.format( - truncate(rotated_end_container.container_area, 1), - truncate(rotated_end_container.container_not_clipped_area, 1), -rotated_end_container.angle) + truncate(rotated_rectangular_container.container_area, 1), + truncate(rotated_rectangular_container.container_not_clipped_area, 1), -rotated_rectangular_container.angle) back_rotated_polygon_plot = plot_polygons_in_single_plot(back_rotated_polygons, render=False, border=(rotated_x_values, rotated_y_values), title=title2) @@ -1034,54 +1068,179 @@ class ConvexContainer(object): smallest_container_polygons = sorted_container[0].polygons smallest_back_rotated_polygons = rotate_polygons(smallest_container_polygons, angle, origin=self.rotate_center) smallest_area = smallest_container.container_area - return (smallest_container, smallest_back_rotated_polygons, abs(angle), smallest_area) + abs_angle = abs(angle) + return smallest_container, smallest_back_rotated_polygons, abs_angle, smallest_area - def collect_polygon_shells(self): + def collect_polygon_shells(self) -> [[Point_xy]]: + """Collects the polygon shells of all packed polygons in the ConvexContainer + + Returns: + polygon_shells ([[Point_xy]]): polygon shells of all packed polygons in the ConvexContainer + """ polygon_shells = [] for polygon in self.polygons: polygon_shells.append(polygon.shell) return polygon_shells - def set_boundarys(self) -> ([Point_xy], [Point_xy]): - container = self.smallest_end_container - boundarys_x_values = [0, 0, self.width, self.width, 0] - boundarys_y_values = [0, self.height, self.height, 0, 0] - boundarys = list(zip(boundarys_x_values, boundarys_y_values)) - rotated_x_values, rotated_y_values = rotate_points_and_split(boundarys, container.angle, + def set_boundaries(self) -> ([Point_xy], [Point_xy]): + """Sets the boundaries for the ConvexContainer + + Returns: + rotated_x_values, rotated_y_values ([Point_xy], [Point_xy]): x and y values of the boundary in a tuple + """ + container = self.smallest_rectangular_container + boundary_x_values = [0, 0, self.width, self.width, 0] + boundary_y_values = [0, self.height, self.height, 0, 0] + boundaries = list(zip(boundary_x_values, boundary_y_values)) + rotated_x_values, rotated_y_values = rotate_points_and_split(boundaries, container.angle, origin=self.rotate_center) - return (rotated_x_values, rotated_y_values) + return rotated_x_values, rotated_y_values + + def build_plot_steps(self) -> Tabs: + """ + Build the plot object with all steps to build the smallest RectangularContainer and all rotated Rectangular- + Containers and back rotated polygons - def plot_rotated_containers(self, render=True, colums=9, plot_width=600, plot_height=600) -> Column: + Returns: + tab_header (Tabs): a plot object which is organized with tabs + """ + convex_c_panels = [] + smallest_c = self.plot_container(render=False, plot_width=800, plot_height=700) + smallest_c_tab = Panel(child=smallest_c, title="Smallest-Convex-Container") + convex_c_panels.append(smallest_c_tab) + + rotated_c = self.plot_rotated_containers(render=False, plot_width=800, plot_height=700) + rotated_c_tab = Panel(child=rotated_c, title="Rotated-Rectangular-Containers") + convex_c_panels.append(rotated_c_tab) + + back_rotated_c = self.plot_back_rotated_polygons(render=False, plot_width=800, plot_height=700) + back_rotated_c_tab = Panel(child=back_rotated_c, title="Convex-Containers (back rotated)") + convex_c_panels.append(back_rotated_c_tab) + + tabs = Tabs(tabs=convex_c_panels) + t_header = Panel(child=tabs, title="Convex-Container") # + tab_header = self.smallest_rectangular_container.plot_steps(render=False) + tab_header.tabs.append(t_header) + return tab_header + + def plot_steps(self, render=True) -> Tabs: + """Plot including the ConvexContainer, rotated RectangularContainers and back rotated polygons + + Args: + render (bool): if True render the plot else not + + Returns: + plot_steps_all (Tabs): a plot object which is organized with tabs + """ + if render: + show(self.plot_steps_all) + return self.plot_steps_all + + def plot_rotated_containers(self, render=True, colums=9, plot_width=600, plot_height=600) -> Row: + """Plot including all rotated RectangularContainers + + Args: + render (bool): if True render the plot else not + colums (int): the colum count in which the container plots will be rendered + plot_width (int): the width of the plot figure + plot_height (int): the height of the plot figure + + Returns: + grid (Row): grid plot including all rotated RectangularContainers + """ grid = gridplot(self.rotated_container_plots, ncols=colums, plot_width=plot_width, plot_height=plot_height, toolbar_location="left") if render: show(grid) return grid - def plot_back_rotated_polygons(self, render=True, colums=9, plot_width=700, plot_height=600) -> Column: + def plot_back_rotated_polygons(self, render=True, colums=9, plot_width=700, plot_height=600) -> Row: + """Plot including all back rotated polygons of the RectangularContainers + + Args: + render (bool): if True render the plot else not + colums (int): the colum count in which the container plots will be rendered + plot_width (int): the width of the plot figure + plot_height (int): the height of the plot figure + + Returns: + grid (Row): grid plot including all back rotated polygons of the RectangularContainers + """ grid = gridplot(self.back_rotated_polygons_plots, ncols=colums, plot_width=plot_width, plot_height=plot_height, toolbar_location="left") if render: show(grid) return grid - def plot_container(self, title="", plot_width=600, plot_height=600, render=True, reverse_legend=True) -> Figure: + def plot_container(self, title="", plot_width=600, plot_height=600, render=True) -> Figure: + """Plot of the ConvexContainer + + Args: + title (str): the title of the ConvexContainer + plot_width (int): width of the plot figure + plot_height (int): height of the plot figure + render (bol): if True the plot will be rendered else not + + Returns: + fig (Figure): ConvexContainer plot object + """ if title == "": title = 'Convex Container area: {} not-clipped-area: {} angle: {}'.format( - truncate(self.smallest_end_container.container_area, 1), - truncate(self.smallest_end_container.container_not_clipped_area, 1), self.angle) + truncate(self.smallest_rectangular_container.container_area, 1), + truncate(self.smallest_rectangular_container.container_not_clipped_area, 1), self.angle) fig = plot_polygons_in_single_plot(self.polygons, title=title, plot_width=plot_width, plot_height=plot_height, - render=render, border=(self.boundarys_x_values, self.boundarys_y_values)) + render=render, border=(self.boundary_x_values, self.boundary_y_values)) return fig def rotate_points_and_split(point_list: [Point_xy], angle, origin=(0, 0)) -> ([float], [float]): + """Rotates the input points and give a tuple with x and y values back + + Uses the affinity.rotated function from the shapely package which creates a dependency, another way would be to use + a own function (rotation matrix). + + Hint: + when writing an own function to rotate the points, their are some special cases in python which need to be + handled, + + this is a code snipped from the shapely package to show these cases + code snipped from: https://github.com/Toblerity/Shapely/blob/master/shapely/affinity.py + angle = angle * pi/180.0 + cosp = cos(angle) + sinp = sin(angle) + if abs(cosp) < 2.5e-16: # if not checked this case could create confusion + cosp = 0.0 + if abs(sinp) < 2.5e-16: # if not checked this case could create confusion + sinp = 0.0 + + Args: + point_list ([Point_xy]): a list of points which need to be rotated + angle (int): the rotation angle + origin (float): the rotation point for all rotations + + Returns: + poly_wrapper_rotated.exterior.xy (([float], [float])): tuple with rotated x and y values + """ + # wrapping the points into a shapely Polygon to use the rotation function poly_wrapper = Polygon(point_list) poly_wrapper_rotated = affinity.rotate(poly_wrapper, angle, origin=origin) return poly_wrapper_rotated.exterior.xy def rotate_and_create_new_convex_polygon(polygon: ConvexPolygon, angle: int, origin=(0, 0)) -> ConvexPolygon: + """Creates a new rotated convex polygon from an input convex polygon + + This function uses again the affinity.rotate() function from shapely. + This creates a dependency to the shapely package. + + Args: + polygon (ConvexPolygon): convex polygon which will "copied" and rotated + angle (int): the rotation angle + origin (float): the rotation point for all vertex rotations + + Returns: + rotated_convex_polygon (ConvexPolygon): rotated convex polygon + """ poly_wrapper = Polygon(polygon.shell) poly_wrapper_rotated = affinity.rotate(poly_wrapper, angle, origin=origin) rotated_convex_polygon = ConvexPolygon(poly_wrapper_rotated.exterior.coords) @@ -1089,6 +1248,16 @@ def rotate_and_create_new_convex_polygon(polygon: ConvexPolygon, angle: int, ori def rotate_polygons(polygons: [ConvexPolygon], angle: int, origin=(0, 0)) -> [ConvexPolygon]: + """Creates several new rotated convex polygons + + Args: + polygons ([ConvexPolygon]): convex polygons which will "copied" and rotated + angle (int): the rotation angle + origin (float): the rotation point for all vertex rotations + + Returns: + rotated_polygons ([ConvexPolygon]): rotated convex polygons + """ rotated_polygons = [] for polygon in polygons: rotated_polygon = rotate_and_create_new_convex_polygon(polygon, angle, origin) @@ -1097,6 +1266,21 @@ def rotate_polygons(polygons: [ConvexPolygon], angle: int, origin=(0, 0)) -> [Co def build_mini_containers_and_plots(container_array: [Container], c=2.214) -> ([MiniContainer], [[Figure]]): + """Divides a Container into boxes and creates mini-containers by extending these + + This function also creates plot objects for every important step to build the mini-containers. + + Args: + container_array ([Container]): a list of all container every container is build from a highclass + c (float): the values which decides the width of the mini-containers for more information look into the paper + + Returns: + mini_container_array, mini_container_plots_list ([MiniContainer], [[Figure]]): a tuple of all build + mini-containers and all import + plot steps, every list of plots + represent a Container and the + resulting mini-containers + """ mini_container_array = [] mini_container_plots_list = [] colors = itertools.cycle(palette) @@ -1106,65 +1290,60 @@ def build_mini_containers_and_plots(container_array: [Container], c=2.214) -> ([ container_and_mini_container_plots = [] box_width = c * container.hc.w_max_polygon box_width_helper = 0 - box_counter = 1 # hilft dabei wie oft der Container in Mini-Container geteilt wird - box_boundarys_x_values = [] - # für den plot die grenzen der miniboxen herauszufinden + box_counter = 1 # helper for dividing the container into boxes + box_boundaries_x_values = [] + # finding the box boundaries for plot while box_width_helper < container.x_boundary: - box_boundarys_x_values.append(box_width_helper) + box_boundaries_x_values.append(box_width_helper) box_width_helper += box_width background_color_list.append(next(colors)) - box_boundarys_x_values_colors_tuple = (box_boundarys_x_values, background_color_list) + box_boundaries_x_values_colors_tuple = (box_boundaries_x_values, background_color_list) container_and_mini_container_plots.append(container.plot_container(container_sigma, render=False, - box_boundarys_x_values_colors_tuple=box_boundarys_x_values_colors_tuple)) # will added to the plots + box_boundaries_x_values_colors_tuple= + box_boundaries_x_values_colors_tuple)) max_width_mini_container = box_width + container.hc.w_max_polygon background_counter = 0 - # wichtig zu kucken ob der container noch Polygone enthält da die linkesten Punkte noch in der anderen Box liegen können und eine Box leer sein kann - # while len(container_sigma) > 0 and (box_width * box_counter) < (container.x_boundary): while len(container_sigma) > 0: - mini_container = MiniContainer(max_width_mini_container, (container.y_boundary), - container.hc.w_max_polygon, container.hc.i) - translation = box_width * (box_counter - 1) + mini_container = MiniContainer(max_width_mini_container, container.y_boundary, + container.hc.w_max_polygon, container.hc.i) min_translation = math.inf mini_container_y_border = 0 mini_container_x_border = 0 - # new - pop_list = [] # enthält die counter der Polygone die zur box gehören + pop_list = [] # holds the indices of polygons which are assigned to the box for counter, polygon in enumerate(container_sigma): if polygon.min_x < (box_width * box_counter): pop_list.append(counter) if polygon.min_x < min_translation: min_translation = polygon.min_x - # selbst wenn man das 0 Element poped gibt es keine Probleme pop_helper = 0 - if pop_list != []: + # translating the polygons assigned the the box and adding them to the mini container + if pop_list: for counter in pop_list: - container_sigma[counter - pop_helper].translation(-min_translation, 0) # new + container_sigma[counter - pop_helper].translation(-min_translation, 0) if mini_container_y_border < container_sigma[counter - pop_helper].max_y: mini_container_y_border = container_sigma[counter - pop_helper].max_y if mini_container_x_border < container_sigma[counter - pop_helper].max_x: mini_container_x_border = container_sigma[counter - pop_helper].max_x mini_container.polygons.append(container_sigma.pop(counter - pop_helper)) pop_helper += 1 - # mini_container.plot_container() mini_container.height = mini_container_y_border mini_container.current_right_boundary = mini_container_x_border mini_container_array.append(mini_container) if (box_width * box_counter) < (container.x_boundary): title = "Mini-Container{} height: {} (hc_{})".format(box_counter, truncate(mini_container.height, 1), container.hc.i) - b_color = background_color_list[background_counter] # ---- + b_color = background_color_list[background_counter] container_and_mini_container_plots.append( mini_container.plot_container(title=title, render=False, background_c=b_color)) box_counter += 1 background_counter += 1 - # für die kürzere box + # for the smaller box else: title = "Mini-Container{} height: {} (hc_{})".format(box_counter, truncate(mini_container.height, 1), container.hc.i) - # mini_container.plot_container(title)- container_and_mini_container_plots.append(mini_container.plot_container(title=title, render=False)) mini_container_plots_list.append(container_and_mini_container_plots) - return (mini_container_array, mini_container_plots_list) + return mini_container_array, mini_container_plots_list def plot_mini_containers(plot_steps: [[Figure]], render=True, colums=3, plot_width=600, plot_height=600) -> Column: @@ -1302,7 +1481,7 @@ def pack_polygons(polygons: [ConvexPolygon], angle=0) -> RectangularContainer: list_hc = build_height_classes(polygons) list_containers = building_containers(list_hc) list_mini_containers, mini_container_plot_steps = build_mini_containers_and_plots(list_containers) - end_container = RectangularContainer(list_mini_containers, angle) + rectangular_container = RectangularContainer(list_mini_containers, angle) # plots p_tab = polygons_to_tab_plot(polygons) @@ -1313,12 +1492,12 @@ def pack_polygons(polygons: [ConvexPolygon], angle=0) -> RectangularContainer: c_header_tab = Panel(child=c_tab, title="Containers") mc_tab = mini_container_plots_to_tab_plot(mini_container_plot_steps) mc_header_tab = Panel(child=mc_tab, title="Mini-Containers") - ec_tab = end_container_to_tab_plot(end_container) + ec_tab = rectangular_container_to_tab_plot(rectangular_container) ec_header_tab = Panel(child=ec_tab, title="Rectangular-Container") all_tabs_with_header = Tabs(tabs=[p_header_tab, hc_header_tab, c_header_tab, mc_header_tab, ec_header_tab]) - end_container.plot_steps_all = all_tabs_with_header - return end_container + rectangular_container.plot_steps_all = all_tabs_with_header + return rectangular_container def polygons_to_tab_plot(polygons: [ConvexPolygon], tab_poly_count=9, ncols=3, plot_width=450, plot_height=450) -> Tabs: @@ -1382,15 +1561,15 @@ def mini_container_plots_to_tab_plot(mini_container_plot_steps: [Figure], plot_w return mini_tabs -def end_container_to_tab_plot(end_container: RectangularContainer, plot_width=800, plot_height=800) -> Tabs: - end_container_tabs = [] - polygons_plot = end_container.plot_polygons(render=False, plot_width=plot_width, plot_height=plot_height) +def rectangular_container_to_tab_plot(rectangular_container: RectangularContainer, plot_width=800, plot_height=800) -> Tabs: + rectangular_container_tabs = [] + polygons_plot = rectangular_container.plot_polygons(render=False, plot_width=plot_width, plot_height=plot_height) tab = Panel(child=polygons_plot, title="Rectangular-Container") - end_container_tabs.append(tab) - container_plot = end_container.plot_container(render=False, plot_width=plot_width, plot_height=plot_height) + rectangular_container_tabs.append(tab) + container_plot = rectangular_container.plot_container(render=False, plot_width=plot_width, plot_height=plot_height) tab = Panel(child=container_plot, title="Show Mini-Containers") - end_container_tabs.append(tab) - end_tabs = Tabs(tabs=end_container_tabs) + rectangular_container_tabs.append(tab) + end_tabs = Tabs(tabs=rectangular_container_tabs) return end_tabs diff --git a/mysite/plots/templates/plots/packed_polygons.html b/mysite/plots/templates/plots/packed_polygons.html index 6584979bee2f8bbdebbd2f179d366d89e49716e2..97e35ffd41d3bcdb2f190db14e6d4dcaf1ac19dd 100644 --- a/mysite/plots/templates/plots/packed_polygons.html +++ b/mysite/plots/templates/plots/packed_polygons.html @@ -19,7 +19,7 @@ </div> <div> <h1>Final Container Polygons Coordinates</h1> -<p>every Row stands for one Polygon<p> +<p>every List stands for one Polygon<p> {% for polygon in coordinates%} {{polygon}}<br> {%endfor%}</div>