用Python打造精彩动画与视频,6.3 项目案例分析

6.3 项目案例分析

在这一节中,我们将通过具体的项目案例,深入探索 Manim 的潜力,并展示如何使用 Manim 创建复杂且富有表现力的动画。这些案例将涵盖数学、物理以及其他科学领域,帮助您更好地理解和应用 Manim。

6.3.1 案例一:展示数学定理

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| from manim import * class PythagoreanTheorem(Scene): def construct(self): # 创建一个直角三角形 triangle = Polygon(ORIGIN, RIGHT, RIGHT + UP, fill_color=BLUE, fill_opacity=0.5) # 标记各边 a_label = MathTex("a").next_to(triangle, LEFT, buff=0.1) b_label = MathTex("b").next_to(triangle, DOWN, buff=0.1) c_label = MathTex("c").next_to(triangle, UR, buff=0.1) # 显示三角形和标记 self.play(Create(triangle)) self.play(Write(a_label), Write(b_label), Write(c_label)) # 创建方形并标记面积 a_square = Square().scale(0.5).move_to(triangle.get_corner(DL)) b_square = Square().scale(0.5).move_to(triangle.get_corner(DR)) c_square = Square().scale(0.5).move_to(triangle.get_corner(UL)) a_area = MathTex("a^2").move_to(a_square) b_area = MathTex("b^2").move_to(b_square) c_area = MathTex("c^2").move_to(c_square) # 显示方形和面积标记 self.play(Create(a_square), Write(a_area)) self.play(Create(b_square), Write(b_area)) self.play(Create(c_square), Write(c_area)) # 展示公式 formula = MathTex("a^2 + b^2 = c^2").to_edge(UP) self.play(Write(formula)) |

在这个案例中,我们将使用 Manim 来展示毕达哥拉斯定理。我们将通过动画的方式来直观地演示这个定理的证明过程。

解释

|----------------------|
| from manim import * |

从 manim导入所有内容。

|-------------------------------------------------------|
| class PythagoreanTheorem(Scene): def construct(self): |

定义一个名为 PythagoreanTheorem的类,继承自 Scene类。

construct 方法定义了场景内容。

|-----------------------------------------------------------------------------------------------|
| # 创建一个直角三角形 triangle = Polygon( ORIGIN, RIGHT, RIGHT + UP, fill_color=BLUE, fill_opacity=0.5) |

使用 Polygon 创建一个三角形,顶点在 ORIGIN(原点)、RIGHT(向右的一个单位)和 RIGHT + UP(右上角的一个单位)的位置。

设置填充颜色为蓝色,透明度为 0.5。

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| # 标记各边 a_label = MathTex("a").next_to(triangle, LEFT, buff=0.1) b_label = MathTex("b").next_to(triangle, DOWN, buff=0.1) c_label = MathTex("c").next_to(triangle, UR, buff=0.1) |

使用 MathTex 创建标签 a、b 和 c,并分别将它们放置在三角形的左侧、下方和右上方(UR)位置,距离为 0.1。

|--------------------------------------------------------------------------------------------------|
| # 显示三角形和标记 self.play(Create(triangle)) self.play(Write(a_label), Write(b_label), Write(c_label)) |

使用 Create 动画绘制三角形。

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| # 创建方形并标记面积 a_square = Square().scale(0.5).move_to(triangle.get_corner(DL)) b_square = Square().scale(0.5).move_to(triangle.get_corner(DR)) c_square = Square().scale(0.5).move_to(triangle.get_corner(UL)) |

使用 Write动画显示标签。

使用 Square创建三个方形并缩放至 0.5 倍大小。

将方形分别移动到三角形的左下角(DL)、右下角(DR)和左上角(UL)。

|----------------------------------------------------------------------------------------------------------------------------------|
| a_area = MathTex("a^2").move_to(a_square) b_area = MathTex("b^2").move_to(b_square) c_area = MathTex("c^2").move_to(c_square) |

使用 MathTex 创建面积标记 a^2、b^2 和 c^2,并分别将它们放置在对应的方形中心。

