Manim学习笔记-初步入门几何图形

Manim学习笔记

本文仅讨论Manim社区版的使用

1. 安装

讲得比我好, 绝对不是我懒得写

Linux/Mac 见自行搜索各自的安装教程 (都用Linux/Mac了相信至少已经不是小白级别的了), 一般来说cairo pango ffmpeg TexLive是必须的

正常来说走完这些流程Manim就可以使用了, 不用其他乱七八糟的操作

1.1 安装Manim(社区版)

1
2
3
4
5
6
# (虚拟环境, 可选)
python -m venv venv
venv/Scripts/activate

# 安装
pip install manim

如果出现Visual C++一类的报错, 安装Visual Studio Build Tools

1.2 安装FFmpeg

下载链接 下载后解压缩, 把bin文件夹加入环境变量Path

1.3 安装Tex

建议用MikTex, 小巧灵活

1.4 安装Sox

下载链接

1.5 验证

1
2
3
4
manim -v
latex -v
ffmpeg
sox

你也可以选择写一个简单的manim脚本测试一下

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
# -*- coding: utf-8 -*-
# test.py
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()

manim环境中输入manim -pql test.py TransformExample即可运行

2. 基础知识

2.1 如何运行(命令行参数)

1
2
# 用于获取参数用法
manim render --help

常用的有下面这些

  • manim -c: 查看配置文件
  • manim --flush_cache: 清除缓存
  • manim --enable_gui: 启用动画窗口化交互
  • manim --fullscreen: 全屏显示
  • manim --dry_run: 仅渲染帧, 不输出视频
  • manim -o 文件名: 制定保存文件名
  • manim --format [png | gif | mp4 | webm | mov]: 制定输出格式
  • manim -q [l | m | h | p | k]: 制定输出质量
    • l: 854x480 15fps
    • m: 1280x720 30fps
    • h: 1920x1080 60fps
    • p: 2560x1440 60fps
    • k: 3840x2160 60fps
  • manim --renderer [cario | opengl]: 制定渲染器(默认是cario)
  • manim --progress_bar [display | leave | none]: 制定进度条显示方式
  • manim -p: 生成后是否预览
  • manim -f: 生成后打开输出文件夹

2.2 代码风格

由于Manim主要用于生成视频, 且其代码一半不直接运行, 所以有其独特的码风, 一般而言, 它长这样:

1
2
3
4
5
6
7
8
9
# example.py
from manim import *

class Example(Scene):
def construct(self):
# 创建对象, 规定属性
# 渲染对象
wait(秒数)
...

其中Example是类名, Scene是继承的类, self是实例本身, self.construct()是构造函数, 这些是必须包含的

博客中所有的渲染指令均为: manim -pqm example.py Example

2.3 通用属性

2.3.1 颜色

  • color: 设置对象的主色(边框或填充色),支持命名颜色(如RED)或十六进制值
  • fill_color: 控制填充颜色(对封闭形状有效)
  • stroke_color: 控制边框/线条颜色
  • stroke_width: 设置边框/线条宽度

2.3.2 透明度

  • opacity: 整体透明度(0为全透明,1为不透明)
  • fill_opacity: 填充部分透明度
  • stroke_opacity: 边框/线条透明度

2.3.3 位置

  • point: 设置对象的位置(二维或三维坐标)

3. 图形

小学生级别

3.1 点

  • 用法: Dot(三维坐标(x, y, z)或二维坐标(x, y, 0))

  • 参数:

    • radius: 点的大小(半径)
  • 示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    from manim import *
    from random import randint

    class DotEg(Scene):
    def construct(self):
    # x: -1~1, y: 1~-1
    for x in range(-1, 2):
    for y in range(1, -2, -1):
    # 在(x, y)处创建一个随机半径的圆点
    dot = Dot([x, y, 0], radius=randint(1, 3) / 10)
    # 在屏幕上显示圆点, 间隔0.5秒
    self.play(Create(dot), run_time=0.5)

3.2 线

3.2.1 线段

  • 用法: Line(起点坐标, 终点坐标)
  • 参数:
    • buff: 端点延伸距离
    • path_arc: 弧度(0为直线, PI/2为90°弯曲)

