极限思想可视化

巴比伦法求平方根

围绕巴比伦法求平方根,观察巴比伦开方法、单调有界原理、数列收敛之间的关系与推理路径。

打开原视频

babylonian_method_animation.py
1from manim import *2import numpy as np3 4config.tex_template = TexTemplateLibrary.ctex5config.tex_template.add_to_preamble(r"\setCJKmainfont{STSong}")6 7class BabylonianMethodAnimation(Scene):8    def construct(self):9        # 标题10        title = Text("巴比伦方法求平方根", font="STSong", font_size=40, color=BLUE)11        self.play(Write(title))12        self.wait(1)13        self.play(FadeOut(title))14 15        # 显示题目(使用数学公式,一行显示)16        problem_title = Text("题目:", font_size=24, color=YELLOW)17        problem_text = MathTex(r"\text{设 } x_0 > 0, x_{n+1} = \frac{1}{2}(x_n + \frac{a}{x_n}), \text{且 } a > 0, \text{证明 } \lim_{n \to \infty} x_n \text{ 存在并求此极限}", font_size=18, color=WHITE)18        19        problem_group = VGroup(problem_title, problem_text).arrange(DOWN, buff=0.2, aligned_edge=LEFT)20        problem_group.to_edge(UP, buff=0.5)21        22        self.play(Write(problem_group))23        self.wait(2)24 25        # 分析思路(左上角)26        analysis_title = Text("分析思路:", font_size=20, color=GREEN)27        analysis_text1 = Text("1. 证明数列单调有界", font_size=16, color=WHITE)28        analysis_text2 = Text("2. 利用单调有界定理", font_size=16, color=WHITE)29        analysis_text3 = Text("3. 求极限值", font_size=16, color=WHITE)30        31        analysis_group = VGroup(analysis_title, analysis_text1, analysis_text2, analysis_text3)32        analysis_group.arrange(DOWN, buff=0.1, aligned_edge=LEFT)33        analysis_group.to_corner(UL, buff=0.3)34        35        self.play(Write(analysis_group))36        self.wait(2)37 38        # 迭代公式分析(移到分析思路下面)39        formula_title = Text("迭代公式分析:", font_size=20, color=ORANGE)40        formula1 = MathTex(r"x_{n+1} = \frac{1}{2}(x_n + \frac{a}{x_n})", font_size=18)41        formula2 = MathTex(r"= \frac{1}{2}(f(x_n) + g(x_n))", font_size=18)42        43        formula_group = VGroup(formula_title, formula1, formula2)44        formula_group.arrange(DOWN, buff=0.15, aligned_edge=LEFT)45        formula_group.to_corner(UL, buff=0.3).shift(DOWN * 1.5)46        47        self.play(Write(formula_group))48        self.wait(2)49 50        # 创建坐标系 - 扩大x轴范围51        axes = Axes(52            x_range=[0, 6, 1],  # 从0-4改为0-653            y_range=[0, 4, 1],54            x_length=8,  # 从6改为855            y_length=4,56            axis_config={"color": BLUE_B}57        )58        axes.to_edge(RIGHT, buff=0.5).shift(DOWN * 0.5)59        60        # 添加标签61        x_label = axes.get_x_axis_label("x")62        y_label = axes.get_y_axis_label("y")63        64        self.play(Create(axes), Create(x_label), Create(y_label))65        self.wait(1)66 67        # 绘制函数 f(x) = x 和 g(x) = a/x68        a = 2  # 取 a = 2 作为例子69        x_line = axes.plot(lambda x: x, x_range=[0, 5], color=RED)  # 从0-3改为0-570        hyperbola = axes.plot(lambda x: a/x, x_range=[0.5, 5], color=GREEN)  # 改为[0.5, 5]71        72        # 添加函数标签 - 增大字体73        f_label = MathTex("f(x) = x", color=RED, font_size=20).next_to(x_line, RIGHT, buff=0.1)74        g_label = MathTex("g(x) = \\frac{a}{x}", color=GREEN, font_size=20).next_to(hyperbola, RIGHT, buff=0.1)75        76        self.play(Create(x_line), Create(hyperbola))77        self.play(Write(f_label), Write(g_label))78        self.wait(1)79 80        # 开始迭代过程81        x0 = 5.0  # 初始值改为5.082        iterations = []83        x_values = [x0]84        85        # 在红色直线上标记f(x₀)点86        f_initial_point = Dot(axes.coords_to_point(x0, x0), color=RED, radius=0.06)87        f_initial_label = MathTex("f(x_0)", font_size=14, color=RED).next_to(f_initial_point, UP, buff=0.1)88        89        # 在绿色双曲线上标记g(x₀)点90        g_initial_point = Dot(axes.coords_to_point(x0, a/x0), color=GREEN, radius=0.06)91        g_initial_label = MathTex("g(x_0)", font_size=14, color=GREEN).next_to(g_initial_point, RIGHT, buff=0.1)92        93        self.play(Create(f_initial_point), Write(f_initial_label))94        self.play(Create(g_initial_point), Write(g_initial_label))95        self.wait(1)96 97        # 执行迭代 - 只显示到x498        for i in range(4):  # 改为4次迭代99            # 计算下一个值100            x_next = 0.5 * (x_values[-1] + a / x_values[-1])101            x_values.append(x_next)102            103            # 在坐标系中显示迭代过程104            current_x = x_values[-2]105            current_y = x_values[-2]106            107            # 垂直线到双曲线108            vertical_line = DashedLine(109                axes.coords_to_point(current_x, current_y),110                axes.coords_to_point(current_x, a/current_x),111                color=BLUE112            )113            114            # 显示中点计算 - 修正:中点应该是 (x_n, (x_n + a/x_n)/2)115            midpoint_x = current_x116            midpoint_y = (current_x + a/current_x) / 2117            midpoint_point = Dot(axes.coords_to_point(midpoint_x, midpoint_y), color=PURPLE_A, radius=0.05)118            119            # 显示具体的迭代公式120            midpoint_label = MathTex(f"x_{i+1} = \\frac{{1}}{{2}}(x_{i} + \\frac{{a}}{{x_{i}}})", font_size=12, color=PURPLE_A)121            122            # 根据迭代次数调整公式标签位置123            if i == 3:  # x₄的情况,显示在交点下方124                midpoint_label.next_to(midpoint_point, DOWN, buff=0.1)125            else:126                midpoint_label.next_to(midpoint_point, RIGHT)127            128            # 从紫色中点直接连线到x轴上的下一个迭代点位置129            horizontal_line = DashedLine(130                axes.coords_to_point(midpoint_x, midpoint_y),131                axes.coords_to_point(x_next, 0),  # 连线到x轴上的x_{i+1}位置132                color=PURPLE_A133            )134            135            # 在x轴上标记下一个迭代点位置136            x_axis_point = Dot(axes.coords_to_point(x_next, 0), color=YELLOW, radius=0.05)137            x_axis_label = MathTex(f"x_{i+1}", font_size=14, color=YELLOW).next_to(x_axis_point, DOWN, buff=0.1)138            139            # 从x轴上的点向上做垂直线找到f(x_{i+1})和g(x_{i+1})140            vertical_line_to_f = DashedLine(141                axes.coords_to_point(x_next, 0),142                axes.coords_to_point(x_next, x_next),143                color=RED144            )145            146            vertical_line_to_g = DashedLine(147                axes.coords_to_point(x_next, 0),148                axes.coords_to_point(x_next, a/x_next),149                color=GREEN150            )151            152            # 在红色直线上标记f(x_{i+1})点153            f_next_point = Dot(axes.coords_to_point(x_next, x_next), color=RED, radius=0.06)154            f_next_label = MathTex(f"f(x_{i+1})", font_size=14, color=RED)155            156            # 在绿色双曲线上标记g(x_{i+1})点157            g_next_point = Dot(axes.coords_to_point(x_next, a/x_next), color=GREEN, radius=0.06)158            g_next_label = MathTex(f"g(x_{i+1})", font_size=14, color=GREEN)159            160            # 根据迭代次数调整标签位置,避免与交点重叠161            if i == 3:  # x₄的情况162                f_next_label.next_to(f_next_point, LEFT, buff=0.1)163                g_next_label.next_to(g_next_point, LEFT, buff=0.1)164            else:165                f_next_label.next_to(f_next_point, UP, buff=0.1)166                g_next_label.next_to(g_next_point, RIGHT, buff=0.1)167            168            self.play(Create(vertical_line))169            self.wait(0.5)170            self.play(Create(midpoint_point), Write(midpoint_label))171            self.wait(1)172            self.play(Create(horizontal_line))173            self.wait(0.5)174            self.play(Create(x_axis_point), Write(x_axis_label))175            self.wait(0.5)176            self.play(Create(vertical_line_to_f), Create(vertical_line_to_g))177            self.wait(0.5)178            self.play(Create(f_next_point), Write(f_next_label))179            self.play(Create(g_next_point), Write(g_next_label))180            self.wait(1)181 182        # 显示收敛性证明(移到迭代分析下面)183        proof_title = Text("收敛性证明:", font_size=20, color=PURPLE)184        proof1 = MathTex(r"1. \text{下界性:} x_n \geq \sqrt{a}", font_size=16)185        proof2 = MathTex(r"2. \text{单调性:} x_{n+1} \leq x_n", font_size=16)186        proof3 = MathTex(r"3. \text{极限:} \lim_{n \to \infty} x_n = \sqrt{a}", font_size=16)187        188        proof_group = VGroup(proof_title, proof1, proof2, proof3)189        proof_group.arrange(DOWN, buff=0.1, aligned_edge=LEFT)190        proof_group.to_corner(UL, buff=0.3).shift(DOWN * 3.5)191        192        self.play(Write(proof_group))193        self.wait(2)194 195        # 显示数值结果196        result_title = Text("数值结果:", font_size=24, color=YELLOW)197        result_text = Text(f"a = {a}, x₀ = {x0}", font_size=18, color=WHITE)198        199        result_group = VGroup(result_title, result_text)200        result_group.arrange(DOWN, buff=0.2, aligned_edge=LEFT)201        result_group.to_edge(LEFT, buff=0.5).shift(DOWN * 5.5)202        203        self.play(Write(result_group))204        self.wait(2)205 206        # 最终结论(移到最下面)207        conclusion_title = Text("结论:", font_size=24, color=GREEN)208        conclusion1 = MathTex(r"\lim_{n \to \infty} x_n = \sqrt{a}", font_size=24, color=YELLOW)209        conclusion2 = Text("这是求平方根的巴比伦方法", font_size=20, color=WHITE)210        211        conclusion_group = VGroup(conclusion_title, conclusion1, conclusion2)212        conclusion_group.arrange(DOWN, buff=0.3, aligned_edge=LEFT)213        conclusion_group.to_corner(DL, buff=0.5)214        215        # 突出显示最终结果216        result_box = SurroundingRectangle(conclusion1, buff=0.2, color=YELLOW)217        218        self.play(Write(conclusion_group))219        self.play(Create(result_box))220        self.wait(3)221 222if __name__ == "__main__":223    # 使用1080p渲染设置224    config.frame_rate = 30225    config.pixel_width = 1920226    config.pixel_height = 1080227    scene = BabylonianMethodAnimation()228    scene.render()

讲解

这个视频围绕「巴比伦法求平方根」展开。画面把问题、图像和公式放在同一条理解路径中,让抽象关系先被看见。

开头先建立问题背景和主要对象,让观察从标题、坐标或第一组关系进入。

画面中出现的文字「巴比伦方法求平方根」给出视觉入口。随后画面通过对象创建、移动、淡入淡出和高亮,把抽象命题拆成可以跟随的步骤。

随后出现更具体的图像或公式提示,动画会把局部对象和整体结论联系起来。这里可以重点观察变量、曲线、区域或向量如何随镜头推进而变化。

核心公式可以写成:

xn+1=12(xn+axn)x_{n+1} = \frac{1}{2}(x_n + \frac{a}{x_n})

这类公式可以和画面中的符号一一对应。

观察路径

观察路径可以分三步:先锁定「巴比伦法求平方根」中的核心对象,尤其留意巴比伦开方法、单调有界原理、数列收敛之间的联系;再跟随画面中变量、图像或向量的变化;最后回到公式或结论,判断局部变化如何支撑整体关系。

本页可以从巴比伦开方法、单调有界原理、数列收敛、迭代法这些概念进入,继续沿相邻问题观察同一类数学结构。