3blue1brown的manim使用分析

什么是manim

之前看线性代数的时候,一直在思考这种视频是通过什么制作的,毕竟自己是做游戏的……并且还接触过视频剪辑的PR,和制作特效的AE,所以感觉要是真的是靠自己手动的抠工作量几乎是天文数字,所以这几天配置了一下它的软件。

本来按照以往的思维,接下来我就应该去看他的源码实现,可是python已经很久没使用了,所以这次还是先尝试分析一下如何使用吧。 我们从他给的示例一一的看过去。

第一个函数SquareToCircle

https://img-blog.csdnimg.cn/20200217133856965.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIzMDMwODQz,size_16,color_FFFFFF,t_70

1
python -m manim example_scenes.py SquareToCircle -pl
  1. -m 是他的引擎

  2. example_scenes.py是文件名称

  3. 后面的SquareToCircle是脚本里的函数

  4. 后面这个是质量控制,先不看

我需要看他的脚本控制,这是他给出的示例函数是

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class SquareToCircle(Scene):
    def construct(self):
        circle = Circle()//1. 如何创建圆
        square = Square()//2. 如何创建正方形
        square.flip(RIGHT)//3. 如何flip
        square.rotate(-3 * TAU / 8)//如何旋转
        circle.set_fill(PINK, opacity=0.5)//5. 如何填充
        //6. 如果play,ShowCreation,Transform,FadeOut
        self.play(ShowCreation(square))
        self.play(Transform(square, circle))
        self.play(FadeOut(square))

视频:

第二个函数OpeningManimExample

https://img-blog.csdnimg.cn/20200217133914603.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIzMDMwODQz,size_16,color_FFFFFF,t_70 有那味了!

 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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

class OpeningManimExample(Scene):
    def construct(self):
        //创建文字
        title = TextMobject("This is some \\LaTeX")
        //另一段文字,不过这里是公式,所以使用了latex的语法,不过要加的斜杠太多了
        basel = TexMobject(
            "\\sum_{n=1}^\\infty "
            "\\frac{1}{n^2} = \\frac{\\pi^2}{6}"
        )
        //这里应该是分组,确立上下关系
        VGroup(title, basel).arrange(DOWN)
        //直接play
        self.play(
            Write(title),
            FadeInFrom(basel, UP),
        )
        //等待,不知道几秒,再说吧
        self.wait()
        //文字的变化
        transform_title = TextMobject("That was a transform")
        //变到左上,太。。
        transform_title.to_corner(UP + LEFT)
        self.play(
            Transform(title, transform_title),
            LaggedStart(*map(FadeOutAndShiftDown, basel)),
        )
        self.wait()
        //建立坐标系
        grid = NumberPlane()
        grid_title = TextMobject("This is a grid")
        grid_title.scale(1.5)
        grid_title.move_to(transform_title)

        self.add(grid, grid_title)  # Make sure title is on top of grid
        self.play(
            FadeOut(title),
            FadeInFromDown(grid_title),
            ShowCreation(grid, run_time=3, lag_ratio=0.1),
        )
        self.wait()

        grid_transform_title = TextMobject(
            "That was a non-linear function \\\\"
            "applied to the grid"
        )
        grid_transform_title.move_to(grid_title, UL)
        //重点
        grid.prepare_for_nonlinear_transform()
        //这里是对坐标系进行变化
        self.play(
            grid.apply_function,
            lambda p: p + np.array([
                np.sin(p[1]),
                np.sin(p[0]),
                0,
            ]),
            run_time=3,
        )
        self.wait()
        self.play(
            Transform(grid_title, grid_transform_title)
        )
        self.wait()

视频:

第三个函数WarpSquare

python -m manim example_scenes.py WarpSquare -pl https://img-blog.csdnimg.cn/20200217133936828.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIzMDMwODQz,size_16,color_FFFFFF,t_70

1
2
3
4
5
6
7
8
class WarpSquare(Scene):
    def construct(self):
        square = Square()
        self.play(ApplyPointwiseFunction(
            lambda point: complex_to_R3(np.exp(R3_to_complex(point))),
            square
        ))
        self.wait()

第四个函数WriteStuff

python -m manim example_scenes.py WriteStuff -pl

https://img-blog.csdnimg.cn/20200217133955405.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIzMDMwODQz,size_16,color_FFFFFF,t_70

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17

class WriteStuff(Scene):
    def construct(self):
        example_text = TextMobject(
            "This is a some text",
            tex_to_color_map={"text": YELLOW}
        )
        example_tex = TexMobject(
            "\\sum_{k=1}^\\infty {1 \\over k^2} = {\\pi^2 \\over 6}",
        )
        group = VGroup(example_text, example_tex)
        group.arrange(DOWN)
        group.set_width(FRAME_WIDTH - 2 * LARGE_BUFF)

        self.play(Write(example_text))
        self.play(Write(example_tex))
        self.wait()

第五个函数UpdatersExample

https://img-blog.csdnimg.cn/20200217134017865.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIzMDMwODQz,size_16,color_FFFFFF,t_70

python -m manim example_scenes.py UpdatersExample -pl

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class UpdatersExample(Scene):
    def construct(self):
        decimal = DecimalNumber(
            0,
            show_ellipsis=True,
            num_decimal_places=3,
            include_sign=True,
        )
        square = Square().to_edge(UP)

        decimal.add_updater(lambda d: d.next_to(square, RIGHT))
        decimal.add_updater(lambda d: d.set_value(square.get_center()[1]))
        self.add(square, decimal)
        self.play(
            square.to_edge, DOWN,
            rate_func=there_and_back,
            run_time=5,
        )
        self.wait()