谢尔平斯基三角形使用和递归函数



我试图理解递归函数,它们看起来很复杂。到目前为止,我唯一了解的是,它们需要是一个基本情况,并且是基于归纳证明的。程序员如何看待简单的基本情况是迄今为止无法思考的。示例分形在一本书中仅使用一行基本情况求解。在谢尔平斯基三角形中,我需要很多行代码。好吧,现在我接近它,但仍然遥不可及。下面是适用于订单 0 和 1 的代码,但对于更高的订单,它增加了更多空间。我知道这不是pythonic代码,但这是我能写的最好的代码。

import math, turtle
window=turtle.Screen()
window.title('Sierpinski')
window.bgcolor('lightblue')
alex=turtle.Turtle()
def sierpinski(a,t,size):
if a==0:
for i in range(3):
t.forward(size)
t.left(120)
else:
sierpinski(a-1,t,size/3)
t.forward(size/3)
sierpinski(a-1,t,size/3)
t.forward(size/3)
t.left(120)
t.forward(size/3)
sierpinski(a-1,t,size/3)
t.forward(size/3)
t.left(120)
t.forward(size*2/3)
t.left(120)
sierpinski(3,alex,200)
window.mainloop()

是的,有点长,我的思维过程仍然不清楚

  1. 谁能解释一下我的代码有什么问题?
  2. 如何让它变得更有pythonic?

好的,我在视频的帮助下找到了如何做到这一点,它指示我将其分成两半而不是三分之一。

所以代码应该是

import math, turtle
window=turtle.Screen()
window.title('Sierpinski')
window.bgcolor('lightblue')
alex=turtle.Turtle()
def sierpinski(a,t,size):
if a==0:
for i in range(3):
t.forward(size)
t.left(120)
else:
sierpinski(a-1,t,size/2)
t.forward(size/2)
sierpinski(a-1,t,size/2)
t.forward(size/2)
t.left(120)
t.forward(size/2)
sierpinski(a-1,t,size/2)
t.forward(size/2)
t.left(120)
t.forward(size)
t.left(120)
sierpinski(3,alex,200)
window.mainloop()

但是代码可以更简洁吗?

编辑

这就足够了:

def sierpinski(a, t, size):
half = size / 2
if a >= 0:
sierpinski(a-1, t, half)
t.forward(half)
sierpinski(a-1, t, half)
t.forward(half)
t.left(120)
t.forward(half)
sierpinski(a-1, t, half)
t.forward(half)
t.left(120)
t.forward(size)
t.left(120)

这是有效的if因为块的末端else都在绘制三角形(else块只是为了移动光标,但仍然如此(,但else块进行了递归调用。

为了使它"更pythonic">,你可以把它们全部放到一个类中:

class SierpinskiTurtle(turtle.Turtle):
def sierpinski(self, depth, size):
half = size / 2
if depth >= 0:
self.sierpinski(depth-1, half)
self.forward(half)
self.sierpinski(depth-1, half)
self.forward(half)
self.left(120)
self.forward(half)
self.sierpinski(depth-1, half)
self.forward(half)
self.left(120)
self.forward(size)
self.left(120)
alex = SierpinskiTurtle()
alex.sierpinski(3, 200)

我们可以使用冲压而不是绘图来使sierpinski()功能更简单、更快捷:

from turtle import Turtle, Screen
CURSOR_SIZE = 20
def sierpinski(depth, turtle, size):
turtle.shapesize(size / CURSOR_SIZE)
turtle.stamp()
if depth < 1:
return
half = size / 2
circumradius = half * 3 ** 0.5 / 3
for _ in range(3):
turtle.forward(circumradius)  # to
sierpinski(depth - 1, turtle, half)
turtle.backward(circumradius)  # and fro
turtle.left(120)
window = Screen()
window.mode('logo')  # make 0 degrees straight up
window.title('Sierpinski')
window.bgcolor('lightblue')
alex = Turtle('triangle')
alex.fillcolor(window.bgcolor())
alex.penup()
sierpinski(3, alex, 300)
alex.hideturtle()
window.mainloop()

这也具有将三角形绘制在屏幕上而不是偏向一侧的优点。 通过让光标围绕三角形的内半径以圆形方式移动,而不是围绕中心来回移动,可以进一步优化绘图。

最新更新