#! /usr/bin/env python3 import numpy as np from math import pi, tan, sqrt, sin, cos import inkex from Path import Path from Pattern import Pattern class Hypar(Pattern): def __init__(self): Pattern.__init__(self) # Must be called in order to parse common options self.add_argument("-p", "--pattern", default="template1", help="Origami pattern") self.add_argument("--radius", type=float, default=10.0, help="Radius of tower (mm)") self.add_argument("--sides", type=int, default=4, help="Number of polygon sides") self.add_argument("--rings", type=int, default=7, help="Number of rings") self.add_argument("--simplify_center", type=inkex.Boolean, default=0, help="Simplify center") def generate_path_tree(self): """ Specialized path generation for your origami pattern """ # retrieve saved parameters unit_factor = self.calc_unit_factor() vertex_radius = self.options.vertex_radius * unit_factor pattern = self.options.pattern radius = self.options.radius * unit_factor sides = self.options.sides rings = self.options.rings simplify_center = self.options.simplify_center sin_ = sin(pi / float(sides)) a = radius*sin_ # half of length of polygon side H = radius*sqrt(1 - sin_**2) polygon = Path.generate_polygon(sides, radius, 'e') # # OLD diagonals generation with universal creases # diagonals = [] # for i in range(sides): # diagonals.append(Path([(0, 0), polygon.points[i]], 'u')) # points = [(x, y) for x, y in polygon.points] # diagonals = diagonals + [Path.generate_separated_paths(points, 'm')] # # modify center if needed # if simplify_center: # for i in range(sides): # if i % 2 == 0: # p2 = diagonals[i].points[1] # diagonals[i].points[0] = (1. / (rings + 1) * p2[0], 1. / (rings + 1) * p2[1]) # separate generic closed ring to create edges self.edge_points = polygon.points # vertex and diagonal lines creation vertex_line = [] diagonal_line = [] for i in range(1, rings + 2): y1 = a * (float(i - 1) / (rings + 1.)) x1 = H * float(i - 1) / (rings + 1.) y2 = a * (float(i) / (rings + 1.)) x2 = H * float(i) / (rings + 1.) vertex_line.append((Path((x2, y2), style='p', radius=vertex_radius))) diagonal_line.append((Path([(x1, y1), (x2, y2)], style='m' if i % 2 else 'v'))) # rotation of vertices and diagonals for completing the drawing diagonals = [] vertices = [Path((0, 0), style='p', radius=vertex_radius)] for i in range(sides): vertices = vertices+Path.list_rotate(vertex_line, i * 2 * pi / float(sides)) diagonals = diagonals+[Path.list_rotate(diagonal_line, i * 2 * pi / float(sides))] # modify center if needed if simplify_center: for i in range(sides): if i % 2 == 0: del diagonals[i][0] # inkex.debug(len(diagonals)) # inkex.debug(len(diagonals[0])) # diagonals = diagonals + diagonal # scale generic closed ring to create inner rings inner_rings = [] for i in range(rings + 1): inner_rings.append(polygon * (float(i)/(rings+1))) inner_rings[i].style = 'v' if i % 2 else 'm' # create points for zig zag pattern zig_zags = [] if pattern != "classic": zig_zag = [] for i in range(1, rings + 1): y_out = a * ((i + 1.) / (rings + 1.)) y_in = a * (float(i) / (rings + 1.)) x_out = H * (i + 1.) / (rings + 1.) x_in = H * float(i) / (rings + 1.) if pattern == "alternate_asymmetric" and i % 2: zig_zag.append(Path([(x_in, -y_in), (x_out, +y_out)], style='u')) else: zig_zag.append(Path([(x_in, +y_in), (x_out, -y_out)], style='u')) # reflect zig zag pattern to create all sides zig_zags.append(zig_zag) for i in range(sides - 1): points = diagonals[i][0].points zig_zags.append(Path.list_reflect(zig_zags[i], points[0], points[1])) self.translate = (radius, radius) self.path_tree = [diagonals, zig_zags, inner_rings, vertices] # Main function, creates an instance of the Class and calls inkex.affect() to draw the origami on inkscape if __name__ == '__main__': Hypar().run()