Opengl 四元数->;矩阵[16]——好的,现在怎么办?(如何从四元数显示对象?)

Opengl 四元数->;矩阵[16]——好的,现在怎么办?(如何从四元数显示对象?),opengl,Opengl,我将对象的旋转和平移转换为四元数,并将其转换为矩阵[16] 如何将该矩阵提供给OpenGL?我想,我可以用我的新的、别致的裤子矩阵来加载矩阵(),一切都会很好,但我得到的是一个空白屏幕 (我有点像GL n00b,所以打字要慢,要用小字;) 我的代码如下所示: glPushMatrix(); [quaternion makeIdentity]; // reset quat [quaternion setPitch: rotation.x yaw: rotation.y roll:

我将对象的旋转和平移转换为四元数,并将其转换为矩阵[16]

如何将该矩阵提供给OpenGL?我想,我可以用我的新的、别致的裤子矩阵来加载矩阵(),一切都会很好,但我得到的是一个空白屏幕

(我有点像GL n00b,所以打字要慢,要用小字;)

我的代码如下所示:

glPushMatrix();

[quaternion makeIdentity];         // reset quat
[quaternion setPitch: rotation.x yaw: rotation.y roll: rotation.z];  // Set up with rotation coords (NOTE: setPitch:yaw:roll: is smart about degrees->radians)

GLdouble matrix[16];
[quaternion matrix: &matrix[0]];   // get quat -> matrix
matrix[12] =  location.x;          // fill in the translation
matrix[13] =  location.y;
matrix[14] =  location.z;

glLoadMatrixd(matrix);

glScaled(scale.x, scale.y, scale.z);

// draw geometry here -- snip

glPopMatrix();
glPushMatrix();

glTranslatef(location.x, location.y, location.z);

glRotated(rotation.z,   0,   0, 1.0);
glRotated(rotation.x, 1.0,   0,   0);
glRotated(rotation.y,   0, 1.0,   0);

// draw geometry here -- snip

glPopMatrix();
mtx[0]=1.f-2.f*qy*qy-2.f*qz*qz;
mtx[1]=0.f+2.f*qx*qy+2.f*qw*qz;
mtx[2]=0.f+2.f*qx*qz-2.f*qw*qy;
mtx[3]=0.f;

mtx[4]=0.f+2.f*qx*qy-2.f*qw*qz;
mtx[5]=1.f-2.f*qx*qx-2.f*qz*qz;
mtx[6]=0.f+2.f*qy*qz+2.f*qw*qx;
mtx[7]=0.f;

mtx[8]=0.f+2.f*qx*qz+2.f*qw*qy;
mtx[9]=0.f+2.f*qy*qz-2.f*qw*qx;
mtx[10]=1.f-2.f*qx*qx-2.f*qy*qy;
mtx[11]=0.f;

mtx[12]=0.f;
mtx[13]=0.f;
mtx[14]=0.f;
mtx[15]=1.f;
我想我已经很接近了,但是当我使用这段代码时,我得到了一个空白显示(一切都是glClearColor)

注意:当我跳过四元数部分并执行以下操作时:

glPushMatrix();

[quaternion makeIdentity];         // reset quat
[quaternion setPitch: rotation.x yaw: rotation.y roll: rotation.z];  // Set up with rotation coords (NOTE: setPitch:yaw:roll: is smart about degrees->radians)

GLdouble matrix[16];
[quaternion matrix: &matrix[0]];   // get quat -> matrix
matrix[12] =  location.x;          // fill in the translation
matrix[13] =  location.y;
matrix[14] =  location.z;

glLoadMatrixd(matrix);

glScaled(scale.x, scale.y, scale.z);

// draw geometry here -- snip

glPopMatrix();
glPushMatrix();

glTranslatef(location.x, location.y, location.z);

glRotated(rotation.z,   0,   0, 1.0);
glRotated(rotation.x, 1.0,   0,   0);
glRotated(rotation.y,   0, 1.0,   0);

// draw geometry here -- snip

glPopMatrix();
mtx[0]=1.f-2.f*qy*qy-2.f*qz*qz;
mtx[1]=0.f+2.f*qx*qy+2.f*qw*qz;
mtx[2]=0.f+2.f*qx*qz-2.f*qw*qy;
mtx[3]=0.f;

mtx[4]=0.f+2.f*qx*qy-2.f*qw*qz;
mtx[5]=1.f-2.f*qx*qx-2.f*qz*qz;
mtx[6]=0.f+2.f*qy*qz+2.f*qw*qx;
mtx[7]=0.f;

mtx[8]=0.f+2.f*qx*qz+2.f*qw*qy;
mtx[9]=0.f+2.f*qy*qz-2.f*qw*qx;
mtx[10]=1.f-2.f*qx*qx-2.f*qy*qy;
mtx[11]=0.f;

