当前位置: 首页 > 工具软件 > Manim > 使用案例 >

manim学习笔记

别浩漫
2023-12-01

manim学习笔记

最近更新时间: 2022-10-10

前言

什么是manim

manim是大佬3Blue1Brown 开发的动画引擎,他使用 manim 创作出了许多直观、美丽的数学科普内容。

它在B站也有也有账号3Blue1Brown

目前 Manim 主要有三个版本: manim-master (3b1b 新版), ManimCommunity (社区版), manim-cairo-backend (3b1b 旧版)

这篇文章学习以社区版即manimce为主,以及有关于manimce的学习也可以去看社区版的官方文档https://docs.manim.community/

安装manim

首先manim本身是一个python项目,安装python是必不可少的,这里默认大家都会。

然后,manim的运行环境的组成分为三个部分:manim、ffmpeg、latex发行版

为了项目的整体可迁移性,我选择了pipenv虚拟环境并安装了以下包:

pip install manim
pip install ffmpeg

latex发行版可以选择Texlive-fullMiKTeX

Manim是怎么工作的

manim的工作流程是由好几个部分组成的。

简单的来说,就是以下几步:

  1. 首先,manim先通过python的生成特殊的图形格式对象传递给cairo
  2. cairo生成一系列图片,每一张图片也就是一帧
  3. 生成的图片传递给ffmpeg
  4. ffmpeg将这些图片组合到一起生成视频

Mobject

在manim里,可以在屏幕里显示的对象,都被称之为Mobject

Mobject是很多其他类的父类:

  • VMobject
  • ImageMobject
  • PMobject
  • ValueTracker
  • Group/VGroup

VMobject十分灵活多变,本质上是贝塞尔曲线,可以展现各式各样的矢量图形,在manim里,文本也是VMobject。

ImageMobject本质上是像素的矩阵。

Group/VGroup这两个可以作为容器包含多个对象,Group可以包含任何MobjectVGroup只能包含VMobjectVMobject的子类实例

动画

动画类型

manim中动画Animations抽象类可以分为两大类,Scene.play动画、Updaters动画。

play动画可以播放类动画(Class动画)或者方法动画(method动画),实质二者并没有什么差别,因为方法动画是类动画的子类型。

而Updaters是动画每一帧都会调用的函数,Updaters有三种不同类型:Simple updatersα updatersdt updaters

Class动画类

所有的Class动画都是继承自Animations抽象类

它有以下几个重要特性:

  1. run_time 表示动画的运行时长
  2. rate_func 动画速率函数
  3. remover 如果改参数为true,那么相应的Mobject将在动画运行结束后从屏幕中删除

方法作用简述

方法名作用
Scene.add立即向屏幕中添加一个或多个Mobject(无需设置持续时间)
Scene.remove立即从屏幕中删除一个或多个Mobject
Scene.wait动画暂停时长,默认1秒
Scene.play在同一个Scene.play方法中可以有多个Class动画,所有动画将在同一时间开始运行
move_to接受一个三维向量,将对象移动到该位置。也可以接受一个对象,移动到该对象的位置
to_edge移动到屏幕边沿,另外可以传递一个buff参数,表示与边沿的距离
to_corner移动到屏幕的一个角,也接受buff参数
shift相对当前位置移动
next_to移动到对象附件,接受两个可选参数,buff距离,alinged_edge,对齐方式
alinged_edge将一个对象对齐于另一个对象
set_z_index设置对象上下顺序,所有对象创建时默认z_index为0,这个方法不能使用"animate"属性调用动画
set_opacity传入一个α,设置绝对数值来设置不透明度
set_fade以相对数值来设置不透明度

位置(Positions)

绝对位置(Absolute)

绝对定位,以屏幕为参考坐标,原点位置在屏幕中心

默认情况下,所有的Mobject都创建在屏幕正中心的位置

  1. .move_to
  2. .to_edge
  3. to_corner

相对位置(Relative)

相对定位,以某个对象或是某个点为参考而相对移动位置

  1. .shift
  2. .next_to
  3. .aligned_edge

需要注意的是,以上方法是立即生效的,如果需要移动动画,可以调用animation属性

# 立即生效
c.move_to(UR)
self.wait()
c.to_edge(RIGHT)
self.wait()
c.align_ti(s.RIGHT)
self.wait()

# 移动动画
self.play(c.animate.move_to(UR))
self.wait()
self.play(c.animate.to_edge(RIGHT))
self.wait()
self.play(
    c.animate(run_time=3)
     .align_to(s.RIGHT)
)
self.wait()

变形变换

所有的对象都有默认的大小,几乎所有的Mobject动画都可以使用animate属性调用

tips: .rotate().flip()这两个方法属于特殊情况

变形方法

Mobjects变形方法可以分为三类

  1. Without stretch (不包含伸缩变形)
  2. With stretch (包含伸缩变形)
  3. Rotation (旋转)
Without stretchWith stretchRotation
.set().stretch_to_fit_width().rotate()
.scale_to_fit_width().stretch_to_fit_height().filp()
.scale_to_fit_height()
.match_width()
.match_height()

也可以通过控制缩放因子.scale()来变形缩放

以上变换都可以使用.apply_matrix()实现

Mobject对象的Setter和Getter方法

Getter方法

Getter就是可以从对象上获取各种信息的方法,这些方法的名字大多都是以get前缀开始的。

