正弦波与单位圆关系的可视化 包括源码
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()