(目录)


参考教程:https://www.cnblogs.com/wang_yb/p/17264724.html 官网:https://github.com/ManimCommunity/manim/

一、简介

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

二、安装相关软件

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

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

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

# 查看manim的版本,确定是否安装成功
manim --version

三、在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()
  • 运行
manim demo.py -p

生成的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")

四、manim的基本元素

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

其他常用命令行参数

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

五、manim的坐标系统

1. 绝对坐标

坐标为标准右手系——(x,y,z)。 image.png

在平面上 image.png 默认宽为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")

image.png

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
)

3. 位置匹配

c.match_x(
    s, # 让c与s的横坐标相等
)

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

c.match_z(
    s, # 让c与s的z坐标相等
)

还可以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