转换偏航,俯仰和滚动到X,Y,Z矢量在世界坐标 [英] Convert yaw, pitch AND roll to x,y,z vector in world coordinates

查看:1532
本文介绍了转换偏航,俯仰和滚动到X,Y,Z矢量在世界坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一些简单的3D图形OpenGL中(Java LWGJL),而我试图找出如何偏航,俯仰和滚转转化为我的运动矢量的x,y和z分量。我知道如何与刚刚俯仰和偏航做到这一点(因为这里解释),但我还没有发现任何的解释如何滚动融入这个公式。

I'm working on some simple 3d graphics in OpenGL (java LWGJL), and I'm trying to figure out how to convert yaw, pitch and roll to the x, y and z components of my movement Vector. I know how to do this with just pitch and yaw (as explained here), but I haven't found anything the explains how to integrate roll into this formula.

据我所知,偏航和变桨是所有需要,以确定在三维空间中的向量,但我还需要滚动在这种情况下。我有一个绑定到相对于相机不同的动作的基本WASD配置( A 是本地的左侧,<大骨节病>是W 是本土前锋,<大骨节病> SPACE 是键当地时),所以卷会影响摄像机移动(如pressing <大骨节病>ð与PI / 2(默认一卷)移动相机右侧(世界coords)使用,但pressing <大骨节病>ð与PI一卷移动相机在世界coords)使用)。

I am aware that yaw and pitch are all that is needed to define a vector in 3d space, but I also need roll in this instance. I have keys bound to different movements relative to the camera in a basic WASD configuration (A is local left, W is local forward, SPACE is local up), so the roll affects how the camera moves (eg pressing D with a roll of pi/2 (the default) moves the camera right (in world coords), but pressing D with a roll of pi moves the camera up in world coords)).

这里的code我到目前为止有:

Here's the code I have so far:

//b = back
//f = forward
//r = right
//l = left
//u = up
//d = down

    private void move()
    {
        double dX = 0, dY = 0, dZ = 0;


        if (f ^ b)
        {
            dZ += cos(yaw) * cos(pitch) * (b ? 1 : -1);
            dX += sin(yaw) * cos(pitch) * (b ? 1 : -1);
            dY += -sin(pitch) * (b ? 1 : -1);
        }

        if (l ^ r)
        {
            dZ += sin(yaw) * sin(roll) * (l ? 1 : -1);
            dX += cos(yaw) * - sin(roll) * (l ? 1 : -1);
            dY += cos(roll) * (l ? 1 : -1);
        }

        if (u ^ d) //this part is particularly screwed up
        {
            dZ += sin(pitch) * sin(roll) * (u ? 1 : -1);
            dX += cos(roll) * (u ? 1 : -1);
            dY += cos(pitch) * sin(roll) * (u ? 1 : -1);
        }



        motion.x = (float) dX;
        motion.y = (float) dY;
        motion.z = (float) dZ;

        if (motion.length() != 0)
        {
            motion.normalise();
            motion.scale(2);
        }

        x += motion.x;
        y += motion.y;
        z += motion.z;

这工作了几转,但对许多人来说,会产生不正确的结果。

This works for a few rotations, but for many it produces incorrect results.

所以,问题是:

如何修改我的code,使其成功地计算出X,Y,和我根据我所希望的方向运动矢量的z分量(什么键是pressed),占我偏航,变桨,的卷?

How do I modify my code such that it successfully calculates the x, y, and z components of my motion vector based upon my desired direction (what key is pressed), accounting for my yaw, pitch, AND roll?

我很好使用的原始触发(因为我试图做),涉及矩阵,或pretty的任何东西的解决方案。

I'm fine with using raw trig (as I am attempting to do), a solution involving matrices, or pretty much anything.

编辑:

请不要只是链接到欧拉角维基百科的文章回答。我读过它,我没有一个足够强大的背景,数学,了解如何将其应用到我的情况。

Please don't answer by just linking to the Wikipedia article on Euler Angles. I've read it and I don't have a strong enough background in math to understand how to apply it to my situation.

编辑#2:

我只使用欧拉角来存储我的方位之间的重新取向相机。对于实际的相机操作,我用旋转矩阵。如果需要,我可以删除欧拉角,只是采用了矩阵。所有的事情是,我可以从我的方向转换为矢量。

I'm only using Euler angles to store my orientation in between re-orienting the camera. For the actual camera manipulations, I use rotational matrices. If needed, I can drop the euler angles and just use a matrix. All that matters is that I can convert from my orientation to a vector.

编辑#3:

实测通过我的旋转矩阵相乘我的前向向量的溶液如在所描述的 注释:

Found a solution by multiplying my forward vector by my rotation matrix as described in the comments:

//b = back
//f = forward
//r = right
//l = left
//u = up
//d = down

private Vector3f motion;

protected void calcMotion()
{
    //1 for positive motion along the axis, -1 for negative motion, 0 for no motion
    motion.x = r&&!l ? -1 : l ? 1 : 0; 
    motion.y = u&&!d ? 1 : d ? -1 : 0;
    motion.z = f&&!b ? 1 : b ? -1 : 0;

    if (motion.length() == 0)
    {
        return;         
    }

    motion.normalise();

    //transform.getRotation() returns a Matrix3f containing the current orientation
    Matrix3f.transform(transform.getRotation(), motion, motion);
}

不过具有这个,虽然。

推荐答案

我不认为你会找到一个答案是纯粹的触发。没有一个优雅的,反正。

I don't think you're going to find an answer that's pure trig. Not an elegant one, anyway.

欧拉角(俯仰/偏航/卷)都没有合适的工具,这项工作。万向接头锁将是一个问题,以及操作的顺序的模糊性。

Euler angles(Pitch/Yaw/Roll) are not the right tool for this job. Gimble-lock will be a problem, as well as the ambiguity of the order of operations.

我建议你保存对象的当前旋转状态在任何一个矩阵或四元数。仅使用欧拉角比较小的增量。

I suggest storing your objects' current rotational state in either a Matrix or a Quaternion. Only use Euler angles for relatively small deltas.

这篇关于转换偏航,俯仰和滚动到X,Y,Z矢量在世界坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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