用 Python 绘制龙形曲线

本文将学习什么是龙形曲线,如何生成龙形曲线,以及如何在Python中创建龙形曲线。

dbcbfe44e3079d9efecaa7f550752717.png

什么是龙形曲线?

龙形曲线是一个分形,在数学中,分形是一个术语,用来描述在任意小的尺度上包含详细结构的几何形状。许多分形在不同的尺度上看起来很相似,如曼德勃罗集的连续放大,如图所示。

66a0755412f326ed9256d58ba159ed95.gif

龙形曲线可能最常被认为是由反复对折的纸条产生的形状,尽管还有其他被称为龙形曲线的曲线是以不同方式产生的。

bd8068f05e4ad61ef80e1298c02adce4.gif

如何构建龙形曲线?

龙形曲线可以通过折叠纸条来构建,这也是最初发现龙形曲线的方法。拿一张纸条,将其向右对折。再把它向右折成两半。如果现在把纸条打开,把每个折痕都解开,变成一个90度的转弯,转弯的顺序就是RRL,也就是龙形曲线的第二次迭代。再把条状物向右对折,展开后的条状物的转弯顺序现在是RRLRRLL —— 龙形曲线的第三次迭代。继续将条状物向右对折,创造出更多迭代的曲线。

cf511fc0cdd2a67feb7ff51e5d1a54a4.png

502f07e21405685ce686bf6dafc5ffaf.png

扫描二维码关注公众号,回复: 15202025 查看本文章

算法

这一连串纸条的折叠模式,作为右(R)和左(L)折叠的序列,是。

  • 第一次迭代:R

  • 第二次迭代:R R L

  • 第三次迭代:R R L R L L

  • 第四次迭代:R R L R L R R L L R R L L

每个迭代都可以通过复制前一个迭代,得到一个R,然后按相反的顺序复制前一个迭代的第二个副本,L和R字母互换。

用 Python 进行实现

让我们一步步地分解这个算法。下面就是该算法:每个迭代都可以通过复制前一个迭代,然后得到一个R,然后是前一个迭代的第二个副本,顺序相反,L和R的字母互换。

步骤:

1、每个迭代都可以通过复制前一个迭代来找到。

sequence = sequence

2、得到R

sequence = sequence+R

3、然后以相反的顺序复制前一次迭代的第二个副本,L和R字母互换。

sequence = sequence+R+swapLetters(sequence[::-1])

如果我们把这一切放在一个Python函数中,我们会得到以下结果:

R = "R"
L = "L"

def iterate(sequence: str) -> str:
    sequence = sequence+R+swapLetters(sequence[::-1])
    return sequence
    
def swapLetters(sequence: str) -> str:
    newSequence = ""
    for letter in sequence:
        if letter == R:
            newSequence = newSequence + L
        else:
            newSequence = newSequence + R
    return newSequence

我们可以创建另一个函数来生成一个特定的迭代,像这样:

def dragon(n_iterations: int) -> str:
    """Takes in a number n, an return the dragon curve sequence i.e.:
    When n=2, returns "RRL"

    Args:
        n_iterations (int): number of iterations of the dragon curve

    Returns:
        str: The dragon curve Sequence
    """
    initial_sequence = R
    for i in range(0, n_iterations):
        initial_sequence = iterate(initial_sequence)
    return initial_sequence

我们可以把所有东西放在一个名为dragon.py的python文件中。

让我们来实现图形

为了实现图形,我们将使用一个叫做turtle的python模块,它提供了海龟图形基础。

1、导入库

from dragon import dragon, R
from turtle import Turtle, Screen

2、Turtle 设置。在这里,我们定义了Turtle 的绘制速度,龙形曲线的颜色,然后我们隐藏Turtle。

# Turtle Setup
turtle = Turtle("turtle")
turtle.hideturtle()
turtle.speed("fastest")
turtle.color("#ff69aa")

3、屏幕设置。我们添加一个标题,一个背景颜色,然后是屏幕大小(调整turtle画布的大小),以及设置,即设置主窗口的大小和位置。

# Screen Setup
screen = Screen()
screen.title("Dragon Curve")
screen.bgcolor("black")
screen.screensize(1920*3, 1080*3)
screen.setup(width=1.0, height=1.0, startx=None, starty=None)

4、绘制龙形曲线。在这里,我们遍历从dragon(17)得到的序列,即第17个序列,根据字母是R还是L,我们向右或向左走。

# Draw
LENGTH = 10
turtle.forward(LENGTH)
for element in dragon(17):
    if element == R:
        turtle.right(90)
        turtle.forward(LENGTH)
    else:
        turtle.left(90)
        turtle.forward(LENGTH)

5、完成后要退出程序。

turtle.color("white")
turtle.write("click to exit", font=("Calibri", 16, "bold"))
screen.exitonclick()

最终结果

如果我们把所有的东西放在两个文件里,我们会得到。

dragon.py

R = "R"
L = "L"

def iterate(sequence: str) -> str:
    sequence = sequence+R+swapLetters(sequence[::-1])
    return sequence


def swapLetters(sequence: str) -> str:
    newSequence = ""
    for letter in sequence:
        if letter == R:
            newSequence = newSequence + L
        else:
            newSequence = newSequence + R
    return newSequence


def dragon(n_iterations: int) -> str:
    initial_sequence = R
    for i in range(0, n_iterations):
        initial_sequence = iterate(initial_sequence)
    return initial_sequence

app.py

from dragon import dragon, R
from turtle import Turtle, Screen

# Turtle setup
turtle = Turtle("turtle")
turtle.hideturtle()
turtle.speed("fastest")
turtle.color("#ff69aa")

# Screen setup
screen = Screen()
screen.title("Dragon Curve")
screen.bgcolor("black")
screen.screensize(1920*3, 1080*3)
screen.setup(width=1.0, height=1.0, startx=None, starty=None)


# Draw
LENGTH = 10
turtle.forward(LENGTH)
for element in dragon(17):
    if element == R:
        turtle.right(90)
        turtle.forward(LENGTH)
    else:
        turtle.left(90)
        turtle.forward(LENGTH)

# When finished, click to exit
turtle.color("white")
turtle.write("click to exit", font=("Calibri", 16, "bold"))
screen.exitonclick()

而这将会是这样:

cecb8f3097a02dfb94e228a04043fb88.png

7e99fc49d2fe152f837ec59a2aed9c19.gif

让它更圆

如果你喜欢,可以改变风格,不使用直线,而是使用圆形,只需改变以下代码。

# Draw
LENGTH = 10
for element in dragon(17):
    if element == R:
        turtle.circle(-4, 90, 36)
    else:
        turtle.circle(4, 90, 36)

447f95faa75069906583bc036cb9c7ad.gif

而最终的结果将如下图所示:

10b3872e04310040d3152ef2626e936e.png

GitHub地址:

https://github.com/francofgp/dragon-curve

总结

乍一看似乎很难的东西原来很简单,通过一步步的分解,我们已经学会了如何在Python中轻松地创建这个惊人的分形。

0d6a89f3b8f5934f7e934bce699909d7.jpeg

- 点击下方阅读原文加入社区会员 -

猜你喜欢

转载自blog.csdn.net/BF02jgtRS00XKtCx/article/details/126791603
今日推荐