文章目录
- 画一棵分形树
- 加入随机量的分形树
- 加入点缀的圣诞树
 
画一棵分形树
分形树,就是用分形的逻辑去画一棵树,所谓分形,若从编程的角度去理解,其实就是简单规则的反复迭代。
例如,现在有一条线段,长为 L L L,在这个线段的端点处再画两个线段,每个线段的长度为 2 3 L \frac23L 32L,与前一个线段的夹角为 ± 10 ° \pm 10° ±10°,将这个规则不断进行下去,直到线段长度小于 δ \delta δ。
接下来,先做一个线段的类
import numpy as np
class segment:
    def __init__(self, st, th, L):
        self.st = st
        self.th = th
        self.L = L
        self.setEd()
    def setEd(self):
        x, y = self.st
        th = np.deg2rad(self.th)
        dx = self.L*np.cos(th)
        dy = self.L*np.sin(th)
        self.ed = (x+dx, y+dy)
    def getAxis(self):
        xs = (self.st[0], self.ed[0])
        ys = (self.st[1], self.ed[1])
        return (xs, ys)
    def getChild(self, dTh, L):
        ths = [self.th + dTh, self.th-dTh]
        return [segment(self.ed, th, L) for th in ths]
其中setEd用于设置线段的终点;getChild通过给定夹角和线段长度比例,得到连接在当前线段端点处的另外两个线段。
然后,实现分形树的迭代逻辑。由于分形树存在一个代际的关系,所以从组织上来看,可以将分形树写成多个代的列表。
def fractal(L, minL, dL, dTh=15, th0=90):
    segs = [[segment((0,0), th0, L)]]
    while L > minL:
        L *= dL
        segs.append([])
        for seg in segs[-2]:
            segs[-1] += seg.getChild(dTh, L)
    return segs
segs = fractal(10, 2, 0.8, 10, 90)
接下来,把这棵分形树画出来
from itertools import chain
import matplotlib.pyplot as plt
segs = list(chain(*segs))
for seg in segs:
    xs, ys = seg.getAxis()
    plt.plot(xs, ys, color='green')
plt.show()
效果如图所示

这棵树要说有什么问题,就是过于死板了,正常的树肯定不会长得这么标致。
加入随机量的分形树
如果让segment在生成子线段的时候,加上一点随机性,效果可能会更好
# 修改segment中的getChild
rand = lambda r : 1 + r*(np.random.rand()-0.5)
def getChild(self, dTh, L, rL=None, rTh=None):
    if type(L) != list:
        L = [L, L]
    if type(dTh) != list:
        dTh = [dTh, -dTh]
    if rL:
        L = [iL*rand(rL) for iL in L]
    if rTh:
        dTh = [iTh*rand(rTh) for iTh in dTh]
    return [segment(self.ed, self.th+dTh[i], L[i])
        for i in range(len(L))]
相应地,分形逻辑改写为
def fractal(L, minL, dL, dTh=15, th0=90, rL=0.1, rTh=0.1):
    segs = [[segment((0,0), th0, L)]]
    while L > minL:
        L *= dL
        segs.append([])
        for seg in segs[-2]:
            segs[-1] += seg.getChild(dTh, L, rL, rTh)
    return segs
最后画图
segs = fractal(10, 1, 0.75, 15, 90, rL=0.5, rTh=0.5)
segs = list(chain(*segs))
for seg in segs:
    xs, ys = seg.getAxis()
    plt.plot(xs, ys, color='green')
plt.axis("off")
plt.show()

加入点缀的圣诞树
如果觉得这棵树空荡荡地不好看,那么可以在树枝的末端添加一些点缀
segs = fractal(10, 1.5, 0.75, 15, 90, rL=0.5, rTh=0.5)
pts = np.array([s.ed for s in segs[-1]])
segs = list(chain(*segs))
for seg in segs:
    xs, ys = seg.getAxis()
    plt.plot(xs, ys, color='g', zorder=1)
xs, ys = pts.T
N = len(xs)
colors = np.random.rand(N)
areas = (np.random.rand(N)*30)**2
plt.scatter(xs, ys, s=areas, c=colors, 
    marker='*', alpha=0.8, zorder=2)
plt.axis("off")
plt.show()
效果为





![[附源码]Python计算机毕业设计高校教室管理系统Django(程序+LW)](https://img-blog.csdnimg.cn/3537950430794cab93861fab584b075d.png)




![[附源码]Python计算机毕业设计高校教室申请管理系统Django(程序+LW)](https://img-blog.csdnimg.cn/0dee9c79e121432aa9fcdf435116c587.png)





![[附源码]Python计算机毕业设计SSM基于Java的租房系统(程序+LW)](https://img-blog.csdnimg.cn/6a17cba39e4740ababaa04c96c8ace60.png)



