如何推导出“标准"使用四元数时来自three.js的旋转? [英] How to derive "standard" rotations from three.js when using quaternions?

查看:38
本文介绍了如何推导出“标准"使用四元数时来自three.js的旋转?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

stackoverflow 新手参与者,3D 新手程序员,并且远离数学奇才......所以我会尽可能清楚地描述这个问题,希望它有道理,并希望得到一个不超过一英里的答案我的头.

Newbie stackoverflow participant, newbie 3D programmer, and far from a math wiz... so I'll try to frame this question as clearly as I can, hoping it makes sense, and hoping for an answer that's not a mile over my head.

我使用three.js 编写了一个非常酷的应用程序,让用户可以在3D 空间中飞行并探索太阳系.飞行模型松散地基于 Three.js 包中的 Fly.Controller 示例/扩展,它教会我使用四元数来保持所有相对于彼此的轴旋转合理.飞行部分都很棒.

I've written a very cool app using three.js that lets the user fly through 3D space and explore a solar system. The flight model is loosely based on the Fly.Controller example/extension in the three.js package which taught me to use quaternions for keeping all the axis rotations sensible relative to each other. The flying part all works great.

这是我的困境:当使用四元数时,我如何推导出正常"(我不知道还能叫它什么)旋转值来确定我面对的方向?使用四元数时,相机对象内部的旋转"结构保持在 0,0,0.所以,虽然我可以以任何角度自由地在太空中飞行,但我无法弄清楚如何确定我实际面对的方向.是否有内置的three.js 函数或其他简单的方法来转换它?

Here's my dilemma: When using quaternions, how do I deduce the "normal" (I don't know what else to call it) rotation values to determine which direction I am facing? When using quaternions, the "rotation" structure inside the camera object stays at 0,0,0. So, while I can freely fly through space at any angle, I can't figure out how to determine what direction I'm actually facing. Is there a built in three.js function, or other easy way to convert this?

我在网络上发现了一些类似的、令人困惑的指针,但我无法在three.js 中破译和使用它们.谢谢.

I've found some similar, confusing, pointers on the web, but nothing I can decipher and put to use in three.js. Thanks.

推荐答案

感谢您的快速回复 - 这不是我想要的,但我可能不知道如何清楚地提出问题.我的具体用例是我想绘制一个 2D 地图来表示 3D 场景中所有对象的相对位置,但我想根据 3D 场景中相机的偏航旋转地图中的对象 -所以我需要知道基于四元数的相机所面对的角度",以便我可以相应地偏移地图上 2D 对象的旋转.似乎工作得很好.我只是希望不必有这么多计算,但至少 Javascript 很快.

Thanks for the quick response - it wasn't exactly what I was looking for, but I probably didn't know how to ask the question clearly. My specific use-case was that I wanted to draw a 2D map the represented the relative positions of all the objects in my 3D scene, but I wanted to rotate the objects in the map based on the yaw of the camera in the 3D scene - so I needed to know the "angle" that the quaternion-based camera was facing so that I could offset the rotations of the 2D objects on the map accordingly. Seems to work pretty well. I just wish there didn't have to be so many calculations, but at least Javascript is fast.

// 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
}

这篇关于如何推导出“标准"使用四元数时来自three.js的旋转?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