正弦波與單位圓關系的可視化 包括源碼
flyfish
正弦波與單位圓的關系
正弦波可以通過單位圓上的點在直線(通常是 y 軸)上的投影來表示。具體來說,考慮一個單位圓,其半徑為 1,圓心在原點。我們可以通過旋轉一個角度 α \alpha α 來描述圓周上的點的坐標。
-
單位圓上的點 : 在單位圓上,給定一個角度 α \alpha α,圓周上的點的坐標為 ( cos ? α , sin ? α ) (\cos \alpha, \sin \alpha) (cosα,sinα)。
這里, cos ? α \cos \alpha cosα 是點在 x 軸上的投影, sin ? α \sin \alpha sinα 是點在 y 軸上的投影。 -
正弦函數 :
當角度 α \alpha α 從 0 變化到 2 π 2\pi 2π 時,單位圓上的點會繞原點一圈。
在這個過程中,點的 y 坐標(即 sin ? α \sin \alpha sinα)會從 0 變化到 1,再變化到 0,然后變化到 -1,最后回到 0。
這個 y 坐標隨著角度變化的曲線就是正弦波的圖像。
正弦波的生成
當我們把單位圓上的點在 y 軸上的投影 sin ? α \sin \alpha sinα 作為 y 軸的值,并將對應的角度 α \alpha α 作為 x 軸的值,就可以得到正弦波的圖像。
可視化解釋
-
單位圓 :在單位圓上,我們選擇一個角度 α \alpha α,則點的坐標為 ( cos ? α , sin ? α ) (\cos \alpha, \sin \alpha) (cosα,sinα)。
-
投影 :在這個角度 α \alpha α 下,點在 y 軸上的投影為 sin ? α \sin \alpha sinα。
-
正弦波 :隨著角度 α \alpha α 的變化,我們將每個角度 α \alpha α 與對應的 sin ? α \sin \alpha sinα 值連成一條曲線,這就是正弦波。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation, PillowWriter
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 初始化參數
omega = np.linspace(0, 2 * np.pi, 200)# 圓
x = np.cos(omega) - 1
y = np.sin(omega)# 正弦函數
x1 = omega
y1 = np.sin(x1)# 創建圖形
fig, ax = plt.subplots(figsize=(12, 6))
ax.set_aspect('equal')
ax.set_xlim(-2.2, 7)
ax.set_ylim(-1.2, 1.2)
ax.grid(True)
ax.set_xticks(np.linspace(-2, 2 * np.pi, 19))
ax.set_xticklabels(['-2', '-1', '0', r'$\pi/8$', r'$\pi/4$', r'$3\pi/8$', r'$\pi/2$', r'$5\pi/8$', r'$3\pi/4$', r'$7\pi/8$', r'$\pi$', r'$9\pi/8$', r'$5\pi/4$', r'$11\pi/8$', r'$3\pi/2$', r'$13\pi/8$', r'$7\pi/4$', r'$15\pi/8$', r'$2\pi$'])
ax.set_title('正弦函數和圓之間的關系', fontsize=22)# 初始化線和點
circle_line, = ax.plot([], [], '-r', lw=3)
sine_line, = ax.plot([], [], '-g', lw=3)
connect_line, = ax.plot([], [], '--', lw=3)
arrow_line, = ax.plot([], [], '-bo', lw=3)
vert_line1, = ax.plot([], [], 'k', lw=3)
vert_line2, = ax.plot([], [], 'k', lw=3)
text1 = ax.text(0, 0, '', fontsize=14)
text2 = ax.text(0, 0, '', fontsize=14)def init():circle_line.set_data([], [])sine_line.set_data([], [])connect_line.set_data([], [])arrow_line.set_data([], [])vert_line1.set_data([], [])vert_line2.set_data([], [])text1.set_text('')text2.set_text('')return circle_line, sine_line, connect_line, arrow_line, vert_line1, vert_line2, text1, text2def update(i):connectLineX = np.linspace(x[i], x1[i], 50)connectLineY = np.zeros(50) + y[i]arrowX = [-1, x[i]]arrowY = [0, y[i]]lineX = np.zeros(20) + x[i]lineY = np.linspace(0, y[i], 20)x3 = np.zeros(20) + x1[i]y3 = np.linspace(0, y1[i], 20)circle_line.set_data(x[:i], y[:i])sine_line.set_data(x1[:i], y1[:i])connect_line.set_data(connectLineX, connectLineY)arrow_line.set_data(arrowX, arrowY)vert_line1.set_data(lineX, lineY)vert_line2.set_data(x3, y3)text1.set_position((x[i] + 0.05, y[i]))text1.set_text(f'{omega[i] / np.pi:.2f}$\pi$')text2.set_position((x1[i] + 0.05, y1[i]))text2.set_text(f'{omega[i] / np.pi:.2f}$\pi$')return circle_line, sine_line, connect_line, arrow_line, vert_line1, vert_line2, text1, text2# 創建動畫
ani = FuncAnimation(fig, update, frames=len(omega), init_func=init, blit=True, repeat=True,interval=20)# 保存動畫
writer = PillowWriter(fps=20)
ani.save("sinePhase.gif", writer=writer)plt.show()