四元数平滑旋转

时间:2014-06-19 16:55:26

标签: java 3d rotation quaternions jmonkeyengine

四元数不仅可以描述旋转,还可以描述方向,即从初始(零)位置旋转。

我希望模拟从一个方向到另一个方向的平滑旋转。我计算了起始方向startOrientation和结束方向endOrientation,并希望将startOrientation*(1-argument) + endOrientation*argument描述为argument01更改为@Override public void simpleUpdate(float tpf) { if( endOrientation != null ) { if( !started ) { started = true; } else { fraction += tpf * speed; argument = (float) ((1 - Math.cos(fraction * Math.PI)) / 2); orientation = startOrientation.mult(1-argument).add(endOrientation.mult(argument)); //orientation = startOrientation.mult(1-fraction).add(endOrientation.mult(fraction)); log.debug("tpf = {}, fraction = {}, argument = {}", tpf, fraction, argument); //log.debug("orientation = {}", orientation); rootNode.setLocalRotation(orientation); if( fraction >= 1 ) { rootNode.setLocalRotation(endOrientation); log.debug("Stopped rotating"); startOrientation = endOrientation = null; fraction = 0; started = false; } } } }

猴子引擎更新功能的代码如下:

fraction

预计余弦公式可以在开始时模拟平滑加速,在结束时减速。

代码有效但不符合预期:平滑旋转开始并在argument1值达到orientation之前很久结束,我不明白,为什么。

为什么endOrientation值如此快地达到{{1}}?

1 个答案:

答案 0 :(得分:4)

您已声明在您的情况下startOrientation正在被修改。然而;以下是真的

四元数之间的插值

为此目的,方法slerp包含在Quaternion类中:interpolating between two rotations.

假设我们有两个四元数startOrientationendOrientation,我们希望它们之间有点interpolation,然后我们使用以下代码进行插值:

float interpolation=0.2f;
Quaternion result=new Quaternion();
result.slerp(startOrientation, endOrientation, interpolation);

为什么你的方法可能很危险

四元数在内部有些复杂,并且遵循一些不同的数学规则来表示向量。您已在四元数上调用multiply(float scalar)方法。在内部,这看起来像这样

public QuaternionD mult(float scalar) {
        return new QuaternionD(scalar * x, scalar * y, scalar * z, scalar * w);
}

所以它只是对所有元素进行简单的乘法运算。这显然不会返回大小为scalar倍的轮换。事实上,这样的四元数不再代表有效的旋转,因为它不再是单位四元数。如果您在此quaterion上调用normalise,它将立即撤消缩放。我确定Quaternion#multiply(float scalar)有一些用处,但我还没找到它们。

同样的情况是"添加"四元数不会将它们组合在一起。事实上,你将它们相乘。因此,结合q1然后q2然后q3将如下实现:

Quaternion q0 = q1.mult(q2).mult(q3);

cheat sheet对此

非常有用

公式与slerp比较

在你的情况下,你的插值公式几乎但不太正确。这显示了使用两种方法在两个四元数之间插值的偏航图

enter image description here