taylor_series.py
1# -*- coding: utf-8 -*-2from manim import *3import numpy as np4 5class TaylorSeriesApproximation(Scene):6 def construct(self):7 # 设置默认字体8 Text.set_default(font="SimSun")9 10 # 标题11 title = VGroup(12 Text("泰勒级数逼近", font="SimSun"),13 MathTex("e^x")14 ).arrange(RIGHT, buff=0.3).scale(0.6)15 title.to_edge(UP, buff=0.3)16 self.play(Write(title))17 self.wait(1)18 19 # 创建坐标系20 axes = Axes(21 x_range=[-4, 4, 1],22 y_range=[-1, 4, 1],23 axis_config={"include_tip": True},24 x_length=10,25 y_length=626 ).scale(0.8)27 axes.shift(DOWN * 1.2)28 29 # 添加坐标轴标签30 x_label = Text("x").scale(0.6)31 y_label = Text("y").scale(0.6)32 x_label.next_to(axes.x_axis, RIGHT)33 y_label.next_to(axes.y_axis, UP)34 35 axes_group = VGroup(axes, x_label, y_label)36 self.play(Create(axes_group))37 38 # 添加局部放大坐标系39 magnified_axes = Axes(40 x_range=[-0.1, 0.1, 0.02],41 y_range=[0.9, 1.1, 0.05],42 axis_config={43 "include_tip": True,44 "numbers_to_exclude": ["all"],45 "tick_size": 0.05,46 },47 x_length=3,48 y_length=3,49 tips=True50 ).scale(0.8)51 magnified_axes.to_corner(UR, buff=0.5)52 53 # 添加放大区域标题54 magnified_title = Text("零点附近放大图", font="SimSun").scale(0.4)55 magnified_title.next_to(magnified_axes, UP, buff=0.2)56 57 # 添加放大区域的边框58 magnified_box = SurroundingRectangle(59 magnified_axes,60 buff=0.2,61 color=YELLOW,62 stroke_width=263 )64 65 self.play(66 Create(magnified_axes),67 Write(magnified_title),68 Create(magnified_box)69 )70 71 # 在主坐标系中标记放大区域72 zoom_region = Rectangle(73 width=0.3,74 height=0.3,75 color=YELLOW,76 stroke_width=277 ).move_to(axes.c2p(0, 1))78 79 # 连接线80 connection_lines = VGroup(81 Line(82 zoom_region.get_corner(UR),83 magnified_box.get_corner(DL),84 color=YELLOW,85 stroke_width=186 ),87 Line(88 zoom_region.get_corner(DR),89 magnified_box.get_corner(DL),90 color=YELLOW,91 stroke_width=192 )93 )94 95 self.play(96 Create(zoom_region),97 Create(connection_lines)98 )99 100 # 绘制原始的 e^x 函数101 exp_curve = axes.plot(102 lambda x: np.exp(x),103 color=BLUE,104 x_range=[-4, 4, 0.01]105 )106 magnified_exp = magnified_axes.plot(107 lambda x: np.exp(x),108 color=BLUE,109 x_range=[-0.1, 0.1, 0.01]110 )111 112 exp_label = Text("e^x", color=BLUE).scale(0.5)113 exp_label.next_to(exp_curve.point_from_proportion(0.8), UP)114 115 self.play(116 Create(exp_curve),117 Create(magnified_exp),118 Write(exp_label)119 )120 121 # 展示泰勒级数公式122 taylor_formula = MathTex(123 r"e^x = ", r"1", r" + ", r"x", r" + ", r"\frac{x^2}{2!}", r" + ", 124 r"\frac{x^3}{3!}", r" + ", r"\frac{x^4}{4!}", r" + \cdots"125 ).scale(0.6)126 taylor_formula.to_edge(UP, buff=1.0)127 self.play(Write(taylor_formula))128 129 # 显示每一项的函数形式130 terms_explanation = VGroup(131 MathTex(r"S_0(x) = 1", color=RED),132 MathTex(r"S_1(x) = 1 + x", color=GREEN),133 MathTex(r"S_2(x) = 1 + x + \frac{x^2}{2!}", color=YELLOW),134 MathTex(r"S_3(x) = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!}", color=PURPLE),135 MathTex(r"S_4(x) = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \frac{x^4}{4!}", color=ORANGE)136 ).arrange(DOWN, aligned_edge=LEFT, buff=0.2).scale(0.5)137 138 # 将函数形式放在右边放大图下方139 terms_explanation.next_to(magnified_box, DOWN, buff=0.5)140 141 # 定义颜色142 colors = [RED, GREEN, YELLOW, PURPLE, ORANGE]143 144 # 初始化累加曲线变量145 current_sum = None146 magnified_sum = None147 current_boxes = None148 149 # 定义每一步要高亮的项的范围150 term_ranges = [151 [1], # f₀: 只高亮 1152 [1, 2, 3], # f₁: 高亮 1 + x153 [1, 2, 3, 4, 5], # f₂: 高亮 1 + x + x²/2!154 [1, 2, 3, 4, 5, 6, 7], # f₃: 高亮到 x³/3!155 [1, 2, 3, 4, 5, 6, 7, 8, 9] # f₄: 高亮到 x⁴/4!156 ]157 158 for i in range(5):159 # 创建当前步骤的高亮框160 box = SurroundingRectangle(161 VGroup(*[taylor_formula[j] for j in term_ranges[i]]),162 color=colors[i],163 buff=0.1,164 stroke_width=1.5,165 fill_opacity=0166 )167 168 # 显示当前项的函数形式和高亮框169 if current_boxes:170 self.play(171 Write(terms_explanation[i]),172 ReplacementTransform(current_boxes, box) # 替换高亮框173 )174 else:175 self.play(176 Write(terms_explanation[i]),177 Create(box)178 )179 180 current_boxes = box181 182 # 修改累加函数,n=0时只显示常数项1183 def get_current_approximation(x, current_i):184 if current_i == 0:185 return np.ones_like(x) # 返回常数1186 return sum(x**n / np.math.factorial(n) for n in range(current_i + 1))187 188 # 在主坐标系中绘制累加曲线189 new_sum = axes.plot(190 lambda x: get_current_approximation(x, i),191 color=colors[i],192 x_range=[-4, 4, 0.01]193 )194 195 # 在放大坐标系中绘制累加曲线196 new_magnified_sum = magnified_axes.plot(197 lambda x: get_current_approximation(x, i),198 color=colors[i],199 x_range=[-0.1, 0.1, 0.01]200 )201 202 # 显示累加曲线203 if current_sum:204 self.play(205 ReplacementTransform(current_sum, new_sum),206 ReplacementTransform(magnified_sum, new_magnified_sum)207 )208 else:209 self.play(210 Create(new_sum),211 Create(new_magnified_sum)212 )213 214 current_sum = new_sum215 magnified_sum = new_magnified_sum216 self.wait(1)217 218 # 添加误差说明219 error_text = Text(220 "随着项数增加,近似误差逐渐减小",221 color=YELLOW222 ).scale(0.4)223 error_text.to_edge(DOWN, buff=0.5)224 self.play(Write(error_text))225 self.wait(2)226 227def main():228 scene = TaylorSeriesApproximation()229 scene.render()230 231if __name__ == "__main__":232 main() 讲解
这个视频围绕「泰勒级数逼近」展开。画面把问题、图像和公式放在同一条理解路径中,让抽象关系先被看见。
开头先建立问题背景和主要对象,让观察从标题、坐标或第一组关系进入。
画面中出现的文字「泰勒级数逼近」给出视觉入口。随后画面通过对象创建、移动、淡入淡出和高亮,把抽象命题拆成可以跟随的步骤。
随后出现更具体的图像或公式提示,动画会把局部对象和整体结论联系起来。这里可以重点观察变量、曲线、区域或向量如何随镜头推进而变化。
核心公式可以写成:
这类公式可以和画面中的符号一一对应。
观察路径
观察路径可以分三步:先锁定「泰勒级数逼近」中的核心对象,尤其留意泰勒级数、函数逼近、幂级数之间的联系;再跟随画面中变量、图像或向量的变化;最后回到公式或结论,判断局部变化如何支撑整体关系。
本页可以从泰勒级数、函数逼近、幂级数这些概念进入,继续沿相邻问题观察同一类数学结构。