curved_trapezoid_area.py
1from manim import *2import numpy as np3 4class CurvedTrapezoidAreaScene(Scene):5 def construct(self):6 # 标题7 title = Text("微元法求曲边梯形面积", font_size=42)8 title.to_edge(UP)9 self.play(Write(title), run_time=1.5)10 11 # 介绍文本12 intro = Text("将曲边梯形划分为无数个矩形微元,通过积分求总面积", font_size=28)13 intro.next_to(title, DOWN, buff=0.8)14 self.play(Write(intro), run_time=1.5)15 self.wait(1)16 17 # 淡出介绍18 self.play(FadeOut(intro), run_time=1)19 20 # 创建坐标系21 axes = Axes(22 x_range=[0, 4, 1],23 y_range=[0, 4, 1],24 x_length=8,25 y_length=6,26 axis_config={"color": BLUE}27 )28 29 # 添加坐标轴标签30 x_label = axes.get_x_axis_label("x")31 y_label = axes.get_y_axis_label("y")32 33 # 显示坐标系34 self.play(35 Create(axes),36 Write(x_label),37 Write(y_label),38 run_time=1.539 )40 41 # 定义函数 f(x) = x^2 + 142 def func(x):43 return x*x*0.3 + 144 45 # 创建函数曲线46 curve = axes.plot(func, x_range=[0.5, 3.5], color=RED)47 curve_label = MathTex("y = f(x)", font_size=32, color=RED)48 curve_label.next_to(curve.get_end(), UP)49 50 self.play(51 Create(curve),52 Write(curve_label),53 run_time=254 )55 self.wait(1)56 57 # 定义积分区间58 a, b = 1, 359 60 # 创建曲边梯形区域61 area = axes.get_area(curve, x_range=[a, b], color=BLUE, opacity=0.3)62 63 # 标记积分区间64 a_line = axes.get_vertical_line(axes.c2p(a, 0), color=GREEN)65 b_line = axes.get_vertical_line(axes.c2p(b, 0), color=GREEN)66 67 a_label = MathTex("a", font_size=28, color=GREEN)68 a_label.next_to(axes.c2p(a, 0), DOWN)69 70 b_label = MathTex("b", font_size=28, color=GREEN)71 b_label.next_to(axes.c2p(b, 0), DOWN)72 73 self.play(74 Create(area),75 Create(a_line),76 Create(b_line),77 Write(a_label),78 Write(b_label),79 run_time=280 )81 self.wait(1)82 83 # 显示面积标记84 area_label = Text("曲边梯形面积", font_size=24, color=BLUE)85 area_label.move_to(axes.c2p(2, 1.5))86 self.play(Write(area_label), run_time=1)87 self.wait(1)88 89 # 开始微元分割90 self.play(FadeOut(area_label), run_time=0.5)91 92 # 创建矩形微元93 n = 8 # 矩形数量94 rectangles = []95 dx = (b - a) / n96 97 for i in range(n):98 x_left = a + i * dx99 x_right = a + (i + 1) * dx100 height = func(x_left) # 使用左端点的函数值101 102 # 创建矩形103 rect = Rectangle(104 width=axes.x_axis.unit_size * dx,105 height=axes.y_axis.unit_size * height,106 fill_opacity=0.4,107 fill_color=YELLOW,108 stroke_color=WHITE,109 stroke_width=2110 )111 112 # 定位矩形113 rect.align_to(axes.c2p(x_left, 0), DOWN + LEFT)114 rectangles.append(rect)115 116 # 逐个绘制矩形117 self.play(118 FadeOut(area),119 *[Create(rect) for rect in rectangles],120 run_time=2121 )122 self.wait(1)123 124 # 高亮显示一个矩形微元125 highlight_index = 3126 rectangles[highlight_index].set_fill(RED, opacity=0.7)127 128 # 标记微元129 x_i = a + highlight_index * dx130 131 # 创建标记线和标签132 dx_line = Line(133 axes.c2p(x_i, 0),134 axes.c2p(x_i + dx, 0),135 color=ORANGE,136 stroke_width=4137 )138 139 height_line = Line(140 axes.c2p(x_i, 0),141 axes.c2p(x_i, func(x_i)),142 color=PURPLE,143 stroke_width=4144 )145 146 # 标签147 dx_label = MathTex("dx", font_size=28, color=ORANGE)148 dx_label.next_to(dx_line, DOWN)149 150 height_label = MathTex("f(x)", font_size=28, color=PURPLE)151 height_label.next_to(height_line, LEFT)152 153 area_element_label = MathTex("dA", font_size=28, color=RED)154 area_element_label.move_to(rectangles[highlight_index].get_center())155 156 self.play(157 Create(dx_line),158 Create(height_line),159 Write(dx_label),160 Write(height_label),161 Write(area_element_label),162 run_time=2163 )164 self.wait(1)165 166 # 显示微元面积公式167 formula_group = VGroup()168 169 # 微元面积公式170 element_formula = MathTex(r"dA = f(x) \cdot dx", font_size=28)171 element_formula.to_corner(UR).shift(LEFT * 2 + DOWN * 0.5)172 formula_group.add(element_formula)173 174 # 积分公式175 integral_formula = MathTex(r"A = \int_a^b f(x) \, dx", font_size=28)176 integral_formula.next_to(element_formula, DOWN, aligned_edge=LEFT, buff=0.3)177 formula_group.add(integral_formula)178 179 # 说明文字180 explanation = Text("总面积 = 所有微元面积之和", font_size=20)181 explanation.next_to(integral_formula, DOWN, aligned_edge=LEFT, buff=0.3)182 formula_group.add(explanation)183 184 self.play(Write(formula_group), run_time=2)185 self.wait(2)186 187 # 演示增加矩形数量的效果188 self.play(189 FadeOut(dx_line),190 FadeOut(height_line),191 FadeOut(dx_label),192 FadeOut(height_label),193 FadeOut(area_element_label),194 run_time=1195 )196 197 # 更多的矩形198 for num_rects in [16, 32]:199 new_rectangles = []200 new_dx = (b - a) / num_rects201 202 for i in range(num_rects):203 x_left = a + i * new_dx204 height = func(x_left)205 206 rect = Rectangle(207 width=axes.x_axis.unit_size * new_dx,208 height=axes.y_axis.unit_size * height,209 fill_opacity=0.4,210 fill_color=YELLOW,211 stroke_color=WHITE,212 stroke_width=1 if num_rects > 16 else 2213 )214 215 rect.align_to(axes.c2p(x_left, 0), DOWN + LEFT)216 new_rectangles.append(rect)217 218 # 淡出旧矩形,淡入新矩形219 self.play(220 *[FadeOut(rect) for rect in rectangles],221 run_time=1222 )223 224 self.play(225 *[FadeIn(rect) for rect in new_rectangles],226 run_time=1.5227 )228 229 # 更新矩形列表230 rectangles = new_rectangles231 self.wait(1)232 233 # 显示极限过程234 limit_text = Text("当 n → ∞ 时,矩形面积和趋向于曲边梯形的精确面积", font_size=24)235 limit_text.to_edge(DOWN)236 self.play(Write(limit_text), run_time=2)237 self.wait(1)238 239 # 最终显示精确的曲边梯形面积240 exact_area = axes.get_area(curve, x_range=[a, b], color=BLUE, opacity=0.6)241 242 self.play(243 *[FadeOut(rect) for rect in rectangles],244 FadeIn(exact_area),245 run_time=2246 )247 248 # 最终结果249 final_formula = MathTex(r"A = \int_a^b f(x) \, dx", font_size=36, color=YELLOW)250 final_box = SurroundingRectangle(final_formula, buff=0.3, color=YELLOW)251 final_group = VGroup(final_formula, final_box)252 final_group.move_to(axes.c2p(2, 3))253 254 self.play(255 FadeOut(formula_group),256 FadeOut(limit_text),257 Write(final_group),258 run_time=2259 )260 261 self.wait(2)262 263 # 结论264 conclusion = Text("微元法的核心:积分是无限细分后的求和过程", font_size=28)265 conclusion.to_edge(DOWN)266 self.play(Write(conclusion), run_time=2)267 268 self.wait(3)269 270 # 淡出所有元素271 self.play(*[FadeOut(mob) for mob in self.mobjects], run_time=1.5)272 273 274if __name__ == "__main__":275 # 直接渲染场景276 scene = CurvedTrapezoidAreaScene()277 scene.render() 讲解
这个视频从曲边梯形面积入手,把“面积”拆成一连串足够窄的矩形微元。设曲线为 ,积分区间为 ,曲线下方的面积可以看成许多小矩形面积的极限。
开场画面先建立坐标系和函数图像,让观众看到曲线 所在的位置。区域标注部分给出区间端点 ,并填充曲线、直线 、 和 轴围成的曲边梯形区域。
微元面积
分割步骤把区间 划分成 个小区间,每个小区间宽度为
构造记录使用左端点 的函数值作为矩形高度,于是第 个小矩形的面积近似为
微元标注画面高亮其中一个矩形,并用 、 和 标出微元的宽、高和面积。这里的 不是一个孤立公式,而是把局部小矩形和整体面积联系起来的桥。
从求和到积分
面积微元关系写成:
因此总面积来自所有微元面积之和:
更完整地说,先得到有限个矩形的面积和
再让分割无限变细:
极限画面
极限演示把矩形数量从 增加到 、。矩形越来越窄,锯齿状近似越来越贴近曲线。最终面积提示强调:当 时,矩形面积和趋向曲边梯形的精确面积。
结尾总结微元法的核心:积分不是凭空出现的符号,而是“无限细分后的求和过程”。