|
|
|
|
from manim import *
|
|
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PythagoreanProof(Scene):
|
|
|
|
|
def update_step(self, current_text, new_content, duration=1.5):
|
|
|
|
|
"""带淡入淡出效果的步骤更新"""
|
|
|
|
|
new_text = Text(new_content, font="Microsoft YaHei", font_size=32).to_edge(UP, buff=0.8)
|
|
|
|
|
new_text.set_color_by_gradient(GOLD, ORANGE)
|
|
|
|
|
|
|
|
|
|
if current_text:
|
|
|
|
|
self.play(
|
|
|
|
|
FadeOut(current_text, shift=UP * 0.3),
|
|
|
|
|
FadeIn(new_text, shift=DOWN * 0.3),
|
|
|
|
|
run_time=0.8
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
self.play(FadeIn(new_text, shift=DOWN))
|
|
|
|
|
|
|
|
|
|
self.wait(duration)
|
|
|
|
|
return new_text
|
|
|
|
|
|
|
|
|
|
def create_polygon(self, points, color, fill_opacity=0.8):
|
|
|
|
|
"""创建带样式的多边形"""
|
|
|
|
|
return Polygon(*points,
|
|
|
|
|
color=color,
|
|
|
|
|
fill_opacity=fill_opacity,
|
|
|
|
|
stroke_width=4)
|
|
|
|
|
|
|
|
|
|
def construct(self):
|
|
|
|
|
current_step = None
|
|
|
|
|
elements = VGroup()
|
|
|
|
|
|
|
|
|
|
# === 步骤1:使用NumPy数组定义坐标 ===
|
|
|
|
|
current_step = self.update_step(None, "步骤1:绘制直角三角形")
|
|
|
|
|
|
|
|
|
|
# 定义三角形顶点(使用NumPy数组)
|
|
|
|
|
A = np.array([-2.0, -1.0, 0.0])
|
|
|
|
|
B = np.array([2.0, -1.0, 0.0])
|
|
|
|
|
C = np.array([1.0, 1.5, 0.0])
|
|
|
|
|
|
|
|
|
|
triangle = self.create_polygon([A, B, C], BLUE)
|
|
|
|
|
elements.add(triangle)
|
|
|
|
|
self.play(Create(triangle), run_time=2)
|
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
|
|
# === 步骤2:构建三个正方形 ===
|
|
|
|
|
current_step = self.update_step(current_step, "步骤2:构建三个正方形")
|
|
|
|
|
|
|
|
|
|
# 计算向量
|
|
|
|
|
vector_AC = C - A
|
|
|
|
|
vector_BC = C - B
|
|
|
|
|
|
|
|
|
|
# 构建正方形坐标点(使用向量运算)
|
|
|
|
|
square_a = Square(side_length=4, color=ORANGE).shift(DOWN * 2)
|
|
|
|
|
|
|
|
|
|
square_b_points = [
|
|
|
|
|
A,
|
|
|
|
|
C,
|
|
|
|
|
C + vector_AC * 0.8,
|
|
|
|
|
A + vector_AC * 0.8
|
|
|
|
|
]
|
|
|
|
|
square_b = self.create_polygon(square_b_points, ORANGE)
|
|
|
|
|
|
|
|
|
|
square_c_points = [
|
|
|
|
|
B,
|
|
|
|
|
C,
|
|
|
|
|
C + vector_BC * 0.8,
|
|
|
|
|
B + vector_BC * 0.8
|
|
|
|
|
]
|
|
|
|
|
square_c = self.create_polygon(square_c_points, ORANGE)
|
|
|
|
|
|
|
|
|
|
self.play(
|
|
|
|
|
LaggedStart(
|
|
|
|
|
Create(square_a),
|
|
|
|
|
Create(square_b),
|
|
|
|
|
Create(square_c),
|
|
|
|
|
lag_ratio=0.4
|
|
|
|
|
),
|
|
|
|
|
run_time=3
|
|
|
|
|
)
|
|
|
|
|
elements.add(square_a, square_b, square_c)
|
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
|
|
# === 步骤3:面积变换演示 ===
|
|
|
|
|
current_step = self.update_step(current_step, "步骤3:面积恒等变换")
|
|
|
|
|
|
|
|
|
|
# 创建可移动三角形
|
|
|
|
|
moving_tri_points = [C, A, A + (A - C) * 0.8]
|
|
|
|
|
moving_tri = self.create_polygon(moving_tri_points, YELLOW)
|
|
|
|
|
|
|
|
|
|
self.play(Create(moving_tri), run_time=1)
|
|
|
|
|
self.play(
|
|
|
|
|
Rotate(
|
|
|
|
|
moving_tri,
|
|
|
|
|
angle=-PI / 2,
|
|
|
|
|
about_point=A,
|
|
|
|
|
rate_func=smooth
|
|
|
|
|
),
|
|
|
|
|
run_time=2
|
|
|
|
|
)
|
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
|
|
# === 步骤4:最终结论 ===
|
|
|
|
|
current_step = self.update_step(current_step, "步骤4:得出结论")
|
|
|
|
|
|
|
|
|
|
# 数学公式
|
|
|
|
|
formula = MathTex(r"a^2 + b^2 = c^2", color=GOLD).scale(2)
|
|
|
|
|
formula_box = SurroundingRectangle(formula, color=WHITE, buff=0.5)
|
|
|
|
|
|
|
|
|
|
self.play(
|
|
|
|
|
FadeOut(elements),
|
|
|
|
|
FadeOut(moving_tri),
|
|
|
|
|
run_time=1
|
|
|
|
|
)
|
|
|
|
|
self.play(
|
|
|
|
|
DrawBorderThenFill(formula_box),
|
|
|
|
|
Write(formula),
|
|
|
|
|
run_time=2
|
|
|
|
|
)
|
|
|
|
|
self.wait(3)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
config = {
|
|
|
|
|
"quality": "high_quality",
|
|
|
|
|
"preview": True,
|
|
|
|
|
"media_dir": "./output",
|
|
|
|
|
"pixel_height": 1080,
|
|
|
|
|
"pixel_width": 1920,
|
|
|
|
|
"background_color": "#333333", # 深色背景
|
|
|
|
|
"format": "png" # 解决部分系统渲染问题
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
with tempconfig(config):
|
|
|
|
|
scene = PythagoreanProof()
|
|
|
|
|
scene.render()
|