奇怪的L系统在蟒蛇图形中

时间:2016-03-26 04:45:59

标签: python python-3.x fractals l-systems

我尝试使用Python 3中的turtles模块重新创建此处的分形: https://en.wikipedia.org/wiki/L-system#Example_7:_Fractal_plant 但每当我尝试它时,它给我一个非常奇怪的结果......

这是我的代码:

import turtle
wn = turtle.Screen()
wn.bgcolor("white")
wn.screensize(10000, 10000)

tess = turtle.Turtle()
tess.color("lightgreen")
tess.pensize(1)
tess.speed(0)
tess.degrees()

inst = 'X'
steps = 3

for counter in range(steps):
    _inst = ''
    for chtr in inst:
        if chtr == 'X':
            _inst += 'F−[[X]+X]+F[+FX]−X'
        elif chtr == 'F':
            _inst += 'FF'
        else:
            _inst += chtr
    inst = _inst
    print(inst)


for chtr in inst:
    if (chtr == 'F'):
        tess.forward(25)
    elif (chtr == '+'):
        tess.right(25)
    elif (chtr == '-'):
        tess.left(25)
    elif (chtr == '['):
        angle = tess.heading()
        pos = [tess.xcor(), tess.ycor()]
    elif (chtr == ']'):
        tess.setheading(angle)
        tess.penup()
        tess.goto(pos[0], pos[1])
        tess.pendown()
wn.exitonclick()

我对所有内容进行了三重检查,但我似乎没有错误 - 但它仍然无效。我做错了什么?

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

根据维基百科页面,符号'['表示保存当前状态(角度位置)。匹配']'表示恢复先前保存的位置。因为'['和']'可以嵌套,所以需要堆栈。

from collections import deque

...

stack = deque()

for chtr in inst:
    if (chtr == 'F'):
        tess.forward(25)

    elif (chtr == '+'):
        tess.right(25)

    elif (chtr == '-'):
        tess.left(25)

    elif (chtr == '['):
        angle = tess.heading()
        pos = [tess.xcor(), tess.ycor()]
        stack.append((angle, pos))         ### New statement

    elif (chtr == ']'):
        angle, pos = stack.pop()           ### New statement
        tess.setheading(angle)
        tess.penup()
        tess.goto(pos[0], pos[1])
        tess.pendown()

. . .

答案 1 :(得分:1)

您的代码中存在两个问题。

首先,您的代码无法正确处理嵌套括号。当看到外部开口支架时,内部开口支架将其状态保存在保存的先前状态的顶部上方。这对于像[[X]+X]这样的直接嵌套括号无关紧要(因为它们具有相同的起始状态),但是一旦你得到更复杂的嵌套(就像你将在几个替换循环之后),问题就开始变得棘手了错。

要解决此问题,您可能希望将已保存的状态值存储到堆栈中(list可以执行此操作)。按下要保存的值,然后在准备好恢复它们时将其弹出。

stack = [] # use a list for the stack
for chtr in inst:
    if (chtr == 'F'):
        tess.forward(25)
    elif (chtr == '+'):
        tess.right(25)
    elif (chtr == '-'):
        tess.left(25)
    elif (chtr == '['):
        angle = tess.heading()
        pos = [tess.xcor(), tess.ycor()]
        stack.append((angle, pos)) # push state to save
    elif (chtr == ']'):
        angle, pos = stack.pop()  # pop state to restore
        tess.setheading(angle)
        tess.penup()
        tess.goto(pos[0], pos[1])
        tess.pendown()

第二个问题更为微不足道。您的解析器会查找“减号”字符(-)。但是,您的模式生成代码使用了另一种稍长的破折号()。更改其中一个以匹配另一个(这并不重要),您的代码将按预期工作。