目录


参考教程: https://www.cnblogs.com/wang_yb/p/17264724.html

一、简介

Manim(Mathematical Animation)
基于Python的数学动画软件。

二、安装相关软件

  • 先完成python3的基础安装,然后
# 进入虚拟环境
mamba activate py3d11

# 安装ffmpeg(选择Anaconda的清华源)
mamba install ffmpeg

# 安装(选择pip的清华源)
pip install manim

# 查看manim的版本,确定是否安装成功
manim --version
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

三、在VSCode中进行测试

  • 测试用代码
from manim import *
class Try(Scene):
    def construct(self):
        c = Circle(fill_opacity=1)
        s = Square(color=YELLOW, fill_opacity=1)
        self.play(FadeIn(c))
        self.wait()
        self.play(ReplacementTransform(c, s))
        self.wait()
        self.play(FadeOut(s))
        self.wait()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 运行
manim demo.py -p
  • 1.

生成的mp4文件见输出的“File ready at”之后。

  • 或者如下测试
# -*- coding: utf-8 -*-
import os
from manim import *


class TransformExample(Scene):
    def construct(self):

        banner = ManimBanner()
        banner.shift(UP * 0.5)
        self.play(banner.create(), run_time=1)
        self.play(banner.animate.scale(0.3), run_time=0.5)
        self.play(banner.expand(), run_time=1)

        t = Text("测试中文能否显示").next_to(banner, DOWN * 2)
        tex = VGroup(
            Text("测试数学公式:", font_size=30),
            Tex(r"$\sum_{n=1}^\infty \frac{1}{n^2} = \frac{\pi^2}{6}$"),
        )
        tex.arrange(RIGHT, buff=SMALL_BUFF)
        tex.next_to(t, DOWN)
        self.play(Write(t), run_time=1)
        self.play(Write(tex), run_time=1)

        self.wait()


# 运行场景
if __name__ == "__main__":
    demo_file = os.path.basename(__file__)
    os.system(f"manim {demo_file} -p")
  • 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.

四、manim的基本元素

  • Scene: 给动画提供一个播放的场景
  • Mobject: 场景中的各种物体,如圆形、方形等。
  • Animation: 作用在Mobject之上,用这些物体制作一些动画。
  • 命令行参数
manim demo.py Try -p
        ^      ^   ^---------- --preview 用播放器播放
        |      |----要精准渲染的类(可选)
        |
       脚本文件
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

其他常用命令行参数

命令行参数作用
-qh,-qm,-ql控制输出视频的画质,分别对应高画质、中等画质、低画质。当该参数不被指定时,默认为高画质。
-s输出视频的最后一帧(保存为图片)
-a渲染一个py文件中所有的Scene。
–renderer[cairo┃opengl]使用cairo或者opengl进行渲染(默认使用cairo)
–disable_caching在渲染时禁用缓存

五、manim的坐标系统

1. 绝对坐标

坐标为标准右手系——(x,y,z)。
Manim学习笔记-1_manim

在平面上
Manim学习笔记-1_math_02
默认宽为x,高为y。默认宽为w=128/9,高为h=8。

x轴:在图中是右正,左负。
y轴:在图中是上正,下负。

默认Mobject物件原点的绝对坐标为(0,0,0)。
改变绝对坐标的方法:

  • move_to()
  • set_x()
  • set_y()
  • set_z()

测试代码如下:

# -*- coding: utf-8 -*-
import os
from manim import *


class MyAnim(Scene):
    def construct(self):
        grid = NumberPlane(
            x_range=(-7, 7, 1),  # x轴范围
            y_range=(-4, 4, 1),  # y轴范围
            x_length=10,  # x轴长度
            y_length=6,  # y轴长度
            background_line_style={
                "stroke_color": TEAL,
                "stroke_width": 4,
                "stroke_opacity": 0.6,
            },
            faded_line_style={"stroke_color": GRAY, "stroke_opacity": 0.3},
            faded_line_ratio=0.8,  # 淡化线与背景线的比例
            make_smooth_after_applying_functions=True,  # 启用平滑处理
        )

        # 添加 NumberPlane 到场景
        self.add(grid)

        # 展示一些文字
        title = Text("Number Plane Example").to_edge(UP)
        self.add(title)

        # 画一个圆
        c = Circle()

        # 添加 Circle 到场景
        self.add(c)

        # 移动圆的位置
        c.move_to(
            [-1, 0, 0],  # [x, y, z]
            # aligned_edge=RIGHT 表示右边届对齐前边给定的坐标
            # 其他取值:LEFT,UP,DOWN,OUT,IN,UR,DL
        )

        # 画一个正方形
        s = Square()

        # 添加 Square 到场景
        self.add(s)

        # 移动正方形的位置
        s.set_x(3, direction=RIGHT)

        # 停一下
        self.wait(10)


# 运行场景
if __name__ == "__main__":
    demo_file = os.path.basename(__file__)
    os.system(f"manim {demo_file} -p")
  • 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.

Manim学习笔记-1_math_03

2. 相对坐标
c.center() # 移动到中心点(0,0,0)

c.to_edge( # 水平,上下平移
    UP, # DOWN,LEFT,RIGHT
    buff=0.5 # 物体与边界的间隙,值为0就贴靠
)

c.to_corner(
    UL, # DL,UR,DR
    buff=0.5 # 物体与边界的间隙,值为0就贴靠
)

# 相对于自身
c.shift(LEFT) # 相对于自身平移

# 相对于一个物体或坐标点
c.next_to( # 左右相邻
    s, # 可以是[x, y, z]
    direction=LEFT, # 代表相对于另一个物体的位置
    buff=0.5 # 物体与边界的间隙,值为0就贴靠
)

# 相对于物体边界对齐
c.align_to(
    s, # 可以是[x, y, z]
    UP
)
  • 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.
3. 位置匹配
c.match_x(
    s, # 让c与s的横坐标相等
)

c.match_y(
    s, # 让c与s的纵坐标相等
)

c.match_z(
    s, # 让c与s的z坐标相等
)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

还可以c.match_color(s),c.match_width(s),c.match_height(s)等

4. 获取位置信息
# 获得c的中心坐标(x,y,z)
c.get_center()

# 获得c的横坐标
c.get_x()

# 获得c的纵坐标
c.get_y()

# 获得c的z坐标
c.get_z()

# 获得c的左边界的中心点坐标
c.get_left()
# 同理:
c.get_right()
c.get_top()
c.get_bottom()
c.get_corner() # 接收参数:UL,DL,UR,DR
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.