3.2.2 箭头

  • 用法: Arrow(起点坐标, 终点坐标)
  • 参数:
    • buff: 箭头尖端与端点的距离(默认为0.25)
    • tip_shape: 箭头形状(可自定义几何对象,如Triangle)
    • tip_length: 箭头头部长度
    • max_tip_length_to_length_ratio: 箭头大小与线段长度的比例(>0.5时可能覆盖线段)
    • max_stroke_width_to_length_ratio: 线段粗细与箭头大小的比例

3.2.3 虚线

  • 用法: DashedLine(起点坐标, 终点坐标)
  • 参数:
    • dash_length: 虚线段长度
    • dashed_ratio: 虚线段与间隔的比例

示例:

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
from manim import *

class LineDemo(Scene):
def construct(self):
# 基础直线
line1 = Line(start=[-4, 2, 0], end=[-2, 2, 0], color=BLUE)
line1_label = Text("基础直线", font_size=20).next_to(line1, DOWN)

# 弯曲效果 (path_arc)
line2 = Line(start=[-4, 1, 0], end=[-2, 1, 0], path_arc=PI/2, color=GREEN)
line2_label = Text("path_arc=PI/2", font_size=20).next_to(line2, DOWN)

# 端点延伸 (buff)
line3 = Line(start=[-4, 0, 0], end=[-2, 0, 0], buff=0.5, color=RED)
line3_label = Text("buff=0.5(缩短)", font_size=20).next_to(line3, DOWN)

line_group = VGroup(line1, line1_label, line2, line2_label,
line3, line3_label)
self.play(Create(line_group), run_time=2)
self.wait(1)

# 基础箭头
arrow1 = Arrow(start=[1, 2, 0], end=[3, 2, 0], color=BLUE)
arrow1_label = Text("基础箭头", font_size=20).next_to(arrow1, DOWN)

# 箭头形状 (tip_shape)
arrow2 = Arrow(start=[1, 1, 0], end=[3, 1, 0], tip_shape=ArrowSquareTip, color=GREEN)
arrow2_label = Text("tip_shape=方形", font_size=20).next_to(arrow2, DOWN)

# 箭头大小比例 (max_tip_length_to_length_ratio)
arrow3 = Arrow(start=[1, 0, 0], end=[3, 0, 0],
max_tip_length_to_length_ratio=0.8, color=RED)
arrow3_label = Text("箭头: 线段=0.8", font_size=20).next_to(arrow3, DOWN)

# 端点距离 (buff)
arrow4 = Arrow(start=[1, -1, 0], end=[3, -1, 0], buff=0, color=YELLOW)
arrow4_label = Text("buff=0(紧贴端点)", font_size=20).next_to(arrow4, DOWN)

arrow_group = VGroup(arrow1, arrow1_label, arrow2, arrow2_label,
arrow3, arrow3_label, arrow4, arrow4_label)
self.play(Create(arrow_group), run_time=2)
self.wait(1)

# 基础虚线
dash1 = DashedLine(start=[-4, -2, 0], end=[-2, -2, 0], color=BLUE, dashed_ratio=0.2)
dash1_label = Text("dashed_ratio=0.2(虚线长)", font_size=20).next_to(dash1, DOWN)

# 虚线长度 (dash_length)
dash2 = DashedLine(start=[-4, -3, 0], end=[-2, -3, 0],
dash_length=0.2, color=GREEN)
dash2_label = Text("虚线: 实线=0.2", font_size=20).next_to(dash2, DOWN)

dash_group = VGroup(dash1, dash1_label, dash2, dash2_label)
self.play(Create(dash_group), run_time=2)
self.wait(2)

3.3 圆相关

3.3.1 圆

  • 用法: Circle(radius=r)
  • 参数:
    • radius: 半径
    • 注意: 圆不能直接规定圆心位置, 只能通过move_to方法移动

3.3.2 椭圆

  • 用法: Ellipse(width, height)
  • 参数:
    • width: 水平轴长度
    • height: 垂直轴长度
    • 其他同Circle

3.3.3 圆弧

  • 用法: Arc(radius, angle)
  • 参数:
    • radius: 半径
    • start_angle: 起始弧度
    • angle: 圆弧弧度
    • arc_center: 圆弧中心

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from manim import *

