使用Manim创建一个直角三角形

今天我们来用Manim来做一个直角三角形,在 Manim的数学动画库中,Triangle 是一个常用的几何图形类,用于创建和操作三角形。但是默认的 Triangle 创建的三角形其实是一个等边三角形,这个等边三角形的中心在屏幕的中心,所以如果我们使用Triangle创建三角形,不会创建出直角或者钝角的三角形,其实,我们创建一个直角三角形,默认的是计算好顶点坐标之后,才进行创建。

1.使用Polygon

1.1基本参数

Manim 中Polygon 是一个用于创建多边形的类,用于创建任意边数的多边形,可以自定义顶点、边、颜色、填充等属性,但是Polygon 必须提供至少三个顶点的参数。

1
Polygon([x1, y1, z1], [x2, y2, z2], [x3, y3, z3], ...)

我们来看示例

1
2
3
4
5
polygon = Polygon(
[-2, -1, 0], # 顶点1
[2, -1, 0], # 顶点2
[0, 2, 0], # 顶点3
)

1.2.其余参数

1.2.1.边框颜色
1
2
color=BLUE,              # 边框颜色(简写)
stroke_color=BLUE, # 边框颜色(完整写法)
1.2.2.填充颜色
1
2
fill_color=YELLOW,       # 填充颜色
fill_opacity=0.5, # 填充不透明度(0-1)
1.2.3.颜色渐变
1
color=Gradient([BLUE, GREEN]),  # 渐变颜色

2.创建基础实例

在下面的代码中,我们就是使用了Polygon创建了一个直角三角形。来看示例代码

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

class RightTriangleWithAngleOne(Scene):
def construct(self):
# 创建直角三角形的三个顶点
A = [-2, -1, 0] # 直角顶点
B = [2, -1, 0] # 水平边端点
C = [-2, 2, 0] # 垂直边端点

# 创建三角形
triangle = Polygon(A, B, C, color=BLUE, fill_opacity=0.3)

# 添加直角标记
right_angle = RightAngle(
Line(A, B), # 水平边
Line(A, C), # 垂直边
length=0.3, # 标记的大小
color=RED,
stroke_width=3
)

# 添加顶点标签
label_A = Text("A").next_to(A, DOWN + LEFT, buff=0.1).scale(0.5)
label_B = Text("B").next_to(B, DOWN, buff=0.1).scale(0.5)
label_C = Text("C").next_to(C, LEFT, buff=0.1).scale(0.5)

# 添加边标签
side_AB = MathTex("a").next_to(Line(A, B), DOWN, buff=0.1).scale(0.5)
side_AC = MathTex("b").next_to(Line(A, C), LEFT, buff=0.1).scale(0.5)
side_BC = MathTex("c").next_to(Line(B, C).get_center(), UP+RIGHT, buff=0.1).scale(0.5)

# 使用动画展示(按顺序显示)

# 1. 先显示三角形
self.play(Create(triangle))
self.wait(0.5)

# 2. 显示直角标记
self.play(Create(right_angle))
self.wait(0.5)

# 3. 显示顶点标签
self.play(
Write(label_A),
Write(label_B),
Write(label_C)
)
self.wait(0.5)

# 4. 显示边标签
self.play(
Write(side_AB),
Write(side_AC),
Write(side_BC)
)
self.wait(2)

来看演示的效果

3.添加坐标系

我们来给上面的实例添加一个简单的坐标系,就会发现里面的一些问题。

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
56
57
58
59
from manim import *

class RightTriangleWithAngleMark(Scene):
def construct(self):
axes=Axes()
self.play(Create(axes))
self.wait()
# 创建直角三角形的三个顶点
A = [-2, -1, 0] # 直角顶点
B = [2, -1, 0] # 水平边端点
C = [-2, 2, 0] # 垂直边端点

# 创建三角形
triangle = Polygon(A, B, C, color=BLUE, fill_opacity=0.3)

# 添加直角标记
right_angle = RightAngle(
Line(A, B), # 水平边
Line(A, C), # 垂直边
length=0.3, # 标记的大小
color=RED,
stroke_width=3
)

