def generate_fused_edge_points(self, base, middle, cell_data): unit_factor = self.calc_unit_factor() base_height = self.options.base_height * unit_factor distance = self.options.distance * unit_factor rows = self.options.rows edges = [] if self.options.add_base_slot: edges.append(base['left'][0]) for i in range(rows): cell_left = cell_data['edge_left'][i] dx = cell_data['dx'][i] edges.append(cell_left + (dx, cell_data['dy'][i] + base_height + i * distance)) if self.options.add_middle_slot and i < rows - 1: edges.append(middle['left'][i] + (0, 0)) if self.options.add_base_slot: edges.append(base['left'][1]) if self.options.add_base_slot: edges.append(base['right'][0]) for i in range(rows): cell_right = cell_data['edge_right'][-(i + 1)] dx = cell_data['dx'][-(i + 2)] edges.append(cell_right + (dx, cell_data['dy'][rows - i - 1] + base_height + (rows - i - 1) * distance)) if self.options.add_middle_slot and i < rows - 1: edges.append(middle['right'][i] + (0, 0)) if self.options.add_base_slot: edges.append(base['right'][1]) return Path.get_points(edges)
def generate_path_tree(self): """ Specialized path generation for your origami pattern """ # retrieve conversion factor for selected unit unit_factor = self.calc_unit_factor() # retrieve saved parameters, and apply unit factor where needed inverted = self.options.inverted sign = -1 if inverted else 1 single_stroke = self.options.single_stroke radius_external = self.options.radius_external * unit_factor radius_type = self.options.radius_type radius_ratio = self.options.radius_ratio radius_internal = radius_external / radius_ratio if inverted else radius_external * radius_ratio # dradius = abs(radius_external-radius_internal) sides = self.options.sides connector_length = self.options.connector_length * unit_factor connector_thickness = self.options.connector_thickness * unit_factor head_length = self.options.head_length * unit_factor head_thickness = self.options.head_thickness * unit_factor angle = pi / sides length_external = 2 * radius_external * sin(angle) length_internal = length_external / radius_ratio if inverted else length_external * radius_ratio external_points = [ (-length_external / 2, 0), (-connector_thickness / 2, 0), (-connector_thickness / 2, -connector_length * sign), (-connector_thickness / 2 - head_thickness / 2, -connector_length * sign), (-connector_thickness / 2, -(connector_length + head_length) * sign), (0, -(connector_length + head_length) * sign), (+connector_thickness / 2, -(connector_length + head_length) * sign), (+connector_thickness / 2 + head_thickness / 2, -connector_length * sign), (+connector_thickness / 2, -connector_length * sign), (+connector_thickness / 2, 0), (length_external / 2, 0) ] internal_points = [(0, 0), (length_internal, 0)] external_lines_0 = Path(external_points, 'm') + (length_external / 2, 0) external_lines = [external_lines_0] for i in range(sides - 1): x, y = external_lines[-1].points[-1] external_lines.append(external_lines_0 * (1, 2 * (i + 1) * angle) + (x, y)) if single_stroke: external_lines = Path(Path.get_points(external_lines), 'm') self.path_tree = [external_lines] if self.options.radius_draw == True: # center point of main strokes outer_average = Path.get_average_point(external_lines) if radius_type == 'polygonal': internal_lines_0 = Path(internal_points, 'm') internal_lines = [internal_lines_0] for i in range(sides - 1): x, y = internal_lines[-1].points[-1] internal_lines.append(internal_lines_0 * (1, 2 * (i + 1) * angle) + (x, y)) # move to center inner_average = Path.get_average_point(internal_lines) delta = ((outer_average[0] - inner_average[0]), (outer_average[1] - inner_average[1])) if single_stroke: internal_lines = Path(Path.get_points(internal_lines), 'm') internal_lines = Path.list_add(internal_lines, delta) elif radius_type == 'circular': internal_lines = Path(outer_average, radius=radius_internal, style='m') self.path_tree.append(internal_lines)
def generate_path_tree(self): """ Specialized path generation for your origami pattern """ # zero distances when slot option not selected if not self.options.add_base_slot: self.options.base_height = 0 self.options.base_slot_height = 0 if not self.options.add_middle_slot: self.options.distance = 0 self.options.middle_slot_height = 0 if self.options.base_height == 0: self.options.add_base_slot = False if self.options.distance == 0: self.options.add_middle_slot = False self.parse_parameters() # pre-calculate width before adding one to sides, for easier attachment self.options.width = 2 * self.options.radius * sin( pi / self.options.sides) self.options.cols = self.options.sides + self.options.extra_column # get cell definitions cell_data = self.generate_cell() # calculate divider if it doesn't exist if 'divider' not in cell_data: points = Path.get_points(cell_data['interior']) x = [p[0] for p in points if p[1] == 0] cell_data['divider'] = Path([(min(x), 0), (max(x), 0)], style='m') points = Path.get_points(cell_data['divider']) x = [p[0] for p in points] DX = max(x) - min(x) # DX = 0 # if 'edge_right' not in cell_data and 'edge_left' not in cell_data: # cell_data['edge_left'] = [] # for interior in cell_data['interior']: # points = Path.get_points(interior) # x = [p[0] for p in points] # y = [p[1] for p in points] # top = [p for p in points if p[1] == min(y)] # top_x = [p[0] for p in top] # # top_y = [p[1] for p in top] # bot = [p for p in points if p[1] == max(y)] # bot_x = [p[0] for p in bot] # # bot_y = [p[1] for p in bot] # top_left = [p for p in top if p[0] == min(top_x)][0] # bot_left = [p for p in bot if p[0] == min(bot_x)][0] # cell_data['edge_left'].append(Path([top_left, bot_left], 'e')) if 'edge_right' not in cell_data and 'edge_left' in cell_data: cell_data['edge_right'] = [] for edge_left in cell_data['edge_left']: edge_right = edge_left + (DX, 0) edge_right.invert() cell_data['edge_right'].append(edge_right) if 'edge_right' in cell_data and 'edge_left' not in cell_data: cell_data['edge_left'] = [] for edge_right in cell_data['edge_right']: edge_left = edge_right + (-DX, 0) edge_left.invert() cell_data['edge_left'].append(edge_left) cell_data['dx'], cell_data['dy'] = self.get_dxdy(cell_data) # get all slots and vertical dividers between slots base, middle = self.generate_all_slots(cell_data) slots = [[base['slots'], middle['slots']]] # get horizontal dividers between cells dividers = self.generate_horizontal_dividers(cell_data) # finish by replicating the actual interior interior = self.generate_interior(cell_data) # use slots and cell data to create the full edge paths self.edge_points = self.generate_fused_edge_points( base, middle, cell_data) self.path_tree = [dividers, interior] if len(self.vertex_points) == 0: self.vertex_points = Path.get_points(self.path_tree) self.path_tree.append(slots)