Dim*_*ims 5 java 3d rotation quaternions jmonkeyengine
四元数不仅可以描述旋转,还可以描述方向,即从初始(零)位置旋转.
我希望模拟从一个方向到另一个方向的平滑旋转.余计算开始定向startOrientation和结束定向endOrientation,并希望描述中间取向为startOrientation*(1-argument) + endOrientation*argument同时argument从变化0到1.
猴子引擎更新功能的代码如下:
@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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
预计余弦公式可以在开始时模拟平滑加速,在结束时减速.
代码可以工作但不是预期的:平滑的旋转开始并很久以前完成fraction并且argument值达到1,我不明白,为什么.
为什么orientation价值endOrientation如此之快?
您已经说过,您的情况startOrientation正在被修改。然而; 以下内容仍然正确
该方法slerp包含在 Quaternion 类中,用于实现以下目的:在两个旋转之间进行插值。
假设我们有两个四元数startOrientation,并且endOrientation我们想要它们之间的点interpolation,那么我们使用以下代码在它们之间进行插值:
float interpolation=0.2f;
Quaternion result=new Quaternion();
result.slerp(startOrientation, endOrientation, interpolation);
Run Code Online (Sandbox Code Playgroud)
四元数内部有些复杂,并且遵循与向量不同的数学规则。您已调用multiply(float scalar)四元数上的方法。内部看起来像这样
public QuaternionD mult(float scalar) {
return new QuaternionD(scalar * x, scalar * y, scalar * z, scalar * w);
}
Run Code Online (Sandbox Code Playgroud)
所以它只是对所有元素进行简单的乘法。这明确不会返回乘以大小的旋转。scalar事实上,这样的四元数根本不再代表有效的旋转,因为它不再是单位四元数。如果您调用normalise这个四元数,它将立即撤消缩放。我确信 Quaternion#multiply(float scalar)有一些用处,但我还没有找到它们。
“添加”四元数也不会合并它们。事实上,你将它们相乘。因此,组合 q1、q2、q3 将得到如下结果:
Quaternion q0 = q1.mult(q2).mult(q3);
Run Code Online (Sandbox Code Playgroud)
备忘单对此非常有用
在您的情况下,您的插值公式几乎但不完全正确。这显示了使用两种方法在 2 个四元数之间插值的偏航图
