一行公式,如何生成一个世界?
一行公式,如何生成一个世界?
从递推公式到分形、混沌与生命——一个纯静态交互式数学可视化画廊的诞生记
你有没有想过,宇宙里那些繁复到近乎无限的图案——云层的边缘、海岸线的轮廓、树叶的脉络、银河的旋臂——可能只是在重复执行一条极其简单的规则?
几十年前,数学家们发现了一个令人不安又着迷的事实:复杂,不需要复杂的原因。
一条递推公式就够了。
什么是递推公式?
递推公式(recurrence relation)是一个"自我喂养"的函数:
它的工作方式可以用三个词概括:取输出,当输入,再来一次。
- 第一步:随便选一个起点
- 第二步:代入函数,得到
- 第三步:把 再喂回去,得到
- ……重复一万次
单看任何一步,都简单得不能再简单。但把结果反复迭代之后,稳定、周期、混沌、分形——一切复杂性都从这一条公式里涌现出来。
这正是我做的交互网站《递推 · 生成的图形世界(Recurrence World)》想传达的核心:用一个纯静态页面,让每个人亲手"玩"出这些图案。
六个可视化:一个公式,六种宇宙
网站用原生 HTML + CSS + JavaScript + Canvas 实现了六个交互式可视化,每一个都由一条递推规则驱动。
| 模块 | 核心递推式 | 一句话亮点 |
|---|---|---|
| 曼德博集 | 复平面上最著名的分形 | |
| 茱莉亚集 | 同一个公式,另一种宇宙 | |
| L-系统分形树 | 用"重写规则"长出一棵树 | |
| 元胞自动机 | 一维规则号 0–255 与生命游戏 | |
| 谢尔宾斯基三角 | 随机掷骰子,掷出确定的分形 | |
| Logistic 映射 | 一条抛物线,孕育整个混沌理论 |
🌀 曼德博集:复杂性的名片
在复平面上取一个点 ,从 开始反复迭代。如果 始终没有跑远, 就属于曼德博集;否则按"多久跑远"给它上色。
这个看似简单的规则,画出来却是那个闻名世界的"阿波罗心脏"——边缘无限细节,任何放大都藏着一片全新的宇宙。网站里你可以在任意位置滚轮缩放、拖拽平移,并且实时切换迭代次数和 5 套调色板,亲眼见证"越迭代,细节越丰富"。
🌌 茱莉亚集:同一个公式,参数决定命运
与曼德博集共用同一个公式,但这次 是固定参数, 取平面上每个像素点。更妙的是:曼德博集里的每个点,恰好对应一种茱莉亚集。
网站做了一个非常直观的小地图——在曼德博集上拖动光点,右边的茱莉亚集就会实时变化。你会看到 穿越曼德博集边界时,茱莉亚集从"连通的火焰"突然碎成"混沌的尘埃"。分形、混沌与参数的关系,尽在这一次拖拽里。
🌳 L-系统分形树:自然界的语法
L-系统(Lindenmayer System)用一套重写规则描述植物的生长:
- 公理(起点):
F - 规则:
F → F[+F][-F]——每段枝干都分叉出左枝和右枝 - 迭代:把规则里的符号反复替换,再交给"乌龟绘图"逐笔画出
仅仅更换角度、迭代次数或规则,就能从同一套语法里长出水杉、蕨类、灌木……自然的形态原来也有"语法"。
🧮 元胞自动机:局部规则,整体生命
元胞自动机让"递推"发生在空间上:每个格子下一时刻的状态,只取决于它自己和邻居。
一维模式下,你可以输入 0–255 之间的任意规则号(例如著名的 Rule 30,被用作随机数发生器);二维模式则是经典的生命游戏(Game of Life)——点击画下细胞,观察"滑翔机""振荡器"如何在纯局部规则里涌现。播放、暂停、单步、变速,节奏由你掌控。
🔺 谢尔宾斯基三角:随机中必然的分形
这是最"反直觉"的一个:
- 画一个三角形,随机选一个顶点
- 从任意点 出发: ——向随机顶点移动一半距离
- 重复几万次
过程完全是随机的,结果却必然收敛出一个精致的三维镂空分形。看起来杂乱无章的随机过程,也可以被一个简单的递推"驯服"成秩序。 网站支持 3/4/5/6 个顶点和着色/单色模式,多几个顶点还能看到更奇妙的"谢尔宾斯基地毯"变体。
📈 Logistic 映射:一条抛物线里的混沌之窗
这是生态学里描述种群数量的方程。当参数 从 3 慢慢增加到 4,会发生:
- :种群稳定在一个值(稳定点)
- :在两个值之间振荡(周期 2)
- :开始进入混沌(周期倍增级联)
把 从 0 到 4 的所有"长期行为"画出来,就是那张著名的分岔图(bifurcation diagram)——一条直线在混沌之门前突然像烟花般炸开。网站里你可以点击图上任意位置选点,同步查看时间序列,并自动检测周期。
技术实现:把"性能"也做成一种优雅
纯静态、零依赖、零构建——整个网站只是几个 HTML/CSS/JS 文件,不需要任何 CDN 或网络。但在表面之下,为了让分形交互足够顺滑,做了几件认真的事:
- ImageData 像素缓冲:曼德博/茱莉亚集逐像素计算,直接写入像素缓冲区,一次
putImageData整帧上屏,避免 Canvas 逐点绘制的开销。 - Web Worker 多线程分块渲染:把画布切成多个块并行计算,页面主线程不卡顿。
- 视图缓存与占位投影:每次渲染结果按视图/参数缓存;平移时用旧帧实时贴合,缩放时用仿射变换把旧帧投影作占位,新帧渲染完成后无缝替换——所以拖动时不会出现"白屏等待"。
- requestAnimationFrame 驱动:元胞自动机的动画按速度累积步进,播放/暂停/变速都基于时间而不是帧数。
界面方面采用深色主题、玻璃拟态卡片、渐变点缀和低调的星空背景动画,并针对移动端做了响应式适配。
如何运行
项目零依赖,任选一种方式:
cd recurrence-world
python3 -m http.server 8080
浏览器打开 localhost:8080 即可。(注意:分形渲染使用了 Web Worker,请通过 HTTP 方式访问,直接用本地文件方式打开在极少数浏览器上可能受限。)
写在最后
这个网站最想让人体验的,其实是一种视角的转换:
与其说世界是"被设计"出来的,不如说世界是"被递归"出来的。
从曼德博集的无限边缘,到 Logistic 映射的混沌之窗,再到生命游戏里秩序与混乱的拉锯——它们共享同一个内核:一条简单的规则,加上足够多的重复。
一行公式,足以生成一个世界。
《递推 · 生成的图形世界(Recurrence World)》:纯静态交互式数学可视化画廊,代码开源在 GitCode 仓库:qin_rui/recurrence-world。
- 点赞
- 收藏
- 关注作者
评论(0)