社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

用 Python 绘制龙形曲线

Python中文社区 • 2 年前 • 873 次点击  

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

什么是龙形曲线?

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

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


如何构建龙形曲线?

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

算法

这一连串纸条的折叠模式,作为右(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()

而这将会是这样:


让它更圆

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

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

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

GitHub地址:

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

总结

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

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

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/147011
 
873 次点击