J S*_*gue 8 rotation quaternions three.js
新手stackoverflow参与者,新手3D程序员,远离数学wiz ...所以我会尝试尽可能清楚地构建这个问题,希望它有意义,并希望得到一个不是一英里的答案.
我使用three.js编写了一个非常酷的应用程序,让用户可以飞过3D空间并探索太阳系.飞行模型松散地基于three.js包中的Fly.Controller示例/扩展,它教会我使用四元数来保持所有轴旋转相对于彼此合理.飞行部分都很棒.
这是我的困境:当使用四元数时,我如何推断出"正常"(我不知道还有什么称之为)旋转值来确定我面临的方向?使用四元数时,相机对象内的"旋转"结构保持为0,0,0.因此,虽然我可以在任何角度自由地飞越太空,但我无法弄清楚如何确定我实际面对的方向.是否有内置的three.js功能,或其他简单的方法来转换它?
我在网上发现了一些类似的,令人困惑的指针,但我无法解读并在三个.js中使用.谢谢.
这是一个很好的问题。
当对象处于其默认方向时,可以认为它是在看其内部的正 z 轴方向。(相机除外,它正朝着其内部负z 轴的方向看。)
因此,当对象旋转时,您可以通过将对象的四元数应用于指向正 z 轴方向(相机的负 z 轴)的单位向量来获得对象面向的方向。
var zVec = new THREE.Vector3( 0, 0, 1 );
zVec.applyQuaternion( object.quaternion );
Run Code Online (Sandbox Code Playgroud)
这将返回一个单位向量,指向对象“面向”的方向。
如果对象是另一个旋转对象的子对象,则情况会更复杂。
编辑:为 r.58 更新。谢谢@eshan。
感谢您的快速回复 - 这并不完全是我想要的,但我可能不知道如何清楚地提出问题。我的具体用例是,我想绘制一个 2D 地图来表示 3D 场景中所有对象的相对位置,但我想根据 3D 场景中相机的偏航旋转地图中的对象 -所以我需要知道基于四元数的相机所面对的“角度”,以便我可以相应地偏移地图上 2D 对象的旋转。看起来效果很好。我只是希望不必有那么多计算,但至少 Javascript 很快。
// Pass the obj.quaternion that you want to convert here:
//*********************************************************
function quatToEuler (q1) {
var pitchYawRoll = new THREE.Vector3();
sqw = q1.w*q1.w;
sqx = q1.x*q1.x;
sqy = q1.y*q1.y;
sqz = q1.z*q1.z;
unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
test = q1.x*q1.y + q1.z*q1.w;
if (test > 0.499*unit) { // singularity at north pole
heading = 2 * Math.atan2(q1.x,q1.w);
attitude = Math.PI/2;
bank = 0;
return;
}
if (test < -0.499*unit) { // singularity at south pole
heading = -2 * Math.atan2(q1.x,q1.w);
attitude = -Math.PI/2;
bank = 0;
return;
}
else {
heading = Math.atan2(2*q1.y*q1.w-2*q1.x*q1.z , sqx - sqy - sqz + sqw);
attitude = Math.asin(2*test/unit);
bank = Math.atan2(2*q1.x*q1.w-2*q1.y*q1.z , -sqx + sqy - sqz + sqw)
}
pitchYawRoll.z = Math.floor(attitude * 1000) / 1000;
pitchYawRoll.y = Math.floor(heading * 1000) / 1000;
pitchYawRoll.x = Math.floor(bank * 1000) / 1000;
return pitchYawRoll;
}
// Then, if I want the specific yaw (rotation around y), I pass the results of
// pitchYawRoll.y into the following to get back the angle in radians which is
// what can be set to the object's rotation.
//*********************************************************
function eulerToAngle(rot) {
var ca = 0;
if (rot > 0)
{ ca = (Math.PI*2) - rot; }
else
{ ca = -rot }
return (ca / ((Math.PI*2)/360)); // camera angle radians converted to degrees
}
Run Code Online (Sandbox Code Playgroud)