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" 字符 (-
)。但是您的模式生成代码使用了一种不同的、稍长的破折号 (−
)。更改其中一个以匹配另一个(哪一个并不重要),您的代码将按预期工作。
我尝试使用 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" 字符 (-
)。但是您的模式生成代码使用了一种不同的、稍长的破折号 (−
)。更改其中一个以匹配另一个(哪一个并不重要),您的代码将按预期工作。