Manim 中的Scene(场景)

0 阅读6分钟

一、Scene简介

在Manim的世界里,Scene(场景) 是所有动画的基石和画布。无论你是想创建一个简单的几何变换,还是复杂的3D旋转,都离不开对Scene的深入理解。

感兴趣可以直接阅读官方文档

1.1 什么是Scene?

Scene是Manim中最核心的类,它是你的动画画布 。每个Manim脚本通常由一个继承自Scene的类组成,你需要在其中重写construct()方法,定义所有的动画逻辑 。

1.2 核心工作流程

一个典型的Scene工作流程包含三个核心方法 :

  • add() / remove() :控制Mobject(可动画对象)在屏幕上的显示与隐藏
  • play() :播放动画,是所有动态效果的执行入口
  • wait() :暂停场景,保持当前画面一段时间

1.3 基础示例

最经典的示例"Hello World"开始 :

from manim import *

class HelloWorld(Scene):
    def construct(self):
        hello = Text("Hello World!")
        self.play(Write(hello))
        self.wait(2)

代码说明

  1. Text("Hello World!") 创建一个文本对象,可以设置字体大小和颜色。
  2. Write 动画模拟手写效果,一笔一划地绘制文字。
  3. wait(2) 让动画结束后画面保持2秒钟。

二、Manim 场景相关模块介绍:功能与适用场景

Manim 提供了一系列场景类和辅助模块,以满足不同动画创作需求。主要包括scene、moving_camera_scene、three_d_scene、vector_space_scene、zoomed_scene、scene_file_writer和section模块。 它们的关系可以分为继承关系和写作关系。

继承关系:作为Scene的子类扩展功能

模块父类关系说明
moving_camera_sceneScene的子类通过内置可移动相机,扩展了镜头运动能力。
three_d_sceneScene的子类提供三维空间渲染、3D相机和对象支持。
vector_space_sceneScene的子类预置向量空间坐标系和便捷方法,简化线性代数可视化。
zoomed_sceneScene的子类实现“画中画”放大效果,通过双相机系统展示局部细节。

类继承层次示意(简化):

Scene
├── MovingCameraScene
├── ThreeDScene
├── VectorScene (或 VectorSpaceScene)
└── ZoomedScene

协作关系:与Scene配合使用的辅助模块

以下两个模块并非Scene的子类,而是与Scene紧密协作的组件:

模块关系说明
section是构建分段视频的API工具,在Scene内部通过self.next_section()等方法调用,用于标记场景的不同段落。
scene_file_writer是负责视频输出的类Scene在渲染时会使用它来调用FFmpeg生成最终文件。每个Scene实例都关联一个SceneFileWriter对象。

协作关系示意

  • Scene 使用 section 方法在动画流中插入章节标记。
  • Scene 依赖 scene_file_writer 将渲染的帧序列编码为视频文件。

2.1 scene

介绍

Scene 是所有 Manim 动画的最基础画布。任何动画都必须继承自 Scene 并实现 construct() 方法。它提供了添加对象 (add)、移除对象 (remove)、播放动画 (play) 和等待 (wait) 等核心功能。

使用场景

  • 所有动画的起点:只要你想用 Manim 制作动画,就离不开 Scene
  • 简单 2D 动画:无需镜头移动、3D 效果或复杂功能的普通教学动画、数学演示等。
  • 自定义动画流程:通过重写 construct() 自由组合 CreateTransformFadeIn 等动画。


2.2 moving_camera_scene

介绍

MovingCameraScene 是继承自 Scene 的一个子类,其核心特性是摄像机(相机)可以实时移动。它使用 MovingCamera 作为默认相机对象,你可以通过操作 self.camera.frame 来平移、缩放甚至旋转镜头,从而引导观众视线。

使用场景

  • 需要镜头运动的动画:例如展示一张大图,先看整体,再平滑移动到局部细节。
  • 对象追踪:让相机跟随一个移动的对象(如运动的小球、路径上的点)。
  • 视角切换:实现类似纪录片中“镜头平移”的效果,增强视觉叙事。
  • 动态放大/缩小:当需要强调某个区域时,通过缩放相机实现“推拉镜头”。

2.3 three_d_scene

介绍

ThreeDScene 是为3D 动画设计的场景类。它内置了 ThreeDCamera,支持三维空间中的对象创建、光照、旋转和透视投影。你可以通过 set_camera_orientation 等方法控制相机在三维空间中的位置,并添加固定于屏幕的文本或图形。

使用场景

  • 立体几何演示:展示立方体、球体、多面体等三维图形的旋转和变换。
  • 物理模拟:模拟刚体运动、光线传播、电磁场等三维物理现象。
  • 数据可视化:将数据映射到三维空间(如三维散点图、表面图)。
  • 动画叙事:通过相机环绕运动,给观众沉浸式的空间体验。

2.4 vector_space_scene

介绍

VectorScene(及其相关子类)是为线性代数和向量空间可视化而设计的场景。它预置了坐标轴、网格、向量等元素,并提供了便捷的方法来绘制向量、进行线性变换、展示基向量变化等。

使用场景

  • 数学教学:讲解向量加法、点积、叉积、线性变换(如旋转、缩放、剪切)等概念。
  • 坐标系演示:展示二维或三维坐标系中的函数图像、向量场。
  • 矩阵变换:可视化矩阵乘法对空间的影响(如特征向量、行列式几何意义)。

2.5 zoomed_scene

介绍

ZoomedScene 允许你在主画面中创建一个放大区域(类似“画中画”效果)。它通过两个相机实现:一个负责整体视图,另一个负责局部放大区域,并将后者嵌入前者画面中。你可以指定放大区域的位置、大小和缩放倍数。

使用场景

  • 展示细节:在整体图中标注并放大某一微小区域(如电路板上的元件、函数图的局部极值点)。
  • 多级信息呈现:同时展示宏观结构和微观细节,适合科学演示。
  • 对比视图:将原图和放大图并排或叠加显示,帮助观众理解比例关系。

2.6 section

介绍

section 是 Manim 中用于构建分段视频的 API 模块。它允许你将一个长场景拆分成多个逻辑部分(sections),每个部分可以单独标记和渲染。这对于制作教学视频、幻灯片式讲解或需要后期剪辑的场景非常有用。

使用场景

  • 分节录制:当你想把动画按知识点分成多个独立视频片段,但又希望共享同一个场景代码时使用。
  • 后期标记:通过 self.next_section() 等方法标记段落,便于在输出文件中获得时间戳信息,辅助后期剪辑。
  • 复杂动画拆解:将复杂的动画逻辑分解为多个可管理的部分,提高代码可读性。

2.7 scene_file_writer

介绍

SceneFileWriter 是 Manim 与 FFmpeg 之间的桥梁,负责管理视频编码、格式转换和文件输出。它处理场景渲染后的帧序列,将它们合成为最终视频文件(如 MP4、GIF),并支持设置分辨率、帧率、编解码器等参数。

使用场景

  • 自定义输出设置:当需要改变默认渲染参数(如分辨率、帧率)时,通过配置文件或代码调整 SceneFileWriter 的行为。
  • 多格式输出:同时生成不同格式(如 MP4 和 GIF)的视频文件。
  • 调试渲染问题:了解文件写入流程有助于排查视频编码失败或格式错误。

3.Scenes简图

Scenes.png