数学视频动画引擎Python库 -- Manim 快速入门 Quickstart

文中内容仅限技术学习与代码实践参考,市场存在不确定性,技术分析需谨慎验证,不构成任何投资建议。

Mathematical Animation Engine

快速入门

注意:在继续之前,请按照安装步骤安装 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 运行所需的所有文件,以及项目产生的任何输出。

制作圆形动画

  1. 打开文本编辑器,例如记事本。打开 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))  # 在屏幕上显示圆形
    
  2. 打开命令行,导航到项目文件夹,并执行以下命令:

    manim -pql main.py CreateCircle
    

Manim 将输出渲染信息,然后创建一个 MP4 文件。您的默认视频播放器将播放 MP4 文件,显示以下动画。

CreateCircle
如果您看到一个粉色圆形被绘制的动画,恭喜您!您刚刚从头开始编写了第一个 Manim 场景。

如果您收到错误消息,没有看到视频,或者视频输出与上述动画不符,很可能 Manim 没有正确安装。请参阅我们的常见问题解答部分,以获取有关常见问题的帮助。

解释

让我们逐行查看刚才执行的脚本,看看 Manim 是如何绘制圆形的。

第一行导入了库中的所有内容:

这是使用 Manim 的推荐方式,因为一个脚本通常会使用 Manim 命名空间中的多个名称。在您的脚本中,您导入并使用了 SceneCirclePINKCreate

现在让我们看看接下来的两行:

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() 方法内。其他代码,例如辅助或数学函数,可以位于类的外部。

将正方形变形为圆形

完成圆形动画后,让我们继续进行稍微复杂一点的操作。

  1. 打开 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))  # 淡出动画
  1. 在命令行中运行以下命令来渲染 SquareToCircle
manim -pql scene.py SquareToCircle

将呈现以下动画:

SquareToCircle
这个示例展示了 Manim 的一个主要功能:能够仅用几行代码实现复杂且数学密集型的动画(例如干净地在两种几何形状之间进行插值)。

定位 Mobject 对象

接下来,让我们了解一下定位 Mobject 的一些基本技巧。

  1. 打开 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))  # 在屏幕上显示形状
  1. 在命令行中运行以下命令来渲染 SquareAndCircle
manim -pql scene.py SquareAndCircle

将呈现以下动画:

SquareAndCircle
next_to 是一个 Mobject 方法,用于定位 Mobject 对象。

我们首先通过将 circle 作为方法的第一个参数,将粉色圆形指定为正方形的参考点。第二个参数用于指定 Mobject 相对于参考点的方向。在这个例子中,我们将方向设置为 RIGHT,告诉 Manim 将正方形放置在圆形的右侧。最后,buff=0.5 在两个对象之间应用了一个小的距离缓冲。

尝试将 RIGHT 改为 LEFTUPDOWN,看看正方形的位置如何变化。

使用定位方法,您可以渲染一个包含多个 Mobject 的场景,使用坐标设置它们在场景中的位置,或者将它们相对于彼此进行定位。

有关 next_to 和其他定位方法的更多信息,请查看我们的参考手册中列出的 Mobject 方法。

使用 .animate 语法来动画化方法

本教程的最后课程是使用 .animate,这是一个 Mobject 方法,可以将您对 Mobject 所做的更改变为动画。当您将 .animate 添加到任何修改 Mobject 的方法调用前时,该方法就变成了一个可以使用 self.play 播放的动画。让我们回到 SquareToCircle,看看在创建 Mobject 时使用方法与使用 .animate 动画化这些方法调用之间的区别。

  1. 打开 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)
        )  # 在屏幕上为圆形上色
  1. 在命令行中运行以下命令来渲染 AnimatedSquareToCircle
manim -pql scene.py AnimatedSquareToCircle

将呈现以下动画:

AnimatedSquareToCircle
第一个 self.play 创建了正方形。第二个动画将正方形旋转了 45 度。第三个将正方形变形为圆形,最后一个将圆形变为粉色。尽管最终结果与 SquareToCircle 相同,但 .animate 展示了 rotateset_fill 是如何动态应用于 Mobject 的,而不是在创建它们时已经应用了这些更改。

尝试其他方法,如 flipshift,看看会发生什么。

  1. 打开 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()
  1. 在命令行中运行以下命令来渲染 DifferentRotations
manim -pql scene.py DifferentRotations

将呈现以下动画:

DifferentRotations
这个 Scene 展示了 .animate 的一些特点。当使用 .animate 时,Manim 实际上会取一个 Mobject 的初始状态和最终状态,并在这两者之间进行插值。在 AnimatedSquareToCircle 类中,当正方形旋转时,您可以观察到这一点:正方形的角似乎在稍微收缩,因为它们移动到第一个正方形变形为第二个正方形所需的位置。

DifferentRotations 中,.animate 对旋转的解释与 Rotate 方法之间的差异更加明显。一个旋转了 180 度的 Mobject 的起始状态和结束状态是相同的,因此 .animate 试图插值两个相同的对象,结果就是左边的正方形。如果您发现自己的 .animate 使用导致了类似的不想要的行为,可以考虑使用像右边正方形那样的传统动画方法,它使用了 Rotate

TransformReplacementTransform

TransformReplacementTransform 的区别在于,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 更有利,例如当您连续转换多个对象时。下面的代码避免了需要保留最后一个被转换的对象的引用。

TwoTransforms
示例: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 的功能、配置和其他设置的概览,请查看其他教程。要查看所有可用功能的列表,请参考参考手册页面。

风险提示与免责声明
本文内容基于公开信息研究整理,不构成任何形式的投资建议。历史表现不应作为未来收益保证,市场存在不可预见的波动风险。投资者需结合自身财务状况及风险承受能力独立决策,并自行承担交易结果。作者及发布方不对任何依据本文操作导致的损失承担法律责任。市场有风险,投资须谨慎。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

船长Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值