lindenmayer systems
This commit is contained in:
parent
ad318ccf54
commit
44eae1157f
|
@ -1,5 +1,6 @@
|
|||
from .device import Device
|
||||
from .drawing import Drawing
|
||||
from .lindenmayer import LSystem
|
||||
from .paths import simplify_paths, sort_paths, join_paths, load_paths
|
||||
from .planner import Planner
|
||||
from .turtle import Turtle
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
import random
|
||||
import re
|
||||
|
||||
from math import sin, cos, radians
|
||||
|
||||
from .drawing import Drawing
|
||||
|
||||
class LSystem(object):
|
||||
def __init__(self, rules):
|
||||
self.rules = rules
|
||||
self.pattern = re.compile('|'.join('(%s)' % x for x in rules))
|
||||
|
||||
def step(self, value):
|
||||
def func(match):
|
||||
rule = self.rules[match.group(0)]
|
||||
if isinstance(rule, basestring):
|
||||
return rule
|
||||
return random.choice(rule)
|
||||
return self.pattern.sub(func, value)
|
||||
|
||||
def steps(self, value, iterations):
|
||||
for i in range(iterations):
|
||||
value = self.step(value)
|
||||
return value
|
||||
|
||||
def run(self, start, iterations, angle=None):
|
||||
program = self.steps(start, iterations)
|
||||
angle = angle and radians(angle)
|
||||
state = (0.0, 0.0, 0.0)
|
||||
stack = []
|
||||
paths = []
|
||||
point = (0.0, 0.0)
|
||||
for instruction in program:
|
||||
x, y, a = state
|
||||
if instruction == '-':
|
||||
a -= angle
|
||||
elif instruction == '+':
|
||||
a += angle
|
||||
elif instruction == '[':
|
||||
stack.append(state)
|
||||
elif instruction == ']':
|
||||
x, y, a = stack.pop()
|
||||
point = (x, y)
|
||||
else:
|
||||
x += cos(a)
|
||||
y += sin(a)
|
||||
if paths and point == paths[-1][-1]:
|
||||
paths[-1].append((x, y))
|
||||
else:
|
||||
paths.append([point, (x, y)])
|
||||
point = (x, y)
|
||||
state = (x, y, a)
|
||||
return Drawing(paths)
|
|
@ -0,0 +1,21 @@
|
|||
import axi
|
||||
|
||||
def main():
|
||||
system = axi.LSystem({
|
||||
'A': 'A-B--B+A++AA+B-',
|
||||
'B': '+A-BB--B-A++A+B',
|
||||
})
|
||||
d = system.run('A', 5, 60)
|
||||
# system = axi.LSystem({
|
||||
# 'X': 'F-[[X]+X]+F[+FX]-X',
|
||||
# 'F': 'FF',
|
||||
# })
|
||||
# d = system.run('X', 6, 20)
|
||||
d = d.rotate_and_scale_to_fit(12, 8.5, step=90)
|
||||
# d = d.sort_paths()
|
||||
# d = d.join_paths(0.015)
|
||||
d.render().write_to_png('out.png')
|
||||
axi.draw(d)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue