如何实现支持指定顺时针/逆时针方向的角度lerp线性插值函数
可指定方向的角度线性插值实现逻辑
核心思路
基于0-360度的角度环规则,先对输入角度做归一化处理,再根据指定方向计算插值总步长,最后结合进度计算当前角度并归一化输出即可。
具体实现步骤
- 角度归一化:先将输入的起始角度
from和目标角度to统一转换到0~360度区间,避免输入负数或超出360的异常值影响计算。 - 计算指定方向的总插值步长:
- 顺时针方向:总步长为顺时针从
from走到to需要转动的角度,计算公式为delta_clockwise = (to - from + 360) % 360 - 逆时针方向:总步长为逆时针从
from走到to需要转动的角度,计算公式为delta_counter = (from - to + 360) % 360
- 顺时针方向:总步长为顺时针从
- 结合进度计算当前角度:
- 顺时针插值结果:
(from + delta_clockwise * progress) % 360 - 逆时针插值结果:
(from - delta_counter * progress + 360) % 360,额外加360是为了避免计算过程中出现负数,取模后自动回归0~360区间
- 顺时针插值结果:
代码实现(JavaScript)
// from = 插值起始角度 // to = 插值目标角度 // direction = 插值路径方向,可选值 'clockwise' / 'counter' // progress = 插值进度,取值范围0-1,0对应起始角度,1对应目标角度 function angle_lerp(from, to, direction, progress) { // 角度归一化到0-360度 const normalize = (angle) => (angle % 360 + 360) % 360; from = normalize(from); to = normalize(to); let result; if (direction === 'clockwise') { const delta = (to - from + 360) % 360; result = (from + delta * progress) % 360; } else if (direction === 'counter') { const delta = (from - to + 360) % 360; result = (from - delta * progress + 360) % 360; } // 可选:处理浮点数精度问题,保留3位小数 return Math.round(result * 1000) / 1000; }
示例验证
可代入所有给出的用例验证,计算结果完全匹配预期:
angle_lerp(350,10,'clockwise',0.5)→ (350 + 20*0.5) % 360 = 0,符合预期angle_lerp(350,10,'counter',0.5)→ (350 - 340*0.5) = 180,符合预期angle_lerp(45,0,'clockwise',0.1)→ (45 + 315*0.1) = 76.5,符合预期angle_lerp(45,0,'counter',0.1)→ (45 - 45*0.1) = 40.5,符合预期
内容的提问来源于stack exchange,提问作者Mads Lee Jensen
相关产品推荐
相关产品推荐

