H-分形与分形树

533 阅读3分钟

学习近世代数时了解到曼德博集合,简简单单画几个分形图形玩(递 归 练 习)

最基础的分形结构是H树(H分形):由互相垂直的线段构成,其中任意一条线段的长度都是次一级线段的2\sqrt{2}倍(使用矩形建的H树即曼德尔布罗树)

H-Tree4.png

对于函数的实现,一方面,需要绘制构成H形的三段线段;另一方面,需要在各顶点建立其子H-分形树,子树线长为原树一半。可以通过递归实现,算法时间复杂度为O(Depth4)O(Depth^4),同时设置随机颜色以便于审阅分形曲线。

下面是绘制H树的Python程序实现。

import turtle
import random

SCREEN_WIDTH = 1280
SCREEN_HEIGHT = 720
PEN_WIDTH = 5
GRAY_SCALE = 255
LINE_LENGTH = 300
TITLE = "H-Tree Fractal with Python"
     
def drawLine(tur, x1, y1, x2, y2):
    #绘制线型
    tur.pencolor([random.randint(0, 255) for i in range(3)])
    tur.penup()
    tur.goto(x1, y1)
    tur.pendown()
    tur.goto(x2, y2)
    tur.penup()     
     
def drawHTree(tur, x, y, length, depth):
    #嵌套递归实现
    def recursivedrawHTree(x, y, length0, depth0):
        if length == 0: return
        if depth0 > depth: return
        #画线
        drawLine(tur, x - length0/2, y, x + length0/2, y)
        drawLine(tur, x - length0/2, y + length0/2, x - length0/2, y - length0/2)
        drawLine(tur, x + length0/2, y + length0/2, x + length0/2, y - length0/2)
        #递归建树,四个子枝节
        recursivedrawHTree(x - length0/2, y + length0/2, length0/2, depth0 + 1)
        recursivedrawHTree(x + length0/2, y + length0/2, length0/2, depth0 + 1)
        recursivedrawHTree(x - length0/2, y - length0/2, length0/2, depth0 + 1)
        recursivedrawHTree(x + length0/2, y - length0/2, length0/2, depth0 + 1)
    return recursivedrawHTree(x, y, length, 1)
     
if __name__ == '__main__':
    depth = 4
    screen = turtle.Screen()
    screen.setup(SCREEN_WIDTH, SCREEN_HEIGHT)
    screen.title(TITLE)
    screen.colormode(GRAY_SCALE)
    artist = turtle.Turtle()
    artist.hideturtle()
    artist.pensize(PEN_WIDTH)
    screen.tracer(False)
    drawHTree(artist, 0, 0, LINE_LENGTH, depth)
    screen.tracer(True)
    fig = artist.getscreen()
    fig.getcanvas().postscript(file = 'H-Tree'+str(depth)+'.eps')

从H分形引申到更普适的情况,可将直角线型推广至子树线段旋转任意角度,由此绘制分形树。

取旋转角度θ=30\theta=30^{\circ},有分形树6阶例如图所示。

FTree6.png

绘制分形树的Python实现代码类同。此处取枝节角度|ANGLE|=3030^{\circ}.

import turtle
import random

SCREEN_WIDTH =500
SCREEN_HEIGHT = 450
PEN_WIDTH = 2
LINE_LENGTH = 200
ANGLE = 30
TITLE = "Fractal Tree with Python"  
     
def drawFTree(tur, length, depth):
    #递归实现
    tur.left(90)
    tur.backward(200)
    def recursivedrawFTree(length0, depth0):
        if length == 0: return
        if depth0 > depth: return
        tur.forward(length0)
        #右子树
        tur.right(30)
        recursivedrawFTree(length0/2, depth0 + 1)
        #左子树
        tur.left(60)
        recursivedrawFTree(length0/2, depth0 + 1)
        #返回根
        tur.right(30)
        tur.backward(length0)
    return recursivedrawFTree(length, 1)
     
if __name__ == '__main__':
    depth = 6
    screen = turtle.Screen()
    screen.setup(SCREEN_WIDTH, SCREEN_HEIGHT,0,-300)
    screen.title(TITLE)
    artist = turtle.Turtle()
    artist.hideturtle()
    artist.pensize(PEN_WIDTH)
    screen.tracer(False)
    drawFTree(artist, LINE_LENGTH, depth)
    screen.tracer(True)
    fig = artist.getscreen()
    fig.getcanvas().postscript(file = 'FTree'+str(depth)+'.eps')

分形曲线具有局部和整体的对称结构。由于满足分形特性的集合具有递归的特性,局部的特征提取即可反应整体信息,在信号/多媒体处理中,如果有相关先验信息(或许)有助于迅速降低计算的复杂度。

不过,更实际的应用一般是在图像处理中用于构造锯齿或者混叠(摩列纹)的样例。当图像的高频部分(例如分形边界的无限小细节)未能正确采样时,可以观察到aliasing失真,在临近边界处的颜色会充满噪点和混叠。通过下采样/最近邻像素下采样/抗锯齿滤波可以缓解失真