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()

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值