边学边做Manim中的对齐方式

在Manim中,arrange()Mobject类的一个重要方法,用于自动排列多个对象,比如图形、文本等,让它们整齐地排列成一行、一列或其他布局。

1.基本语法

1
mobjects.arrange(direction=RIGHT, buff=0.2, aligned_edge=ORIGIN, center=True)

2.主要参数详解

2.1. direction - 排列方向

1
2
3
# 水平排列(默认)
objects.arrange(RIGHT) # 从左到右
objects.arrange(LEFT) # 从右到左
1
2
3
# 垂直排列
objects.arrange(DOWN) # 从上到下
objects.arrange(UP) # 从下到上
1
2
# 对角线排列
objects.arrange(RIGHT+DOWN) # 对角线排列

2.2. buff - 对象间距

1
objects.arrange(buff=0.5)  # 间距0.5个单位
1
objects.arrange(buff=2)    # 间距2个单位
1
objects.arrange(buff=0)    # 紧挨着

2.3. aligned_edge 对齐边缘

1
objects.arrange(aligned_edge=LEFT)    # 左边缘对齐
1
objects.arrange(aligned_edge=RIGHT)   # 右边缘对齐
1
objects.arrange(aligned_edge=UP)      # 上边缘对齐
1
objects.arrange(aligned_edge=DOWN)    # 下边缘对齐
1
objects.arrange(aligned_edge=ORIGIN)  # 中心对齐(默认)

2.4.center 是否居中

1
objects.arrange(center=True)   # 整体居中(默认)
1
objects.arrange(center=False)  # 保持当前位置,只调整相对位置

3.实用示例

3.1.基本水平排列

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

class ArrangeExample(Scene):
def construct(self):
# 创建3个不同颜色的圆
circles = VGroup(
Circle(color=RED,radius=2),
Circle(color=GREEN,radius=2),
Circle(color=BLUE,radius=2)
).scale(0.5)

# 水平排列,间距0.5
circles.arrange(RIGHT, buff=0.5)

self.play(Create(circles))
self.wait()

3.2.垂直排列与对齐

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

class ArrangeVertical(Scene):
def construct(self):
squares = VGroup(
Square(side_length=1, color=RED),
Square(side_length=1.5, color=GREEN),
Square(side_length=0.8, color=BLUE)
)

# 垂直排列,左对齐
squares.arrange(DOWN, buff=0.3, aligned_edge=LEFT)

self.play(Create(squares))
self.wait(2)

3.3.复杂排列布局

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

class ComplexArrange(Scene):
def construct(self):
# 创建三组对象
group1 = VGroup(*[Circle(radius=0.3) for _ in range(3)])
group2 = VGroup(*[Square(side_length=0.6) for _ in range(3)])
group3 = VGroup(*[Triangle() for _ in range(3)])

# 每组内部水平排列
group1.arrange(RIGHT, buff=0.2)
group2.arrange(RIGHT, buff=0.2)
group3.arrange(RIGHT, buff=0.2)

# 三组之间垂直排列
all_groups = VGroup(group1, group2, group3)
all_groups.arrange(DOWN, buff=0.5)

self.play(Create(all_groups))
self.wait(2)

3.4.网格排列(使用循环)

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

class GridArrange(Scene):
def construct(self):
# 创建3x3网格
dots = VGroup()
for i in range(3):
row = VGroup()
for j in range(3):
dot = Dot()
row.add(dot)
row.arrange(RIGHT, buff=1) # 行内水平排列
dots.add(row)

dots.arrange(DOWN, buff=1) # 行间垂直排列

self.play(Create(dots))
self.wait()

3.5.自定义排列布局

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

class CustomArrange(Scene):
def construct(self):
shapes = VGroup(
Circle(radius=0.5, color=RED),
Square(side_length=1, color=GREEN),
Triangle().scale(0.7).set_color(BLUE)
)

# 先水平排列
shapes.arrange(RIGHT, buff=1)
self.play(Create(shapes))
self.wait()

# 再垂直排列
self.play(shapes.animate.arrange(DOWN, buff=0.5))
self.wait()

4.实际应用场景

4.1.数学公式排列

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

class MathArrange(Scene):
def construct(self):
equations = VGroup(
MathTex("x^2 + y^2 = r^2"),
MathTex("\\frac{d}{dx}f(x) = \\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}"),
MathTex("e^{i\\pi} + 1 = 0")
)
equations.arrange(DOWN, buff=0.5, aligned_edge=LEFT)
self.play(Write(equations))

4.2创建按钮菜单

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

class MenuArrange(Scene):
def construct(self):
# 创建按钮矩形
rect_start = Rectangle(width=2, height=0.8, color=BLUE)
rect_options = Rectangle(width=2, height=0.8, color=GREEN)
rect_exit = Rectangle(width=2, height=0.8, color=RED)

# 创建文本
text_start = Text("Start", color=WHITE).scale(0.6)
text_options = Text("Options", color=WHITE).scale(0.6)
text_exit = Text("Exit", color=WHITE).scale(0.6)

# 将文本放在矩形中心
text_start.move_to(rect_start)
text_options.move_to(rect_options)
text_exit.move_to(rect_exit)

# 创建按钮组(矩形+文本)
button_start = VGroup(rect_start, text_start)
button_options = VGroup(rect_options, text_options)
button_exit = VGroup(rect_exit, text_exit)

# 创建所有按钮的组
buttons = VGroup(button_start, button_options, button_exit)

# 垂直排列按钮
buttons.arrange(DOWN, buff=0.3)

self.play(Create(buttons))

5.知识总结

5.1.配合VGroup使用

1
2
3
# 正确:先创建VGroup再arrange
group = VGroup(obj1, obj2, obj3)
group.arrange(RIGHT)
1
2
# 错误:直接对列表使用arrange
[obj1, obj2, obj3].arrange(RIGHT) # 这样不行!

5.2.链式排列

1
2
3
4
# 可以先水平排列,再整体垂直排列
group1.arrange(RIGHT)
group2.arrange(RIGHT)
VGroup(group1, group2).arrange(DOWN)

5.3.结合shift调整位置

1
objects.arrange(RIGHT).shift(UP*2)

5.4.与next_to()的区别

arrange():自动批量排列多个对象,next_to():手动指定一个对象相对于另一个对象的位置

1
2
# 使用arrange
circles.arrange(RIGHT, buff=0.5)
1
2
3
# 使用next_to(需要手动)
circle2.next_to(circle1, RIGHT, buff=0.5)
circle3.next_to(circle2, RIGHT, buff=0.5)

写在最后,arrange()是Manim中非常实用的布局工具,可以大大简化多对象的位置管理,让代码更简洁!