LS文法构图算法(3) Hilbert-Peano曲线

        在前面一篇中讲了如何用递归算法来画Hilbert-Peano曲线,这一篇再尝试一下使用LS文法构图算法来构建它。这就要使用多规则的LS文法了,多规则情况下的字母表中,有1个以上的字符,在迭代时更加复杂,每一个字符都要用相应的规则来替换;在绘图时,可以为各种字符规定不同的绘图动作,有的画图,有的可以不画图。
        要画Hilbert-Peano这种比较复杂的图,关键就是要规定好文法生成规则,这也是最难的一步。如下图所示,再分析一下Hilbert-Peano曲线的绘制过程:

 LS文法构图算法(3) Hilbert-Peano曲线_第1张图片

        把其中A所示的迭代过程照这样来理解:如B所示,曲线从左下角开始绘制,线段的每一个端点都认为存在一个绘图过程,在其中将绘制一个子图,而三条线段正是用来连接这四个子图的,如果把子图也绘制出来,就完成了一次迭代。B左图所画的是一个红色的“父图”,四个要画子图的端点已用绿色圆圈标出,这四个子图将用绿色来画;B右图就是子图画出来之后的效果,四个子图都已完成,红色的仍是原来“父图”中原有的三条线,它们是用来连接各子图的。

        一个基本的Hilbert-Peano图的绘制是有方向的,可能是顺时针,也可能是逆时针,这就要规定两种迭代规则。假如把X定为顺时针绘子图,把Y定为逆时针绘子图,而整个图按照顺时针来绘制的话,就有如下规则:

       omega = X

       X = +YF-XFX-FY+

       Y = -XF+YFY+FX-

        解释一下:以X = +YF-XFX-FY+为例,这一规则所描述的正是B左图所示的绘图过程,进入绘图区的初始方向当然是角度为0的方向,先逆时针转90度,方向向上;然后先画第一个子图,这个子图是逆时针的,即Y;画完之后,向前走,即F;到了左上角,先右转,然后画一个顺时针的子图X;再向前走,F;再画一个顺时针子图X;再右转,向前走F,再画一个逆时针的子图;最后还要再转个逆时针的90度,这是离开此图的方向。

        Y = -XF+YFY+FX-X = +YF-XFX-FY+是对称的,道理一样。别忘了,父图的绘制方向与第二、三个子图的绘制方向是相同的,而与第一、四个相反。

        以下是使用多规则LS文法绘制Hilbert-Peano曲线的Python代码以及运行结果:

#!/apps/bin/python
from Tkinter import *
import  math

class
 HilbertPeano(Frame):

    delta 
= math.pi/2

    omega 
= "X"
    replacementX 
= "+YF-XFX-FY+"
    replacementY 
= "-XF+YFY+FX-"
    endX 
= 100
    endY 
= 20
    step 
= 5
    direction 
=  0
    level 
= 7

    statement 
=  omega
    
    
def __init__(self, master=
None):
        self.calcuStatement()
        Frame.
__init__
(self, master)
        self.grid()
        self.createWidgets()

    
def
 calcuStatement(self):
        
for currentLevel in
 range(0, self.level):
            newStatement 
= ""

            
for index in  range(0,len(self.statement)):
                
if (self.statement[index] == "X"
):
                    newStatement 
= newStatement +
 self.replacementX
                
elif (self.statement[index] == "Y"
):
                    newStatement 
= newStatement +
 self.replacementY
                
else
 :
                    newStatement 
= newStatement +
 self.statement[index]
            self.statement 
=
 newStatement
            
print
 self.statement

    
def
 createWidgets(self):
        
#self.quitButton = Button(self, text="QUIT", command=self.quit)

        #self.quitButton.pack(side=BOTTOM, fill=BOTH)
        self.draw = Canvas(self, width=800, height=700 )
        self.draw.pack(side
=
LEFT)
        self.drawCanvas()

    
def
 drawCanvas(self):
        
for index in
 range(0,len(self.statement)):
            
if (self.statement[index] == "F"
):
                startX 
=
 self.endX
                startY 
=
 self.endY
                self.endX 
= startX + self.step*
(math.cos(self.direction))
                self.endY 
= startY + self.step*
(math.sin(self.direction))
                self.draw.create_line(startX,startY,self.endX,self.endY)
            
elif (self.statement[index] == "-"
):
                self.direction 
= self.direction -
 self.delta
            
elif (self.statement[index] == "+"
):
                self.direction 
= self.direction +
 self.delta

app 
=
 HilbertPeano()
app.master.title(
"HilbertPeano (LS)"
)
app.mainloop()

 

LS文法构图算法(3) Hilbert-Peano曲线_第2张图片

你可能感兴趣的:(分形)