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

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

 

        把其中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曲线_第1张图片

你可能感兴趣的:(Math,算法,python,command,import,button)