转换偏航,俯仰和滚动到X,Y,Z矢量在世界坐标 [英] Convert yaw, pitch AND roll to x,y,z vector in world coordinates
问题描述
我工作的一些简单的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屋!