级数与函数逼近可视化

傅立叶级数逼近

围绕傅立叶级数逼近,观察傅立叶级数、函数逼近、波形叠加之间的关系与推理路径。

打开原视频

fourier_series.py
1# -*- coding: utf-8 -*-2from manim import *3import numpy as np4 5class FourierSeriesVisualization(Scene):6    def construct(self):7        # 设置默认字体8        Text.set_default(font="SimSun")9        10        # 标题11        title = Text("傅立叶级数逼近").scale(0.8)12        title.to_edge(UP, buff=0.3)13        self.play(Write(title))14        self.wait(1)15 16        # 创建坐标系17        axes = Axes(18            x_range=[-4, 4, 1],19            y_range=[-2, 2, 1],20            axis_config={"include_tip": True},21            x_length=10,22            y_length=623        ).scale(0.8)24        axes.shift(DOWN * 0.5 + LEFT * 3)  # 更多的左移25        26        # 添加坐标轴标签27        x_label = Text("x").scale(0.6)28        y_label = Text("y").scale(0.6)29        x_label.next_to(axes.x_axis, RIGHT)30        y_label.next_to(axes.y_axis, UP)31        32        axes_group = VGroup(axes, x_label, y_label)33        self.play(Create(axes_group))34 35        # 先显示原函数表达式36        function_text = VGroup(37            Text("原函数:", font="SimSun").scale(0.5),38            MathTex(39                r"f(x) = \begin{cases} 1, & 0 \leq x < \pi \\ -1, & -\pi \leq x < 0 \end{cases}"40            ).scale(0.5)41        ).arrange(RIGHT, buff=0.3)42        function_text.to_corner(UL, buff=0.8)43        self.play(Write(function_text))44        self.wait(1)45 46        # 定义方波函数47        def square_wave(x):48            return np.where(np.sin(x) >= 0, 1, -1)  # 恢复原来的方波函数定义49 50        # 定义傅立叶级数部分和函数51        def get_fourier_series(x, n):52            result = 053            for k in range(1, n+1, 2):54                result += 4/(k*np.pi) * np.sin(k*x)55            return result56 57        # 显示原函数图像58        original = axes.plot(59            square_wave,60            color=BLUE,61            x_range=[-4, 4, 0.01]  # 移除discontinuities和dt参数62        )63        original_label = Text("原函数", font="SimSun", color=BLUE).scale(0.5)64        original_label.next_to(original.point_from_proportion(0.8), UP)65        66        self.play(67            Create(original),68            Write(original_label)69        )70        self.wait(1)71 72        # 显示傅立叶级数表达式73        final_series = VGroup(74            Text("傅立叶级数展开:", font="SimSun").scale(0.5),75            MathTex(76                r"f(x) = \frac{4}{\pi} \sum_{n=1,3,5,\cdots}^{\infty} \frac{\sin(nx)}{n}"77            ).scale(0.5)78        ).arrange(RIGHT, buff=0.3)79        final_series.to_corner(UR, buff=0.8)80        self.play(Write(final_series))81        self.wait(1)82 83        # 显示部分和表达式84        fourier_terms = VGroup(85            MathTex(r"S_1(x) = \frac{4}{\pi} \sin(x)", color=RED),86            MathTex(r"S_3(x) = \frac{4}{\pi} (\sin(x) + \frac{1}{3}\sin(3x))", color=GREEN),87            MathTex(r"S_5(x) = \frac{4}{\pi} (\sin(x) + \frac{1}{3}\sin(3x) + \frac{1}{5}\sin(5x))", color=YELLOW),88            MathTex(r"S_9(x) = \frac{4}{\pi} (\sin(x) + \frac{1}{3}\sin(3x) + \cdots + \frac{1}{9}\sin(9x))", color=PURPLE),89            MathTex(r"S_{15}(x) = \frac{4}{\pi} (\sin(x) + \frac{1}{3}\sin(3x) + \cdots + \frac{1}{15}\sin(15x))", color=WHITE),90            MathTex(r"S_{23}(x) = \frac{4}{\pi} (\sin(x) + \frac{1}{3}\sin(3x) + \cdots + \frac{1}{23}\sin(23x))", color=ORANGE)91        ).scale(0.4).arrange(DOWN, aligned_edge=LEFT, buff=0.2)92        93        # 调整部分和位置到右上角,并向右移动更多以避免重叠94        fourier_terms.next_to(final_series, DOWN, buff=0.3)95        fourier_terms.shift(RIGHT * 1)  # 向右移动更多以避免重叠96 97        # 绘制不同阶数的傅立叶级数98        colors = [RED, GREEN, YELLOW, PURPLE, WHITE, ORANGE]99        approximations = []100        labels = []101        102        for i, n in enumerate([1, 3, 5, 9, 15, 23]):103            # 绘制第n项逼近104            approx = axes.plot(105                lambda x: get_fourier_series(x, n),106                color=colors[i],107                x_range=[-4, 4, 0.01]108            )109            approximations.append(approx)110            111            # 添加标签112            label = MathTex(f"n = {n}", color=colors[i]).scale(0.5)113            label.next_to(approx.point_from_proportion(0.6), UP + RIGHT)  # 向右偏移114            labels.append(label)115            116            if i == 0:117                self.play(118                    Create(approx),119                    Write(label),120                    Write(fourier_terms[0])  # 显示第一项121                )122            else:123                self.play(124                    ReplacementTransform(approximations[i-1], approx),125                    ReplacementTransform(labels[i-1], label),126                    Write(fourier_terms[i])  # 显示新的展开式127                )128            self.wait(0.5)129 130        # 添加说明文字131        explanation = Text(132            "随着项数增加,傅立叶级数逐渐逼近原函数",133            font="SimSun"134        ).scale(0.5)135        explanation.next_to(axes, DOWN, buff=0.5)136        137        self.play(Write(explanation))138        self.wait(2)139 140def main():141    scene = FourierSeriesVisualization()142    scene.render()143 144if __name__ == "__main__":145    main()

讲解

这个视频围绕「傅立叶级数逼近」展开。画面把问题、图像和公式放在同一条理解路径中,让抽象关系先被看见。

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

画面中出现的文字「傅立叶级数逼近」给出视觉入口。随后画面通过对象创建、移动、淡入淡出和高亮,把抽象命题拆成可以跟随的步骤。

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

核心公式可以写成:

S1(x)=4πsin(x)S_1(x) = \frac{4}{\pi} \sin(x)

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

观察路径

观察路径可以分三步:先锁定「傅立叶级数逼近」中的核心对象,尤其留意傅立叶级数、函数逼近、波形叠加之间的联系;再跟随画面中变量、图像或向量的变化;最后回到公式或结论,判断局部变化如何支撑整体关系。

本页可以从傅立叶级数、函数逼近、波形叠加这些概念进入,继续沿相邻问题观察同一类数学结构。