class ShapeParameterDemo(Scene):
def construct(self):
circles = Circle(radius=0.5, color=RED).move_to([-2, 0, 0])

ellipses = Ellipse(width=1, height=2).move_to([0, 0, 0])

arcs = Arc(angle=PI/2, arc_center=[2, 0, 0], radius=1)

self.play(
Create(circles),
Create(arcs),
Create(ellipses),
)
self.wait()

3.4 多边形

3.4.1 等边三角形

  • 用法: Triangle()
  • 参数:
    • 不能直接设置边长, 需用scale(边长)方法
    • 不能直接设置位置, 需用move_to([x, y, z])方法

3.4.2 正方形

  • 用法: Square()
  • 参数:
    • side_length: 边长
    • 不能直接设置位置, 需用move_to([x, y, z])方法

3.4.3 矩形

3.4.3.1 基础矩形
  • 用法: Rectangle(宽, 高)
  • 参数:
    • width: 宽度
    • height: 高度
    • grid_xstep: 垂直网格间距(None为不显示网格)
    • grid_ystep: 水平网格间距(None为不显示网格)
3.4.3.2 圆角矩形
  • 用法: RoundedRectangle(宽, 高, 圆角半径)
  • 参数:
    • corner_radius: 圆角半径(传入一个数代表所有的角都为圆角, 传入一个长度为4的列表代表每个角对应不同的圆角半径)
    • 其他同Rectangle

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from manim import *

class ShapeParameterDemo(Scene):
def construct(self):
triangles = Triangle().scale(1).move_to([-4, 0, 0])

squares = Square(side_length=1).move_to([-2, 0, 0])

rectangles = Rectangle(width=1, height=2).move_to([2, 0, 0])

rounded_rectangles = RoundedRectangle(width=2, height=1, corner_radius=[0.2, 0.3, 0.1, 0.4]).move_to([4, 0, 0])

self.play(
Create(triangles),
Create(squares),
Create(rectangles),
Create(rounded_rectangles)
)

self.wait(2)

3.4.4 多边形

3.4.4.1 正多边形
  • 用法: RegularPolygon(n)
  • 参数:
    • n: 边数
    • 注意: 不能直接设置边长, 需用scale(边长)方法
    • 注意: 不能直接设置位置, 需用move_to([x, y, z])方法
3.4.4.2 多边形
  • 用法: Polygon(list[points])
  • 参数:
    • points: 多边形顶点坐标列表
3.4.4.3 ​​广义正多边形​​
  • 用法: RegularPolygram(n, m)
  • 参数:
    • num_vertices: 顶点数(≥3)
    • density: 顶点连接间隔
      • density=1: 正多边形
      • density=2: 正多角星
      • density=3: 更牛逼的多角星
    • radius: 外接圆半径(可间接理解为边长)
    • start_angle: 初始旋转角度(弧度制,0表示右侧起始)
    • 注意: 不能直接设置位置, 需用move_to([x, y, z])方法

示例:

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
from manim import *

class PolygonDemo(Scene):
def construct(self):
# 1. 正多边形 (RegularPolygon)
pentagon = RegularPolygon(n=5, color=BLUE, fill_opacity=0.5).scale(2).move_to(LEFT*3 + UP*2)

# 2. 多边形 (Polygon)
custom_poly = Polygon(
[-1, 0.5, 0], [1, 1, 0], [1.5, -1, 0], [0, -1.5, 0], [-1.5, -0.5, 0],
color=RED, fill_opacity=0.5
).move_to(RIGHT*3 + UP*2)

# 3. 广义多边形 (RegularPolygram)
# density=2 (五角星)
star5 = RegularPolygram(
num_vertices=5,
density=2,
color=GOLD
).move_to(LEFT*3 + DOWN*2)

# density=3 (七角星)
star7 = RegularPolygram(
num_vertices=7,
density=3,
color=PURPLE,
radius=1.5,
).move_to(RIGHT*3 + DOWN*2)

# 同时创建所有形状
self.play(
Create(pentagon),
Create(custom_poly),
Create(star5),
Create(star7)
)

self.wait(3)