使用Python绘制海威的龙曲线

简介|龙曲线

null

龙曲线是一种递归的非相交曲线,也称为哈特-海威龙或侏罗纪公园龙曲线。这是一条数学曲线,可以用林登迈耶系统等递归方法来近似。 林登迈耶系统: Lindenmayer系统,也称为L系统,是一种可以用来生成分形的字符串重写系统。两个主要领域包括分形的生成和植物的真实建模。Lindenmayer系统以一系列被称为公理的符号开始,并将一组用于重写公理的产生式规则应用于公理。递归L-系统更有趣,因为它用自身的副本和额外的东西来替换符号。L系统遵循一些规则:

An L-system is a formal grammar consisting of 4 parts:
1. A set of variables: symbols that can be replaced by production rules.
2. A set of constants: symbols that do not get replaced.e.g: !, [, ], +, -.
3. A single axiom: a string & is the initial state of the system.
4. A set of production rules: defining the way/rule variables can be replaced.

让我们以以下L系统为例:

L-系统规则

递归L-系统
公理 skk
规则 s=ksk
第一代: (ksk)kk=kskkk
第二代: k(ksk)kkk=kkskkkk
第三代: kk(ksk)kkkk=kkkkkkkkkk
gen 1 takes help of gen 0 (axiom)
generation 1 -> apply rule in generation 0
generation 0 = skk
replace s with "ksk" in gen 0 to get gen 1
gen 1 = (s)kk = (ksk)kk = kskskk
replace s with "ksk" in gen 1 to get gen 2
Iterate the same rule for all generations

递归L-系统通常会产生复杂的模式,这些模式在多个尺度上是自相似的。这些复杂的模式可以通过应用于基于海龟图形的L系统的图形解释来可视化。当L系统与海龟图形一起使用时,海龟的状态定义为四重(x、y、a、c)。笛卡尔坐标(x,y)代表海龟的位置。被称为航向的角度a被解释为海龟所面对的方向。颜色c被解释为乌龟当前压在地板上的颜色笔,因此乌龟的任何移动都会产生该颜色的线条。给定步长d和角度增量b,海龟可以根据以下说明响应L系统字符串中的符号:

Move forward (in the dir of the current heading) a distance d while drawing a line of color c.
The state of the turtle changes to (x', y', a, c), where 
x' = x + d cos(a) and y' = y + d sin(a)

龙曲线L系统

龙曲线的有限近似可以用L系统来创建。龙曲线L系统可以表示为:

龙曲线L系统
变量: f h
常数: + –
公理: F
规则: f=f-h h=f+h
角度增量: 90度
第一代: f-h
第二代: f-h f+h
第三代: f-h f+h f-h + f+h
第四代: f-h f+h f-h + f+h f-h f+h + f-h + f+h
                2 rules
              /          
replace f with f-h    replace h with f+h

+ & - are constants

build up generations by following rules on axiom
gen 1 forms gen 2; gen 2 forms gen 3 and so on...

The generation 2 string is: 'f-h - f+h'

图片[1]-使用Python绘制海威的龙曲线-yiteyi-C++库

在上面的L系统中,假设海龟的初始航向在屏幕上向上,那么第一个“f”将直接向上画一条线。“-”使海龟改变90度的航向,直接指向左侧。“h”直接在屏幕左侧画一条线。第二个“-”符号再次将海龟向左旋转90度,该角度正好位于屏幕下方。f符号在向下方向绘制一条单位长度的线。字符串中的最后一个转弯符号是“+”,它将海龟向右旋转90度。但是,由于海龟的当前航向是向下的,所以它的右侧是屏幕的左侧,因此海龟的航向也是在屏幕的左侧。最后,h符号在屏幕左侧绘制一条单位长度的线。因此我们得到了彩色的结果图像。 如果我们继续形成更多的世代,我们会得到美丽的曲线称为龙曲线。正如我们在下面看到的,随着我们一代又一代的成长,曲线变得更加复杂。 迭代3: 图片[2]-使用Python绘制海威的龙曲线-yiteyi-C++库 迭代9: 图片[3]-使用Python绘制海威的龙曲线-yiteyi-C++库

龙纹纸

