python 海龟图形中的奇怪 L 系统

Strange L-system in python turtle graphics

我尝试使用 Python 3 中的海龟模块来重新创建此处找到的分形: 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()

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

在此先感谢您的帮助!

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

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()

. . .

您的代码中有两个问题。

首先是您的代码没有正确处理嵌套括号。内开括号将其状态保存在看到外开括号时保存的先前状态的顶部。这对于像 [[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()

第二个问题比较琐碎。您的解析器查找 "minus" 字符 (-)。但是您的模式生成代码使用了一种不同的、稍长的破折号 ()。更改其中一个以匹配另一个(哪一个并不重要),您的代码将按预期工作。