|----------------------------------------------------------------------------------------------------------------------------------------------|
| # 显示方形和面积标记 self.play(Create(a_square), Write(a_area)) self.play(Create(b_square), Write(b_area)) self.play(Create(c_square), Write(c_area)) |

使用 Create 动画绘制方形。

使用 Write 动画显示面积标记。

|--------------------------------------------------------------------------------------|
| # 展示公式 formula = MathTex("a^2 + b^2 = c^2").to_edge(UP) self.play(Write(formula)) |

使用 MathTex 创建毕达哥拉斯定理公式 a^2 + b^2 = c^2,并将其移动到屏幕顶部。

使用 Write动画显示公式。

6.3.2 案例二:模拟物理现象

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| from manim import * class FreeFall(Scene): def construct(self): # 创建一个球体 ball = Circle().set_fill(RED, opacity=0.8).move_to(UP*3) ground = Line(LEFT*5, RIGHT*5).shift(DOWN*3) # 显示地面和球体 self.play(Create(ground)) self.play(Create(ball)) # 自由落体运动 self.play(ball.animate.shift(DOWN*5), rate_func=rate_functions.ease_in_quad, run_time=2) # 加速度和速度标记 accel_label = MathTex("a = 9.8 \\frac{m}{s^2}").to_edge(UP) speed_label = MathTex("v = gt").next_to(ball, RIGHT) self.play(Write(accel_label)) self.play(Write(speed_label)) |

代码示例

解释

|----------------------|
| from manim import * |

从 manim导入所有内容。

|---------------------------------------------|
| class FreeFall(Scene): def construct(self): |

定义一个名为 FreeFall的类,继承自 Scene类。

|--------------------------------------------------------------------------------------------------------------------|
| # 创建一个球体 ball = Circle().set_fill(RED, opacity=0.8).move_to(UP*3) ground = Line(LEFT*5, RIGHT*5).shift(DOWN*3) |

construct方法定义了场景内容。

使用 Circle创建一个红色的球体,透明度为 0.8,并将其移动到屏幕上方。

|-------------------------------------------------------------|
| # 显示地面和球体 self.play(Create(ground)) self.play(Create(ball)) |

使用 Line创建一条线作为地面,长度为 10(从左到右各 5 个单位),并将其向下移动 3 个单位。

|----------------------------------------------------------------------------------------------------|
| # 自由落体运动 self.play(ball.animate.shift(DOWN*5), rate_func=rate_functions.ease_in_quad, run_time=2) |

使用 Create动画绘制地面和球体。

使用 animate和 shift方法将球体向下移动 5 个单位,使用 ease_in_quad作为速率函数,运行时间为 2 秒。

|--------------------------------------------------------------------------------------------------------------------------------|
| # 加速度和速度标记 accel_label = MathTex("a = 9.8 \\frac{m}{s^2}").to_edge(UP) speed_label = MathTex("v = gt").next_to(ball, RIGHT) |

使用 MathTex创建加速度标记 a = 9.8 \frac{m}{s^2}并将其移动到屏幕顶部。

|-------------------------------------------------------------|
| self.play(Write(accel_label)) self.play(Write(speed_label)) |

使用 MathTex创建速度标记 v = gt并将其放置在球体的右侧。

使用 Write动画显示加速度和速度标记。

6.3.3 案例三:可视化数据分析

代码示例

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| from manim import * class BarChart(Scene): def construct(self): # 创建轴 axes = Axes(x_range=[0, 5, 1], y_range=[0, 10, 2], axis_config={"color": BLUE} ) # 创建柱状图 bars = VGroup() heights = [6, 7, 3, 5, 9] for i, height in enumerate(heights): bar = Rectangle(width=0.5, height=height, fill_color=GREEN, fill_opacity=0.8) bar.next_to(axes.c2p(i + 1, 0), UP, buff=0) bars.add(bar) # 显示轴和柱状图 self.play(Create(axes)) self.play(LaggedStart(*[GrowFromEdge(bar, DOWN) for bar in bars], lag_ratio=0.1)) # 添加数据标记 labels = VGroup(*[MathTex(str(height)).next_to(bar, UP, buff=0.1) for height, bar in zip(heights, bars)]) self.play(LaggedStart(*[Write(label) for label in labels], lag_ratio=0.1)) |

