如上图所示,这就是一个Hilbert-Peano曲线,它的特点是蜿蜒曲折、一气呵成,能经过平面上某一正方形区域内所有的点。 Hilbert-Peano曲线也是一种分形图形,它可以画得无限复杂。它的初始图元是正方形,在迭代生成的过程中,不断细化出小的正方形,图中的线段其实是用于连接各正方形的连线。 参照下图所示,以一次基本的迭代为例,这次迭代从原图的左下角出发,顺时针画折线到右下角。 要想实现如图中A部分所示的绘制过程,首先要把它放在一个正方形里来看。把一个正方形等分为四个小正方形,原图是从左下角开始延顺时针方向依次连接四个小正方形中心的线段,称这些线段为1级线; 接下来,把四个小正方形再次细化,把每一个小正方形再划分为小小正方形,即在每个小正方形中再绘折线,称这些线段为2级线; 这样,1级线就成为连接各2级线的折线,2级线再不断连接到N级线,最后就绘制成了复杂的Hilbert-Peano曲线。 在细化的过程中,在连接一个正方形的4个小正方形的时候,有的时候是顺时针画的,有的时候又是逆时针画的,有什么规律呢? 如下图中B所示,在大正方形中折线是顺时针画的,那么在4个小正方形中绘制折线的方向分别是[逆顺顺逆],这是一条规律,即在细化过程中,一个绘图过程被分为4个小的绘图过程,原绘图方向与第2、3个子图的绘图方向是一致的。即如果原方向为X方向,那么各子图的绘图方向分别为[-X,X,X,-X]。
以下是绘制Hilbert-Peano曲线的python代码以及运行的效果图:
# !/apps/bin/python from Tkinter import * class HilbertPeano(Frame): beginning = 1 anticlockwise = 1 startX = 0 startY = 0 level = 4 def __init__ (self, master = None): Frame. __init__ (self, master) self.grid() self.createWidgets() 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 = 600 ) self.draw.pack(side = LEFT) self.drawCanvas(self.level, - (self.anticlockwise), 200 , 100 , 600 , 500 ) def drawCanvas(self, level, direction, x1, y1, x2, y2): dx = x2 - x1 dy = y2 - y1 if (level == 1 ): self.lineTo((x1 + dx / 4 ),(y1 + dy / 4 )) self.lineTo((x1 + dx / 4 + ( 1 - direction) * dx / 4 ),(y1 + dy / 4 + ( 1 + direction) * dy / 4 )) self.lineTo((x1 + 3 * dx / 4 ),(y1 + 3 * dy / 4 )) self.lineTo((x1 + dx / 4 + ( 1 + direction) * dx / 4 ),(y1 + dy / 4 + ( 1 - direction) * dy / 4 )) else : if (direction == self.anticlockwise) : self.drawCanvas(level - 1 , - direction,x1,y1,(x1 + x2) / 2 ,(y1 + y2) / 2 ) self.drawCanvas(level - 1 ,direction,x1,(y1 + y2) / 2 ,(x1 + x2) / 2 ,y2) self.drawCanvas(level - 1 ,direction,(x1 + x2) / 2 ,(y1 + y2) / 2 ,x2,y2) self.drawCanvas(level - 1 , - direction,x2,(y1 + y2) / 2 ,(x1 + x2) / 2 ,y1) else : self.drawCanvas(level - 1 , - direction,x1,y1,(x1 + x2) / 2 ,(y1 + y2) / 2 ) self.drawCanvas(level - 1 ,direction,(x1 + x2) / 2 ,y1,x2,(y1 + y2) / 2 ) self.drawCanvas(level - 1 ,direction,(x1 + x2) / 2 ,(y1 + y2) / 2 ,x2,y2) self.drawCanvas(level - 1 , - direction,(x1 + x2) / 2 ,y2,x1,(y1 + y2) / 2 ) def lineTo (self, endX, endY) : if (self.beginning == 1 ) : self.beginning = 0 else : self.draw.create_line(self.startX,self.startY,endX,endY) self.startX = endX self.startY = endYapp = HilbertPeano()app.master.title( " HilbertPeano (recursive) " )app.mainloop()
