【编程德鲁伊】系列是我的横向编程练习笔记,每期围绕一个主题(数学物理电子图形声音...),用几种程序语言分别实现。战法牧贼同时修,能抗能打能奶能开溜。
编程德鲁伊 - 数学篇 - 傅里叶级数可视化
JavaScript (React) 实现

上一章做了三角函数可视化,分别用 MaxMSP, JavaScript (React), Python, 以及 Unity:

这一章准备重新体验下被傅里叶支配的恐惧,搞一搞傅里叶级数的可视化。
不禁想起那一年夕阳下的奔跑,高数考了7分。
所以本节决定先从最称手的 JavaScript (React) 开始,以防坑上加坑爬不出来。
谈到傅里叶变换、傅里叶分析,通常会分为两部分内容来讲,傅里叶级数和连续傅里叶变换。本章先试试傅里叶级数。
数学基础
在数学中,傅里叶级数可以看作一组正弦曲线组成的周期函数,由加权求和组合而成。
(wikipedia)
举个例子,假设有一个周期性方波,它可以分解成多个正弦波:

正弦波越多,合成后的曲线越接近方波:

下面正式开始傅里叶级数的推导(公式抄写)。
假设 f(x) 是一个区间为 x∈[−π,π] 的周期函数, 周期为 2π:
f(x)=⎩⎨⎧−1,−π≤x<01,0≤x<π 它的傅里叶级数正弦函数式:
f(x)=2a0+n=1∑∞(ancos(nx)+bnsin(nx)) 傅里叶系数:
an=π1∫−ππf(x)cos(nx)dx
=π1∫−π0(−1)cos(nx)dx+π1∫0π(1)cos(nx)dx
=0(n=0,1,2,...)
bn=π1∫−ππf(x)sin(nx)dx
=π1∫−π0(−1)sin(nx)dx+π1∫0π(1)sin(nx)dx
=π1⋅n1[cos(nx)]−π0+π1⋅(−n1)[cos(nx)]0π
=nπ2(1−cos(nπ))
=nπ2[1−(−1)n]
=⎩⎨⎧nπ4,n=1,3,5,...0,n=2,3,4,...
系数带入傅里叶级数,最终得到:
f(x)=π4∑1∞2n−12 x
=π4(sinx+31sin3x+51sin5x+...)
(−∞<x<+∞,and x=0,±1,±2,...)
上述公式参考了 "Advanced Mathematics - (Engineering Course) 高等数学-工科"。
详细的傅里叶级数在维基百科里也有定义和解释:wikipedia。
维基百科里有一张图,是以傅里叶级数正弦函数展开式取了前四项的和为例,展示了如何去近似接近一个方波:
f(x)=π4(sinx+31sin3x+51sin5x+71sin7x) 
本次练习就来实现这张图的曲线。
Visualization
上一章我重构实现了正弦曲线:

这次接着上回单位圆和正弦部分的代码,继续使用React Hooks来做傅里叶级数可视化。
React把js、html、css揉在一起,写起来还是逻辑很清晰(?)的:

f(x)=π4(sinx+31sin3x+51sin5x+...)
(x=1,3,5,7,9,...)

数据刷新部分,继续使用 React Hooks:

完整源代码请见后文。
最终结果:

随着n的增加,即正弦波的增加,合成后的波形越来越接近方波。
通过做这个例子,我感觉再考高数的话,傅里叶级数的题应该稳了,这次拿个八九分不成问题,100分在招手。
参考资源
Talk is cheap. Show me the code!
本例及【编程德鲁伊】系列大部分代码都开源在这里:
https://github.com/avantcontra/coding-druid
公众号/B站/小红书/抖音/知乎:实验编程
实验编程社群资源、公开课:
https://ghc.h5.xeknow.com/s/hzkMX
实验编程情报中心(会员):
https://ghc.h5.xeknow.com/s/2BCFuJ
Cheers🍻
Contra