unified_mean_value_theorems.py
1from manim import *2import numpy as np3 4class ParametricCauchyTheorem(Scene):5 def construct(self):6 # 创建标题7 title = Text("柯西中值定理的参数曲线解释", font="SimSun").to_edge(UP)8 self.play(Write(title))9 10 # 参数方程说明11 parametric_eq = MathTex(12 r"\gamma(t) = \begin{cases} x = g(t) \\ y = f(t) \end{cases}, t \in [a,b]"13 ).next_to(title, DOWN)14 self.play(Write(parametric_eq))15 16 # 参数方程解释17 param_explanation = Text(18 "用参数方程表示曲线,柯西中值定理有更直观的几何意义", 19 font="SimSun"20 ).scale(0.6).next_to(parametric_eq, DOWN)21 self.play(Write(param_explanation))22 self.wait()23 24 # 添加淡出标题的动画25 self.play(FadeOut(title), FadeOut(parametric_eq))26 27 # 创建参数曲线的坐标系28 axes = Axes(29 x_range=[-1, 3, 0.5],30 y_range=[-1, 3, 0.5],31 axis_config={"color": BLUE},32 )33 axes_labels = axes.get_axis_labels(x_label="g(t)", y_label="f(t)")34 35 # 定义函数 f(t) 和 g(t)36 def f(t):37 return t**3 - 3*t**2 + 2*t38 39 def g(t):40 return t41 42 # 计算导数43 def df(t):44 return 3*t**2 - 6*t + 245 46 def dg(t):47 return 148 49 # 区间端点50 a, b = 0, 251 52 # 满足柯西定理的c值53 c_cauchy = self.find_cauchy_c(f, df, g, dg, a, b)54 55 # 在坐标系创建前进行淡出56 self.play(57 FadeOut(param_explanation),58 Create(axes), 59 Write(axes_labels)60 )61 62 # 绘制参数曲线 (g(t), f(t))63 parametric_curve = ParametricFunction(64 lambda t: axes.c2p(g(t), f(t)),65 t_range=[0, 2.5],66 color=BLUE67 )68 69 curve_eq = MathTex(70 r"\gamma(t) = \begin{cases} x = g(t) \\ y = f(t) \end{cases}"71 ).scale(0.6).to_corner(UL)72 self.play(Create(parametric_curve), Write(curve_eq))73 74 # 参数化图示 - 添加箭头从t到曲线点75 t_line = NumberLine(76 x_range=[0, 2, 0.5],77 length=3,78 include_numbers=True,79 ).to_edge(DOWN, buff=1)80 t_label = Text("参数 t", font="SimSun").scale(0.5).next_to(t_line, LEFT)81 82 self.play(Create(t_line), Write(t_label))83 84 # 展示参数t如何映射到曲线上的点85 t_points = [0, 0.5, 1, 1.5, 2]86 animations = []87 88 for t in t_points:89 dot_t = Dot(t_line.n2p(t), color=YELLOW, radius=0.05)90 dot_curve = Dot(axes.c2p(g(t), f(t)), color=YELLOW, radius=0.05)91 arrow = Arrow(dot_t.get_center(), dot_curve.get_center(), buff=0.1, color=YELLOW_A)92 93 animations.append(AnimationGroup(94 Create(dot_t),95 Create(arrow),96 Create(dot_curve),97 lag_ratio=0.398 ))99 100 for anim in animations:101 self.play(anim, run_time=0.8)102 103 self.wait()104 self.play(*[FadeOut(obj) for obj in animations])105 106 # 标记曲线上的端点107 point_a = Dot(axes.c2p(g(a), f(a)), color=RED)108 point_b = Dot(axes.c2p(g(b), f(b)), color=RED)109 110 label_a = MathTex(r"\gamma(a)").next_to(point_a, DOWN)111 label_b = MathTex(r"\gamma(b)").next_to(point_b, DOWN)112 113 self.play(Create(point_a), Create(point_b))114 self.play(Write(label_a), Write(label_b))115 116 # 绘制从A到B的割线(参数视角下的弦)117 secant_line = Line(118 axes.c2p(g(a), f(a)),119 axes.c2p(g(b), f(b)),120 color=RED121 )122 self.play(Create(secant_line))123 124 # 创建沿曲线移动的点125 moving_point = Dot(axes.c2p(g(a), f(a)), color=YELLOW)126 moving_label = MathTex(r"\gamma(t)").next_to(moving_point, UP, buff=0.1)127 128 # 切线 - 参数曲线视角下的切向量129 tangent = always_redraw(130 lambda: Line(131 axes.c2p(132 g(moving_point.get_center()[0]/axes.c2p(1,0)[0]) - 0.5, 133 f(moving_point.get_center()[0]/axes.c2p(1,0)[0]) - 134 0.5 * (df(moving_point.get_center()[0]/axes.c2p(1,0)[0])/dg(moving_point.get_center()[0]/axes.c2p(1,0)[0]))135 ),136 axes.c2p(137 g(moving_point.get_center()[0]/axes.c2p(1,0)[0]) + 0.5, 138 f(moving_point.get_center()[0]/axes.c2p(1,0)[0]) + 139 0.5 * (df(moving_point.get_center()[0]/axes.c2p(1,0)[0])/dg(moving_point.get_center()[0]/axes.c2p(1,0)[0]))140 ),141 color=GREEN142 )143 )144 145 tangent_label = VGroup(146 Text("切线:", font="SimSun").scale(0.5),147 MathTex(r"\gamma'(t)").scale(0.6)148 ).arrange(RIGHT, buff=0.2).set_color(GREEN)149 tangent_label.to_corner(UR)150 151 # 在移动点的动画部分,添加参数值显示152 t_tracker = DecimalNumber(153 a,154 num_decimal_places=2,155 include_sign=False,156 ).scale(0.6).next_to(moving_point, RIGHT, buff=0.1)157 158 t_label = MathTex(r"t = ").scale(0.6).next_to(t_tracker, LEFT, buff=0.05)159 160 t_group = VGroup(t_label, t_tracker)161 162 self.play(163 Create(moving_point),164 Write(moving_label),165 Write(t_group),166 Create(tangent),167 Write(tangent_label)168 )169 170 # 修改点移动动画,同时更新t值171 def update_t_value(mob):172 # 获取当前点的x坐标,对应参数t173 x = moving_point.get_center()[0]174 # 转换回参数t值175 t_value = x / axes.c2p(1,0)[0]176 # 更新数值177 mob.set_value(t_value)178 179 t_tracker.add_updater(update_t_value)180 t_group.add_updater(lambda m: m.next_to(moving_point, RIGHT, buff=0.1))181 182 # 在点移动动画结束后记得移除updater183 t_tracker.remove_updater(update_t_value)184 t_group.remove_updater(lambda m: m.next_to(moving_point, RIGHT, buff=0.1))185 186 # 沿曲线移动点187 curve_points = []188 num_points = 30189 for i in range(num_points + 1):190 t = a + i * (c_cauchy - a) / num_points191 curve_points.append(axes.c2p(g(t), f(t)))192 193 self.play(194 MoveAlongPath(moving_point, VMobject().set_points_as_corners(curve_points)),195 MaintainPositionRelativeTo(moving_label, moving_point),196 run_time=3197 )198 199 # 高亮显示c点,此时切线平行于割线200 self.play(Flash(moving_point, color=YELLOW, flash_radius=0.3))201 202 # 标记c点203 point_c = Dot(axes.c2p(g(c_cauchy), f(c_cauchy)), color=YELLOW)204 label_c = MathTex(r"\gamma(\xi)").next_to(point_c, UP)205 206 self.play(207 ReplacementTransform(moving_point, point_c),208 ReplacementTransform(moving_label, label_c),209 FadeOut(t_group)210 )211 212 # 显示切向量和弦向量以强调平行关系213 secant_slope_display = VGroup(214 Text("弦斜率:", font="SimSun").scale(0.4),215 MathTex(r"\frac{f(b) - f(a)}{g(b) - g(a)}").scale(0.5)216 ).arrange(RIGHT, buff=0.1).set_color(RED)217 secant_slope_display.next_to(secant_line.get_center(), UP, buff=0.2)218 219 tangent_slope_display = VGroup(220 Text("切线斜率:", font="SimSun").scale(0.4),221 MathTex(r"\frac{f'(\xi)}{g'(\xi)}").scale(0.5)222 ).arrange(RIGHT, buff=0.1).set_color(GREEN).next_to(point_c, UP+RIGHT, buff=0.2)223 224 self.play(Create(point_c), Write(label_c))225 self.play(Create(secant_line))226 self.play(Write(secant_slope_display), Write(tangent_slope_display))227 228 # 等显示完斜率后,再显示柯西定理内容229 self.wait(1) # 给观众一点时间理解斜率230 231 # 显示参数形式的柯西中值定理232 theorem_text = MathTex(233 r"\exists \xi \in (a,b) : \frac{f'(\xi)}{g'(\xi)} = \frac{f(b) - f(a)}{g(b) - g(a)}"234 ).scale(0.7)235 236 # 使用参数形式重写237 parametric_theorem = MathTex(238 r"\exists \xi \in (a,b) : \gamma'(\xi) \parallel (\gamma(b) - \gamma(a))"239 ).scale(0.7)240 241 theorem_group = VGroup(theorem_text, parametric_theorem).arrange(DOWN, buff=0.3)242 theorem_group.to_edge(DOWN)243 244 self.play(Write(theorem_text))245 self.play(Write(parametric_theorem))246 247 # 显示切向量和弦向量以强调平行关系248 secant_slope_display = VGroup(249 Text("弦斜率:", font="SimSun").scale(0.4),250 MathTex(r"\frac{f(b) - f(a)}{g(b) - g(a)}").scale(0.5)251 ).arrange(RIGHT, buff=0.1).set_color(RED)252 secant_slope_display.next_to(secant_line.get_center(), UP, buff=0.2)253 254 tangent_slope_display = VGroup(255 Text("切线斜率:", font="SimSun").scale(0.4),256 MathTex(r"\frac{f'(\xi)}{g'(\xi)}").scale(0.5)257 ).arrange(RIGHT, buff=0.1).set_color(GREEN).next_to(point_c, UP+RIGHT, buff=0.2)258 259 self.play(Create(point_c), Write(label_c))260 self.play(Create(secant_line))261 self.play(Write(secant_slope_display), Write(tangent_slope_display))262 263 # 强调平行关系264 parallel_text = Text(265 "柯西中值定理:存在点ξ使得切线斜率等于弦斜率", 266 font="SimSun"267 ).scale(0.6).next_to(parametric_theorem, UP, buff=0.3)268 269 self.play(Write(parallel_text))270 271 # 高亮显示平行关系272 self.play(273 Indicate(secant_line, color=RED, scale_factor=1.1),274 Indicate(secant_slope_display, color=RED, scale_factor=1.1),275 Indicate(tangent_slope_display, color=GREEN, scale_factor=1.1),276 run_time=2277 )278 279 self.wait(2)280 281 # 在显示参数形式的柯西中值定理部分(约在第160行),添加更直观的参数表达282 # 在parametric_theorem之后添加:283 param_explanation = Text(284 "其中 γ'(t) = (g'(t), f'(t)) 是切向量", 285 font="SimSun"286 ).scale(0.6).next_to(parametric_theorem, DOWN, buff=0.2)287 self.play(Write(param_explanation))288 289 290class UnifiedMeanValueTheorems(Scene):291 def construct(self):292 # 标题保持不变293 title = Text("从柯西到拉格朗日到罗尔:三个中值定理的联系", font="SimSun").scale(0.8).to_edge(UP)294 self.play(Write(title))295 296 # 添加初始说明297 intro_text = Text(298 "三个中值定理体现了数学中的一般到特殊的演化", 299 font="SimSun"300 ).scale(0.6).next_to(title, DOWN)301 self.play(Write(intro_text))302 self.wait()303 304 # 添加淡出标题的动画305 self.play(FadeOut(title), FadeOut(intro_text))306 307 # 创建坐标系308 axes = Axes(309 x_range=[-0.5, 3.5, 0.5],310 y_range=[-2, 4, 0.5],311 axis_config={"color": BLUE},312 )313 axes_labels = axes.get_axis_labels(x_label="g(t)", y_label="f(t)") # 改为参数形式的标记314 315 # 选用一个函数能同时展示三个定理316 def f(t):317 return t**3 - 3*t**2 + 2*t318 319 def df(t):320 return 3*t**2 - 6*t + 2321 322 def g(t):323 return t # 改回与ParametricCauchyTheorem类相同的定义324 325 def dg(t):326 return 1327 328 # 绘制坐标系和曲线329 self.play(330 Create(axes), 331 Write(axes_labels)332 )333 334 # 绘制参数曲线 (g(t), f(t))335 parametric_curve = ParametricFunction(336 lambda t: axes.c2p(g(t), f(t)),337 t_range=[0, 3],338 color=BLUE339 )340 341 curve_label = MathTex(342 r"\gamma(t) = \begin{cases} x = g(t) \\ y = f(t) \end{cases}"343 ).scale(0.8).to_edge(UP, buff=0.5)344 self.play(Create(parametric_curve), Write(curve_label))345 346 # 1. 柯西中值定理 - 参数曲线视角347 cauchy_title = Text("柯西中值定理(参数曲线视角)", font="SimSun").scale(0.7)348 cauchy_title.to_edge(DOWN, buff=0.1)349 350 a, b = 0.5, 2.5 # 选择参数端点351 c_cauchy = self.find_cauchy_c(f, df, g, dg, a, b)352 353 # 标记端点354 point_a = Dot(axes.c2p(g(a), f(a)), color=RED)355 point_b = Dot(axes.c2p(g(b), f(b)), color=RED)356 label_a = MathTex(r"\gamma(a)").next_to(point_a, DOWN)357 label_b = MathTex(r"\gamma(b)").next_to(point_b, DOWN)358 359 self.play(Write(cauchy_title))360 self.play(Create(point_a), Create(point_b), Write(label_a), Write(label_b))361 362 # 绘制从A到B的割线(参数视角下的弦)363 secant_line = Line(364 axes.c2p(g(a), f(a)),365 axes.c2p(g(b), f(b)),366 color=RED367 )368 self.play(Create(secant_line))369 370 # 找到满足平行条件的c点371 c_point = Dot(axes.c2p(g(c_cauchy), f(c_cauchy)), color=YELLOW)372 c_label = MathTex(r"\gamma(\xi)").next_to(c_point, UP)373 374 # 切线 - 参数曲线在c点的导数375 c_tangent_line = Line(376 axes.c2p(g(c_cauchy) - 0.5, f(c_cauchy) - 0.5 * (df(c_cauchy)/dg(c_cauchy))),377 axes.c2p(g(c_cauchy) + 0.5, f(c_cauchy) + 0.5 * (df(c_cauchy)/dg(c_cauchy))),378 color=GREEN379 )380 381 secant_slope_display = VGroup(382 Text("弦斜率:", font="SimSun").scale(0.4),383 MathTex(r"\frac{f(b) - f(a)}{g(b) - g(a)}").scale(0.5)384 ).arrange(RIGHT, buff=0.1).set_color(RED)385 secant_slope_display.next_to(secant_line.get_center(), UP, buff=0.2)386 387 tangent_slope_display = VGroup(388 Text("切线斜率:", font="SimSun").scale(0.4),389 MathTex(r"\frac{f'(\xi)}{g'(\xi)}").scale(0.5)390 ).arrange(RIGHT, buff=0.1).set_color(GREEN).next_to(c_point, UP+RIGHT, buff=0.2)391 392 self.play(Create(c_point), Write(c_label))393 self.play(Create(c_tangent_line))394 self.play(Write(secant_slope_display), Write(tangent_slope_display))395 396 # 先等待观察斜率397 self.wait(1) 398 399 # 然后再显示柯西定理公式400 cauchy_formula = MathTex(401 r"\exists \xi \in (a,b) : \frac{f'(\xi)}{g'(\xi)} = \frac{f(b) - f(a)}{g(b) - g(a)}"402 ).scale(0.7).next_to(cauchy_title, UP)403 404 # 参数化形式的解释405 cauchy_explanation = Text(406 "柯西定理表明:存在一点ξ,使得该点切线方向与弦平行", 407 font="SimSun"408 ).scale(0.5).next_to(cauchy_formula, UP)409 410 self.play(Write(cauchy_formula))411 self.play(Write(cauchy_explanation))412 413 # 突出显示切向量与弦向量平行414 self.play(415 Indicate(c_tangent_line, scale_factor=1.2, color=GREEN),416 Indicate(secant_slope_display, scale_factor=1.1, color=RED),417 Indicate(tangent_slope_display, scale_factor=1.1, color=GREEN),418 Indicate(secant_line, color=RED, scale_factor=1.1),419 run_time=2420 )421 422 self.wait(2)423 424 # 2. 拉格朗日中值定理 (g(t)=t时的特例)425 self.play(426 FadeOut(cauchy_explanation),427 FadeOut(cauchy_formula),428 FadeOut(curve_label),429 FadeOut(secant_slope_display),430 FadeOut(tangent_slope_display),431 FadeOut(c_tangent_line)432 )433 434 lagrange_title = Text("拉格朗日中值定理 (g(t)=t时的特例)", font="SimSun").scale(0.7)435 436 self.play(ReplacementTransform(cauchy_title, lagrange_title))437 438 # 为拉格朗日定理选择新的端点439 a_lag, b_lag = 0.8, 2.3 # 新的非坐标轴上点440 441 # 更新端点 - 确保在曲线上442 self.play(FadeOut(point_a), FadeOut(point_b), FadeOut(label_a), FadeOut(label_b))443 444 point_a = Dot(axes.c2p(a_lag, f(a_lag)), color=RED) # 重新创建点445 point_b = Dot(axes.c2p(b_lag, f(b_lag)), color=RED)446 label_a = MathTex("a").next_to(point_a, DOWN)447 label_b = MathTex("b").next_to(point_b, DOWN)448 449 self.play(450 Create(point_a),451 Create(point_b),452 Write(label_a),453 Write(label_b)454 )455 456 # 更新割线457 new_secant = Line(458 axes.c2p(a_lag, f(a_lag)),459 axes.c2p(b_lag, f(b_lag)),460 color=RED461 )462 self.play(ReplacementTransform(secant_line, new_secant))463 secant_line = new_secant464 465 # 计算拉格朗日定理的c值466 c_lag = self.find_lagrange_c(f, df, a_lag, b_lag)467 468 # 先显示拉格朗日定理的公式469 lag_formula = MathTex(470 r"\exists \xi \in (a,b) : f'(\xi) = \frac{f(b) - f(a)}{b - a}"471 ).scale(0.7).next_to(lagrange_title, UP, buff=0.2)472 473 self.play(Write(lag_formula))474 475 # 更新c点位置和标签476 new_c_label = MathTex(r"\xi").next_to(axes.c2p(c_lag, f(c_lag)), UP, buff=0.1)477 478 self.play(479 c_point.animate.move_to(axes.c2p(c_lag, f(c_lag))),480 FadeOut(c_label),481 FadeIn(new_c_label)482 )483 c_label = new_c_label # 更新标签引用484 485 # 添加c点处的切线486 lag_tangent_line = Line(487 axes.c2p(c_lag - 0.5, f(c_lag) - 0.5 * df(c_lag)),488 axes.c2p(c_lag + 0.5, f(c_lag) + 0.5 * df(c_lag)),489 color=GREEN490 )491 self.play(Create(lag_tangent_line))492 493 # 强调切线斜率等于割线斜率494 self.play(495 Indicate(lag_tangent_line, scale_factor=1.2, color=GREEN),496 Indicate(secant_line, scale_factor=1.2, color=RED),497 run_time=2498 )499 500 self.wait(1)501 502 # 3. 罗尔中值定理 (当f(a)=f(b)时的特例)503 self.play(504 FadeOut(lag_formula),505 FadeOut(c_label),506 FadeOut(c_point),507 FadeOut(lag_tangent_line),508 FadeOut(point_a),509 FadeOut(point_b),510 FadeOut(label_a),511 FadeOut(label_b),512 FadeOut(secant_line)513 )514 515 rolle_title = Text("罗尔中值定理 (f(a)=f(b)时的特例)", font="SimSun").scale(0.7)516 517 self.play(ReplacementTransform(lagrange_title, rolle_title))518 519 # 为罗尔定理选择函数值相等的两点520 # 对于f(t) = t^3 - 3t^2 + 2t = t(t-1)(t-2),函数在t=0,1,2处为0521 rolle_a, rolle_b = 1, 2 # 选择t=1和t=2,使得f(1)=f(2)=0522 523 # 标记罗尔定理的端点 - 两个函数值相同的点524 rolle_point_a = Dot(axes.c2p(rolle_a, f(rolle_a)), color=PURPLE)525 rolle_point_b = Dot(axes.c2p(rolle_b, f(rolle_b)), color=PURPLE)526 rolle_label_a = MathTex("a").next_to(rolle_point_a, DOWN)527 rolle_label_b = MathTex("b").next_to(rolle_point_b, DOWN)528 529 self.play(530 Create(rolle_point_a),531 Create(rolle_point_b),532 Write(rolle_label_a),533 Write(rolle_label_b)534 )535 536 # 绘制罗尔区间的割线(水平线,因为f(a)=f(b)=0)537 rolle_secant = Line(538 axes.c2p(rolle_a, f(rolle_a)),539 axes.c2p(rolle_b, f(rolle_b)),540 color=PURPLE541 )542 self.play(Create(rolle_secant))543 544 # 修改f(a)=f(b)的显示方式(大约在第523行)545 # 将:546 equal_values = MathTex(r"f(a) = f(b) = 0").scale(0.7).next_to(rolle_title, UP)547 548 # 修改为:549 equal_values = MathTex(r"f(a) = f(b)").scale(0.7).next_to(rolle_title, UP)550 self.play(Write(equal_values))551 552 # 找到f'(c)=0的点553 # 解方程f'(c) = 0,即 3c^2 - 6c + 2 = 0554 # 这个方程有两个解:c ≈ 0.423 和 c ≈ 1.577555 # 对于区间[1,2],我们需要使用1.577556 c_rolle = (6 + np.sqrt(12))/6 # 约等于1.577,在[1,2]区间内的极值点557 558 # 标记c点559 c_rolle_point = Dot(axes.c2p(c_rolle, f(c_rolle)), color=YELLOW)560 c_rolle_label = MathTex(r"\xi").next_to(c_rolle_point, DOWN)561 562 # 水平切线563 horizontal_tangent = Line(564 axes.c2p(c_rolle - 0.8, f(c_rolle)),565 axes.c2p(c_rolle + 0.8, f(c_rolle)),566 color=GREEN567 )568 569 self.play(570 Create(c_rolle_point),571 Write(c_rolle_label),572 Create(horizontal_tangent)573 )574 575 # 添加等待时间,让观众有时间观察水平切线576 self.wait(2)577 578 # 显示罗尔定理公式579 rolle_formula = MathTex(580 r"\exists \xi \in (a,b) : f'(\xi) = 0"581 ).scale(0.7).next_to(equal_values, UP, buff=0.2)582 self.play(Write(rolle_formula))583 584 # 再次等待,强调水平切线与公式的关系585 self.play(586 Indicate(horizontal_tangent, scale_factor=1.2, color=GREEN),587 Indicate(c_rolle_point, scale_factor=1.2, color=YELLOW),588 run_time=1.5589 )590 self.wait(1)591 592 # 清除所有内容,展示定理关系图593 self.play(594 *[FadeOut(mob) for mob in self.mobjects if mob != title]595 )596 597 # 创建定理关系图598 relation_diagram = VGroup()599 600 # 创建三个框和文本601 cauchy_box = Rectangle(height=1, width=4, color=BLUE)602 cauchy_text = Text("柯西中值定理", font="SimSun").scale(0.6)603 cauchy_group = VGroup(cauchy_box, cauchy_text).arrange(ORIGIN)604 605 lagrange_box = Rectangle(height=1, width=4, color=GREEN)606 lagrange_text = Text("拉格朗日中值定理", font="SimSun").scale(0.6)607 lagrange_group = VGroup(lagrange_box, lagrange_text).arrange(ORIGIN)608 609 rolle_box = Rectangle(height=1, width=4, color=RED)610 rolle_text = Text("罗尔中值定理", font="SimSun").scale(0.6)611 rolle_group = VGroup(rolle_box, rolle_text).arrange(ORIGIN)612 613 # 排列定理框614 relation_diagram.add(cauchy_group, lagrange_group, rolle_group)615 relation_diagram.arrange(DOWN, buff=1.5)616 617 # 添加箭头和说明618 arrow1 = Arrow(cauchy_group.get_bottom(), lagrange_group.get_top(), color=BLUE)619 arrow_text1 = Text("g(t)=t, g'(t)=1", font="SimSun").scale(0.4).next_to(arrow1, RIGHT)620 621 arrow2 = Arrow(lagrange_group.get_bottom(), rolle_group.get_top(), color=GREEN)622 arrow_text2 = Text("f(a)=f(b)", font="SimSun").scale(0.4).next_to(arrow2, RIGHT)623 624 # 创建公式组625 formulas = VGroup(626 MathTex(r"\frac{f'(\xi)}{g'(\xi)} = \frac{f(b)-f(a)}{g(b)-g(a)}").scale(0.5).next_to(cauchy_group, LEFT, buff=0.5),627 MathTex(r"f'(\xi) = \frac{f(b)-f(a)}{b-a}").scale(0.5).next_to(lagrange_group, LEFT, buff=0.5),628 MathTex(r"f'(\xi) = 0").scale(0.5).next_to(rolle_group, LEFT, buff=0.5)629 )630 631 # 组合所有元素632 final_diagram = VGroup(633 relation_diagram, 634 arrow1, arrow_text1, 635 arrow2, arrow_text2,636 formulas637 )638 639 final_diagram.move_to(ORIGIN)640 641 # 显示关系图642 self.play(Create(relation_diagram))643 self.play(Create(arrow1), Write(arrow_text1), Create(arrow2), Write(arrow_text2))644 self.play(Write(formulas))645 646 # 总结文字647 summary = Text(648 "三个中值定理展示了数学中特例与一般化的美妙关系", 649 font="SimSun"650 ).scale(0.6).to_edge(DOWN)651 652 self.play(Write(summary))653 654 self.wait(3)655 656 def find_cauchy_c(self, f, df, g, dg, a, b):657 """计算满足柯西中值定理的c值"""658 # 计算割线斜率659 secant_slope = (f(b) - f(a)) / (g(b) - g(a))660 661 # 定义方程 f'(\xi)/g'(\xi) = secant_slope662 def equation(x):663 return df(x) / dg(x) - secant_slope664 665 # 使用二分法求解666 left, right = a, b667 epsilon = 1e-10668 while right - left > epsilon:669 mid = (left + right) / 2670 if equation(mid) * equation(left) <= 0:671 right = mid672 else:673 left = mid674 675 return (left + right) / 2676 677 def find_lagrange_c(self, f, df, a, b):678 """计算满足拉格朗日中值定理的c值"""679 # 计算割线斜率680 secant_slope = (f(b) - f(a)) / (b - a)681 682 # 定义方程 f'(\xi) = secant_slope683 def equation(x):684 return df(x) - secant_slope685 686 # 使用二分法求解687 left, right = a, b688 epsilon = 1e-10689 while right - left > epsilon:690 mid = (left + right) / 2691 if equation(mid) * equation(left) <= 0:692 right = mid693 else:694 left = mid695 696 return (left + right) / 2 讲解
这个视频围绕「三个微分中值定理的关系」展开。画面把问题、图像和公式放在同一条理解路径中,让抽象关系先被看见。
开头先建立问题背景和主要对象,让观察从标题、坐标或第一组关系进入。
画面中出现的文字「柯西中值定理的参数曲线解释」给出视觉入口。随后画面通过对象创建、移动、淡入淡出和高亮,把抽象命题拆成可以跟随的步骤。
随后出现更具体的图像或公式提示,动画会把局部对象和整体结论联系起来。这里可以重点观察变量、曲线、区域或向量如何随镜头推进而变化。
核心公式可以写成:
这类公式可以和画面中的符号一一对应。
观察路径
观察路径可以分三步:先锁定「三个微分中值定理的关系」中的核心对象,尤其留意微分中值定理、柯西中值定理、导数之间的联系;再跟随画面中变量、图像或向量的变化;最后回到公式或结论,判断局部变化如何支撑整体关系。
本页可以从微分中值定理、柯西中值定理、导数、参数曲线、切向量这些概念进入,继续沿相邻问题观察同一类数学结构。