Setter方法

Setter方法可以用来更改对象的属性

VMobject对象

属性

属性名属性
stroke_color描边颜色
stroke_width描边宽度
stroke_opacity描边不透明度
fill_color填充颜色
fill_opacity填充区域不透明度
background_stroke_color描边背景颜色
background_stroke_width描边背景宽度
background_stroke_opacity描边背景不透明度

manim自定义配置

manim提供了三种方法给我们自定义配置:config.cfg文件CLI(命令行接口)CONFIG字典对象

config.cfg文件

manim所有的默认配置可以用以下命令查看:

manim cfg show

我们可以通过创建自己的cfg文件来启用自己想要的配置。

cfg文件中可以配置的选项可以分为五个类别:[CLI]custom_folders[logger][ffmpeg][jupyter]

使用以下的命令格式就可以使用自己指定的配置文件,不使用-c默认使用当前目录下的manim.cfg

manim <scripts.py> <scene-name> <quality-flag> -c <config-file.cfg>

使用下列命令可以很容易的生成配置文件:

manim cfg write -o

tips: 如果当前目录已存在manim.cfg,这个命令会覆盖当前的manim.cfg!

常用配置项

[CLI]
background = #000000
# debug相关
preview = False
verbosity = INFO
#         = [DEBUG|INFO|WARNING|ERROR|CRITICAL]
progress_bar = display
#            = [display|leave|none]
# caching相关
max_files_cached = 100
disable_caching = False
disable_caching_warning = False
# folders相关
media_dir = ./media
assets_dir = ./
video_dir = {media_dir}/videos/{module_name}/{quality}
images_dir = {media_dir}/images/{module_name}
tex_dir = {media_dir}/Tex
text_dir = {media_dir}/texts
partial_movie_dir = {video_dir}/partial_movie_files/{scene_name}

个人在用配置:

media_dir = ./exports
assets_dir = ./assets
video_dir = {media_dir}/videos/{module_name}/{quality}
images_dir = {media_dir}/images/{module_name}/{quality}
tex_dir = ./tmp/Tex
text_dir = ./tmp/texts
partial_movie_dir = ./tmp/partial_movie_files/{module_name}/{quality}/{scene_name}

以及我们可以定义[custom_folders]

[custom_folders]
media_dir = custom_export
assets_dir = {media_dir}
section_dir = {medeia_dir}
images_dir = {media_dir}
tex_dir = {media_dir}/temp_files
text_dir = {media_dir}/temp_files
log_dir = {media_dir}/temp_files
partial_movie_dir = {media_dir}/partial_movie_files/{scene_name}

只有在使用--custom_folders命令行选项参数才可与激活这种文件夹结构,同时[CLI]结构里的属性会被忽略,比较适合用来临时测试

CLI(命令行接口)

仅列出较为常用的

# config,指定使用的.cfg文件
-c file.cfg

# preview,渲染完成后打开预览
-p

# quality,质量参数,可选对应质量渲染
# -l 480p 15fps, -m 720p 30fps, -h 1080p 60fps, -p 1440p 60fps, -k 2160p 60fps
-q

# 自定义分辨率
--fps=SOME_FPS
-r WIDTH,HEIGHT

# 将帧一帧帧输出格式为png
--format=png
# 输出格式为gif
--format=gif
# 默认输出格式,输出格式为mp4
--format=mp4
# 输出格式为webm,浏览器里特有的格式
--format=webm
# 输出格式为mov,这个选项是输出质量最好的,它不会压缩视频,所以输出文件会比其他选项要大得多
--format=mov

# 将最后一帧渲染为图片
-s

# 渲染有透明背景的视频或图片
-t

CONFIG 字典

这是manim中的全局变量,包含有manim项目的各种配置信息。

这个字典变量里包含的各种属性和通过[CLI(命令行接口)]或是.cfg配置文件里配置的选项是一样的。

修改它十分简单,修改方式和python修改字典对象的方式是一样的:

config.property = VALUE
config["property"] = VAlUE

代码中可以获取config字典的属性值

配置的优先级

这三种方式,CONGFIG字典的优先级是最高的

  1. CONFIG 字典
  2. CLI(命令行接口)
  3. .cfg 配置文件

动画速率函数(rate_functions)

自定义动画速率函数

可以传入0~1之间的参数t,可以定义其他参数,只要其他参数有默认值即可

def parabola(t, amp=0.5):
    return (1-(2*t-2)**2)*amp

circle = Circle()

self.play(ScaleInPlace(
		circle, 3,
    	run_time=5,
    	rate_func=parabola
	)
)

Group 和 VGroup

grp = Group(mob1, mob2, ..., mobn)
grp.add(other_mob) # 添加到最上层
grp.add_to_back(other_mob) # 添加到最底层
grp.remove(other_mob)

文本和公式

manim中并不实际存在文本对象。

本质上,manim中的文本包括latex都是svg图形。

manim通过调用一个名为Pango的工具将文本转化为svg,然后将其导入(通过哈希值确定其唯一命名)

查看操作系统已安装的字体

可以使用这段命令行查看已安装的字体:

python -c "import manimpango; from pprint import pprint; pprint(manimpango.list_fonts())"

变形动画

Transform是一个父类,所有其他的变形动画类都继承自该类,它也是一个动画类。

Transform(base_object, target)
ReplacementTransform(base_object, target)
 类似资料: