前提
实践一选取一段使用manim做出的动画视频,看使用了manim中的哪些API做出来这个视频,这些API的使用介绍。
动画视频来自b站,b站链接:【可视化】Transformer中多头注意力的计算过程
manim相关组件介绍
1.Title
带有下划线title的mobject。
参数:
match_underline_width_to_text(bool)
:下划线的宽度是否与文本对齐
underline_buff
:下划线与文本之间的举例
使用方法:
title = Title("Step1. Word to vector", include_underline=True, match_underline_width_to_text=False, underline_buff=0.25, color=YELLOW)
2.FadeIn
淡入动画。属于Animations
类。
参数:
shift
:从哪个方向淡入
target_position
:淡入时开始的位置
scale
:淡入时的缩放系数
使用方法:
from manim import *
class FadeInExample(Scene):
def construct(self):
dot = Dot(UP * 2 + LEFT)
self.add(dot)
tex = Tex(
"FadeIn with ", "shift ", " or target\_position", " and scale"
)
animations = [
FadeIn(tex[0]),
FadeIn(tex[1], shift=UP),
FadeIn(tex[2], target_position=dot),
FadeIn(tex[3], scale=5.5),
]
self.play(AnimationGroup(*animations, lag_ratio=0.5))
同理还有FadeOut
动画。
3.Unwrite
擦除动画,属于Animation
类。
参数:
reverse(bool)
:设置为True可让动画首先从最后一个子对象开始擦除,默认为True
使用方法:
self.play(Unwrite(title, reverse=False))
同理还有Write
动画。
4.to_edge
Mobjects 类的成员方法。将Mobject移动到屏幕边缘。
to_edge(edge=array([-1., 0., 0.]), buff=0.5)
buff
:与边缘的距离
5.Create
创建动画,属于Animation
类。只可以对VMobject(Mobject的子类)对象使用。
6.Transform
将一个Mobject转换到一个目标Mobject,属于Animation
类。
参数:
path_func
:移动的路径,需要是一个函数
path_arc
:如果使用原型路径弧,到达目标的弧度。
使用方法:
from manim import *
class TransformExample(Scene):
def construct(self):
sentence_origin = Text("Tim likes kitchen", font_size=30)
print(sentence_origin.get_center()) # [0.0, 0.0, 0.0]
sentence = Text("Tim like kitchen", font_size=30).move_to(3 * UP + RIGHT * 2)
self.play(Transform(sentence_origin, sentence))
self.wait(1)
print(sentence_origin.get_center()) # [2.0, 3.0, 0.0]
7.RoundedRectangle
带圆角的矩形,属于Mobject类。
参数:
corner_radius
:矩形四个内角的半径
height
:矩形的高
width
:矩形的宽
grid_xstep
:垂直网格线之间的间距
grid_ystep
:水平网格线之间的间距
使用方法:
embedding_block = RoundedRectangle(corner_radius=0.2, width=4, height=1.5, color=GREEN).move_to(RIGHT * 2 + UP * 0.2)
8.Tex
Latex的normal模式的string。
9.VGroup
将多个mobjects组成一组。
使用方法:
from manim import *
class ArcShapeIris(Scene):
def construct(self):
colors = [DARK_BROWN, BLUE_E, BLUE_D, BLUE_A, TEAL_B, GREEN_B, YELLOW_E]
radius = [1 + rad * 0.1 for rad in range(len(colors))]
circles_group = VGroup()
# zip(radius, color) makes the iterator [(radius[i], color[i]) for i in range(radius)]
circles_group.add(*[Circle(radius=rad, stroke_width=10, color=col)
for rad, col in zip(radius, colors)])
self.add(circles_group)
10.Arrow
一个箭头,基类是Line
。
参数:
stroke_width
:箭头的粗细
start
:起始位置
end
: 终止位置
buff
:缓冲距离
使用方法:
arrow_in = Arrow(start_pos, start_pos + 2.2 * DOWN, buff=0.3)
11.MathTex
在数学模式下使用 LaTeX 编译的字符串。也就是数学公式,想展示数学公式,就要使用这个类。
使用说明:
from manim import *
class Formula(Scene):
def construct(self):
t = MathTex(r"\int_a^b f'(x) dx = f(b)- f(a)")
self.add(t)
总结
在了解了这么多的组件以后,再结合动画分析代码,就能够对如何产生这么一个动画的过程有所了解。
在了解了要使用的工具后,我觉得要想制作这种数学解释动画,尤其还是用代码做一个。必须要在写代码之前,将整个动画的流程构思出来,细分到每一小步,然后再进行编码。
最后贴一段3D坐标轴旋转的实现过程:
class TransitionFrom2Dto3D(ThreeDScene):
def construct(self):
# Add start caption
start_caption = Text("This video will intro rotate problem").scale(0.8)
self.play(Write(start_caption))
self.wait(0.5)
self.play(FadeOut(start_caption))
# the first scene
first_caption = Tex("Let's start with 2D scene").scale(1.5)
self.play(Write(first_caption))
self.play(first_caption.animate.move_to(UP*3))
# Start with 2D scene
axes2D = Axes(axis_config = {"tip_shape":StealthTip}).scale(0.8)
self.play(FadeIn(axes2D)) # TODO need to add the animation
# Transition to 3D
self.play(FadeOut(axes2D))
self.wait(2)
self.play(FadeOut(first_caption))
self.set_camera_orientation(phi=2*PI/5, theta = PI/5)
axes3D = ThreeDAxes()
labels = axes3D.get_axis_labels(
Text("x").scale(0.7).rotate(PI/2, axis=RIGHT),
Text("y").scale(0.45).rotate(PI/2, axis=RIGHT),
Text("z").scale(0.45))
group = VGroup(axes3D, labels)
self.play(Write(group))
self.play(Rotate(group, 2*PI, axis=OUT, rate_func=linear, about_point=ORIGIN, run_time=5))
参考链接
- https://github.com/Aye10032/ManimLearn/blob/master/LLM/01transformer.py
- https://docs.manim.community/en
第一幕
展示一个三维坐标系,并且它在旋转的效果。