这些龙形曲线也可以通过折纸形成:概念非常简单,但潜力惊人。拿一张长条纸对折。你会得到一张有折叠的纸条!重新折叠纸张,然后再对折。当你往里看时,你有两个褶皱朝一个方向,一个褶皱朝另一个方向。重新折叠,再对折,当你展开时,你会得到更多的折叠,有些是单向的,有些是反向的。

展开条带,沿着每条折叠线做一个牢固的折痕,注意保持正确的折叠方向。将纸带放在边缘,每个折叠成90度角,向下看。你会看到一个复杂的方块图案,还有曲折。这些长条之所以被称为“龙曲线”,是因为经过几次折叠后,它们开始呈现出一条长着大头、大腿和大尾的龙的样子。

数字档案 在他们的视频中很好地解释了龙曲线的形成。你也可以在这里观看龙的曲线过渡:

规划龙曲线

PSEUDOCODE

→ IMPORT TURTLE → TURN TURTLE - RIGHT SIDE('r') #OLD PATTERN = 'r' → NEW PATTERN = OLD PATTERN → USER INPUT [ Number of Iterations(n), Segment size, Pen color & Background color ] → CYCLE = 1 → WHILE CYCLE < ITERATION : → FORM DRAGON CURVE L-SYSTEM → STORE THE PATTERN OF 'l'/'r' in NEW PATTERN → NEW PATTERN += OLD PATTERN → OLD PATTERN = NEW PATTERN → INCREMENT CYCLE → USER INPUT [Whether to display 'r'/'l' Dragon curve L-system in console] → INITIATE THE TURTLE TO DRAW [pencolor, bgcolor, draw right = segment size] → ITERATE OVER FULL L SYSTEM FOR n ITERATIONS: → IF CHAR == 'r' → DRAW RIGHT(90) → DRAW FORWARD(Segment Size) → ELSE IF CHAR == 'l' → DRAW LEFT(90) → DRAW FORWARD(Segment Size) → END

# import the turtle module to use turtle graphics
import turtle
# make variables for the right and left containing 'r' and 'l'
r = 'r'
l = 'l'
# assign our first iteration a right so we can build off of it
old = r
new = old
# for inputs
iteration = int ( input ( 'Enter iteration:' ))
length = int ( input ( 'Enter length of each segment:' ))
pencolor = input ( 'Enter pen color:' )
bgcolor = input ( 'Enter background color:' )
# set the number of times we have been creating
# the next iteration as the first
cycle = 1
# keep on generating the next iteration until desired iteration is reached
while cycle<iteration:
# add a right to the end of the old iteration and save it to the new
new = (old) + (r)
# flip the old iteration around(as in the first charicter becomes last)
old = old[:: - 1 ]
# cycling through each character in the flipped old iteration:
for char in range ( 0 , len (old)):
# if the character is a right:
if old[char] = = r:
# change it to a left
old = (old[:char]) + (l) + (old[char + 1 :])
# otherwise, if it's a left:
elif old[char] = = l:
#change it to a right
old = (old[:char]) + (r) + (old[char + 1 :])
# add the modified old to the new iteration
new = (new) + (old)
# save the new iteration to old as well for use next cycle
old = new
# advance cycle variable to keep track of the number of times it's been done
cycle = cycle + 1
printans = input ( 'Display r/l form?(y/n):' )
if printans = = 'y' :
print (new)
# for  not show the turtle icon when drawing
turtle.ht()
turtle.speed( 0 )
turtle.color(pencolor)
turtle.bgcolor(bgcolor)
turtle.forward(length)
# cycling through all the characters in the iteration
for char in range ( 0 , len (new)):
# if the character is a right:
if new[char] = = (r):
turtle.right( 90 )
turtle.forward(length)
# otherwise, if the character is a left:
elif new[char] = = (l):
turtle.left( 90 )
turtle.forward(length)


输出:

从中获取不同语言的龙曲线代码 罗斯塔码 .你会很高兴亲自检查分形。还要检查一下, 欧拉项目: 问题220 :海威龙 .

参考资料:

本文由 阿马蒂亚·兰扬·赛基亚 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 贡献极客。组织 或者把你的文章寄到contribute@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。

如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享