112 lines
4.6 KiB
Python
112 lines
4.6 KiB
Python
#! /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() |