仅使用递归和python制作Sierpinski地毯有困难吗

仅使用递归和python制作Sierpinski地毯有困难吗,python,python-3.x,recursion,turtle-graphics,fractals,Python,Python 3.x,Recursion,Turtle Graphics,Fractals,我很难只使用递归而不使用循环来绘制Sierpinski地毯。然而,在画完前三个方块后,我试着向左旋转,然后在巢址上做下两个方块,这些方块会偏离直线。如果你想,你可以试试这段代码,看看它是什么样子。顺便说一句,颜色与周围的白色和内部的黑色相反,而不是通常的地毯式黑白方块。以下是我在开始之前注意到的概念: 定义一个函数,该函数接受一个坐标和一个正方形大小,并返回周围的8个坐标 定义一个函数,该函数接受一个坐标和一个正方形大小,并绘制一个以给定大小为长度、以给定坐标为中心点的正方形 定义将采用坐标

我很难只使用递归而不使用循环来绘制Sierpinski地毯。然而,在画完前三个方块后,我试着向左旋转,然后在巢址上做下两个方块,这些方块会偏离直线。如果你想,你可以试试这段代码,看看它是什么样子。顺便说一句,颜色与周围的白色和内部的黑色相反,而不是通常的地毯式黑白方块。

以下是我在开始之前注意到的概念:

  • 定义一个函数,该函数接受一个坐标和一个正方形大小,并返回周围的8个坐标

  • 定义一个函数,该函数接受一个坐标和一个正方形大小,并绘制一个以给定大小为长度、以给定坐标为中心点的正方形

  • 定义将采用坐标、大小和递归次数的主函数。坐标将是Sierpinski地毯的中心,尺寸将是成品Sierpinski地毯的尺寸


  • 记住以上注意事项,让我们开始构建我们的程序:

    func((0, 0), 600, 5)
    turtle.update()
    
  • 导入
    海龟
    模块,关闭跟踪器(可选)以提高效率,并隐藏海龟光标:
  • 定义接受坐标和单位的函数,并返回给定坐标周围所有8个坐标的列表:
  • 定义将接受坐标、大小和计数的递归函数。它将画一个正方形,其中心在给定的坐标处,其大小为给定大小的三分之一,这样成品地毯的侧面将达到给定的大小。计数用于告诉函数何时停止递归;当计数达到
    0
    时:
  • 定义接受坐标和大小的递归函数。它将使用前面定义的
    environment
    功能将该坐标转换为环绕坐标列表。然后,它将使用前面定义的
    draw_square
    函数在每个周围坐标处绘制一个正方形:
  • 最后,调用主函数
    func
    ,并更新
    turtle
    屏幕(如果tracer设置为
    0
  • 总共:

    func((0, 0), 600, 5)
    turtle.update()
    
    输出:


    我将对您的代码做一个简化版本——尽管重复,但您的启动代码确实只实现了递归的目标。但是,我将使用冲压而不是绘图,因此我们可以关注递归图像,而不是使用海龟绘制正方形的机制:

    import turtle
    
    turtle.tracer(0)
    turtle.hideturtle()
    
    def surrounding(cor, size):
        x, y = cor
        return [(x - size, y + size),
                (x + size, y + size),
                (x - size, y - size),
                (x + size, y - size),
                (x - size, y),
                (x + size, y),
                (x, y + size),
                (x, y - size)]
    
    def draw_square(cor, size, count):
        size /= 3
        count -= 1
        turtle.penup()
        turtle.goto(cor[0] - size / 2, cor[1] + size / 2)
        turtle.pendown()
        turtle.begin_fill()
        turtle.forward(size)
        turtle.right(90)
        turtle.forward(size)
        turtle.right(90)
        turtle.forward(size)
        turtle.right(90)
        turtle.forward(size)
        turtle.right(90)
        turtle.end_fill()
        if count:
            func(surrounding(cor, size), size, count)
    
    def func(cors, size, count):
        if len(cors) == 2:
            draw_square(cors, size, count)
        else:
            draw_square(cors[0], size, count)
            draw_square(cors[1], size, count)
            draw_square(cors[2], size, count)
            draw_square(cors[3], size, count)
            draw_square(cors[4], size, count)
            draw_square(cors[5], size, count)
            draw_square(cors[6], size, count)
            draw_square(cors[7], size, count)
    
    func((0, 0), 600, 5)
    turtle.update()
    
    从海龟导入屏幕,海龟
    边长=200
    光标大小=20
    def牵引填充方形(t,侧面透镜):
    t、 形状大小(侧面/光标大小)
    t、 邮票()
    定义sier_鲤鱼(t、l、n):
    绘制填充正方形(t,l)
    如果n<1:
    返回
    x、 y=t.位置()
    t、 setx(x+l)
    鲤鱼(t,l/3,n-1)
    t、 sety(y+l)
    鲤鱼(t,l/3,n-1)
    t、 setx(x)
    鲤鱼(t,l/3,n-1)
    t、 setx(x-l)
    鲤鱼(t,l/3,n-1)
    t、 赛蒂(y)
    鲤鱼(t,l/3,n-1)
    t、 赛蒂(y-l)
    鲤鱼(t,l/3,n-1)
    t、 setx(x)
    鲤鱼(t,l/3,n-1)
    t、 setx(x+l)
    鲤鱼(t,l/3,n-1)
    t、 后藤(x,y)
    screen=screen()
    屏幕设置(宽度=1.0,高度=1.0)
    海龟
    乌龟
    龟形('square'))
    乌龟
    sier_鲤鱼(海龟,侧长,4)
    screen.exitonclick()
    
    我故意避免使用
    screen.tracer(False)
    来加快速度,因为您应该看到它是如何以逆时针模式绘制的

    我相信问题比你想的要简单。在这种绘图中,递归函数将海龟返回到函数启动时的位置非常重要。这允许调用者对其位置做出有效的假设

    def draw_square(cor, size, count):
        size /= 3
        count -= 1
        turtle.penup()
        turtle.goto(cor[0] - size / 2, cor[1] + size / 2)
        turtle.pendown()
        turtle.begin_fill()
        turtle.forward(size)
        turtle.right(90)
        turtle.forward(size)
        turtle.right(90)
        turtle.forward(size)
        turtle.right(90)
        turtle.forward(size)
        turtle.right(90)
        turtle.end_fill()
        if count:
            func(surrounding(cor, size), size, count)
    
    def func(cors, size, count):
        if len(cors) == 2:
            draw_square(cors, size, count)
        else:
            draw_square(cors[0], size, count)
            draw_square(cors[1], size, count)
            draw_square(cors[2], size, count)
            draw_square(cors[3], size, count)
            draw_square(cors[4], size, count)
            draw_square(cors[5], size, count)
            draw_square(cors[6], size, count)
            draw_square(cors[7], size, count)
    
    func((0, 0), 600, 5)
    turtle.update()
    
    import turtle
    
    turtle.tracer(0)
    turtle.hideturtle()
    
    def surrounding(cor, size):
        x, y = cor
        return [(x - size, y + size),
                (x + size, y + size),
                (x - size, y - size),
                (x + size, y - size),
                (x - size, y),
                (x + size, y),
                (x, y + size),
                (x, y - size)]
    
    def draw_square(cor, size, count):
        size /= 3
        count -= 1
        turtle.penup()
        turtle.goto(cor[0] - size / 2, cor[1] + size / 2)
        turtle.pendown()
        turtle.begin_fill()
        turtle.forward(size)
        turtle.right(90)
        turtle.forward(size)
        turtle.right(90)
        turtle.forward(size)
        turtle.right(90)
        turtle.forward(size)
        turtle.right(90)
        turtle.end_fill()
        if count:
            func(surrounding(cor, size), size, count)
    
    def func(cors, size, count):
        if len(cors) == 2:
            draw_square(cors, size, count)
        else:
            draw_square(cors[0], size, count)
            draw_square(cors[1], size, count)
            draw_square(cors[2], size, count)
            draw_square(cors[3], size, count)
            draw_square(cors[4], size, count)
            draw_square(cors[5], size, count)
            draw_square(cors[6], size, count)
            draw_square(cors[7], size, count)
    
    func((0, 0), 600, 5)
    turtle.update()
    
    from turtle import Screen, Turtle
    
    SIDE_LENGTH = 200
    CURSOR_SIZE = 20
    
    def draw_filled_square(t, side_len):
        t.shapesize(side_len / CURSOR_SIZE)
        t.stamp()
    
    def sier_carp(t, l, n):
        draw_filled_square(t, l)
        
        if n < 1:
            return
    
        x, y = t.position()
    
        t.setx(x + l)
        sier_carp(t, l/3, n - 1)
    
        t.sety(y + l)
        sier_carp(t, l/3, n - 1)
    
        t.setx(x)
        sier_carp(t, l/3, n - 1)
    
        t.setx(x - l)
        sier_carp(t, l/3, n - 1)
    
        t.sety(y)
        sier_carp(t, l/3, n - 1)
    
        t.sety(y - l)
        sier_carp(t, l/3, n - 1)
    
        t.setx(x)
        sier_carp(t, l/3, n - 1)
    
        t.setx(x + l)
        sier_carp(t, l/3, n - 1)
    
        t.goto(x, y)
    
    screen = Screen()
    screen.setup(width=1.0, height=1.0)
    
    turtle = Turtle()
    turtle.hideturtle()
    turtle.shape('square')
    turtle.penup()
    
    sier_carp(turtle, SIDE_LENGTH, 4)
    
    screen.exitonclick()