You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
4.6 KiB
117 lines
4.6 KiB
from manim import *
|
|
|
|
class ClearProof(Scene):
|
|
def construct(self):
|
|
config.frame_width = 12.8
|
|
config.frame_height = 10.24
|
|
colors = {
|
|
"a": "#4D9DE0",
|
|
"b": "#E15554",
|
|
"c": "#3BB273",
|
|
"bg": "#1E1E1E",
|
|
"text": "#FFFFFF"
|
|
}
|
|
self.camera.background_color = colors["bg"]
|
|
a, b = 3, 4 # 直角边长度
|
|
c = 5 # 斜边长度
|
|
|
|
# ========== 第一步:初始构造 ==========
|
|
step1 = Text("构造直角三角形", font_size=36, color=colors["text"]).to_edge(UP)
|
|
tri = Polygon([-4, -2, 0], [2, -2, 0], [-4, 2, 0],
|
|
color=colors["text"], stroke_width=4)
|
|
labels = VGroup(
|
|
MathTex("a", color=colors["a"]).next_to(tri.get_bottom(), DOWN, buff=0.3),
|
|
MathTex("b", color=colors["b"]).next_to(tri.get_left(), LEFT, buff=0.3),
|
|
MathTex("c", color=colors["c"]).move_to(tri.get_vertices()[2] + UR*0.5)
|
|
)
|
|
|
|
self.play(Write(step1), run_time=1.5)
|
|
self.play(Create(tri), run_time=2)
|
|
self.play(LaggedStart(*[Write(l) for l in labels], lag_ratio=0.4))
|
|
self.wait(2)
|
|
|
|
# ========== 第二步:构建正方形 ==========
|
|
step2 = Text("构建边长的正方形", font_size=36, color=colors["text"]).to_edge(UP)
|
|
square_a = Square(a, color=colors["a"], fill_opacity=0.3).next_to(tri, RIGHT, buff=2)
|
|
square_b = Square(b, color=colors["b"], fill_opacity=0.3).next_to(tri, LEFT, buff=2)
|
|
square_c = Square(c, color=colors["c"], fill_opacity=0.3).move_to(ORIGIN + DOWN*1.5)
|
|
|
|
self.play(
|
|
ReplacementTransform(step1, step2),
|
|
DrawBorderThenFill(square_a),
|
|
DrawBorderThenFill(square_b),
|
|
run_time=2
|
|
)
|
|
self.wait(1.5)
|
|
|
|
# ========== 第三步:分割图形 ==========
|
|
step3 = Text("分割正方形为可重组部件", font_size=36, color=colors["text"]).to_edge(UP)
|
|
# 分割a²正方形
|
|
a_pieces = VGroup(
|
|
tri.copy().set_fill(colors["a"], 0.3),
|
|
tri.copy().rotate(PI/2).set_fill(colors["a"], 0.3).shift(RIGHT*a)
|
|
)
|
|
# 分割b²正方形
|
|
b_pieces = VGroup(
|
|
tri.copy().rotate(-PI/2).set_fill(colors["b"], 0.3),
|
|
tri.copy().rotate(PI).set_fill(colors["b"], 0.3).shift(LEFT*b)
|
|
)
|
|
|
|
self.play(
|
|
ReplacementTransform(step2, step3),
|
|
square_a.animate.set_fill(opacity=0),
|
|
square_b.animate.set_fill(opacity=0),
|
|
LaggedStart(
|
|
Transform(square_a, a_pieces),
|
|
Transform(square_b, b_pieces),
|
|
lag_ratio=0.5
|
|
),
|
|
run_time=3
|
|
)
|
|
self.wait(2)
|
|
|
|
# ========== 第四步:重组图形 ==========
|
|
step4 = Text("重组部件构成大正方形", font_size=36, color=colors["text"]).to_edge(UP)
|
|
# 计算重组后的位置
|
|
final_positions = [
|
|
[-c/2, -c/2 -1.5, 0], [c/2, -c/2 -1.5, 0],
|
|
[c/2, c/2 -1.5, 0], [-c/2, c/2 -1.5, 0]
|
|
]
|
|
# 创建重组动画
|
|
animations = []
|
|
for i, piece in enumerate(a_pieces):
|
|
animations.append(piece.animate.move_to(final_positions[i]))
|
|
for i, piece in enumerate(b_pieces):
|
|
animations.append(piece.animate.move_to(final_positions[i+2]))
|
|
|
|
self.play(
|
|
ReplacementTransform(step3, step4),
|
|
LaggedStart(*animations, lag_ratio=0.3),
|
|
FadeIn(square_c, shift=UP),
|
|
run_time=4
|
|
)
|
|
self.wait(2)
|
|
|
|
# ========== 第五步:面积等式 ==========
|
|
step5 = Text("面积守恒证明定理", font_size=36, color=colors["text"]).to_edge(UP)
|
|
equation = MathTex(
|
|
"a^2", "+", "b^2", "=", "c^2",
|
|
substrings_to_isolate=["a^2", "b^2", "c^2"]
|
|
).scale(1.5).set_color_by_tex("a^2", colors["a"]).set_color_by_tex("b^2", colors["b"]).set_color_by_tex("c^2", colors["c"])
|
|
|
|
self.play(
|
|
ReplacementTransform(step4, step5),
|
|
FadeOut(VGroup(a_pieces, b_pieces, square_c)),
|
|
Write(equation),
|
|
run_time=2
|
|
)
|
|
self.wait(3)
|
|
|
|
# ========== 最终总结 ==========
|
|
conclusion = Text("勾股定理得证!", font_size=48, color=colors["c"])
|
|
self.play(
|
|
FadeOut(equation),
|
|
FadeOut(step5),
|
|
Write(conclusion, run_time=2)
|
|
)
|
|
self.wait(3) |