我有一个标准化的 2D 向量,用于旋转其他 2D 向量。在一种情况下,它表示“自旋”(或“角动量”)并用于旋转简单多边形的“方向”。我的向量类包含这个方法:
rotateByXY(x, y) {
let rotX = x * this.x - y * this.y;
let rotY = y * this.x + x * this.y;
this.x = rotX;
this.y = rotY;
}
到目前为止,这一切都很有效,并且没有使用任何三角函数。
但是,我希望“旋转”随着时间的推移而减弱。这意味着旋转角度应趋向于零。在这里,我不知道如何在没有像这样昂贵的三角调用的情况下做到这一点:
let angle = Math.atan2(spin.y, spin.x);
angle *= SPIN_DECAY;
spin = new Vector2D(Math.cos(angle), Math.sin(angle));
有更好/更快的方法来完成这个任务吗?
如果确实是三角函数拖慢了计算速度,您可以尝试用它们的泰勒展开式来近似它们。
对于
x
接近于零,以下恒等式成立:
cos(x) = 1 - (x^2)/2! + (x^4)/4! - (x^6)/6! + ...
sin(x) = x - (x^3)/3! + (x^5)/5! - (x^7)/7! + ...
atan(x) = x - (x^3)/3 + (x^5)/5 - (x^7)/7 + ...
根据您的应用所需的精确度,您可以修剪系列。例如,
cos(x) = 1 - (x^2)/2
有
x^3
量级的错误(实际上是 x^4
,因为 x^3
的项无论如何都是零)。
但是,我认为这不会解决您的问题:
atan
的实际实现很可能已经使用了相同的技巧,该技巧是由在加速这些事情方面拥有丰富经验的人编写的。所以这并不是一个真正正确的答案,但我希望它仍然有用。
如果你的自旋向量被这样命名并且在帧之间持续存在,你可以通过以下方式衰减自旋:
spin = vec2.normalize(spin + decay_rate * vec2(1.0, 0.0));
其中衰减率是自上次更新以来经过的时间的函数。