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.
208 lines
6.2 KiB
208 lines
6.2 KiB
# difference_of_squares_final.py
|
|
from manim import *
|
|
|
|
class SquareDifference(Scene):
|
|
def construct(self):
|
|
# 高清配置
|
|
config.frame_width = 16
|
|
config.frame_height = 9
|
|
config.pixel_height = 1440
|
|
config.pixel_width = 2560
|
|
|
|
# 参数配置
|
|
a = 4
|
|
b = 1
|
|
colors = {
|
|
"a": "#1F77B4",
|
|
"b": "#FF7F0E",
|
|
"text": "#FFFFFF",
|
|
"bg": "#2E2E2E"
|
|
}
|
|
self.camera.background_color = colors["bg"]
|
|
step_delay = 2.5
|
|
|
|
# ========== 标题部分 ==========
|
|
title = Text("东师理想数学课件生成助手",
|
|
font_size=48,
|
|
color=colors["text"],
|
|
weight=BOLD,
|
|
stroke_width=8,
|
|
stroke_color=BLACK)
|
|
|
|
sub_title = Text("平方差公式可视化演示",
|
|
font_size=32,
|
|
color=colors["text"],
|
|
stroke_width=4,
|
|
stroke_color=BLACK).next_to(title, DOWN)
|
|
|
|
self.play(
|
|
Write(title, run_time=1.5),
|
|
FadeIn(sub_title, shift=UP),
|
|
run_time=2
|
|
)
|
|
self.wait(step_delay)
|
|
self.play(
|
|
FadeOut(title, shift=UP),
|
|
FadeOut(sub_title, shift=DOWN),
|
|
run_time=1.5
|
|
)
|
|
|
|
# ========== 公式推导部分 ==========
|
|
formula_steps = VGroup(
|
|
MathTex("(", "a", "+", "b", ")(", "a", "-", "b", ")", font_size=40),
|
|
MathTex("=", "a", "^2", "-", "b", "^2", font_size=40),
|
|
MathTex("=", f"{a**2}", "-", f"{b**2}", font_size=40),
|
|
MathTex("=", f"{(a+b)*(a-b)}", font_size=48, color=GREEN)
|
|
).arrange(DOWN, aligned_edge=LEFT, buff=0.8)
|
|
|
|
formula_board = SurroundingRectangle(
|
|
formula_steps,
|
|
color=WHITE,
|
|
stroke_width=2,
|
|
fill_color=BLACK,
|
|
fill_opacity=0.7,
|
|
corner_radius=0.2
|
|
)
|
|
|
|
self.play(
|
|
DrawBorderThenFill(formula_board),
|
|
FadeIn(formula_steps, shift=UP),
|
|
run_time=2
|
|
)
|
|
self.wait(step_delay)
|
|
|
|
# ========== 坐标系部分(最终修复) ==========
|
|
# 使用新版背景线直接生成网格
|
|
axes = Axes(
|
|
x_range=[0, a+b+1, 1],
|
|
y_range=[0, a+b+1, 1],
|
|
x_length=8,
|
|
y_length=6,
|
|
axis_config={
|
|
"color": colors["text"],
|
|
"stroke_width": 3,
|
|
"include_numbers": True
|
|
}
|
|
).shift(DOWN*0.5)
|
|
|
|
|
|
# 大正方形动画
|
|
big_square = Rectangle(
|
|
width=a+b,
|
|
height=a+b,
|
|
color=colors["a"],
|
|
fill_opacity=0.4,
|
|
stroke_width=4
|
|
).move_to(axes.c2p((a+b)/2, (a+b)/2))
|
|
|
|
self.play(
|
|
formula_board.animate.scale(0.8).to_edge(UP, buff=0.5),
|
|
Create(axes, run_time=2),
|
|
DrawBorderThenFill(big_square),
|
|
run_time=2
|
|
)
|
|
self.wait(step_delay)
|
|
|
|
|
|
# ========== 剩余动画部分 ==========
|
|
# 垂直分割线
|
|
v_line = Line(
|
|
start=axes.c2p(a, 0),
|
|
end=axes.c2p(a, a+b),
|
|
color=colors["text"],
|
|
stroke_width=4
|
|
)
|
|
v_label = MathTex("a",
|
|
color=colors["text"],
|
|
stroke_width=3,
|
|
stroke_color=BLACK).next_to(v_line, RIGHT, buff=0.2)
|
|
|
|
# 水平分割线
|
|
h_line = Line(
|
|
start=axes.c2p(0, a),
|
|
end=axes.c2p(a+b, a),
|
|
color=colors["text"],
|
|
stroke_width=4
|
|
)
|
|
h_label = MathTex("a",
|
|
color=colors["text"],
|
|
stroke_width=3,
|
|
stroke_color=BLACK).next_to(h_line, UP, buff=0.2)
|
|
|
|
self.play(
|
|
Create(v_line),
|
|
Write(v_label),
|
|
Create(h_line),
|
|
Write(h_label),
|
|
run_time=2
|
|
)
|
|
self.wait(step_delay)
|
|
|
|
# ========== 面积计算部分 ==========
|
|
part_a = Rectangle(
|
|
width=a,
|
|
height=a,
|
|
color=colors["a"],
|
|
fill_opacity=0.6
|
|
).move_to(axes.c2p(a/2, a/2))
|
|
|
|
part_b = Rectangle(
|
|
width=b,
|
|
height=a+b,
|
|
color=colors["b"],
|
|
fill_opacity=0.6
|
|
).move_to(axes.c2p(a + b/2, (a+b)/2))
|
|
|
|
self.play(
|
|
Transform(big_square, part_a),
|
|
FadeIn(part_b),
|
|
run_time=2
|
|
)
|
|
self.wait(step_delay)
|
|
|
|
# 移动并计算面积差
|
|
moved_part = part_b.copy().shift(DOWN*b)
|
|
area_diff = Rectangle(
|
|
width=b,
|
|
height=2*b,
|
|
color=RED,
|
|
fill_opacity=0.3
|
|
).move_to(axes.c2p(a + b/2, a - b))
|
|
|
|
self.play(
|
|
part_b.animate.shift(DOWN*b),
|
|
FadeIn(area_diff),
|
|
run_time=2
|
|
)
|
|
self.wait(step_delay)
|
|
|
|
# ========== 最终联动 ==========
|
|
final_formula = formula_steps[-1].copy()
|
|
final_formula.generate_target()
|
|
final_formula.target.scale(1.5).move_to(ORIGIN)
|
|
|
|
self.play(
|
|
MoveToTarget(final_formula),
|
|
FadeOut(axes),
|
|
FadeOut(part_a),
|
|
FadeOut(part_b),
|
|
FadeOut(area_diff),
|
|
run_time=2
|
|
)
|
|
self.wait(step_delay*2)
|
|
|
|
# 结束动画
|
|
self.play(
|
|
final_formula.animate.scale(0.5).to_edge(DOWN, buff=1),
|
|
run_time=1.5
|
|
)
|
|
self.wait(2)
|
|
|
|
# 版权信息
|
|
copyright = Text("© 东师理想 版权所有",
|
|
font_size=24,
|
|
color=colors["text"],
|
|
stroke_width=2,
|
|
stroke_color=BLACK).to_edge(DOWN, buff=0.3)
|
|
self.play(Write(copyright), run_time=1)
|
|
self.wait(3) |