parent
3d11bdc6af
commit
5d65b74fff
Binary file not shown.
@ -0,0 +1,208 @@
|
||||
# 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)
|
Loading…
Reference in new issue