Manim使用指南:从安装到生成数学动画(二)
第一部分见 https://blog.csdn.net/cnds123/article/details/165888604
针对数学教学/科普的实用避坑建议
1.中文字符使用Text,公式使用MathTex:
纯汉字标题、解释性口播字幕,使用
Text("中文", font="Microsoft YaHei");
纯公式或变量,使用
MathTex(r"\int_{0}^{\infty} f(x)dx")
(前面加r防止斜杠转义)。只要在 Manim(或任何 Python 代码)中编写 LaTeX 数学公式 或 正则表达式,引号前面加上r是最规范、绝不报错的好习惯。
2.善用TransformMatchingTex替代生硬的Transform:
讲解数学推导时,使用
TransformMatchingTex
可以让相同部分(如等号、已知项)固定在原地,只让变化的系数发生形变飞渡,观众的注意力不会被破坏。
3、可以通过self.next_section()把长视频分章节切片,只单独渲染修改的那一小节,极大节省等待时间。在 Scene 的 construct() 方法中,你可以在任意位置插入self.next_section(),它的作用是在时间轴上标记一个"章节边界"。长视频利用 --save_sections 和 --section 进行部分渲染。
在渲染时加上 --save_sections 参数:
manim -pql --save_sections my_scene.py MyLongScene
这样 Manim 会:
把每个章节单独导出为一个视频文件;
在输出目录中生成一个名为 MyLongScene.sections.json 的文件,记录了每个章节的起止时间、名称等信息。
这些分章节视频通常命名为 MyLongScene_0000.mp4、MyLongScene_0001.mp4 等。
Manim基础语法知识
1、Manim (Mathematical Animation Engine) 的核心概念
****·****Mobject(数学对象): 所有能出现在画面里的对象,如 Circle、Text、Axes、Dot。它不一定真是数学对象,也可以是普通文字或图片。
****·****Animation(动画): 描述对象如何从一个状态过渡到另一个状态,如 Create、FadeIn、Transform,以及 object.animate.shift(...)。
****·****Scene(场景): 连接对象和动画的容器。画面逻辑通常写在继承 Scene 的类里,并放进 construct() 方法。
【一个视频 ≈ 一个 Scene,但不完全等同。Scene 是一个独立的 "片段单元""
-
一个 `Scene` 类,渲染出来**默认生成一个独立的 mp4 视频文件**。
-
一个 py 脚本文件里面,可以写多个 Scene 类。】
· self.play() 播放一个或多个动画
· self.wait() 停顿(秒),控制节奏
以"导演思维"理解 Manim
对于"完全的小白",学习 Manim 最重要的不是去背 API,而是建立正确的"导演思维"。
写 Manim 代码就像是在写电影剧本,主要由四个核心概念组成:
1.舞台 (Scene)
·所有动画发生的空间。在代码中,你通常需要继承 Scene 类,并在其 construct 方法中写剧本。
2.演员/道具 (Mobject - Mathematical Object)
·屏幕上出现的任何东西都是道具。
·几何图形:Circle(圆)、Square(正方形)、Line(线条)。
·文字与公式:Text(普通文字)、MathTex(LaTeX 排版的数学公式)。
·坐标轴与函数图像:Axes、FunctionGraph。
3.表演/动画 (Animation)
·道具不会自己动,需要你给它们安排动作:
·出场:Create(画出来)、Write(写出来)、FadeIn(淡入)。
·变形:Transform(把 A 变成 B)。
·移动/变化:.animate 语法(比如让圆变大并向右移)。
·退场:FadeOut(淡出)、Uncreate。
4.时间流逝 (Time / Controller)
·self.play(...):播放一段动画(默认耗时 1 秒,可设置)。
·self.wait(2):画面停顿 2 秒,给观众思考时间。
2、基础语法知识
- 坐标系和空间定位
Manim 的屏幕是一个笛卡尔坐标系,中心是 (0, 0, 0)(简称 ORIGIN)。
Manim 遵循右手坐标系,方向非常直观:
X 轴:向右为正(对应预定义常量 RIGHT),向左为负(LEFT)。
Y 轴:向上为正(对应预定义常量 UP),向下为负(DOWN)。
Z 轴:垂直于屏幕,向外(朝向观察者)为正(OUT),向里(远离观察者)为负(IN)。这在制作 3D 旋转或图层叠加时非常有用。
Manim 的单位是抽象的"Manim 单位",与屏幕分辨率(像素)无关。默认情况下,Frame(镜头框) 的宽度为 8 个单位,高度为 4.5 个单位(适配 16:9 宽高比)。
2D 与 3D 的兼容性, 2D 动画,所有 Mobject(如圆形、正方形)默认的 z 坐标也是 0。
定位:怎么把东西放到正确的位置?
·绝对定位:
·circle.move_to(ORIGIN)(移动到中心)
·circle.move_to(2, 1, 0)(移动到 x=2, y=1 的位置)
·相对定位(更常用):
·circle.shift(UP * 2)(向上平移 2 个单位)
·text.next_to(circle, RIGHT, buff=0.5)(紧贴在圆的右侧,间距 0.5)
·obj.to_edge(UP)(移动到屏幕顶部边缘)
·obj.to_corner(UL)(移动到屏幕左上角 - Upper Left)
- 最强动画魔法:.animate
在较新的 ManimCE 中,.animate 是一个强大的"语法糖",它的核心作用就是将原本瞬间完成的属性修改,自动转换为平滑的动画过渡。你不需要为每个动作找特定的动画类,只需给对象的修改方法前加上 .animate 即可:
瞬间完成(没有动画):
circle.set_color(YELLOW)
circle.scale(2)
变成动画(在 2 秒内平滑过渡):self.play(circle.animate.set_color(YELLOW).scale(2), run_time=2)
使用方式:
在对象和方法之间插入 .animate;
将整个表达式放入 self.play() 中。
- 数学公式 (MathTex)
Manim 最强大的地方是排版公式。如果你懂一点 LaTeX,就会觉得无比丝滑:
注意:字符串前面要加 r,防止反斜杠转义
formula = MathTex(r"e^{i\pi} + 1 = 0")self.play(Write(formula))
注意:****MathTex 的功能在底层依赖 LaTeX 系统,****Windows中推荐 MiKTeX。这就是前面提到的建议安装 MiKTeX原因。
3、之后高效学习路线
第一阶段目标:能用代码摆出静止的排版。
掌握基本图形:Dot, Line, Arrow, Circle, Rectangle。也熟悉 Square、Triangle、Polygon 和 Tex/MathTex(用于文字/公式)。所有图形默认中心在 ORIGIN。
熟练使用 shift, move_to, next_to, align_to 排布图形位置。shift 是相对移动,move_to 是移动到绝对位置,next_to 和 align_to 是排版布局的核心。next_to 可以指定方向(UP, DOWN, LEFT, RIGHT)和对齐方式。
学会用 VGroup(矢量组)把多个小零件捆绑在一起统一缩放和移动。这是组织复杂图形的关键。当你想整体旋转或移动多个元素时,不用逐一操作,直接操作 VGroup 即可。
示例:
python
from manim import *
class Stage1Layout(Scene):
def construct(self):
# 1. 创建几个基本图形
dot = Dot(point=LEFT * 3, color=BLUE)
circle = Circle(radius=0.5, color=YELLOW)
rect = Rectangle(width=2, height=1, color=GREEN)
tex = MathTex(r"E = mc^2", color=RED)
# 2. 使用 next_to 进行排版
# 圆在点的右侧,边距0.5
circle.next_to(dot, RIGHT, buff=0.5)
# 矩形在圆的上方,对齐方式为圆心对圆心(也可以对边缘)
rect.next_to(circle, UP, aligned_edge=ORIGIN)
# 公式在矩形的内部
tex.move_to(rect.get_center())
# 3. 用 VGroup 统一管理并整体移动
group = VGroup(dot, circle, rect, tex)
group.shift(UP * 2) # 整体上移2个单位
# 4. 添加到场景
self.add(dot, circle, rect, tex)
self.wait(1)
第二阶段目标:能让元素以多种方式动起来。
常用出场动画:Create, Write, FadeIn, GrowFromCenter。Create 常用于"绘制"线条和轮廓,Write 专用于文字公式(手写效果),FadeIn 是淡入,GrowFromCenter 是从中心生长出来。
属性变化:熟练使用 .animate 修改大小、颜色、位置。.animate 是 ManimCE 的灵魂。它可以链式调用,例如 self.play(circle.animate.scale(2).set_color(RED).shift(RIGHT))。
变形动画:Transform 和 ReplacementTransform(把一个对象替换为另一个)。Transform 是把一个物体变成另一个,颜色和位置会平滑过渡。ReplacementTransform 会直接替换,常用于更彻底的变形。
补充一个技巧:善用 run_time 和 rate_func 来控制动画的速度和节奏。
示例:
python
from manim import *
class Stage2Animation(Scene):
def construct(self):
# 1. 创建一个正方形并入场
square = Square()
self.play(Create(square), run_time=1)
# 2. 使用 .animate 改变属性(缩放 + 变色)
self.play(square.animate.scale(1.5).set_color(BLUE), run_time=2)
# 3. 使用 Transform 变形为圆形
circle = Circle(color=RED)
self.play(Transform(square, circle)) # 这里 square 会变成 circle
# 4. 使用 ReplacementTransform 替换为公式
tex = MathTex(r"\int_0^1 x^2 dx")
self.play(ReplacementTransform(square, tex))
self.wait(1)
第三阶段目标:数学与图表目标:绘制函数曲线和坐标系。
创建平面直角坐标系 Axes。使用 Axes(或 NumberPlane)创建坐标轴,并可以设置 x_range、y_range、axis_config 等。
使用 axes.plot(lambda x: x**2) 绘制数学函数图像。用 axes.plot(lambda x: ...) 绘制曲线,并可以着色。
学习 ValueTracker(变量追踪器)------比如让切线随着切点在函数上平滑滑动(这是 Manim 的灵魂所在)。这是一个能存储数值的"容器"。你可以改变它的值,同时让对象(如点、切线、图形)通过 add_updater 跟随这个值的变化而更新。这确实就是"灵魂",因为实现了数据驱动动画。
示例:
python
from manim import *
class Stage3Graph(Scene):
def construct(self):
# 1. 创建坐标系
axes = Axes(
x_range=[-5, 5, 1],
y_range=[0, 5, 1],
x_length=10,
y_length=5,
tips=False
)
# 2. 绘制函数图像
graph = axes.plot(lambda x: x**2, color=YELLOW)
graph_label = axes.get_graph_label(graph, label="x^2")
# 3. 核心:用 ValueTracker 控制一个点在函数上运动
x_tracker = ValueTracker(-3) # 初始 x = -3
# 这个点会随着 x_tracker 的值改变而移动
dot = Dot(color=RED)
# 用 add_updater 让 dot 的位置每帧都根据 x_tracker 更新
dot.add_updater(
lambda d: d.move_to(axes.coords_to_point(x_tracker.get_value(), x_tracker.get_value()**2))
)
self.add(axes, graph, graph_label, dot)
self.wait(1)
# 让 x_tracker 从 -3 移动到 3,dot 就会跟着动!
self.play(x_tracker.animate.set_value(3), run_time=4)
self.wait(1)
第四阶段:进阶
学习使用 add_updater(每一帧自动更新对象状态,用于制作复杂的力学模拟或联动)。add_updater除了让点跟随,还可以做更复杂的事情,比如让多个物体进行"物理模拟"或"逻辑联动"。注意:使用 updater 时,如果对象被移动或变换,可能需要重新调用 add_updater 或使用 always_redraw。
学习三维场景 ThreeDScene。开启三维世界,需要导入 ThreeDScene,并可以用 set_camera_orientation 设置相机初始角度,用 begin_ambient_camera_rotation 让相机自动旋转。
示例:
python
from manim import *
class Stage4ThreeD(ThreeDScene):
def construct(self):
# 创建3D物体
sphere = Sphere(radius=1, color=BLUE)
axes = ThreeDAxes()
self.set_camera_orientation(phi=60 * DEGREES, theta=30 * DEGREES)
self.play(Create(axes), Create(sphere))
# 让相机自动旋转,产生3D效果
self.begin_ambient_camera_rotation(rate=0.2)
self.wait(3)
self.stop_ambient_camera_rotation()
# 移动相机
self.move_camera(phi=30 * DEGREES, theta=-45 * DEGREES, run_time=1.5)
self.wait(1)