通用数学动画框架,基于 Manim Community。 不是只做最小二乘法,而是提供一套可复用的通用组件,让后续 OLS、梯度下降、PCA、Attention 等 动画共享同一套坐标系 / 字幕 / 公式板 / 统计面板。
参考了原 ols.html(保留在根目录作对照),但按 3Blue1Brown 风格重新设计:
- 用
ValueTracker + always_redraw驱动整条视觉链路,不需要手写帧循环 - 一句
self.play(slope.animate.set_value(target))让直线 / 残差 / 正方形 / RSS 数字一起动 TransformMatchingTex让公式之间自然过渡(y = β₀ + β₁x + ε→RSS = Σ...→min Σ ε²)- 每个 demo 一个目录,包含
scene.py/objects.py/config.yaml config.yaml驱动数据点 + 字幕 + 公式文本 + 主题色
math-animator/
├── README.md, requirements.txt, render.py
├── ols.html # 原 HTML 演示, 保留作对照
├── common/ # 通用组件 (任意 demo 复用)
│ ├── theme.py # 配色主题
│ ├── subtitle.py # 双语字幕条
│ ├── panel.py # StatPanel (实时数字)
│ ├── formula.py # FormulaBoard (公式变换)
│ ├── axes.py # 坐标系工厂
│ ├── title.py # 标题卡
│ └── utils.py # config 加载 / ease 函数
├── math_core/ # 纯数学计算, 不依赖 manim
│ ├── ols.py # OLS 解析解 + RSS
│ └── gradient_descent.py # 一维梯度下降
└── scenes/
├── ols/ # demo: 最小二乘法
│ ├── scene.py # OLSAnimation, 8 个 phase
│ ├── objects.py # RegressionLine / Residuals / Squares
│ └── config.yaml
└── gradient_descent/ # demo: 梯度下降 (验证框架通用性)
├── scene.py # GDAnimation, 7 个 phase
├── objects.py # LossCurve / Ball / Tangent / Trajectory
└── config.yaml
需要 Python 3.9+、ffmpeg、LaTeX(用于 MathTex 渲染)。
# 1. 系统依赖
brew install ffmpeg
brew install --cask basictex # 较小的 LaTeX (~100MB); 完整版用 mactex-no-gui
eval "$(/usr/libexec/path_helper)" # 让 PATH 包含 /Library/TeX/texbin
# 2. Python 依赖
cd math-animator
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txtmanim --version # 应输出 0.18+
python3 -c "from manim import Scene; print('ok')"# 列出所有 demo
python render.py --list
# 渲染 OLS (默认 1080p mp4)
python render.py ols
# 720p + 渲染完自动播放
python render.py ols -q m -p
# 梯度下降导出 gif
python render.py gd --format gif
# 只渲染某个 section (开发调试用)
python render.py ols --section optimize输出在 media/videos/<scene>/<quality>/ 目录下。
也可以直接用 manim CLI:
manim scenes/ols/scene.py OLSAnimation -qh
manim scenes/gradient_descent/scene.py GDAnimation -qh --format gif| phase | 内容 | 公式 |
|---|---|---|
| intro | 标题 + 主公式 FadeIn | y = β₀ + β₁x + ε |
| points | 坐标系 + 9 个数据点逐个出现 | (同上) |
| line | 出现初始水平直线 | (同上) |
| residual | 每个点画到直线的虚线 (残差) | yᵢ − ŷᵢ |
| square | 残差线长出正方形 (面积 = ε²) | εᵢ² |
| rss | 右侧面板出现, 实时 β₁ / β₀ / RSS | RSS = Σ(yᵢ − ŷᵢ)² |
| optimize | 一句 play 让直线连续旋转/平移到 OLS 解, RSS 同步下降 | (同上) |
| summary | 公式变绿, 拟合线变绿 | min Σ εᵢ² |
- 在
math_core/加一个纯算法模块(如pca.py),不依赖 manim - 在
scenes/新建目录<name>/,包含:config.yaml: 数据点 / 字幕 / 公式 / 主题objects.py: 该 demo 专用的 mobject 工厂(用always_redraw绑定 tracker)scene.py: 一个Scene子类,construct里调用next_section()分阶段
- 在
render.py的DEMOS字典里登记
参考 scenes/gradient_descent/ —— 它就是按这套规则复用 common/ 组件实现的,
和 OLS 共享 Axes / TitleCard / FormulaBoard / Subtitle / StatPanel,但表达的是完全不同的算法。
always_redraw用在该用的地方:连续参数变化时(拟合线、残差、球位置、切线)才用, 静态元素用普通 mobject,性能与可读性更好。Scene一个类 + phase 方法 +next_section():不是 8 个独立 Scene 文件(那样要 ffmpeg 拼接)。next_section既能让一次渲染出完整视频,也支持--from_section --to_section部分渲染便于调试。- YAML 驱动数据 + 字幕 + 公式文本,但编排逻辑保留在 Python。 ChatGPT 原方案末尾"动画引擎自动生成整个视频"对 OLS 行,但对 Attention/Transformer 这种复杂 动画不现实,因此框架只把可参数化的部分(数据、字幕、配色、公式字符串)放进 YAML。
- 数学计算与动画分离:
math_core/不 import manim,可单独pytest测试。