![Figure_1]()
import numpy as np
import matplotlib.pyplot as plt
# 全局字体配置
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# ===================== 基础参数 =====================
A = 1.0
theta_p = np.pi / 4.5
theta_max = 3.7 * np.pi
theta = np.linspace(0, theta_max, 1500)
x_cos = A * np.cos(theta)
y_sin = A * np.sin(theta)
xp = A * np.cos(theta_p) # P点统一x坐标
yp = A * np.sin(theta_p) # P点统一y坐标
# 坐标轴末端箭头
def add_axis_arrow(ax):
ax.plot(1, 0, ">k", transform=ax.get_yaxis_transform(), clip_on=False, markersize=9, zorder=10)
ax.plot(0, 1, "^k", transform=ax.get_xaxis_transform(), clip_on=False, markersize=9, zorder=10)
# ===================== 创建画布 =====================
fig = plt.figure(figsize=(12, 10), dpi=120, facecolor='white')
# ---------- 1. 左上:x方向余弦投影 ----------
ax1 = fig.add_axes([0.14, 0.55, 0.30, 0.30])
ax1.plot(x_cos, theta, 'k', linewidth=1.2)
ax1.spines['left'].set_position(('data', 0))
ax1.spines['bottom'].set_position(('data', 0))
ax1.spines['top'].set_visible(False)
ax1.spines['right'].set_visible(False)
add_axis_arrow(ax1)
ax1.set_yticks([np.pi, 2*np.pi, 3*np.pi])
ax1.set_yticklabels([r'$\pi$', r'$2\pi$', r'$3\pi$'], fontsize=10)
ax1.set_xticks([])
ax1.set_ylabel(r'$\theta=\omega t$', fontsize=12, rotation=0, labelpad=22, y=0.93)
ax1.set_xlabel(r'$x$', fontsize=12, x=0.98)
ax1.set_xlim(-A*1.35, A*1.35)
ax1.set_ylim(0, theta_max)
# P点
ax1.plot(xp, theta_p, 'ko', markersize=4)
ax1.text(xp + 0.07, theta_p, 'P', fontsize=11)
# 竖直虚线:从P点向下延伸,刚好穿过x轴接入下方圆形,不超长
ax1.plot([xp, xp], [theta_p, -0.8], 'k--', linewidth=0.8, dashes=(5, 3), clip_on=False)
# 振幅A标注
ax1.annotate('', xy=(A, 2*np.pi), xytext=(0, 2*np.pi),
arrowprops=dict(arrowstyle='<->', color='k', lw=1))
ax1.text(A/2, 2*np.pi + 0.1, 'A', fontsize=11, ha='center')
# 1个运动周期
ax1.annotate('', xy=(-A*1.22, 0), xytext=(-A*1.22, 2*np.pi),
arrowprops=dict(arrowstyle='<->', color='k', lw=1.2))
ax1.text(-A*1.34, np.pi, '1个运动周期', fontsize=10.5, rotation=90, va='center', ha='center')
# x = Acosωt 带箭头标注
ax1.annotate('', xy=(xp, -0.22), xytext=(0, -0.22),
arrowprops=dict(arrowstyle='<->', color='k', lw=1))
ax1.text(xp/2, -0.42, r'$x=A\cos\ \omega t$', fontsize=12, ha='center')
# ---------- 2. 左下:旋转矢量参考圆(正圆 + x方向与上图对齐) ----------
ax2 = fig.add_axes([0.14, 0.13, 0.30, 0.36])
# 画圆
circle_t = np.linspace(0, 2*np.pi, 500)
ax2.plot(A*np.cos(circle_t), A*np.sin(circle_t), 'k', lw=1.2)
# 旋转矢量OP(带箭头)
ax2.annotate('', xy=(xp, yp), xytext=(0, 0),
arrowprops=dict(arrowstyle='->', color='k', lw=1.4))
ax2.plot(xp, yp, 'ko', markersize=4)
ax2.text(xp + 0.06, yp + 0.08, 'P', fontsize=11)
# 坐标轴
ax2.spines['left'].set_position(('data', 0))
ax2.spines['bottom'].set_position(('data', 0))
ax2.spines['top'].set_visible(False)
ax2.spines['right'].set_visible(False)
add_axis_arrow(ax2)
ax2.set_xticks([])
ax2.set_yticks([])
ax2.set_xlim(-A*1.35, A*1.35)
ax2.set_ylim(-A*1.35, A*1.35)
ax2.text(-0.1, -0.12, 'O', fontsize=11)
# 相位角圆弧
arc_t = np.linspace(0, theta_p, 100)
r_arc = 0.32
ax2.plot(r_arc*np.cos(arc_t), r_arc*np.sin(arc_t), 'k', lw=0.8)
ax2.text(0.38, 0.06, r'$\theta=\omega t$', fontsize=11)
# 角速度ω
ax2.annotate('', xy=(-0.18, 0.28), xytext=(0.18, 0.28),
arrowprops=dict(arrowstyle='->', color='k', lw=1, connectionstyle="arc3,rad=0.9"))
ax2.text(-0.24, 0.33, r'$\omega$', fontsize=11)
# 矢量A标注
ax2.text(xp/2 - 0.1, yp/2 + 0.08, 'A', fontsize=13)
# 竖直虚线:仅在圆形范围内,上下不超长,与上图精准对齐
ax2.plot([xp, xp], [-A*1.35, A*1.35], 'k--', lw=0.8, dashes=(5, 3))
# 水平虚线:仅在圆形范围内,左端不长,右端到圆边界
ax2.plot([-A*1.35, A*1.35], [yp, yp], 'k--', lw=0.8, dashes=(5, 3))
# ---------- 3. 中间竖排标注 y=Asinωt ----------
fig.text(0.462, 0.265, r'$y=A\sin\ \omega t$', fontsize=12, rotation=90, va='center')
# 竖直双向箭头
ax2.annotate('', xy=(1.58, yp), xytext=(1.58, 0),
xycoords='axes fraction', textcoords='axes fraction',
arrowprops=dict(arrowstyle='<->', color='k', lw=1))
# ---------- 4. 右下:y方向正弦波形(与左圆同高同底,y方向对齐) ----------
ax3 = fig.add_axes([0.51, 0.13, 0.42, 0.36])
ax3.plot(theta, y_sin, 'k', lw=1.2)
ax3.spines['left'].set_position(('data', 0))
ax3.spines['bottom'].set_position(('data', 0))
ax3.spines['top'].set_visible(False)
ax3.spines['right'].set_visible(False)
add_axis_arrow(ax3)
ax3.set_xticks([np.pi, 2*np.pi, 3*np.pi])
ax3.set_xticklabels([r'$\pi$', r'$2\pi$', r'$3\pi$'], fontsize=10)
ax3.set_yticks([])
ax3.set_xlabel(r'$\theta=\omega t$ 角位移', fontsize=11, x=0.93)
ax3.set_ylabel(r'$y$', fontsize=12, rotation=0, labelpad=18, y=0.9)
ax3.set_xlim(0, theta_max)
ax3.set_ylim(-A*1.35, A*1.35)
# P点
ax3.plot(theta_p, yp, 'ko', markersize=4)
ax3.text(theta_p + 0.08, yp + 0.06, 'P', fontsize=11)
# 水平虚线:从y轴向左延伸接入圆形,右端精准到P点
ax3.plot([0, theta_p], [yp, yp], 'k--', lw=0.8, dashes=(5, 3))
# 振幅A竖直箭头
ax3.annotate('', xy=(np.pi/2, A), xytext=(np.pi/2, 0),
arrowprops=dict(arrowstyle='<->', color='k', lw=1))
ax3.text(np.pi/2 + 0.12, A/2, 'A', fontsize=12, va='center')
# 1个运动周期
ax3.annotate('', xy=(0, -A*1.22), xytext=(2*np.pi, -A*1.22),
arrowprops=dict(arrowstyle='<->', color='k', lw=1.2))
ax3.text(np.pi, -A*1.38, '1个运动周期', fontsize=10.5, ha='center')
# ---------- 底部图题 ----------
fig.text(0.5, 0.04, '图 1.47 简谐运动-旋转矢量端点的投影', fontsize=13, ha='center')
plt.show()