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.

140 lines
4.5 KiB

from manim import *
import numpy as np
class PythagoreanProof(Scene):
def construct(self):
self.show_title()
self.show_triangle()
self.create_squares()
self.transform_shapes()
self.show_final_equation()
def show_title(self):
"""显示标题"""
title = Text("勾股定理证明", font_size=48)
title.set_color_by_gradient(BLUE, GREEN)
self.play(Write(title))
self.wait(2)
self.play(title.animate.to_edge(UP))
self.title = title
def show_triangle(self):
"""创建初始三角形"""
# 使用三维坐标定义三角形顶点
self.A = [-2, -1, 0]
self.B = [2, -1, 0]
self.C = [2, 2, 0]
self.triangle = Polygon(self.A, self.B, self.C,
color=WHITE, fill_opacity=0.5)
self.play(Create(self.triangle), run_time=2)
# 添加边标签
self.label_a = MathTex("a").next_to(self.triangle, LEFT)
self.label_b = MathTex("b").next_to(self.triangle, DOWN)
self.label_c = MathTex("c", color=YELLOW).next_to(self.triangle, UR)
self.play(LaggedStart(
Write(self.label_a),
Write(self.label_b),
Write(self.label_c),
lag_ratio=0.3
))
self.wait()
def create_squares(self):
"""创建三个正方形"""
# 计算正方形边长
a_length = np.linalg.norm(np.array(self.B) - np.array(self.A))
b_length = np.linalg.norm(np.array(self.C) - np.array(self.B))
c_length = np.linalg.norm(np.array(self.C) - np.array(self.A))
# 创建正方形并保存为实例属性
self.square_a = Square(side_length=a_length, color=RED, fill_opacity=0.3)
self.square_a.next_to(self.triangle, LEFT)
self.square_b = Square(side_length=b_length, color=BLUE, fill_opacity=0.3)
self.square_b.next_to(self.triangle, DOWN)
self.square_c = Square(side_length=c_length, color=GREEN, fill_opacity=0.3)
self.square_c.rotate(np.arctan2(3, 4)).next_to(self.triangle, UR)
# 添加面积标签
self.area_a = MathTex("a^2").next_to(self.square_a, LEFT)
self.area_b = MathTex("b^2").next_to(self.square_b, DOWN)
self.area_c = MathTex("c^2").next_to(self.square_c, UR)
# 动画序列
self.play(
LaggedStart(
Create(self.square_a),
Create(self.square_b),
Create(self.square_c),
lag_ratio=0.5
),
run_time=3
)
self.play(
Write(self.area_a),
Write(self.area_b),
Write(self.area_c)
)
self.wait(2)
def transform_shapes(self):
"""形状变换动画"""
# 分解正方形为三角形
self.triangles = VGroup()
for _ in range(4):
tri = Polygon(self.A, self.B, self.C,
color=RED, fill_opacity=0.3)
self.triangles.add(tri)
# 定义目标位置(三维坐标)
target_positions = [
[3, 2, 0], # 右上
[-3, 2, 0], # 左上
[3, -3, 0], # 右下
[-3, -3, 0] # 左下
]
# 创建动画序列
animations = []
for i, pos in enumerate(target_positions):
anim = self.triangles[i].animate.rotate(PI / 2).move_to(pos)
animations.append(anim)
# 执行动画
self.play(
Transform(self.square_a, self.triangles),
*animations,
run_time=3
)
self.wait()
# 创建最终正方形
final_square = Square(side_length=5, color=GOLD, fill_opacity=0.3)
self.play(Create(final_square))
self.wait(2)
def show_final_equation(self):
"""显示最终公式"""
equation = MathTex("a^2 + b^2 = c^2", color=YELLOW).scale(2)
equation.set_color_by_gradient(RED, BLUE, GREEN)
self.play(
Write(equation),
Flash(equation, color=YELLOW, line_length=1),
run_time=2
)
self.wait(3)
if __name__ == "__main__":
config.background_color = "#1a1a1a"
config.frame_width = 16
config.frame_height = 9
config.pixel_width = 1920
config.pixel_height = 1080
scene = PythagoreanProof()
scene.render()