如何从XYZ旋转中找到四元数的向量

我正在OpenGL上创建一个非常简单的项目,并且我被困在旋转中。 我试图在所有3个轴上单独旋转一个对象:X,Y和Z.由于围绕一个轴旋转后出现“万向节锁定”问题,我已经过了不眠之夜。 然后我知道四元数会解决我的问题。 我研究过四元数并实现了它,但是我还没有能够将旋转转换为四元数。 例如,如果我想围绕Z轴旋转90度,则只需为我的四元数创建{0,0,1}矢量,然后使用此处的代码围绕该轴旋转90度:

http://iphonedevelopment.blogspot.com/2009/06/opengl-es-from-ground-up-part-7_04.html(朝底部最复杂的矩阵)

对于一个矢量来说没关系,但是,比如说,我首先要绕Z旋转90度,然后绕X旋转90度(就像一个例子)。 我需要传入什么向量? 我如何计算这个向量。 我对矩阵和三角学不太了解(我知道基本知识和一般规则,但我只是不是专家),但我需要完成这些。 有很多关于四元数的教程,但我似乎没有理解(或者他们不回答我的问题)。 我只需要学习构建围绕多个轴组合的旋转矢量。

更新 :我发现这个关于四元数的好页面,并决定以这种方式实现它们:http://www.cprogramming.com/tutorial/3d/quaternions.html

这是我的四元数乘法的代码:

void cube::quatmul(float* q1, float* q2, float* resultRef){
 float w = q1[0]*q2[0] - q1[1]*q2[1] - q1[2]*q2[2] - q1[3]*q2[3];
 float x = q1[0]*q2[1] + q1[1]*q2[0] + q1[2]*q2[3] - q1[3]*q2[2];
 float y = q1[0]*q2[2] - q1[1]*q2[3] + q1[2]*q2[0] + q1[3]*q2[1];
 float z = q1[0]*q2[3] + q1[1]*q2[2] - q1[2]*q2[1] + q1[3]*q2[0];

 resultRef[0] = w;
 resultRef[1] = x;
 resultRef[2] = y;
 resultRef[3] = z;
}

这是我的四元数应用于我的模型视图矩阵(我有一个tmodelview变量,是我的目标模型视图矩阵)的代码:

void cube::applyquat(){
 float& x = quaternion[1];
 float& y = quaternion[2];
 float& z = quaternion[3];
 float& w = quaternion[0];
 float magnitude = sqrtf(w * w + x * x + y * y + z * z);
 if(magnitude == 0){
     x = 1;
     w = y = z = 0;
 }else
 if(magnitude != 1){
     x /= magnitude;
     y /= magnitude;
     z /= magnitude;
     w /= magnitude;
  }

 tmodelview[0] = 1 - (2 * y * y) - (2 * z * z);
 tmodelview[1] = 2 * x * y + 2 * w * z;
 tmodelview[2] = 2 * x * z - 2 * w * y;
 tmodelview[3] = 0; 

 tmodelview[4] = 2 * x * y - 2 * w * z;
 tmodelview[5] = 1 - (2 * x * x) - (2 * z * z);
 tmodelview[6] = 2 * y * z - 2 * w * x;
 tmodelview[7] = 0;

 tmodelview[8] = 2 * x * z + 2 * w * y;
 tmodelview[9] = 2 * y * z + 2 * w * x;
 tmodelview[10] = 1 - (2 * x * x) - (2 * y * y);
 tmodelview[11] = 0;

 glMatrixMode(GL_MODELVIEW);
 glPushMatrix();
 glLoadMatrixf(tmodelview);
 glMultMatrixf(modelview);
 glGetFloatv(GL_MODELVIEW_MATRIX, tmodelview);
 glPopMatrix();
}

和我的代码旋转(我称之为外部),其中quaternion是立方体的类变量:

void cube::rotatex(int angle){
 float quat[4];
 float ang = angle * PI / 180.0;
 quat[0] = cosf(ang / 2);
 quat[1] = sinf(ang/2);
 quat[2] = 0;
 quat[3] = 0;
 quatmul(quat, quaternion, quaternion);
 applyquat();
}

void cube::rotatey(int angle){
 float quat[4];
 float ang = angle * PI / 180.0;
 quat[0] = cosf(ang / 2);
 quat[1] = 0;
 quat[2] = sinf(ang/2);
 quat[3] = 0;
 quatmul(quat, quaternion, quaternion);
 applyquat();
}

void cube::rotatez(int angle){
 float quat[4];
 float ang = angle * PI / 180.0;
 quat[0] = cosf(ang / 2);
 quat[1] = 0;
 quat[2] = 0;
 quat[3] = sinf(ang/2);
 quatmul(quat, quaternion, quaternion);
 applyquat();
}

我称rotatex为10-11次,仅旋转1度,但我的立方体在1度10-11次后旋转了将近90度,这没有意义。 此外,在调用不同轴的旋转函数之后,My cube会发生扭曲,变得二维,并且不可逆地消失(模型视图矩阵中的一列全部为零),这显然不应该在正确实现四元数时发生。


你正在接近这个错误的方式。 如果X,Y和Z轴有三个欧拉角旋转,将它们变成四元数,然后变成矩阵不会对您有所帮助。 由于您所需的旋转表示,出现万向节锁。 如果您将旋转存储为XYZ欧拉角,那么您将获得Gimbal锁定。

您需要将您想要的方向存储为四元数以获得优势。 也就是说,可以将当前的方向作为一个四元数,然后问“我如何绕Z轴旋转90度并将其用作我的新方向?”,但询问“我的电流方向由这些XYZ欧拉角度定义,我如何将它转换为四元数?“。

对四元数相关部分的全面处理将会很漫长。 这个网站可能会帮助你。 值得注意的是,你链接的网站似乎确实在谈论轴角旋转,而不是四元数。

编辑:你发布的代码是正确的,除了tmodelview[6]tmodelview[9]的标志是错误的。

链接地址: http://www.djcxy.com/p/14347.html

上一篇: How to find vector for the quaternion from X Y Z rotations

下一篇: Using Quaternions for OpenGL Rotations