使用 GPT + Manim 生成动画的体验非常好
·
使用 GPT + Manim 生成动画的体验非常好。
应该是提示词还不够详细,生成的内容还需要人工微调一下,但是大体结构是非常好的,只需要稍微花费一点力气就可以调整好。
我希望用几何的方式展示平方公式,提示词:
请你使用 Manim 库为我实现下面的动画,它演示了如何用几何的方式表示 (a + b) 的平方 = a 的平方 + b 的平方 + 2 ab。我希望最后展现的效果是这样:
原始正方形(被涂色成4种) = 小正方形a + 2 ab 的长方形 + 小正方形b
他们中线位于同一个水平线上,以达到美观平衡的效果。他们使用 =、+相连接。
class MyManim(Scene):
def construct(self):
// draw a square
// split the square into four parts, 2 smaller squares, 2 rectangles.
// color the four parts with different color
// squares width are a and b. draw a and b too.
// decompose the four part, seperate them a little bit
// duplicate the four parts, group the duplicated 4 parts into 3 groups:
// group 1: square with width a
// group 2: square with width b
// group 3: two rectanges with width a x b. keep the relative location for the two rectangles unchanged.
最终,通过稍微的调整,输入了如下代码,效果非常棒。可以在 playground 跑跑看:
%%manim -qm SquareOfSum
from manim import *
class SquareOfSum(Scene):
def construct(self):
# 定义 a 和 b 的比例
a = 2
b = 1
total = a + b
# 颜色配置
color_a2 = BLUE
color_b2 = GREEN
color_ab1 = ORANGE
color_ab2 = YELLOW
# 创建四个小块(用于大正方形)
square_a = Square(side_length=a, fill_opacity=0.9, fill_color=color_a2).set_stroke(BLACK)
rect_ab1 = Rectangle(width=b, height=a, fill_opacity=0.9, fill_color=color_ab1).set_stroke(BLACK)
rect_ab2 = Rectangle(width=a, height=b, fill_opacity=0.9, fill_color=color_ab2).set_stroke(BLACK)
square_b = Square(side_length=b, fill_opacity=0.9, fill_color=color_b2).set_stroke(BLACK)
# 组成大正方形
group_square = VGroup(square_a, rect_ab1, rect_ab2, square_b)
square_a.move_to(ORIGIN)
rect_ab1.next_to(square_a, RIGHT, buff=0)
rect_ab2.next_to(square_a, UP, buff=0)
square_b.next_to(rect_ab2, RIGHT, buff=0)
# 边框和标签
big_border = Square(side_length=total, color=WHITE).move_to(group_square)
label_total = MathTex("(a + b)^2").next_to(big_border, DOWN)
# 显示大正方形
self.play(Create(big_border))
self.play(FadeIn(group_square))
self.play(Write(label_total))
self.wait(1)
# -----------------------------
# 添加左侧大括号 a, b, (a+b)
# -----------------------------
# 计算顶点
top_left = big_border.get_corner(UL)
bottom_left = big_border.get_corner(DL)
# “b” 段大括号(上半部分)
brace_b = BraceBetweenPoints(
top_left,
top_left + DOWN * b,
direction=LEFT
)
label_b = brace_b.get_text("b").scale(0.8)
# “a” 段大括号(下半部分)
brace_a = BraceBetweenPoints(
top_left + DOWN * b,
bottom_left,
direction=LEFT
)
label_a = brace_a.get_text("a").scale(0.8)
self.play(Create(brace_a), Write(label_a))
self.play(Create(brace_b), Write(label_b))
self.wait(1.5)
# 为每个部分标注面积
label_a2 = MathTex("a^2").move_to(square_a)
label_b2 = MathTex("b^2").move_to(square_b)
label_ab1 = MathTex("ab").move_to(rect_ab1)
label_ab2 = MathTex("ab").move_to(rect_ab2)
self.play(Write(label_a2), Write(label_b2), Write(label_ab1), Write(label_ab2))
self.wait(1)
# -----------------------------
# 将整个正方形移到左侧
# -----------------------------
big_group = VGroup(group_square, label_total, label_a2, label_b2, label_ab1, label_ab2,
brace_a, brace_b, label_a, label_b)
self.play(
big_group.animate.shift(LEFT * 4),
FadeOut(big_border),
run_time=1.5
)
self.wait(0.5)
# -----------------------------
# 准备右侧分解部分:a², 2ab, b²
# -----------------------------
group_a2 = VGroup(square_a.copy(), label_a2.copy())
group_b2 = VGroup(square_b.copy(), label_b2.copy())
# 2ab 组:保持两个矩形相对位置
ab1_copy = rect_ab1.copy()
ab2_copy = rect_ab2.copy()
label_ab1_copy = label_ab1.copy()
label_ab2_copy = label_ab2.copy()
group_2ab = VGroup(ab1_copy, ab2_copy, label_ab1_copy, label_ab2_copy)
label_ab1_copy.move_to(ab1_copy)
label_ab2_copy.move_to(ab2_copy)
# 对齐三个部分到一条水平线上
eq_sign = MathTex("=").next_to(big_group, RIGHT, buff=0.7)
group_a2.next_to(eq_sign, RIGHT, buff=0.5)
group_2ab.next_to(group_a2, RIGHT, buff=0.6)
group_b2.next_to(group_2ab, RIGHT, buff=0.6)
# 添加符号
plus1 = MathTex("+").next_to(group_a2, RIGHT, buff=0.2)
plus2 = MathTex("+").next_to(group_2ab, RIGHT, buff=0.2)
# 展示等式排列动画
self.play(
FadeIn(eq_sign),
FadeIn(group_a2),
FadeIn(group_2ab),
FadeIn(group_b2),
FadeIn(plus1),
FadeIn(plus2),
run_time=2
)
# 居中整体
all_expr = VGroup(big_group, eq_sign, group_a2, plus1, group_2ab, plus2, group_b2)
self.play(all_expr.animate.move_to(ORIGIN).scale(0.9))
self.wait(2)
# 最终公式淡入
final_eq = MathTex("(a+b)^2 = a^2 + 2ab + b^2").next_to(all_expr, DOWN)
self.play(Write(final_eq))
self.wait(3)
更多推荐


所有评论(0)