四元数的增量应用

时间:2017-03-03 15:25:47

标签: javascript three.js game-engine quaternions cannon.js

我想弄清楚如何以多个增量应用旋转, 到一个动态的方向(即我不能使用slerp )。

详细信息: 我在3D空间中有一个对象,其方向可由四元数Q描述。 当此对象旋转时,它会从另一台服务器接收定期更新, 它定义了真正的方向。例如,在时间t1,对象的方向 已Q1,并收到正确方向应为K1的更新。

我不能简单地将Q1替换为K1,因为视觉效果不会很顺利, 所以我宁愿在一系列10个步骤中逐渐从Q1K1进行纠正。 另外,我不能使用slerp,因为Q1不是静态的。相反,我想 派生增量修正,我称之为dK,直到下一次服务器更新 到达。

现在我以下列方式派生dK

  1. delK = K1 * Q1.conjugate()
  2. dk = delK / 10
  3. 第2步实际发生的是我将delK转换为轴+角度表示, 然后将角度除以10.然后我转换回四元数。

    问题1:上述方法在数学上是否正确?

    问题2:我看到的情况是dk不是一个小的修正,可能会向相反的方向旋转。可能导致这种情况的原因。

    这是用于在JavaScript incheon中实现客户端预测。

1 个答案:

答案 0 :(得分:1)

您可以将“十步走”的方法替换为“坚定的”解决方案:

Q = slerp(Q, Q1, 1 - Math.pow(smoothingRatio, deltaTime)

此解决方案将以帧速率独立的方式将Q推向Q1,并使Q1是动态的。插值1秒后,到Q1的“距离”的剩余分数将为smoothingRatio。了解更多here

如果每次更新旋转的角度大于180度,则最接近的旋转轴将不同于服务器上的旋转轴。天真的解决方案是更频繁地发送更新,或者限制对象的旋转速度。

如果要随更新一起发送角速度,则可以进行更好的客户端预测,并且可以解决“相反方向”的问题。这个想法是使四元数沿最后一次更新发送的角速度旋转。

Cannon.js中的Quaternion#integrate函数实现了四元数集成,您可以使用它。

// Rotate Q along the angular velocity provided in the last update
Q = Q.integrate(angularVelocity, deltaTime, Vec3.ZERO);