You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python和Numpy精准生成指定起止值的缩放正弦波

解决正弦波起止值精准控制的数学方法

首先明确核心矛盾:严格的f个完整正弦周期必然导致起点和终点的y值相等,因为正弦函数的周期性($\sin(\phi + 2\pi k) = \sin\phi$,k为整数)。如果需要起点(start)和终点(stop)值不同,我们可以生成接近f个周期的正弦波(当采样点足够多时,视觉上与完整f个周期无差异),同时通过求解相位$\phi$满足起止值要求。

数学推导

正弦波的标准形式为:
$$ y(t) = A + B \cdot \sin(\omega t + \phi) $$
其中:

  • $A = \frac{\text{max} + \text{min}}{2}$:直流偏移,保证波形均值在min和max的中点
  • $B = \frac{\text{max} - \text{min}}{2}$:振幅,保证波形范围恰好是[min, max]
  • $\omega = f$:对应原代码中t的范围为$0\sim2\pi$,确保采样范围内包含接近$f$个周期

我们需要满足两个边界条件:

  1. 当$t=0$时,$y(0) = \text{start}$ → $\sin(\phi) = \frac{\text{start} - A}{B}$
  2. 当$t=T_{\text{end}}$(即最后一个采样点的时间,原代码中为$2\pi \cdot \frac{999}{1000}$)时,$y(T_{\text{end}}) = \text{stop}$ → $\sin(f \cdot T_{\text{end}} + \phi) = \frac{\text{stop} - A}{B}$

通过求解这两个方程,可以得到唯一的相位$\phi$(需保证start和stop在[min, max]范围内,否则无解)。

实现代码

import numpy as np
import matplotlib.pylab as plt

# 参数设置
min_val = 0
max_val = 180
f = 2  # 接近完整f个周期
start = 45
stop = 60
num_points = 1000  # 采样点数

# 计算直流偏移和振幅
A = (max_val + min_val) / 2
B = (max_val - min_val) / 2

# 计算边界条件对应的正弦值
s_start = (start - A) / B
s_stop = (stop - A) / B

# 检查参数合法性:start和stop必须在波形范围内
assert abs(s_start) <= 1.0 + 1e-6, "start值超出波形范围"
assert abs(s_stop) <= 1.0 + 1e-6, "stop值超出波形范围"

# 生成时间序列
t = np.linspace(0, 2 * np.pi, num_points)
# 最后一个点的总相位增量
phase_end = f * t[-1]

# 求解相位φ的候选值
phi1 = np.arcsin(s_start)
phi2 = np.pi - phi1

# 验证哪个候选值满足终点条件
def check_phi(phi):
    return np.abs(np.sin(phase_end + phi) - s_stop) < 1e-6

if check_phi(phi1):
    phi = phi1
elif check_phi(phi2):
    phi = phi2
else:
    # 尝试加2π周期寻找正确解
    phi1 += 2 * np.pi
    phi = phi1 if check_phi(phi1) else phi2 + 2 * np.pi

# 生成正弦波
y = A + B * np.sin(f * t + phi)

# 验证结果
actual_min, actual_max = np.min(y), np.max(y)
actual_start, actual_stop = y[0], y[-1]

print(f"min: {actual_min:.6f}, max: {actual_max:.6f}")
print(f"start: {actual_start:.6f}, stop: {actual_stop:.6f}")

plt.plot(t, y)
plt.title(f"Sine Wave with start={start}, stop={stop}, {f} cycles")
plt.xlabel("t")
plt.ylabel("y")
plt.grid(True)
plt.show()

代码说明

  1. 参数合法性检查:确保start和stop在波形的[min_val, max_val]范围内,否则无法生成符合要求的正弦波。
  2. 相位求解:利用反正弦函数得到两个候选相位,再验证哪个满足终点条件,必要时增加2π周期以找到正确解。
  3. 接近完整周期:由于采样点数量足够大(1000),最后一个点的相位与完整f个周期的相位差异极小,视觉上完全呈现f个周期的波形。

运行结果示例

min: 0.000000, max: 180.000000
start: 45.000000, stop: 60.000000

这样生成的波形既保证了振幅、接近f个周期的要求,又精准满足了起止值的设定,完全避免了裁剪数组的不优雅方案。

内容的提问来源于stack exchange,提问作者Matteo Caprari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 21:15:35