三步跑出洛伦兹吸引子:把蝴蝶效应画成动画

发布时间:2026/8/24 4:53:54
三步跑出洛伦兹吸引子:把蝴蝶效应画成动画 三步跑出洛伦兹吸引子把蝴蝶效应画成动画【免费下载链接】videosCode for the manim-generated scenes used in 3blue1brown videos项目地址: https://gitcode.com/GitHub_Trending/vi/videos七天后的天气预报为什么总差那么一点答案藏在洛伦兹吸引子里。开源项目 vi/videos3Blue1Brown 的动画代码库里有这套经典 Python 混沌模拟的完整代码照着做就能自己跑起来最后亲手画出蝴蝶效应——十条几乎相同的初始轨迹逐步分岔的画面。先看效果 洛伦兹吸引子可视化长什么样最终画面是一个缓慢旋转的 3D 场景左上角固定着三个微分方程x 标红、y 标绿、z 标蓝。画面里共有十条曲线颜色从深蓝渐变到浅蓝起点挤在同一个位置附近。动画开始后每条曲线末端跟着一颗发光圆点还拖着约 3 秒的尾迹。前几秒十条曲线几乎重合随后彼此分开各自绕着左右两个翅膀来回穿行互不重复。转着镜头看整个结构像一只对称的蝴蝶翅膀——这就是洛伦兹吸引子的标准长相。原理速览确定性方程为什么会乱洛伦兹系统由三个耦合的常微分方程ODE, Ordinary Differential Equation组成dx/dt σ(y - x) dy/dt x(ρ - z) - y dz/dt x·y - βz取 σ10、ρ28、β8/3 时轨迹始终被限制在有界区域内却永不重复。乱的原因在非线性项 x(ρ−z) 和 x·y状态变化率取决于状态本身初始差异会被指数级放大。初始只差 1e-5几十秒后两条轨迹就面目全非。第一步把洛伦兹系统写成函数目的把三行方程变成一个 Python 函数让数值求解器随时能问此刻该往哪走。def lorenz_system(t, state, sigma10, rho28, beta8 / 3): # state 是三个数 x, y, z x, y, z state dxdt sigma * (y - x) # x 的变化率 dydt x * (rho - z) - y # y 的变化率 dzdt x * y - beta * z # z 的变化率 return [dxdt, dydt, dzdt]产出给当前状态函数返回该状态此刻的变化率正是数值积分所需的导数信息。第二步通用求解函数算出轨迹点目的把 ODE 的数值积分交给 SciPy 的 solve_ivp你只负责提供方程、初值和时间范围。def ode_solution_points(function, state0, time, dt0.01): solution solve_ivp( function, # 传入方程函数 t_span(0, time), # 积分区间 y0state0, # 初始状态 t_evalnp.arange(0, time, dt) # 每 dt 记录一个点 ) return solution.y.T # 形状 (n_points, 3)产出一个 (n_points, 3) 的轨迹点数组每行是一个 3D 坐标可以直接拿来画图。第三步搭好 3D 坐标系和旋转相机目的Manim 是数学动画引擎3D 场景需要坐标系再配一台绕着场景转的相机。axes ThreeDAxes( x_range(-50, 50, 5), y_range(-50, 50, 5), z_range(0, 50, 5), width16, height16, depth8, ) axes.set_width(FRAME_WIDTH) axes.center() # 相机从 43°、76° 视角出发持续旋转 self.frame.reorient(43, 76, 1, IN, 10) self.frame.add_updater( lambda m, dt: m.increment_theta(dt * 3 * DEGREES) ) self.add(axes)产出一个带坐标轴、镜头每秒转 3 度的 3D 舞台后续所有曲线都画在axes上。第四步画十条轨迹并渲染动画目的给初始条件加 1e-5 级扰动生成十组状态算出轨迹让发光圆点沿曲线同步移动。epsilon 1e-5 # 微小扰动只有 z 不同 evolution_time 30 states [[10, 10, 10 n * epsilon] for n in range(10)] colors color_gradient([BLUE_E, BLUE_A], len(states)) curves VGroup() for state, color in zip(states, colors): points ode_solution_points(lorenz_system, state, evolution_time) curve VMobject().set_points_smoothly(axes.c2p(*points.T)) curve.set_stroke(color, 1, opacity0.25) curves.add(curve) # 每条曲线末端一颗发光圆点跟随曲线终点移动 dots Group(GlowDot(colorc, radius0.25) for c in colors) dots.add_updater(lambda d: [dot.move_to(c.get_end()) for dot, c in zip(dots, curves)]) self.play(*[ShowCreation(c, rate_funclinear) for c in curves], run_timeevolution_time)产出十条曲线随发光圆点逐帧生长30 秒动画画完蝴蝶效应就在屏幕上。原版代码还用 TracingTail 给每颗圆点加了 3 秒尾迹。跑起来 装依赖并执行渲染命令先拿到代码、装依赖再执行渲染命令git clone https://gitcode.com/GitHub_Trending/vi/videos cd videos pip install manim scipy numpymanim -pql _2024/manim_demo/lorenz.py LorenzAttractor参数含义适合场景-p渲染完成后自动播放日常调试-ql低质量快速渲染480p、15 帧快速确认动画流程-qh高质量渲染1080p、60 帧输出较清晰版本-4k4K 分辨率渲染最终出片--save_last_frame只渲染最后一帧最快检查静态效果注意两点项目基于 3Blue1Brown 版的 Manimmanimgl若社区版命令对不上按仓库 README 从源码安装方程部分用 LaTeX 排版系统没装 LaTeX 会报错。新手坑位 容易卡住的三个地方渲染太慢。十条 3D 曲线加旋转相机用 -4k 会等很久。先用 -ql 或 --save_last_frame 调试出片前再换高质量。扰动太小看不出分岔。若发现十条曲线像黏在一起别把 epsilon 调得更小而是把 evolution_time 拉长。混沌需要时间放大微小差异30 秒足够让 1e-5 的差异爆发。ρ 一改效果全变。ρ28 时系统处于混沌态降到 10轨迹收敛到固定点蝴蝶直接消失。曲线不对劲时先检查这个参数。调参与延伸 三个进阶玩法扫一遍 ρ 看分岔。把_2024/manim_demo/lorenz.py中 lorenz_system 的默认 ρ 从 5、15 一路调到 28你会亲眼看到轨迹从静止点、闭合环切换到蝴蝶形态。换成 Rössler 吸引子。Rössler 系统同样是三条 ODE只需替换 lorenz_system 的函数体ode_solution_points 一行都不用改。把粒子思路搬到流场。_2015/ka_playgrounds/fluid_flow.py演示了如何把速度场变成流动粒子动画_2018/turbulence.py则是 3D 湍流版本借它们的粒子技法可以画 2D 混沌流。代码跑起来蝴蝶翅膀就飞起来了——你已能用这套轨迹向任何人讲清混沌。【免费下载链接】videosCode for the manim-generated scenes used in 3blue1brown videos项目地址: https://gitcode.com/GitHub_Trending/vi/videos创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考