使用海龟图形和递归的希尔伯特曲线

Posted

技术标签:

【中文标题】使用海龟图形和递归的希尔伯特曲线【英文标题】:Hilbert curve using turtle graphics and recursion 【发布时间】:2019-04-14 02:25:31 【问题描述】:

我正在尝试实现 L 系统生成的希尔伯特曲线,利用 python 海龟图形和递归。我的代码似乎适用于递归 n=1 和 n=2 的前两个级别,但除此之外,图形只是纠缠在一起(尽管我能够观察其中的更多模块),我似乎无法掌握这里可能有什么问题,我是否需要一些中间步骤来重新生成希尔伯特模块以进行更深层次的递归?请看我下面的代码,比较简单:

import turtle

def Hilbert_curve(A,rule,t,n):

    if n>=1:
        if rule:
            t.left(90)
            Hilbert_curve(A,not rule,t, n-1)
            t.forward(A)
            t.right(90)
            Hilbert_curve(A, rule,t, n-1)
            t.forward(A)
            Hilbert_curve(A,rule,t, n-1)
            t.right(90)
            t.forward(A)
            Hilbert_curve(A,not rule,t, n-1)
            t.left(90)
        else:
            t.right(90)
            Hilbert_curve(A,rule,t, n-1)
            t.forward(A)
            t.left(90)
            Hilbert_curve(A,not rule,t, n-1)
            t.forward(A)
            Hilbert_curve(A,not rule,t, n-1)
            t.left(90)
            t.forward(A)
            Hilbert_curve(A, rule,t, n-1)
            t.right(90)

def main():
    A=10
    t=turtle.Turtle()
    my_win=turtle.Screen()
    n=2
    rule=True
    Hilbert_curve(A,rule,t,n)
    my_win.exitonclick()

main()

Hilbert n=2

Hilbert n=3

【问题讨论】:

如果你喜欢 R,这里是一行代码 n=scan();a=1+1i;b=1-1i;z=0;for(k in 1:n)z=c((w<-1i*Conj(z))-a,z-b,z+a,b-w)/2;plot(z,t="s") 只需在 for 循环中更改 n,例如for(k in 1:5)z=...这并不能解决您的问题,但以防万一您想四处看看:) 嗯,我不熟悉 R,所以我不太明白你的代码行是什么,但我会检查一下 【参考方案1】:

问题在于您的else 子句。 rule 已经倒置到函数中,因此您需要将 rule 视为与 then 子句相同:

    else:
        t.right(90)
        Hilbert_curve(A, not rule, t, n - 1)
        t.forward(A)
        t.left(90)
        Hilbert_curve(A, rule, t, n - 1)
        t.forward(A)
        Hilbert_curve(A, rule, t, n - 1)
        t.left(90)
        t.forward(A)
        Hilbert_curve(A, not rule, t, n - 1)
        t.right(90)

但是,如果我们将 rule 从布尔值更改为数字 parity,即 1 或 -1,然后将 parity 乘以角度,我们可以消除原来的两个子句之一if声明:

from turtle import Screen, Turtle

def hilbert_curve(turtle, A, parity, n):

    if n < 1:
        return

    turtle.left(parity * 90)
    hilbert_curve(turtle, A, - parity, n - 1)
    turtle.forward(A)
    turtle.right(parity * 90)
    hilbert_curve(turtle, A, parity, n - 1)
    turtle.forward(A)
    hilbert_curve(turtle, A, parity, n - 1)
    turtle.right(parity * 90)
    turtle.forward(A)
    hilbert_curve(turtle, A, - parity, n - 1)
    turtle.left(parity * 90)

screen = Screen()

yertle = Turtle()
yertle.speed('fastest')  # because I have no patience

hilbert_curve(yertle, 10, 1, 4)

screen.exitonclick()

【讨论】:

谢谢,这很好用。谢谢你给我奇偶变量的想法,我以前没有考虑过。我的想法是为 L-System 中给出的两个生成规则生成两个案例。您的奇偶校验解决方案更加优雅

以上是关于使用海龟图形和递归的希尔伯特曲线的主要内容,如果未能解决你的问题,请参考以下文章

递归的入门介绍

Android UI贝塞尔曲线 ⑥ ( 贝塞尔曲线递归算法原理 | 贝塞尔曲线递归算法实现 )

JavaScript图形实例:Levy曲线及其变形

JavaScript图形实例:Koch曲线

排序(选择插入希尔)

8种面试经典!排序详解--选择,插入,希尔,冒泡,堆排,3种快排,快排非递归,归并,归并非递归,计数(图+C语言代码+时间复杂度)