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_square(self, start, end, color): """创建与边垂直的正方形""" # 计算边的向量 edge_vector = end - start # 获取垂直向量(逆时针90度) perp_vector = np.array([-edge_vector[1], edge_vector[0], 0]) # 标准化垂直向量 perp_unit = perp_vector / np.linalg.norm(perp_vector) # 生成正方形四个顶点 return Polygon( start, end, end + perp_unit * np.linalg.norm(edge_vector), start + perp_unit * np.linalg.norm(edge_vector), color=color, fill_opacity=0.8, stroke_width=4 ) def construct(self): current_step = None elements = VGroup() # === 步骤1:绘制直角三角形 === 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([0.0, 2.0, 0.0]) # 调整为更明显的直角三角形 triangle = Polygon(A, B, C, color=BLUE, fill_opacity=0.8, stroke_width=4) elements.add(triangle) self.play(Create(triangle), run_time=2) self.wait() # === 步骤2:构建三个正方形 === current_step = self.update_step(current_step, "步骤2:构建三个正方形") # 创建三个边的正方形(正确垂直方向) square_AB = self.create_square(A, B, ORANGE) square_BC = self.create_square(B, C, GREEN) square_AC = self.create_square(C, A, YELLOW) # 调整正方形位置使其向外扩展 square_AB.shift((A + B) / 2 - square_AB.get_center() + DOWN * 0.5) square_BC.rotate(PI / 2, about_point=B) square_AC.rotate(-PI / 2, about_point=C) self.play( LaggedStart( Create(square_AB), Create(square_BC), Create(square_AC), lag_ratio=0.3 ), run_time=4 ) elements.add(square_AB, square_BC, square_AC) self.wait() # === 步骤3:面积变换演示 === current_step = self.update_step(current_step, "步骤3:面积恒等变换") # 创建可移动三角形(从AC边开始) moving_tri = self.create_square(A, C, PINK) self.play(FadeIn(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" } with tempconfig(config): scene = PythagoreanProof() scene.render()