文中内容仅限技术学习与代码实践参考,市场存在不确定性,技术分析需谨慎验证,不构成任何投资建议。
快速入门
注意:在继续之前,请按照安装步骤安装 Manim,并确保其能够正常运行。如果需要了解如何在 JupyterLab 或 Jupyter Notebook 中使用 Manim,请查阅有关 IPython magic command
的文档,即 %%manim
。
重要提示:如果您按照推荐的方式使用 Python 管理工具 uv
安装了 Manim,那么您需要确保对应的虚拟环境已激活(按照运行 uv venv
时打印的说明进行操作),或者记得在控制台中使用 manim
命令时加上前缀 uv run
,即 uv run manim ...
。
概述
本快速入门指南将引导您使用 Manim 创建一个示例项目:Manim 是一个用于精确编程动画的动画引擎。
首先,您将使用命令行界面创建一个 Scene
类,Manim 通过该类生成视频。在 Scene
中,您将制作一个圆形的动画。然后,您将添加另一个 Scene
,展示一个正方形如何变形为圆形。这将带您初步了解 Manim 的动画功能。之后,您将定位多个数学对象(Mobject
)。最后,您将学习 .animate
语法,这是一个强大的功能,可以将您用于修改 Mobject
的方法变为动画。
开始新项目
首先创建一个新文件夹:
manim init project my-project --default
my-project
文件夹是项目的根文件夹。它包含 Manim 运行所需的所有文件,以及项目产生的任何输出。
制作圆形动画
-
打开文本编辑器,例如记事本。打开
my-project
文件夹中的main.py
文件。它应该看起来像这样:from manim import * class CreateCircle(Scene): def construct(self): circle = Circle() # 创建一个圆形 circle.set_fill(PINK, opacity=0.5) # 设置颜色和透明度 self.play(Create(circle)) # 在屏幕上显示圆形
-
打开命令行,导航到项目文件夹,并执行以下命令:
manim -pql main.py CreateCircle
Manim 将输出渲染信息,然后创建一个 MP4 文件。您的默认视频播放器将播放 MP4 文件,显示以下动画。
如果您看到一个粉色圆形被绘制的动画,恭喜您!您刚刚从头开始编写了第一个 Manim 场景。
如果您收到错误消息,没有看到视频,或者视频输出与上述动画不符,很可能 Manim 没有正确安装。请参阅我们的常见问题解答部分,以获取有关常见问题的帮助。
解释
让我们逐行查看刚才执行的脚本,看看 Manim 是如何绘制圆形的。
第一行导入了库中的所有内容:
这是使用 Manim 的推荐方式,因为一个脚本通常会使用 Manim 命名空间中的多个名称。在您的脚本中,您导入并使用了 Scene
、Circle
、PINK
和 Create
。
现在让我们看看接下来的两行:
class CreateCircle(Scene):
def construct(self):
[...]
大多数情况下,编写动画的代码完全包含在 Scene
类的 construct()
方法中。在 construct()
内部,您可以创建对象、在屏幕上显示它们,并对它们进行动画处理。
接下来的两行创建了一个圆形并设置了它的颜色和透明度:
circle = Circle() # 创建一个圆形
circle.set_fill(PINK, opacity=0.5) # 设置颜色和透明度
最后,最后一行使用动画 Create
在屏幕上显示圆形:
self.play(Create(circle)) # 在屏幕上显示圆形
提示:所有动画都必须位于从 Scene
派生的类的 construct()
方法内。其他代码,例如辅助或数学函数,可以位于类的外部。
将正方形变形为圆形
完成圆形动画后,让我们继续进行稍微复杂一点的操作。
- 打开
scene.py
,并在CreateCircle
类下方添加以下代码片段:
class SquareToCircle(Scene):
def construct(self):
circle = Circle() # 创建一个圆形
circle.set_fill(PINK, opacity=0.5) # 设置颜色和透明度
square = Square() # 创建一个正方形
square.rotate(PI / 4) # 旋转一定角度
self.play(Create(square)) # 动画创建正方形
self.play(Transform(square, circle)) # 将正方形插值变形为圆形
self.play(FadeOut(square)) # 淡出动画
- 在命令行中运行以下命令来渲染
SquareToCircle
:
manim -pql scene.py SquareToCircle
将呈现以下动画:
这个示例展示了 Manim 的一个主要功能:能够仅用几行代码实现复杂且数学密集型的动画(例如干净地在两种几何形状之间进行插值)。
定位 Mobject
对象
接下来,让我们了解一下定位 Mobject
的一些基本技巧。
- 打开
scene.py
,并在SquareToCircle
方法下方添加以下代码片段:
class SquareAndCircle(Scene):
def construct(self):
circle = Circle() # 创建一个圆形
circle.set_fill(PINK, opacity=0.5) # 设置颜色和透明度
square = Square() # 创建一个正方形
square.set_fill(BLUE, opacity=0.5) # 设置颜色和透明度
square.next_to(circle, RIGHT, buff=0.5) # 设置位置
self.play(Create(circle), Create(square)) # 在屏幕上显示形状
- 在命令行中运行以下命令来渲染
SquareAndCircle
:
manim -pql scene.py SquareAndCircle
将呈现以下动画:
next_to
是一个 Mobject
方法,用于定位 Mobject
对象。
我们首先通过将 circle
作为方法的第一个参数,将粉色圆形指定为正方形的参考点。第二个参数用于指定 Mobject
相对于参考点的方向。在这个例子中,我们将方向设置为 RIGHT
,告诉 Manim 将正方形放置在圆形的右侧。最后,buff=0.5
在两个对象之间应用了一个小的距离缓冲。
尝试将 RIGHT
改为 LEFT
、UP
或 DOWN
,看看正方形的位置如何变化。
使用定位方法,您可以渲染一个包含多个 Mobject
的场景,使用坐标设置它们在场景中的位置,或者将它们相对于彼此进行定位。
有关 next_to
和其他定位方法的更多信息,请查看我们的参考手册中列出的 Mobject
方法。
使用 .animate
语法来动画化方法
本教程的最后课程是使用 .animate
,这是一个 Mobject
方法,可以将您对 Mobject
所做的更改变为动画。当您将 .animate
添加到任何修改 Mobject
的方法调用前时,该方法就变成了一个可以使用 self.play
播放的动画。让我们回到 SquareToCircle
,看看在创建 Mobject
时使用方法与使用 .animate
动画化这些方法调用之间的区别。
- 打开
scene.py
,并在SquareAndCircle
类下方添加以下代码片段:
class AnimatedSquareToCircle(Scene):
def construct(self):
circle = Circle() # 创建一个圆形
square = Square() # 创建一个正方形
self.play(Create(square)) # 在屏幕上显示正方形
self.play(square.animate.rotate(PI / 4)) # 旋转正方形
self.play(Transform(square, circle)) # 将正方形变形为圆形
self.play(
square.animate.set_fill(PINK, opacity=0.5)
) # 在屏幕上为圆形上色
- 在命令行中运行以下命令来渲染
AnimatedSquareToCircle
:
manim -pql scene.py AnimatedSquareToCircle
将呈现以下动画:
第一个 self.play
创建了正方形。第二个动画将正方形旋转了 45 度。第三个将正方形变形为圆形,最后一个将圆形变为粉色。尽管最终结果与 SquareToCircle
相同,但 .animate
展示了 rotate
和 set_fill
是如何动态应用于 Mobject
的,而不是在创建它们时已经应用了这些更改。
尝试其他方法,如 flip
或 shift
,看看会发生什么。
- 打开
scene.py
,并在AnimatedSquareToCircle
类下方添加以下代码片段:
class DifferentRotations(Scene):
def construct(self):
left_square = Square(color=BLUE, fill_opacity=0.7).shift(2 * LEFT)
right_square = Square(color=GREEN, fill_opacity=0.7).shift(2 * RIGHT)
self.play(
left_square.animate.rotate(PI), Rotate(right_square, angle=PI), run_time=2
)
self.wait()
- 在命令行中运行以下命令来渲染
DifferentRotations
:
manim -pql scene.py DifferentRotations
将呈现以下动画:
这个 Scene
展示了 .animate
的一些特点。当使用 .animate
时,Manim 实际上会取一个 Mobject
的初始状态和最终状态,并在这两者之间进行插值。在 AnimatedSquareToCircle
类中,当正方形旋转时,您可以观察到这一点:正方形的角似乎在稍微收缩,因为它们移动到第一个正方形变形为第二个正方形所需的位置。
在 DifferentRotations
中,.animate
对旋转的解释与 Rotate
方法之间的差异更加明显。一个旋转了 180 度的 Mobject
的起始状态和结束状态是相同的,因此 .animate
试图插值两个相同的对象,结果就是左边的正方形。如果您发现自己的 .animate
使用导致了类似的不想要的行为,可以考虑使用像右边正方形那样的传统动画方法,它使用了 Rotate
。
Transform
与 ReplacementTransform
Transform
和 ReplacementTransform
的区别在于,Transform(mob1, mob2)
会将 mob1
的点(以及其他属性,如颜色)转换为 mob2
的点/属性。
而 ReplacementTransform(mob1, mob2)
则是在场景中直接用 mob2
替换 mob1
。
使用 ReplacementTransform
还是 Transform
主要取决于个人偏好。它们可以用来实现相同的效果,如下所示。
class TwoTransforms(Scene):
def transform(self):
a = Circle()
b = Square()
c = Triangle()
self.play(Transform(a, b))
self.play(Transform(a, c))
self.play(FadeOut(a))
def replacement_transform(self):
a = Circle()
b = Square()
c = Triangle()
self.play(ReplacementTransform(a, b))
self.play(ReplacementTransform(b, c))
self.play(FadeOut(c))
def construct(self):
self.transform()
self.wait(0.5) # 等待 0.5 秒
self.replacement_transform()
然而,在某些情况下,使用 Transform
更有利,例如当您连续转换多个对象时。下面的代码避免了需要保留最后一个被转换的对象的引用。
示例:TransformCycle
from manim import *
class TransformCycle(Scene):
def construct(self):
a = Circle()
t1 = Square()
t2 = Triangle()
self.add(a)
self.wait()
for t in [t1,t2]:
self.play(Transform(a,t))
恭喜您完成
安装了 Manim 并完成了这个示例项目后,您就可以开始自己制作动画了。要了解更多关于 Manim 内部运作的信息,请继续学习下一个教程:Manim 的输出设置。要了解 Manim 的功能、配置和其他设置的概览,请查看其他教程。要查看所有可用功能的列表,请参考参考手册页面。
风险提示与免责声明
本文内容基于公开信息研究整理,不构成任何形式的投资建议。历史表现不应作为未来收益保证,市场存在不可预见的波动风险。投资者需结合自身财务状况及风险承受能力独立决策,并自行承担交易结果。作者及发布方不对任何依据本文操作导致的损失承担法律责任。市场有风险,投资须谨慎。