当前位置: 首页 > news >正文

Python画一棵茂盛的分形树

文章目录

    • 前情回顾
    • 添加分岔
    • 茂盛的分形树

前情回顾

上次画了一棵分形树:用Python画一棵分形树,得到的图如下

在这里插入图片描述

发现看的人还是挺多的,但没什么人点赞,这说明我能给大家画分形树,大家很高兴,但这棵树太秃了,大家不喜欢。

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

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

添加分岔

如想让分形树变得茂盛,第一步就是让树枝多一些分岔点,如果仍旧以线段为骨架,那么树枝将不在端点分岔,而在某个位置分岔。

不过无论如何变化,作为骨架的线段类是不会变的,变的是分岔方法,即getChild

import numpy as np
rand = lambda r : 1 + r*(np.random.rand()-0.5)

class segment:
    def __init__(self, st, th, L):
        self.st = np.array(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 = np.array([x+dx, y+dy])
    def getAxis(self):
        xs = (self.st[0], self.ed[0])
        ys = (self.st[1], self.ed[1])
        return (xs, ys)
    # dL表示树枝生长的位置
    def getChild(self, dTh, L, dL):
        st = (1-dL)*self.st + dL*self.ed
        return segment(st, self.th+dTh, L)

接下来更改分形逻辑,由于这次的getChild一次只产生一个子线段,所以在分形逻辑中,需要将生成子线段的个数也考虑进去。

def fractal(L, minL, dL, st=0.7, 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].append(seg.getChild(dTh*rand(rTh), 
                L*rand(rL), st))
            segs[-1].append(seg.getChild(-dTh*rand(rTh), 
                L*rand(rL), st))
    return segs

然后写测试和绘图代码

from itertools import chain
import matplotlib.pyplot as plt
segs = fractal(10, 1, 0.7, 0.7, 15, 90, rL=1, rTh=1)

def drawSegs(segs):
    segs = list(chain(*segs))
    pts = np.array([s.ed for s in segs])
    for seg in segs:
        xs, ys = seg.getAxis()
        test = 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()

得到如图所示,发现,从观感上来说,貌似比之前更秃了

在这里插入图片描述

茂盛的分形树

为了摆脱这种尴尬的局面,第一步就是在树干的正前方添加一根树枝,即在fractal中的for循环里,添加一个

segs[-1].append(seg.getChild(0, L*rand(rL), 0.7))

然后再生成,绘图

segs = fractal(10, 1, 0.7, 0.7, 15, 90, rL=1, rTh=1)
drawSegs(segs)

最后得到的树如下图所示,枝繁叶茂了许多

在这里插入图片描述

相关文章:

  • css知识复习点
  • 公益校园网页制作 大学生网页设计作业 HTML CSS公益网页模板 大学生校园介绍网站毕业设计
  • Qt之天气预报——界面优化篇(含源码+注释)
  • 如果你不是前端,一定不知道我在说什么
  • Spring BOOT 手写一个starter并使用这个starter
  • C/C++停车场管理系统
  • 【C++进阶】C++11新特性上篇(万字详解)
  • C/C++KTV点歌系统
  • 【Linux修炼手册:基本指令(完结)】
  • vmware ESXI 7 升级ESXI 8
  • 毕业设计 单片机温湿度环境检测仪 - stm32 物联网 嵌入式
  • 为什么在SPI通信中提供不同的模式?
  • 马上跨年了,如何用代码写一个“跨年倒计时”呢?
  • Arcgis中创建Python脚本工具
  • 内存读写指令 —— LDR / STR
  • 【前端学习】-粗谈选择器
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • Android单元测试 - 几个重要问题
  • Apache Zeppelin在Apache Trafodion上的可视化
  • Create React App 使用
  • CSS居中完全指南——构建CSS居中决策树
  • es6
  • JS 面试题总结
  • ReactNativeweexDeviceOne对比
  • 阿里云前端周刊 - 第 26 期
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 对象管理器(defineProperty)学习笔记
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 时间复杂度与空间复杂度分析
  • 【云吞铺子】性能抖动剖析(二)
  • kubernetes资源对象--ingress
  • 阿里云移动端播放器高级功能介绍
  • ​520就是要宠粉,你的心头书我买单
  • # 计算机视觉入门
  • #WEB前端(HTML属性)
  • (1)常见O(n^2)排序算法解析
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (C#)获取字符编码的类
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (Ruby)Ubuntu12.04安装Rails环境
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (接口自动化)Python3操作MySQL数据库
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • (四) Graphivz 颜色选择
  • (一一四)第九章编程练习
  • (转)setTimeout 和 setInterval 的区别
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .Net mvc总结
  • .NET 设计一套高性能的弱事件机制
  • .net 托管代码与非托管代码
  • .NET/C# 使窗口永不获得焦点
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .NET开发人员必知的八个网站
  • .NET企业级应用架构设计系列之应用服务器
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国