解释

|---------------------------------------------|
| class BarChart(Scene): def construct(self): |

定义一个名为BarChart的类,继承自Scene类。

|-------------------------------------------------------------------------------------------|
| # 创建轴 axes = Axes(x_range=[0, 5, 1], y_range=[0, 10, 2], axis_config={"color": BLUE}) |

construct方法定义了场景内容。

使用 Axes创建一个坐标轴,x 轴范围为 0 到 5,步长为 1;y 轴范围为 0 到 10,步长为 2

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| # 创建柱状图 bars = VGroup() heights = [6, 7, 3, 5, 9] for i, height in enumerate(heights): bar = Rectangle(width=0.5, height=height, fill_color=GREEN, fill_opacity=0.8) bar.next_to(axes.c2p(i + 1, 0), UP, buff=0) bars.add(bar) |

设置轴的颜色为蓝色。

使用 VGroup创建一个组来容纳所有的柱形条。

定义每个柱形条的高度为 `heights` 列表中的值。

使用 `Rectangle创建柱形条,宽度为 0.5,高度为 height,填充颜色为绿色,透明度为 0.8。

使用 next_to方法将每个柱形条放置在相应的 x 轴位置。

|------------------------------------------------------------------------------------------------------------------------|
| # 显示轴和柱状图 self.play(Create(axes)) self.play(LaggedStart(*[GrowFromEdge(bar, DOWN) for bar in bars], lag_ratio=0.1)) |

将每个柱形条添加到bars 组中。

使用 Create动画绘制坐标轴。

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| # 添加数据标记 labels = VGroup(*[MathTex(str(height)).next_to(bar, UP, buff=0.1) for height, bar in zip(heights, bars)]) self.play(LaggedStart(*[Write(label) for label in labels], lag_ratio=0.1)) |

使用 LaggedStart逐个显示柱形条,从下到上生长,每个柱形条之间有 0.1 的延迟。

使用 VGroup创建一个组来容纳所有的高度标签。

使用 MathTex创建高度标签,将其放置在相应的柱形条上方。

使用LaggedStart逐个显示高度标签,每个标签之间有 0.1 的延迟。

总结

通过上述三个案例,我们展示了如何使用 Manim 来创建数学定理演示、物理现象模拟以及数据可视化。这些案例不仅展示了 Manim 的强大功能,也为您提供了实践参考,帮助您在自己的项目中应用 Manim。

展示数学定理:通过动画展示几何定理的证明过程,使抽象的数学概念更加直观易懂。

模拟物理现象:通过动画模拟物理现象,可以更好地理解物理概念和原理。

可视化数据分析:通过动画展示数据变化和趋势,帮助更好地理解和分析数据。

在接下来的章节中,我们将进一步探讨 Manim 的高级用法以及优化技巧,帮助您更高效地制作动画。

相关推荐
Swift社区40 分钟前
在 Swift 中实现字符串分割问题:以字典中的单词构造句子
开发语言·ios·swift
没头脑的ht41 分钟前
Swift内存访问冲突
开发语言·ios·swift
没头脑的ht44 分钟前
Swift闭包的本质
开发语言·ios·swift
wjs20241 小时前
Swift 数组
开发语言
stm 学习ing2 小时前
FPGA 第十讲 避免latch的产生
c语言·开发语言·单片机·嵌入式硬件·fpga开发·fpga
湫ccc3 小时前
《Python基础》之字符串格式化输出
开发语言·python
mqiqe3 小时前
Python MySQL通过Binlog 获取变更记录 恢复数据
开发语言·python·mysql
AttackingLin3 小时前
2024强网杯--babyheap house of apple2解法
linux·开发语言·python