ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Julia分形图生成:科赫曲线与毕达哥拉斯树的递归绘制

Julia分形图生成:科赫曲线与毕达哥拉斯树的递归绘制 分形图形看起来复杂但很多经典分形背后的生成规则其实非常简单定义一次局部变换然后不断重复。这次用Julia分别实现了两个经典分形——科赫曲线Koch Curve和毕达哥拉斯树Pythagoras Tree。前者不断细分线段后者不断生成更小的正方形。随着递归层数增加两种简单规则都会逐渐生成结构非常复杂的图形。运行过程中我重点核对了递归层数、科赫曲线线段数量、毕达哥拉斯树节点数量以及分支比例并分别生成了最终结果和不同递归层级之间的对比图。一、两个分形分别是怎样生成的这个案例包含两个对象。1科赫曲线科赫曲线从一条普通线段开始。每次迭代时把原线段三等分然后用一个向外凸起的等边三角形替换中间三分之一。这样一条线段 → 四条更短的线段。下一轮再对这四条线段分别执行同样的操作。随着递归不断进行原本简单的直线就会逐渐变成非常曲折的分形边界。2毕达哥拉斯树毕达哥拉斯树从一个正方形开始。在正方形顶部继续生成两个尺寸更小、方向不同的正方形再分别以这两个正方形为父节点继续递归。当前脚本采用5:4:3直角三角形确定两个子正方形的边长比例因此左右两个分支大小并不完全相同。这两个案例对应了两类比较典型的递归构造方式科赫曲线线段不断细分。毕达哥拉斯树几何结构不断复制和缩放。二、运行环境与脚本参数本次使用MWORKS Syslab 26.6.1中的Julia 1.10.10运行脚本绘图主要使用TyPlot。两个主要脚本分别为koch_curve_animation.jlpythagoras_tree_syslab.jl科赫曲线的关键参数1最大递归层数 max_depth6。2初始线段从(0.0, -0.10)到(1.0, -0.10)。3每层停留时间level_pause_seconds0.10秒。4最终结果停留时间final_hold_seconds1.40秒。5总关键层级数量为7对应初始状态以及第16层递归结果。毕达哥拉斯树的关键参数1最大递归层数 max_depth12。2分支角 branch_angleatan(3.0, 4.0)。3初始正方形边长 root_size1.0。4初始左下角为(-0.5, 0.0)。5动画总时长5秒。6目标帧率36帧/秒。三、科赫曲线一条线段怎样变成4096条科赫曲线最核心的一步是对单条线段进行细分。假设原线段为AB。首先把AB三等分得到P1和P3。然后以P1、P3为底边构造一个等边三角形其顶点记为P2。这样原来的AB就被替换为A-P1P1-P2P2-P3P3-B一条线段因此变成四条线段。核心代码如下function subdivide_segment(seg) x1, y1, x2, y2 seg p1x, p1y, p3x, p3y trisection_points(seg) # 三等分点 p2x, p2y equilateral_apex(p1x, p1y, p3x, p3y) # 等边三角形顶点 return Segment[ make_segment(x1, y1, p1x, p1y), make_segment(p1x, p1y, p2x, p2y), make_segment(p2x, p2y, p3x, p3y), make_segment(p3x, p3y, x2, y2), ] end这段代码做的事情并不复杂输入一条线段计算两个三等分点和一个等边三角形顶点然后返回四条新的线段。真正让图形变复杂的是递归。因为每一层都会让线段数量变成原来的4倍所以第1层4条第2层16条第3层64条……第6层4096条图1 第6层科赫曲线生成结果图1 第6层科赫曲线生成结果这是递归到第6层后的最终结果共包含4096条线段。初始图形只是一条水平线段经过不断细分以后边界逐渐形成大量尺寸越来越小的尖角结构。虽然当前只计算到第6层但已经可以明显看到科赫曲线典型的分形特征。四、从第1层到第6层发生了什么如果只看最终结果很容易忽略分形实际上是如何一点点形成的。因此把第1层、第3层和第6层单独拿出来对比。图2 MWORKS Syslab科赫曲线层级递进对比第1层只有4条线段可以清楚看到一次“中间凸起”的基本规则。到第3层时每一条较大的边又已经经历多次细分曲线开始出现明显的锯齿状结构。到第6层时小尺度结构大量出现从整体看已经形成非常复杂的边界。因此科赫曲线的复杂性并不是来自某一个复杂公式而是来自简单规则 × 大量重复。这也是递归生成分形最直观的特点。五、毕达哥拉斯树怎样递归生长毕达哥拉斯树采用的是另一种方式。每个节点不再是一条线而是一个正方形。脚本通过以下信息描述一个正方形x、y位置size边长theta正方形方向level当前递归层级每次生成两个子正方形时首先获取当前正方形顶部的位置然后根据分支角计算两个子正方形的大小和方向。当前分支角为branch_angleatan(3.0, 4.0)对应一个5:4:3直角三角形。因此两个子正方形的边长分别为父正方形边长的4/5和3/5function generate_children(node, angle) verts get_square_vertices(node.x, node.y, node.size, node.theta) top_left verts[4, :] left_size node.size * cos(angle) right_size node.size * sin(angle) left_theta node.theta angle apex_x top_left[1] left_size * cos(left_theta) apex_y top_left[2] left_size * sin(left_theta) right_theta node.theta angle - pi / 2 left_child SquareNode( top_left[1], top_left[2], left_size, left_theta, node.level 1 ) right_child SquareNode( apex_x, apex_y, right_size, right_theta, node.level 1 ) return left_child, right_child end图3 MWORKS Syslab毕达哥拉斯树生成结果每一个父节点都会继续生成两个子节点。因此节点数量会按照二叉树的方式迅速增长。六、12层递归后有多少个正方形本次最大递归层数设置为12。完整运行后总节点数量为4095这个结果可以直接通过二叉树节点数量进行核对。第1层有1个正方形。第2层增加2个。第3层增加4个。第4层增加8个。……第12层增加2048个。所有层相加后1 2 4 … 2048 4095程序运行结果与这一计算结果一致。图中共包含4095个正方形。颜色根据递归层级逐渐变化从树干附近的深棕色逐渐过渡到较高层级的绿色。随着正方形不断缩小并向两侧分叉最终形成类似树冠的整体结构。虽然视觉上已经很像一棵树但它并不是模拟真实植物生长而是完全由固定的几何递归规则生成。七、为什么科赫曲线和毕达哥拉斯树会越来越复杂两种分形虽然长得完全不同但背后的增长规律非常相似。科赫曲线每一条线段生成4条新线段。因此元素数量随递归深度快速增长。毕达哥拉斯树每一个正方形生成2个子正方形。节点数量同样按照指数方式增长。这也是为什么分形算法通常不需要很多代码却能生成非常复杂的结果。复杂性来自递归层数而不是单次计算本身。八、运行结果核对本次运行后对几个关键结果进行了单独检查。1科赫曲线线段数量最终输出4096条计算关系4的6次方4096程序结果与递归规则一致。2毕达哥拉斯树节点数量最终输出4095个即12层完整二叉结构的节点总数。程序结果与理论计算一致。3分支比例分支角使用atan(3,4)。因此cos(angle)4/5sin(angle)3/5两个子正方形的边长分别为父正方形的4/5和3/5与代码设置一致。4动画参数科赫曲线共有7个关键层级状态。毕达哥拉斯树动画时长5秒目标帧率36帧/秒对应约180帧的绘制过程。这些参数与源码设置一致。九、关于图像导出的一个小问题原脚本中的科赫曲线采用黑色背景和白色线条。但实际测试exportgraphics导出结果时画布会使用白色背景因此重新生成的图片采用了白底黑线。需要注意的是这里发生变化的只是背景颜色线条颜色没有变化的是线段坐标递归层级线段数量几何结构因此白底版本和原脚本黑底版本在分形结构上完全一致。毕达哥拉斯树则采用白色背景并按照递归层级使用棕色到绿色的渐变。十、修改参数还能看到哪些变化1增加科赫曲线递归深度如果把max_depth从6提高到7每一条第6层线段还会继续分成4条。因此线段数量会从4096增加到16384图形边界会更加精细但绘制时间和数据量也会明显增加。2修改科赫曲线初始线段改变起点和终点可以改变整个分形的位置、尺寸和方向。递归规则本身并不会发生变化。3修改毕达哥拉斯树分支角branch_angle直接决定左右两个子正方形的尺寸比例和方向。例如改成45度以后左右两侧会更加对称。使用其他角度时树冠则可能明显向一侧偏移。4增加毕达哥拉斯树递归深度每增加一层最末层节点数量都会翻倍。因此树冠会越来越密但绘制量也会快速增加。5修改配色trunk_color、leaf_color以及show_level_colors只控制显示效果。修改它们不会改变树的几何结构。十一、模型适用范围与局限这两个案例主要用于递归算法与分形可视化因此仍存在几个需要说明的边界。1递归深度有限数学意义上的分形通常对应无限递归。程序不可能真正执行无限次所以max_depth只是有限近似。本次科赫曲线只计算到第6层。2元素数量指数增长科赫曲线每层线段数量变为4倍。毕达哥拉斯树每层节点数量变为2倍。因此递归深度提高以后计算量和绘图量都会迅速增加。3图形属于数学可视化科赫曲线和毕达哥拉斯树都是数学构造。动画展示的是递归生成过程不代表任何真实物理过程。4屏幕尺寸获取存在回退机制毕达哥拉斯树脚本使用pyimport(PyQt5.QtWidgets)尝试获取屏幕尺寸。如果当前环境没有安装PyQt5则自动使用默认尺寸1920×1080。这不会影响分形几何结构。十二、总结这两个案例使用两种非常简单的递归规则生成了结构完全不同的分形。科赫曲线采用一条线段 → 四条更短的线段不断重复以后第6层达到4096条线段。毕达哥拉斯树采用一个正方形 → 两个更小的正方形不断递归以后12层共有4095个正方形节点。从实际结果可以看到分形图形的复杂性并不一定来自复杂算法。很多时候只需要定义一个简单的局部规则再让程序重复执行足够多次就能得到非常复杂的整体结构。这两个脚本也比较适合用来练习Julia中的递归、几何坐标计算以及动态图形绘制。案例参考https://mohub.net/model/26009/summary
返回列表