算法与数据结构 / 动画引擎原理 · 从插值到播放控制 / 三角函数:正弦波与圆周运动 待审核 18 / 47
sin/cos · 单位圆 · 李萨如

三角函数:正弦波与圆周运动

噪声用随机信号驱动无尽的微动;三角函数给出另一类不收敛、永不停止的运动——规则的周期。一个 Math.sin(t) 就是最简单的周期性「时间到值」:输入均匀流逝的时间,输出一条在 [1,1][-1, 1] 之间平滑往返、永远重复的曲线。

1 · 三个旋钮

通式是 Asin(ωt+φ)A \sin(\omega t + \varphi),三个参数各管一件互不重叠的事。

振幅 AA 是纵向缩放,把 [1,1][-1, 1] 拉伸到 [A,A][-A, A],决定往返幅度而不改变节奏。频率 ff 是横向缩放,每秒完成 ff 个完整周期,周期 T=1/fT = 1/f;角频率 ω=2πf\omega = 2\pi f 是它的弧度表述。相位 φ\varphi 是横向平移,决定 t=0t = 0 时停在周期的哪一点。

图 1-1 · 一维正弦振荡与它的滚动波形。可分别调三个参数,读数同步给出周期与角频率。

2 · 圆周运动就是两路正弦

让角度 θ=ωt\theta = \omega t 随时间匀速增长,点 (Rcosθ, Rsinθ)(R\cos\theta,\ R\sin\theta) 就沿半径 RR 的圆匀速绕行。盯着整个点看是圆周运动——行星轨道、loading 转圈、时钟指针;只盯一个坐标看,那一维的来回就是纯正弦振荡。

余弦不过是相位超前 90°90° 的正弦(cosθ=sin(θ+π/2)\cos\theta = \sin(\theta + \pi/2)),所以 xxyy 两路天生差四分之一周期。

图 2-1 · 单位圆上的点与它在两个轴上的投影展开成的波。可调转速或暂停,观察半径线、垂足与波形右端的对应关系。

3 · 行波是相位交错

给相邻元素一个固定的相位差 Δφ\Delta\varphi,某一时刻它们就停在周期的不同位置,连起来便是一条沿排列方向行进的波。相位差为 0 时所有元素同相,整排一起上下,看不出波。

相位差与时间延迟可以互换:Δφ\Delta\varphi 度等价于延迟 Δφ360T\frac{\Delta\varphi}{360} T。这与关键帧编排里给一组元素各加一点 delay 的 stagger 是同一回事,只是改用连续相位表达,运动天然循环、无始无终。

图 3-1 · 13 个同频同幅、相位逐格错开的元素。读数给出相位差换算成的每格时间延迟。

4 · 李萨如曲线

xxyy 不再同步,而是各自以频率 aabb 振荡、相差 δ\deltaa:ba : b 是简单整数比时,曲线在有限时间内闭合成稳定花纹;比值越接近无理数,图案越久才重复。

图 4-1 · 两轴频率比与相位差决定的李萨如图案。可调 a、b 与 δ,1:1 时随 δ 在直线、椭圆、圆之间变化。

注 · 这个 lab 的曲线用 computed 缓存,只在 aabbδ\delta 变化时重算那 481 个采样点;随时间移动的只有一个小圆点。原先的实现靠一个 lastKey 字符串手动比对参数是否变化——迁到 Vue 后这层缓存由响应式系统免费提供,那段脏检查代码直接删掉了。

const TAU = Math.PI * 2;

// 单位圆: 角度 θ 随时间匀速增长, 点的坐标就是 (cos θ, sin θ)
const theta = TAU * freq * t;            // ω = 2π·freq
const x = R * Math.cos(theta);           // 水平投影 → 余弦
const y = R * Math.sin(theta);           // 垂直投影 → 正弦

// 只取一个分量 → 一维振荡 (脉动 / 上下浮动)
const bob = amplitude * Math.sin(TAU * freq * t + phase);

// 一排元素相位各错开 Δφ → 行波
dots.forEach((el, i) => {
  const v = amplitude * Math.sin(TAU * freq * t - i * dPhi);
  el.style.transform = `translateY(${v}px)`;
});

// 两轴各跑一个正弦, 频率比 a:b → 李萨如曲线
const px = Math.sin(a * u + delta);
const py = Math.sin(b * u);

至此「不演化到目标」的两类运动都齐了:噪声给出随机而有机的微动,三角函数给出规则而精确的周期。需要演化到固定目标的塑形见缓动,交给物理系统自行收敛的见弹簧