mtx[12]=0.f;
mtx[13]=0.f;
mtx[14]=0.f;
mtx[15]=1.f;

显示与预期一致。唯一的问题是,我的旋转是扭曲的,因为被应用顺序。因此,我希望使用四元数。

如果您没有忘记将当前矩阵模式设置为
GL\u MODELVIEW
,则应正确加载矩阵。检查您的quat->矩阵计算。我将从零角度旋转开始,并将结果与单位矩阵进行比较。

四元数没有平移部分。翻译必须单独维护,第二个代码段就是这样

无论如何,我不确定代码是否能达到预期效果。四元数不能解决万向节锁,如果问题是以一开始引入万向节锁的方式来描述的话。如果从每帧的俯仰/偏航/滚动重新设置四元数,将出现与以前相同的问题,原因也相同。(如果情况并非如此,那是因为四元数构造代码所做的事情与矩阵构造代码所做的事情相同,但在本例中并非如此:依次围绕每个旋转的轴旋转,而不是围绕固定的轴旋转。)

若要解决此问题,请将四元数作为对象状态的一部分,并直接对其应用每个旋转。不过,这并不能真正买到很多矩阵无法轻松实现的功能。(我还没有计算操作的数量,所以这并不是说这种方法可能比另一种更有效。)

四元数的主要优点是很容易在它们之间进行插值,只需将加权输入相加并对结果进行归一化,就可以在每个中间步骤得到合理的结果。SLERP也是一种选择。在某些情况下(例如,两个矩阵代表相反的方向,你将得到一个完全由零组成的列…)矩阵上的等效操作会失败,而尝试对俯仰/偏航/滚动进行类似操作只会产生一个大混乱

至于将一个转化为矩阵,如果你有一个四元数,它的向量部分是
(qx,qy,qz)
,而标量部分是
qw
,你可以使用如下代码将它转化为OpenGL矩阵:

glPushMatrix();

[quaternion makeIdentity];         // reset quat
[quaternion setPitch: rotation.x yaw: rotation.y roll: rotation.z];  // Set up with rotation coords (NOTE: setPitch:yaw:roll: is smart about degrees->radians)

GLdouble matrix[16];
[quaternion matrix: &matrix[0]];   // get quat -> matrix
matrix[12] =  location.x;          // fill in the translation
matrix[13] =  location.y;
matrix[14] =  location.z;

glLoadMatrixd(matrix);

glScaled(scale.x, scale.y, scale.z);

// draw geometry here -- snip

glPopMatrix();
glPushMatrix();

glTranslatef(location.x, location.y, location.z);

glRotated(rotation.z,   0,   0, 1.0);
glRotated(rotation.x, 1.0,   0,   0);
glRotated(rotation.y,   0, 1.0,   0);

// draw geometry here -- snip

glPopMatrix();
mtx[0]=1.f-2.f*qy*qy-2.f*qz*qz;
mtx[1]=0.f+2.f*qx*qy+2.f*qw*qz;
mtx[2]=0.f+2.f*qx*qz-2.f*qw*qy;
mtx[3]=0.f;

mtx[4]=0.f+2.f*qx*qy-2.f*qw*qz;
mtx[5]=1.f-2.f*qx*qx-2.f*qz*qz;
mtx[6]=0.f+2.f*qy*qz+2.f*qw*qx;
mtx[7]=0.f;

mtx[8]=0.f+2.f*qx*qz+2.f*qw*qy;
mtx[9]=0.f+2.f*qy*qz-2.f*qw*qx;
mtx[10]=1.f-2.f*qx*qx-2.f*qy*qy;
mtx[11]=0.f;

mtx[12]=0.f;
mtx[13]=0.f;
mtx[14]=0.f;
mtx[15]=1.f;

上面的内容是搜索并替换为上面的形式,所以我真的希望我没有把它搞砸。

好的,对身份矩阵进行编码,我在从网站上得到的矩阵计算中发现了几个错误(反向符号)。你能推荐一个权威的地方来获得正确的四元数->四元数公式吗?也许这个---(也有4x4矩阵的代码)--记住,四元数矩阵是列主数。在这里,我想我应该补充一点,四元数的另一个优点是它只有4个浮点数,而不是9个浮点数。“四元数没有平移部分……”没错,但4x4矩阵有。那是mtx[12-14],对吗?因此,一旦我得到quat来返回矩阵,我就可以用xyz填充12-14,所有这些都应该工作,对吗?是的。事实上,我在阅读时似乎遗漏了这部分代码,所以你可以忽略我的答案。看起来四元数和位置正确地用于生成矩阵。为我的误读道歉!