SciTech-Mathmatics-Manim: 数学动画制作引擎 @由3Blue1Brown(Grant Sanderson)
SciTech-Mathmatics-Manim: 数学动画制作引擎@由3Blue1Brown(Grant Sanderson)
Manim: 数学动画制作引擎@由3Blue1Brown(Grant Sanderson)
1. 基础知识与环境配置
1.1 什么是Manim?
Manim是一个强大的数学动画制作引擎,由3Blue1Brown(Grant Sanderson)开发。
它使用Python语言,能够创建高质量的数学解释视频和其他教学动画。
1.2 环境配置
首先需要安装Python环境(建议Python 3.7+),然后安装以下必要的包:
安装 Manim主程序 + 必要的依赖包
pip install manim
pip install numpy # 数学计算库
pip install pillow # 图像处理库
1.3 第一个Manim场景
让我们从一个最简单的例子开始,创建一个显示文字的场景:
# 导入Manim所有内容
from manim import *
# 创建一个简单的场景类
# 创建文字对象,使用SimHei字体以显示中文; # 使用Write动画显示文字, 并等待两秒
class HelloManim(Scene):
def construct(self):
text = Text("你好,Manim!", font="SimHei")
self.play(Write(text))
self.wait(2)
运行这个场景:
manim 命令行参数:
-p: 运行完成后预览- 渲染画质:
-ql: 低质量渲染(快速预览)
manim -pql hello_manim.py HelloManim-qh: 高质量渲染(生成视频用)
manim -pqh hello_manim.py HelloManim
1.4 基本图形绘制
让我们学习如何绘制一些基本图形:
class BasicShapes(Scene):
def construct(self):
# 1. 创建一个圆形
circle = Circle(
radius=1.0, # 半径
color=BLUE, # 颜色
stroke_width=2.0 # 线条宽度
)
# 添加圆形到场景
self.play(Create(circle))
self.wait(1)
# 2. 创建一个方形
square = Square(
side_length=2.0, # 边长
color=RED, # 颜色
fill_opacity=0.5 # 填充透明度
)
# 将方形移动到圆形右边
square.next_to(circle, RIGHT)
# 添加方形到场景
self.play(Create(square))
self.wait(1)
1.5 颜色使用
Manim提供了多种方式来使用颜色:
class ColorDemo(Scene):
def construct(self):
# 1. 使用内置颜色
text1 = Text("内置颜色", color=RED, font="SimHei")
self.play(Write(text1))
self.wait(1)
# 2. 使用RGB颜色
text2 = Text(
"RGB颜色",
color=rgb_to_color([0.5, 0.8, 0.2]),
font="SimHei"
).next_to(text1, DOWN)
self.play(Write(text2))
self.wait(1)
# 3. 使用HEX颜色
text3 = Text(
"HEX颜色",
color="#FF6B6B",
font="SimHei"
).next_to(text2, DOWN)
self.play(Write(text3))
self.wait(1)
1.6 简单动画
让我们学习一些基本的动画效果:
class SimpleAnimations(Scene):
def construct(self):
# 1. 创建一个圆形
circle = Circle(color=BLUE)
# 渐现动画
self.play(FadeIn(circle))
self.wait(1)
# 移动动画
self.play(circle.animate.shift(RIGHT * 2))
self.wait(1)
# 缩放动画
self.play(circle.animate.scale(2))
self.wait(1)
# 改变颜色动画
self.play(circle.animate.set_color(RED))
self.wait(1)
1.7 坐标系统基础
下面介绍如何使用坐标系统:
class CoordinateSystemDemo(Scene):
def construct(self):
# 1. 创建一个简单的坐标轴
axes = Axes(
x_range=[-3, 3], # x轴范围
y_range=[-2, 2], # y轴范围
axis_config={
"include_numbers": True, # 显示数字
"include_tip": True # 显示箭头
}
)
# 添加坐标轴标签
labels = axes.get_axis_labels(
x_label="x",
y_label="y"
)
# 显示坐标轴和标签
self.play(Create(axes), Write(labels))
self.wait(1)
# 2. 在坐标系中画一个点
point = Dot(axes.coords_to_point(1, 1))
point_label = Text("(1,1)", font="SimHei").next_to(point, UR, buff=0.1)
self.play(Create(point), Write(point_label))
self.wait(1)
每个代码示例都包含了详细的中文注释,解释了每一步的操作。
建议初学者按顺序学习,每个例子都可以单独运行和测试。
在理解一个概念后再继续学习下一个概念。
1.8 运行建议
每个示例都保存为单独的.py文件
开发时使用 -ql 参数快速预览
最终渲染时使用 -qh 参数获得高质量输出
可以使用 -s 参数跳过已经渲染的部分
2. 进阶动画技巧
2.1 动画组合
学习如何同时播放多个动画或按顺序播放动画:
class AnimationGroups(Scene):
def construct(self):
# 1. 创建多个形状
circle = Circle(color=BLUE)
square = Square(color=RED)
triangle = Triangle(color=GREEN)
# 将形状排列
shapes = VGroup(circle, square, triangle).arrange(RIGHT, buff=1)
# 同时显示所有形状
self.play(
*[Create(shape) for shape in shapes]
)
self.wait(1)
# 依次改变颜色
self.play(
circle.animate.set_color(YELLOW),
square.animate.set_color(PURPLE),
triangle.animate.set_color(ORANGE),
lag_ratio=0.5 # 动画之间的延迟
)
self.wait(1)
2.2 自定义动画
学习如何创建自定义的动画效果:
class CustomAnimation(Scene):
def construct(self):
# 1. 创建一个正方形
square = Square(color=BLUE)
# 2. 自定义动画类
class RotateAndScale(Animation):
def interpolate_mobject(self, alpha):
# alpha从0变化到1
self.mobject.rotate(alpha * PI) # 旋转
self.mobject.scale(1 + alpha) # 放大
# 使用自定义动画
self.play(RotateAndScale(square))
self.wait(1)
2.3 路径动画
学习如何让物体沿着特定路径移动:
class PathAnimation(Scene):
def construct(self):
# 1. 创建一个圆形路径
circle = Circle(radius=2, color=GRAY)
dot = Dot(color=RED)
# 将点放在圆上
dot.move_to(circle.point_at_angle(0))
# 显示圆形和点
self.play(Create(circle), FadeIn(dot))
# 让点沿着圆移动
self.play(
MoveAlongPath(dot, circle),
run_time=3 # 动画持续3秒
)
self.wait(1)
2.4 变换动画
学习如何实现形状之间的变换:
class TransformExample(Scene):
def construct(self):
# 1. 创建起始形状
circle = Circle(color=BLUE)
# 2. 创建目标形状
square = Square(color=RED)
# 显示圆形
self.play(Create(circle))
self.wait(1)
# 将圆形变换为方形
self.play(Transform(circle, square))
self.wait(1)
# 创建文字
text1 = Text("你好", font="SimHei")
text2 = Text("世界", font="SimHei")
# 文字变换
self.play(Write(text1))
self.wait(1)
self.play(ReplacementTransform(text1, text2))
self.wait(1)
2.5 相机动画
学习如何使用相机动画来改变视角:
class CameraExample(Scene):
def construct(self):
# 1. 创建一些物体
circle = Circle(radius=1)
square = Square()
triangle = Triangle()
shapes = VGroup(circle, square, triangle).arrange(RIGHT, buff=2)
# 显示所有形状
self.play(Create(shapes))
self.wait(1)
# 相机缩放
self.camera.frame.save_state()
self.play(
self.camera.frame.animate.scale(0.5).move_to(circle)
)
self.wait(1)
# 移动到方形
self.play(
self.camera.frame.animate.move_to(square)
)
self.wait(1)
# 恢复相机
self.play(Restore(self.camera.frame))
self.wait(1)
每个新添加的示例都保持了相同的风格:
- 代码块简短且专注于单个概念
- 详细的中文注释
- 清晰的步骤划分
- 适当的等待时间
- 渐进式的学习曲线
建议学习者:
- 先理解每个示例的基本概念
- 尝试修改参数来观察效果
- 尝试组合不同的动画效果
- 创建自己的场景来巩固学习
3. 数学与物理动画
3.1 函数图像
学习如何绘制和动画展示数学函数:
class FunctionPlotting(Scene):
def construct(self):
# 1. 创建坐标系
axes = Axes(
x_range=[-3, 3],
y_range=[-2, 2],
axis_config={"include_numbers": True}
)
# 添加标签
labels = axes.get_axis_labels(
x_label="x", y_label="f(x)"
)
# 显示坐标系
self.play(Create(axes), Write(labels))
self.wait(1)
# 2. 绘制函数 f(x) = x^2
parabola = axes.plot(
lambda x: x**2,
color=BLUE,
x_range=[-2, 2]
)
# 添加函数表达式
func_label = MathTex("f(x)=x^2").next_to(parabola, UR)
# 显示函数图像
self.play(Create(parabola), Write(func_label))
self.wait(1)
3.2 参数方程
学习如何绘制参数方程曲线:
class ParametricCurve(Scene):
def construct(self):
# 1. 创建坐标系
axes = Axes(
x_range=[-4, 4],
y_range=[-4, 4]
)
# 2. 创建参数曲线(心形线)
heart = ParametricFunction(
lambda t: np.array([
16 * np.sin(t)**3,
13 * np.cos(t) - 5 * np.cos(2*t) - 2 * np.cos(3*t) - np.cos(4*t)
]) / 16,
t_range=[0, TAU],
color=RED
)
# 显示坐标系和曲线
self.play(Create(axes))
self.play(Create(heart))
self.wait(1)
3.3 动态更新
学习如何创建动态更新的图形:
class DynamicUpdating(Scene):
def construct(self):
# 1. 创建一个点和一个圆
dot = Dot(RIGHT * 2)
circle = Circle(radius=2)
# 2. 创建一条连接圆心和点的线
line = Line(ORIGIN, dot.get_center())
line.add_updater(
lambda l: l.become(
Line(ORIGIN, dot.get_center())
)
)
# 显示所有元素
self.play(Create(circle), Create(dot), Create(line))
# 移动点,线会自动更新
self.play(
Rotating(
dot,
about_point=ORIGIN,
angle=TAU,
run_time=4
)
)
self.wait(1)
3.4 物理模拟
学习如何创建简单的物理模拟动画:
class SimplePhysics(Scene):
def construct(self):
# 1. 创建一个小球
ball = Circle(radius=0.2, fill_color=BLUE, fill_opacity=1)
ball.move_to(UP * 3)
# 2. 创建地面
ground = Line(LEFT * 4, RIGHT * 4, color=WHITE)
# 显示物体
self.play(Create(ground), Create(ball))
# 3. 模拟自由落体
def get_y(t):
g = 9.8 # 重力加速度
y0 = 3 # 初始高度
v0 = 0 # 初始速度
return y0 - 0.5 * g * t**2
# 创建动画
ball.add_updater(
lambda m, dt: m.move_to([
m.get_center()[0],
get_y(self.time),
0
])
)
# 运行1秒
self.wait()
self.play(ball.animate.move_to(ground.get_center() + UP * 0.2))
self.wait(1)
3.5 向量场
学习如何绘制向量场:
class VectorField(Scene):
def construct(self):
# 1. 创建坐标系
plane = NumberPlane(
x_range=[-5, 5],
y_range=[-5, 5]
)
# 2. 创建向量场函数
def field_func(pos):
x, y = pos[:2]
return np.array([
-y, # x分量
x, # y分量
0 # z分量
]) / 2
# 3. 创建向量场
vector_field = ArrowVectorField(
field_func,
x_range=[-4, 4, 1],
y_range=[-4, 4, 1],
length_func=lambda x: 0.5
)
# 显示坐标系和向量场
self.play(Create(plane))
self.play(Create(vector_field))
self.wait(1)
# 4. 添加一个跟随场的粒子
dot = Dot(RIGHT * 2, color=RED)
# 让粒子沿着场移动
self.play(Create(dot))
self.play(
MoveAlongPath(
dot,
ParametricFunction(
lambda t: np.array([
2 * np.cos(t),
2 * np.sin(t),
0
]),
t_range=[0, TAU]
)
),
run_time=4
)
self.wait(1)
这些新示例展示了如何使用Manim创建数学和物理相关的动画。每个示例都:
- 专注于一个具体的数学或物理概念
- 包含详细的中文注释
- 展示了如何组合基本元素来创建复杂的动画
- 提供了可以扩展和修改的基础代码
建议
- 尝试修改数学函数来创建不同的图像
- 实验不同的物理参数
- 组合多个概念来创建更复杂的演示
- 添加文字说明来增强教学效果
4. LaTeX与文本动画
4.1 基础LaTeX
学习如何在Manim中使用LaTeX:
class BasicLaTeX(Scene):
def construct(self):
# 1. 简单的数学公式
formula1 = MathTex(r"e^{i\pi} + 1 = 0")
# 显示公式
self.play(Write(formula1))
self.wait(1)
# 2. 多行公式
formula2 = MathTex(
r"\frac{d}{dx} e^x &= e^x \\",
r"\frac{d}{dx} \ln(x) &= \frac{1}{x}"
)
formula2.next_to(formula1, DOWN, buff=1)
# 显示多行公式
self.play(Write(formula2))
self.wait(1)
4.2 公式动画
学习如何制作公式变换动画:
class FormulaTransformation(Scene):
def construct(self):
# 1. 创建初始公式
formula1 = MathTex(
r"(a + b)^2"
)
# 2. 创建展开步骤
formula2 = MathTex(
r"a^2 + 2ab + b^2"
)
# 显示初始公式
self.play(Write(formula1))
self.wait(1)
# 变换到展开形式
self.play(
TransformMatchingTex(
formula1,
formula2
)
)
self.wait(1)
4.3 分步公式推导
学习如何制作分步数学推导:
class StepByStepDerivation(Scene):
def construct(self):
# 1. 创建推导步骤
steps = VGroup(
MathTex(r"\int x^2 dx"),
MathTex(r"= \frac{x^3}{3}"),
MathTex(r"= \frac{x^3}{3} + C")
).arrange(DOWN, buff=0.5)
# 2. 添加推导箭头
arrows = VGroup(*[
Arrow(
steps[i].get_bottom(),
steps[i+1].get_top(),
buff=0.1
)
for i in range(len(steps)-1)
])
# 3. 逐步显示推导过程
for i, step in enumerate(steps):
self.play(Write(step))
if i < len(arrows):
self.play(Create(arrows[i]))
self.wait(1)
4.4 文本样式与效果
学习如何设置文本样式和特效:
class TextStylesAndEffects(Scene):
def construct(self):
# 1. 基本样式
text1 = Text(
"不同的文字样式",
font="SimHei",
color=BLUE,
weight=BOLD
)
# 2. 渐变色文字
text2 = Text(
"渐变色文字效果",
font="SimHei",
gradient=[RED, YELLOW, GREEN]
).next_to(text1, DOWN)
# 3. 描边文字
text3 = Text(
"描边文字效果",
font="SimHei",
stroke_width=5,
stroke_color=YELLOW,
fill_color=RED
).next_to(text2, DOWN)
# 显示所有文本
self.play(Write(text1))
self.play(Write(text2))
self.play(Write(text3))
self.wait(1)
4.5 动态文字效果
学习如何创建动态文字效果:
class DynamicText(Scene):
def construct(self):
# 1. 创建打字机效果
text = Text(
"这是一个打字机效果",
font="SimHei"
)
# 逐字显示
for i in range(len(text)):
self.play(
Create(text[i]),
run_time=0.2
)
self.wait(1)
# 2. 创建波浪效果
wave_text = Text(
"波浪效果文字",
font="SimHei"
).next_to(text, DOWN)
def wave_effect(mob, dt):
for i, char in enumerate(mob):
char.shift(
UP * np.sin(
self.time - i/3
) * 0.02
)
# 显示文字并添加波浪效果
self.play(Write(wave_text))
wave_text.add_updater(wave_effect)
self.wait(3)
4.6 公式与文本组合
学习如何组合公式和文本:
class CombineFormulaAndText(Scene):
def construct(self):
# 1. 创建标题
title = Text(
"二次函数公式",
font="SimHei",
color=BLUE
).to_edge(UP)
# 2. 创建公式
formula = MathTex(
r"f(x) = ax^2 + bx + c"
).next_to(title, DOWN)
# 3. 创建说明文本
description = VGroup(
Text("其中:", font="SimHei"),
Text("a 是二次项系数", font="SimHei"),
Text("b 是一次项系数", font="SimHei"),
Text("c 是常数项", font="SimHei")
).arrange(DOWN, aligned_edge=LEFT).next_to(formula, DOWN)
# 显示所有元素
self.play(Write(title))
self.play(Write(formula))
self.play(Write(description))
self.wait(1)
# 4. 添加动画效果
# 依次高亮各个系数
for i, term in enumerate(['a', 'b', 'c']):
self.play(
formula.get_part_by_tex(term).animate.set_color(YELLOW),
description[i+1].animate.set_color(YELLOW),
run_time=0.5
)
self.wait(0.5)
self.play(
formula.get_part_by_tex(term).animate.set_color(WHITE),
description[i+1].animate.set_color(WHITE),
run_time=0.5
)
这些新示例展示了如何:
- 使用LaTeX创建数学公式
- 制作公式变换动画
- 创建分步数学推导
- 设置不同的文本样式
- 制作动态文字效果
- 组合公式和说明文本
建议:
- 先熟悉基本的LaTeX语法
- 从简单的公式开始,逐步尝试复杂的数学表达式
- 注意中文字体的设置
- 合理使用动画时间和等待时间
- 适当添加说明文字,提高可读性
5. 三维动画制作
5.1 基本三维物体
学习如何创建和操作基本的三维物体:
class Basic3DObjects(ThreeDScene):
def construct(self):
# 设置相机角度
self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
# 1. 创建一个立方体
cube = Cube(
side_length=2,
fill_opacity=0.8,
stroke_width=2
)
# 显示立方体
self.play(Create(cube))
self.wait(1)
# 旋转立方体
self.play(
Rotate(
cube,
angle=2*PI,
axis=RIGHT,
run_time=3
)
)
self.wait(1)
5.2 三维坐标系
学习如何使用三维坐标系:
class ThreeDCoordinates(ThreeDScene):
def construct(self):
# 设置相机角度
self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
# 1. 创建三维坐标系
axes = ThreeDAxes(
x_range=[-3, 3],
y_range=[-3, 3],
z_range=[-3, 3]
)
# 添加坐标轴标签
labels = VGroup(
Text("x", font="SimHei").next_to(axes.x_axis, RIGHT),
Text("y", font="SimHei").next_to(axes.y_axis, UP),
Text("z", font="SimHei").next_to(axes.z_axis, OUT)
)
# 显示坐标系和标签
self.play(Create(axes), Write(labels))
self.wait(1)
# 2. 在坐标系中添加一个点
point = Dot3D(
point=axes.coords_to_point(2, 1, 1),
color=RED
)
# 显示点
self.play(Create(point))
self.wait(1)
5.3 参数曲面
学习如何创建参数曲面:
class ParametricSurface(ThreeDScene):
def construct(self):
# 设置相机角度
self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
# 1. 创建一个球面
sphere = Surface(
lambda u, v: np.array([
np.cos(u) * np.cos(v),
np.cos(u) * np.sin(v),
np.sin(u)
]),
u_range=[-PI/2, PI/2],
v_range=[0, TAU],
resolution=(30, 30),
checkerboard_colors=[BLUE_D, BLUE_E]
)
# 显示球面
self.play(Create(sphere))
self.wait(1)
# 旋转相机查看不同角度
self.begin_ambient_camera_rotation(rate=0.2)
self.wait(5)
self.stop_ambient_camera_rotation()
5.4 三维图形变换
学习如何制作三维图形变换动画:
class ThreeDTransformations(ThreeDScene):
def construct(self):
# 设置相机角度
self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
# 1. 创建一个棱柱
prism = Prism(dimensions=[2, 1, 1])
# 显示棱柱
self.play(Create(prism))
self.wait(1)
# 2. 进行一系列变换
# 缩放
self.play(
prism.animate.scale(1.5)
)
self.wait(1)
# 旋转
self.play(
Rotate(
prism,
angle=PI/2,
axis=UP
)
)
self.wait(1)
# 移动
self.play(
prism.animate.shift(RIGHT * 2)
)
self.wait(1)
5.5 三维文字
学习如何在三维空间中使用文字:
class ThreeDText(ThreeDScene):
def construct(self):
# 设置相机角度
self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
# 1. 创建3D文字
text3d = Text3D(
"Manim 3D",
font="SimHei",
depth=0.5
)
# 显示文字
self.play(Create(text3d))
self.wait(1)
# 旋转文字
self.play(
Rotate(
text3d,
angle=TAU,
axis=UP,
run_time=3
)
)
self.wait(1)
5.6 复杂三维场景
学习如何创建包含多个元素的复杂三维场景:
class Complex3DScene(ThreeDScene):
def construct(self):
# 设置相机角度
self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
# 1. 创建坐标系
axes = ThreeDAxes()
# 2. 创建一个球体
sphere = Surface(
lambda u, v: np.array([
np.cos(u) * np.cos(v),
np.cos(u) * np.sin(v),
np.sin(u)
]),
u_range=[-PI/2, PI/2],
v_range=[0, TAU],
resolution=(15, 15)
)
# 3. 创建一些点
points = [
Dot3D(point=axes.coords_to_point(*pos), color=RED)
for pos in [(1,1,1), (-1,-1,1), (1,-1,-1)]
]
# 4. 创建连接线
lines = VGroup(*[
Line3D(
start=points[i].get_center(),
end=points[i-1].get_center(),
color=YELLOW
)
for i in range(len(points))
])
# 5. 添加标签
labels = VGroup(*[
Text(f"P{i+1}", font="SimHei").next_to(point, UP)
for i, point in enumerate(points)
])
# 逐步构建场景
self.play(Create(axes))
self.play(Create(sphere))
for point in points:
self.play(Create(point))
self.play(Create(lines))
self.play(Write(labels))
# 旋转场景
self.begin_ambient_camera_rotation(rate=0.2)
self.wait(5)
self.stop_ambient_camera_rotation()
这些新示例展示了如何:
- 创建基本的三维物体
- 使用三维坐标系
- 创建参数曲面
- 进行三维变换
- 在三维空间中使用文字
- 构建复杂的三维场景
使用三维动画的建议:
- 注意相机角度的设置,确保物体可以清晰地看到
- 使用适当的光照和材质设置
- 添加相机动画来展示不同视角
- 合理安排动画时间,让观众能够理解场景
- 适当使用标签和说明文字
- 在复杂场景中逐步添加元素
注意事项:
- 三维场景需要更多的渲染时间
- 复杂的三维物体可能会影响性能
- 建议先在低质量模式下预览
- 最终渲染时再使用高质量设置
发布于 2025-07-10 22:13・广东
Manim常用总结
Manim教程
谈老师 · 发表于科学与技术
Manim教程
manim新版本manimgl笔记(一)安装与基本的使用方法
manim新版本manimgl笔记(二)manim整体的组织结构与基本的常量

浙公网安备 33010602011771号