将欧拉角度旋转转换为轴+角度

时间:2016-09-30 02:42:17

标签: opengl 3d openscenegraph babylonjs

我的目标是允许用户上传3D模型并使用他们的网络浏览器定位它们。要做到这一点,我正在使用BabylonJS - &它的工作正常。之后,我希望我的用户能够在本机应用程序中查看相同的模型,其定位与使用Web浏览器设置的相同。我用于本机应用程序的框架是OpenSceneGraph(OSG)。我遇到的问题是我无法正常工作,因此OpenSceneGraph正确地反映了BabylonJS中发生的事情。

我在BabylonJS中使用欧拉角 - 因为它们很容易让网站用户理解(例如围绕X轴旋转90度,围绕Y旋转180度,绕Z旋转0度;例如模型.rotation = new BABYLON.Vec3(90,180,0))。然而,OSG使用OpenGL glrotate()函数,该函数需要旋转轴和旋转角度。要做到这一点,我使用BabylonJS从欧拉角创造一个四元数;然后使用我在此页面上基于Java示例编写的函数:

http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm

function getAxisAngle(){
    var q = BABYLON.Quaternion.RotationYawPitchRoll(m.rotation.y,     m.rotation.x, m.rotation.z),s,r={};
    /*Convert quaternion to axis+angle*/
    if(q.w > 1){
        q = q.normalise();
    }
    r.angle = BABYLON.Tools.ToDegrees(2 * Math.acos(q.w));
    s = Math.sqrt(1-q.w*q.w);
    if(s < 0.001){
       r.ax = q.x;
       r.ay = q.y;
       r.az = q.z;
    }else{
       r.ax = q.x / s;
       r.ay = q.y / s; 
       r.az = q.z / s;
    }
    return r;
}

我意识到BJS和OSG之间的根本区别在于BJS是左手坐标系; OSG是右撇子;所以我通过将面部绕组设置为顺时针方向使OSG左手;并将我的模型的z轴缩放-1。

如果我一次隔离1个轴,它在基本级别工作;例如如果我只围绕y轴旋转;并且不要绕任何其他轴旋转 - 它看起来很好。但是,如果我尝试同时组合两个或三个欧拉角;我无法在OSG中看到相同的内容。

我已经读过不建议使用欧拉角;部分原因是旋转应用于每个轴的顺序很重要。这是可能的原因吗?

1 个答案:

答案 0 :(得分:0)

在我看来,不要试图让左撇子OSG,而是翻译你的旋转角度的“逻辑”含义,并按照它的使用方式将它们应用于OSG。

将加载的模型放在osg :: PositionAttitudeTransform(或MatrixTransform)下,然后通过连接2个四元数来计算应用于它的正确旋转(姿态),以便向用户显示2个旋转角度。
例如,如果您将“投球”视为围绕X轴的旋转,并将“标题”视为Y,请执行以下操作:

osg::Quat attitude = osg::Quat(pitchAngle, osg::X_AXIS) * osg::Quat(headAngle, osg::Y_AXIS);
transform->setAttitude(attitude);

您可能必须反转角度符号才能获得正确的结果(从左手到右手)。