用傅里葉級數表示複平面上的圖形

設圖形爲時間的函數 f(t)=a(t)+ib(t)f(t) = a(t) + i b(t) (a(t)和b(t)爲時間的函數)
f(t)爲閉環曲線或者有限的曲線
f(t)爲閉環曲線時,隨着時間t的增加,f(t)在曲線上轉圈圈。
f(t)爲有限的曲線時,隨着時間t的增加,f(t)會從曲線頭部走到尾部,然後跳到頭部從新走起
顯然以上兩種情況下f(t)都是時間t下的周期函數,可以由傅里葉級數表示

設f(t)爲週期爲1的函數,(0,1)爲f(t)的一個週期區間
則傅里葉級數的指數形式:
f(t)=cnei2πnt++c2ei4πt+c1ei2πt+c0++c1ei2πt+c2ei4πt++cnei2πntf(t)=c_{-n}e^{-i2\pi nt}+\cdots +c_{-2}e^{-i4\pi t}+c_{-1}e^{-i2\pi t}+c_{0}++c_{1}e^{i2\pi t}+c_{2}e^{i4\pi t}+\cdots +c_{n}e^{i2\pi nt}
其中:
cn=01f(t)ei2πntdtc_n=\int_0^1 f(t)e^{-i2\pi nt}dt
cnc_n爲f(t)傅里葉級數的各項係數,由f(t)可確定唯一一組cnc_n
由於f(t)是複數函數,則cnc_n可以由複數表示 cn=an+ibnc_n=a_n+ib_n (an,bna_n,b_n爲常數)

綜上,知道圖形的函數表達式就可以求出圖形的各項傅里葉係數,然後帶入傅里葉級數表達式就可以得到圖形的傅里葉級數,只要係數cnc_n求得足夠多,傅里葉級數就可以表示任何複雜圖形

以下是用傅里葉級數表示一個正方形的python代碼:

import numpy as np
import turtle as tl


def f_t(N,l):  #定義函數圖形,N爲取樣次數
    n=N/4  #這裏直接生成一個複平面上的正方形
    dl=l/int(n) #邊被分的最小單元
    f_t=[[0,0] for x in range(4*int(n))] #存儲函數座標的實部與虛部
    for i in range(int(n)):
        f_t[i]=([i*dl,0])
        f_t[i+int(n)]=([l,i*dl])
        f_t[i+2*int(n)]=([l-i*dl,l])
        f_t[i+3*int(n)]=([0,l-i*dl])
    print("函數分割完畢")
    return f_t
        
def c_n(f_t,M):  #求出傅里葉級數的係數cn,M爲求取傅里葉係數給個數
    m=M/2 #正負係數各有m個
    N=len(f_t) #f_t的長度,及取樣次數
    dt=1/N  #以1/N代替積分算子0.
    c_n=[[0,0] for x in range(2*int(m)+1)] #存儲c_n的實部與虛部
    for i in range(-int(m),int(m)+1): #加上一個初始係數c0
        re=0     #暫存c_n的實部
        im=0     #暫存c_n的虛部
        for j in range(N):
            t=dt*j
            re+=(f_t[j][0]*np.cos(2*np.pi*i*t)+f_t[j][1]*np.sin(2*np.pi*i*t))*dt  #實部積分
            im+=(f_t[j][1]*np.cos(2*np.pi*i*t)-f_t[j][0]*np.sin(2*np.pi*i*t))*dt  #虛部積分
        c_n[i+int(m)]=[re,im]
    print("傅里葉係數生成完畢")
    return c_n

if __name__ == '__main__':
    N = 10000  #函數份數
    l = 500 #正方形邊長
    
    M = 200  #係數個數
    m = M/2
    c_n=c_n(f_t(N,l),M) #獲取f_t對應傅里葉級數的係數c_n
    
    tl.setup(2000,1000)
    tl.penup()
    tl.pensize(2) # 畫筆粗細
    
    x = [0] * M
    y = [0] * M
    for t in range(N+1):
        for i in range(-int(m),int(m)+1):
            x[i] = c_n[i+int(m)][0] * np.cos(2 * i * np.pi * t / N) - c_n[i+int(m)][1] * np.sin(2 * i * np.pi * t / N)
            y[i] = c_n[i+int(m)][0] * np.sin(2 * i * np.pi * t / N) + c_n[i+int(m)][1] * np.cos(2 * i * np.pi * t / N)
            
        tl.goto(int(sum(x))-800,int(sum(y))-400) # 正負可以控制圖形的左右鏡像,上下鏡像,乘除可以控制縮放
        tl.pendown()
    
    
    #直接畫出來的圖形
    tl.penup()
    f_t=f_t(N,l)
    for t in range(N):
        tl.goto(int(f_t[t][0]),int(f_t[t][1])-400)
        tl.pendown()
    tl.done() 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章