# 添加顶点标签
label_A = Text("A").next_to(A, DOWN + LEFT, buff=0.1).scale(0.5)
label_B = Text("B").next_to(B, DOWN, buff=0.1).scale(0.5)
label_C = Text("C").next_to(C, LEFT, buff=0.1).scale(0.5)

# 添加边标签
side_AB = MathTex("a").next_to(Line(A, B), DOWN, buff=0.1).scale(0.5)
side_AC = MathTex("b").next_to(Line(A, C), LEFT, buff=0.1).scale(0.5)
side_BC = MathTex("c").next_to(Line(B, C).get_center(), UP+RIGHT, buff=0.1).scale(0.5)

# 使用动画展示(按顺序显示)

# 1. 先显示三角形
self.play(Create(triangle))
self.wait(0.5)

# 2. 显示直角标记
self.play(Create(right_angle))
self.wait(0.5)

# 3. 显示顶点标签
self.play(
Write(label_A),
Write(label_B),
Write(label_C)
)
self.wait(0.5)

# 4. 显示边标签
self.play(
Write(side_AB),
Write(side_AC),
Write(side_BC)
)
self.wait(2)

来看演示的效果

我们用来描点的坐标,与坐标系的坐标并不是对应的,这是因为我们用来描点的坐标是绝对坐标,坐标系的坐标是相对坐标,为了让描点的坐标与坐标系的坐标相匹配,我们使用了下面的代码

1
2
3
4
# 创建直角三角形的三个顶点(与坐标轴刻度对应)
A = axes.c2p(-2, -1) # 直角顶点 (-2, -1)
B = axes.c2p(2, -1) # 水平边端点 (2, -1)
C = axes.c2p(-2, 2) # 垂直边端点 (-2, 2)

4.坐标系中的直角三角形

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
from manim import *

class RightTriangleWithAngleMark(Scene):
def construct(self):
# 创建坐标轴,指定合适的范围
axes = Axes(
x_range=[-3, 3, 1], # x从-3到3,步长为1
y_range=[-2, 3, 1], # y从-2到3,步长为1
x_length=6,
y_length=5,
axis_config={"color": GRAY}
)

self.play(Create(axes))
self.wait(0.5)

# 创建直角三角形的三个顶点(与坐标轴刻度对应)
A = axes.c2p(-2, -1) # 直角顶点 (-2, -1)
B = axes.c2p(2, -1) # 水平边端点 (2, -1)
C = axes.c2p(-2, 2) # 垂直边端点 (-2, 2)

# 创建三角形
triangle = Polygon(A, B, C, color=BLUE, fill_opacity=0.3)

# 添加直角标记
right_angle = RightAngle(
Line(A, B), # 水平边
Line(A, C), # 垂直边
length=0.3,
color=RED,
stroke_width=3
)

# 添加顶点标签
label_A = Text("A").next_to(A, DOWN + LEFT, buff=0.1).scale(0.5)
label_B = Text("B").next_to(B, DOWN, buff=0.1).scale(0.5)
label_C = Text("C").next_to(C, LEFT, buff=0.1).scale(0.5)

# 添加边标签
side_AB = MathTex("a").next_to(Line(A, B), DOWN, buff=0.1).scale(0.5)
side_AC = MathTex("b").next_to(Line(A, C), LEFT, buff=0.1).scale(0.5)
side_BC = MathTex("c").next_to(Line(B, C).get_center(), UP+RIGHT, buff=0.1).scale(0.5)

# 创建网格
grid = axes.get_lines_to_point(axes.c2p(0,0)) # 获取网格线
self.play(Create(grid), run_time=1)

# 显示三角形
self.play(Create(triangle))
self.wait(0.5)

# 显示直角标记
self.play(Create(right_angle))
self.wait(0.5)

# 显示顶点标签
self.play(
Write(label_A),
Write(label_B),
Write(label_C)
)
self.wait(0.5)

# 显示边标签
self.play(
Write(side_AB),
Write(side_AC),
Write(side_BC)
)
self.wait(2)

来看演示视频

好了,今天的经验分享就到了,以后这篇文章还会更新写心得。谢谢大家。