diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:24:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:24:48 +0000 |
commit | cca66b9ec4e494c1d919bff0f71a820d8afab1fa (patch) | |
tree | 146f39ded1c938019e1ed42d30923c2ac9e86789 /share/extensions/lindenmayer.py | |
parent | Initial commit. (diff) | |
download | inkscape-12fc8abae6d434cac7670a59ed3a67301cc2eb10.tar.xz inkscape-12fc8abae6d434cac7670a59ed3a67301cc2eb10.zip |
Adding upstream version 1.2.2.upstream/1.2.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'share/extensions/lindenmayer.py')
-rwxr-xr-x | share/extensions/lindenmayer.py | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/share/extensions/lindenmayer.py b/share/extensions/lindenmayer.py new file mode 100755 index 0000000..04e896a --- /dev/null +++ b/share/extensions/lindenmayer.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python +# coding=utf-8 +# +# Copyright (C) 2005 Aaron Spike, aaron@ekips.org +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# + +import random +import inkex +from inkex import turtle as pturtle + + +class Lindenmayer(inkex.GenerateExtension): + def add_arguments(self, pars): + pars.add_argument("--tab") + pars.add_argument("--order", type=int, default=3, help="number of iteration") + pars.add_argument( + "--langle", type=float, default=16.0, help="angle for turning left" + ) + pars.add_argument( + "--rangle", type=float, default=16.0, help="angle for turning right" + ) + pars.add_argument("--step", type=float, default=25.0, help="step size") + pars.add_argument( + "--randomizestep", type=float, default=0.0, help="randomize step" + ) + pars.add_argument( + "--randomizeangle", type=float, default=0.0, help="randomize angle" + ) + pars.add_argument("--axiom", default="++F", help="initial state of system") + pars.add_argument( + "--rules", default="F=FF-[-F+F+F]+[+F-F-F]", help="replacement rules" + ) + self.stack = [] + self.turtle = pturtle.pTurtle() + + def iterate(self): + self.rules = dict( + [ + map((lambda s: s.strip()), i.split("=")) + for i in self.options.rules.upper().split(";") + if i.count("=") == 1 + ] + ) + string = self.__recurse(self.options.axiom.upper(), 0) + self.__compose_path(string) + return self.turtle.getPath() + + def __compose_path(self, string): + self.turtle.pu() + point = self.svg.namedview.center + self.turtle.setpos(point) + self.turtle.pd() + for c in string: + if c in "ABCDEF": + self.turtle.pd() + self.turtle.fd( + self.options.step + * (random.normalvariate(1.0, 0.01 * self.options.randomizestep)) + ) + elif c in "GHIJKL": + self.turtle.pu() + self.turtle.fd( + self.options.step + * (random.normalvariate(1.0, 0.01 * self.options.randomizestep)) + ) + elif c == "+": + self.turtle.lt( + self.options.langle + * (random.normalvariate(1.0, 0.01 * self.options.randomizeangle)) + ) + elif c == "-": + self.turtle.rt( + self.options.rangle + * (random.normalvariate(1.0, 0.01 * self.options.randomizeangle)) + ) + elif c == "|": + self.turtle.lt(180) + elif c == "[": + self.stack.append([self.turtle.getpos(), self.turtle.getheading()]) + elif c == "]": + self.turtle.pu() + pos, heading = self.stack.pop() + self.turtle.setpos(pos) + self.turtle.setheading(heading) + + def __recurse(self, rule, level): + level_string = "" + for c in rule: + if level < self.options.order: + try: + level_string = level_string + self.__recurse( + self.rules[c], level + 1 + ) + except KeyError: + level_string = level_string + c + else: + level_string = level_string + c + return level_string + + def generate(self): + self.options.step = self.svg.unittouu(str(self.options.step) + "px") + sty = { + "stroke-linejoin": "miter", + "stroke-width": str(self.svg.unittouu("1px")), + "stroke-opacity": "1.0", + "fill-opacity": "1.0", + "stroke": "#000000", + "stroke-linecap": "butt", + "fill": "none", + } + return inkex.PathElement(style=str(inkex.Style(sty)), d=self.iterate()) + + +if __name__ == "__main__": + Lindenmayer().run() |