用Python画一棵分形树
创始人
2024-04-24 04:42:14
0

文章目录

    • 画一棵分形树
    • 加入随机量的分形树
    • 加入点缀的圣诞树

画一棵分形树

分形树,就是用分形的逻辑去画一棵树,所谓分形,若从编程的角度去理解,其实就是简单规则的反复迭代。

例如,现在有一条线段,长为LLL,在这个线段的端点处再画两个线段,每个线段的长度为23L\frac23L32​L,与前一个线段的夹角为±10°\pm 10°±10°,将这个规则不断进行下去,直到线段长度小于δ\deltaδ。

接下来,先做一个线段的类

import numpy as np
class segment:def __init__(self, st, th, L):self.st = stself.th = thself.L = Lself.setEd()def setEd(self):x, y = self.stth = 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 *= dLsegs.append([])for seg in segs[-2]:segs[-1] += seg.getChild(dTh, L)return segssegs = 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 *= dLsegs.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()

效果为

在这里插入图片描述

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...