当前位置: 首页 > 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)

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

在这里插入图片描述

相关文章:

  • vite+vue3 部署后,总是需要清除缓存的问题
  • 如何管理测试用例?测试用例有什么管理工具?YesDev
  • JVM运行时内存:本地方法接口与本地方法栈
  • 音视频开发4-补充 FFmpeg 开发环境搭建 -- 配置环境 Ubuntu 22.04.2 LTS +FFmpeg 7.0
  • 未来已来:Spring Cloud引领微服务新纪元
  • JVM内存模型最新面试题(持续更新)
  • R 贝叶斯输出分析和诊断MCMC:coda包
  • 你知道什么是物联网MQTT么?
  • 千帆AppBuilder产品更新日志 速来围观~
  • 【从零开始学习重要知识点 | 第一篇】快速了解什么是幂等性以及常见解决方案
  • 【QT】关于QSerialPort的错误处理 (Error Handling)及错误类型
  • opencv图像腐蚀
  • 汇编条件转移指令
  • 核心面试题:MVCC、间隙锁、Undo Log链、表级锁、行级锁、页级锁、共享锁、排它锁、记录锁等等
  • 安卓面经_安卓基础面全解析(7/30)之消息机制全解析(上)
  • Android中AP和BP概念
  • 【OpenFOAM】-olaFlow-算例3- currentWaveFlume
  • 【2022年度系列工作总结】「国内软件质量调查问卷」针对于本年度软件质量分析总结报告
  • Java——LRUCache
  • 实战讲解及分析Spring新建Bean的几种方式以及创建过程(图+文+源码)
  • SpringBoot请求参数传递与接收
  • 数据结构刷题训练营1
  • 泰勒公式的应用
  • ADI Blackfin DSP处理器-BF533的开发详解61:DSP控制ADXL345三轴加速度传感器-LCD(含源码)
  • [附源码]Nodejs计算机毕业设计基于与协同过滤算法的竞赛项目管理Express(程序+LW)
  • SpringSecurity(前后端分离版)[6]-跨域
  • 基于Java毕业设计校园一卡通服务平台源码+系统+mysql+lw文档+部署软件
  • HttpRunner4.x 安装与使用
  • 知到/智慧树——程序设计基础(C语言)进阶篇
  • 10.union all、N天连续登录
  • Nacos系列——Nacos概述(2.x版本)1-1
  • [山东科技大学OJ]1840 Problem N: 幸运单词