
在动画制作中,尤其是数学和科学可视化领域,有时我们需要将观众的注意力集中在场景的某个特定部分。Manim提供了一个强大的工具 ZoomedScene,它允许我们在场景中创建一个独立的缩放视图,从而实现对局部细节的深入展示。本文将详细介绍ZoomedScene的作用、参数、方法,并通过实际示例展示其强大功能。
1. ZoomedScene概要
ZoomedScene是Manim中一个专门用于局部缩放的场景类。其核心功能是允许我们在主场景中创建一个独立的“缩放窗口”,通过这个窗口,可以清晰地展示场景中某个部分的细节。这种设计特别适用于以下场景:
- 数学公式推导:在展示复杂的数学公式时,可以使用
ZoomedScene对公式中的关键部分进行放大,帮助观众更好地理解
- 科学实验演示:在展示微观现象(如细胞结构、分子运动)时,通过缩放功能,可以让观众更直观地观察细节。
- 工程设计展示:对于复杂的机械结构或电路设计,
ZoomedScene可以帮助观众聚焦于关键部件
- 教育动画:在教学视频中,通过局部缩放,可以更有效地引导学生关注重点内容
1.1. 主要参数
ZoomedScene的主要参数有:
| 参数名称 |
类型 |
说明 |
| camera_class |
class |
用于定义场景的相机类,默认为MultiCamera。它决定了场景的渲染方式 |
| zoomed_display_height |
float |
缩放窗口的高度,默认值为 3 |
| zoomed_display_width |
float |
缩放窗口的宽度,默认值为 3 |
| zoomed_display_center |
array |
缩放窗口的中心位置,默认为None,表示自动计算 |
| zoomed_display_corner |
array |
缩放窗口在场景中的角落位置,默认为[1, 1, 0],表示窗口位于右上角 |
| zoomed_display_corner_buff |
float |
缩放窗口与角落的距离,默认值为 0.5 |
| zoomed_camera_config |
dict |
缩放相机的配置参数,例如背景透明度和边框宽度 |
| zoomed_camera_image_mobject_config |
dict |
缩放相机图像的配置参数 |
| zoomed_camera_frame_starting_position |
array |
缩放相机的初始位置,默认为[0, 0, 0] |
| zoom_factor |
float |
缩放比例,默认值为 0.15。它决定了缩放窗口与主场景的比例关系 |
| image_frame_stroke_width |
float |
缩放窗口边框的宽度,默认值为3 |
| zoom_activated |
bool |
是否激活缩放功能,默认为False |
1.2. 主要方法
ZoomedScene的主要方法有:
| 名称 |
说明 |
| activate_zooming |
激活缩放功能 |
| get_zoom_factor |
获取当前的缩放比例 |
| get_zoom_in_animation |
返回一个缩放动画 |
| get_zoomed_display_pop_out_animation |
返回缩放窗口弹出的动画 |
2. 使用示例
为了更好地理解ZoomedScene的功能,我们将通过四个实际示例展示其特点。
2.1. 公式的局部放大
视频中展示欧拉公式时,在另一个位置中展示公式的局部放大。在讲解复杂的公式时,可以使用这个功能来突出显示其中的正在讲解的参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| from manim import *
class ZoomedFormulaExample(ZoomedScene): def __init__(self): super().__init__( zoomed_display_height=2, zoomed_display_width=5, zoomed_display_center=[0, 1.75, 0], zoomed_camera_config={"default_frame_stroke_width": 1}, image_frame_stroke_width=1, ) def construct(self): # 添加标题 title = Text("公式的局部放大", font="STLiti", font_size=25).to_edge(UP).shift(LEFT) line = Line(LEFT * 3, RIGHT * 5, color=BLUE).next_to(title, DOWN, buff=0.1) self.play(Write(title), Create(line)) self.wait(0.5) # 添加公式 formula = MathTex("e^{i\\pi} + 1 = 0").scale(2) self.play(Create(formula)) self.wait(0.5) # 激活放大 self.activate_zooming(animate=True) self.wait(0.5) # 放大动画 self.play(self.get_zoom_in_animation(run_time=2)) self.wait(2)
|
实际的显示效果如下:
我感觉这段代码比较有意思
1 2 3 4 5 6 7 8
| def __init__(self): super().__init__( zoomed_display_height=2, zoomed_display_width=5, zoomed_display_center=[0, 1.75, 0], zoomed_camera_config={"default_frame_stroke_width": 1}, image_frame_stroke_width=1, )
|
这段代码实际上就是对方法框的一个设置,可以对应查阅里面的属性,缩放窗口的高度,缩放窗口的宽度,缩放窗口的中心位置,同时,将 __init__ 方法添加到类中,使用 super().__init__() 初始化父类,在 __init__ 方法中传入放大相关的配置参数:
zoomed_display_height=2: 放大显示区域的高度
zoomed_display_width=5: 放大显示区域的宽度
zoomed_display_center=[0, 1.75, 0]: 放大显示区域的中心位置
zoomed_camera_config: 放大相机的配置
image_frame_stroke_width=1: 图像框的边框宽度
2.2. 不同图形的细节
这个示例交互式切换圆形 / 正方形的局部观察。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| from manim import *
class ZoomedShapesExample(ZoomedScene): def __init__(self, **kwargs): super().__init__( zoomed_display_height=2, zoomed_display_width=5, zoomed_display_center=[0, 1.75, 0], zoomed_camera_config={"default_frame_stroke_width": 1}, image_frame_stroke_width=1, ) def construct(self): # 创建图形并设置位置 circle = Circle(color=RED).shift(LEFT * 2) square = Square(color=BLUE).shift(RIGHT * 2) # 创建标题 title = Text("图形细节演示", font_size=25).to_edge(UP) self.play(Write(title)) # 显示图形 self.play(Create(circle), Create(square)) # 激活缩放并设置初始位置 self.activate_zooming(animate=True) zoom_frame = self.zoomed_camera.frame # 缩放圆形区域 self.play(zoom_frame.animate.move_to(circle)) self.wait(0.5) # 缩放正方形区域 self.play(zoom_frame.animate.move_to(square)) self.wait()
|
来看演示的动画效果
2.3. 切换不同的部分
这个示例演示逐步放大图中不同节点的过程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| from manim import *
class ZoomedDotsExample(ZoomedScene): def __init__(self, **kwargs): super().__init__( zoomed_display_height=2, zoomed_display_width=5, zoomed_display_center=[0, 1.75, 0], zoomed_camera_config={"default_frame_stroke_width": 1}, image_frame_stroke_width=1, ) def construct(self): # 创建标题 title = Text("切换不同部分", font_size=25).to_edge(UP) self.play(Write(title)) # 创建三个点 dots = VGroup( Dot(color=GREEN), Dot(color=YELLOW), Dot(color=BLUE) ).arrange(RIGHT, buff=2) self.play(Create(dots)) # 激活缩放 self.activate_zooming(animate=True) zoom_frame = self.zoomed_camera.frame # 依次缩放每个点 for dot in dots: self.play(zoom_frame.animate.move_to(dot)) self.wait(0.5) self.wait()
|
来看演示的效果
我个人更感兴趣的是这个代码
for...in 循环 是 Python 中的一种循环结构,用于遍历序列(如列表、元组、字符串)或其他可迭代对象的元素。
1 2 3 4 5 6 7 8
| # 遍历列表 fruits = ["苹果", "香蕉", "橙子"] for fruit in fruits: print(fruit) # 输出: # 苹果 # 香蕉 # 橙子
|
有些时候还是要学一学Python语言的基础知识的,虽然AI可以帮助我们写代码,更多的时候我们还是需要自己适当的调整代码,知识储备还是要有的。