用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 的高级用法以及优化技巧,帮助您更高效地制作动画。

相关推荐
笑笑布丁26 分钟前
一些python实践
linux·python
程序猿进阶26 分钟前
ThreadLocal 释放的方式有哪些
java·开发语言·性能优化·架构·线程池·并发编程·threadlocal
战族狼魂29 分钟前
java代码 识别pdf文件是否含有表格
java·python·pdf
程序者王大川32 分钟前
【大数据】如何读取多个Excel文件并计算列数据的最大求和值
开发语言·python·excel·big data
Mryan200533 分钟前
OpenJudge | 寻找中位数
开发语言·数据结构·c++·算法·openjudge
lizi888881 小时前
打包Python代码的常用方法实现程序exe应用
开发语言·python
yava_free2 小时前
机器学习TFIDF的情感分类文章
python·机器学习·分类·tf-idf
api茶飘香2 小时前
守护应用边界:通过反射API实现安全的输入输出过滤
java·开发语言·python·安全·django·virtualenv·pygame
杀死一只知更鸟debug2 小时前
策略模式的小记
java·开发语言·策略模式
efls1112 小时前
Qt_了解Qt Creator
开发语言·qt