#! /usr/bin/env python3 import inkex import numpy as np from math import pi, sin, cos from Path import Path from Pattern import Pattern # Select name of class, inherits from Pattern # TODO: # 1) Implement __init__ method to get all custom options and then call Pattern's __init__ # 2) Implement generate_path_tree to define all of the desired strokes class PleatCircular(Pattern): def __init__(self): Pattern.__init__(self) self.add_argument("-p", "--pattern", default="pleat_circular", help="Origami pattern") self.add_argument("--radius", type=float, default=55.0, help="Radius of circle") self.add_argument("--ratio", type=float, default=0.4, help="Opening ratio") self.add_argument("--rings", type=int, default=15, help="Number of rings") self.add_argument("--simulation_mode", type=inkex.Boolean, default=True, help="Approximate circle and draw semicreases for simulation?") self.add_argument("--sides", type=int, default=20, help="Number of sides for polygon approximating half circle") def generate_path_tree(self): """ Specialized path generation for your origami pattern """ # retrieve saved parameters unit_factor = self.calc_unit_factor() R = self.options.radius * unit_factor ratio = self.options.ratio r = R * ratio rings = self.options.rings dr = (1.-ratio)*R/rings self.translate = (R, R) if not self.options.simulation_mode: inner_circles = [] for i in range(1, rings): inner_circles.append(Path((0, 0), radius=r + i*dr, style='m' if i % 2 else 'v')) edges = [Path((0, 0), radius=R, style='e'), Path((0, 0), radius=r, style='e')] self.path_tree = [inner_circles, edges] # append semicreases for simulation else: sides = self.options.sides dtheta = pi / sides # create diagonals diagonals = [] for i in range(sides): p1 = (0, 0) p2 = (R * cos((1 + i * 2) * dtheta), R * sin((1 + i * 2) * dtheta)) diagonals.append(Path([p1, p2], 'u')) s = sin(dtheta) c = cos(dtheta) # Edge paths = [Path([(c * R, -s * R), (R, 0), (c * R, s * R)], style='e'), Path([(c * r, -s * r), (r, 0), (c * r, s * r)], style='e')] # MV circles for i in range(1, rings): r_i = r + i * dr paths.append(Path([(c * r_i, -s * r_i), (r_i, 0), (c * r_i, s * r_i)], style='m' if i % 2 else 'v')) # Semicreases top = [] bottom = [] for i in range(rings + 1): r_i = r + i*dr top.append((r_i*(1 + (i % 2)*(c-1)), -(i % 2)*s*r_i)) bottom.append((r_i*(1 + (i % 2)*(c-1)), (i % 2)*s*r_i)) paths = paths + [Path([(r, 0), (R, 0)], 's'), # straight line 1 Path([(r*c, r*s), (R*c, R*s)], 's', invert=True), # straight line 2 Path(top, 's'), # top half of semicrease pattern Path(bottom, 's')] # bottom half of semicrease pattern all_paths = [paths] for i in range(1, sides): all_paths.append(Path.list_rotate(all_paths[0], i*2*dtheta)) self.path_tree = all_paths # Main function, creates an instance of the Class and calls inkex.affect() to draw the origami on inkscape if __name__ == '__main__': PleatCircular().run()