(目录)
参考教程: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)。
在平面上
默认宽为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")
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