旋转:四元数到矩阵

时间:2015-07-09 00:00:42

标签: opengl rotation quaternions

我正在尝试使用IMU显示360度全景以进行头部跟踪。

偏航正常但滚动和俯仰是相反的。我还注意到音高包含一些滚动(反之亦然)。

我从IMU接收(W,X,Y,Z)坐标,我将其作为X,Y,Z,W存储在数组中。

下一步是将四元数转换为旋转矩阵。我查看了很多示例,但似乎无法找到以下代码:

static GLfloat rotation[16];

// Quaternion (x, y, z, w)
static void quaternionToRotation(float* quaternion)
{
  // Normalize quaternion
  float magnitude = sqrt(quaternion[0] * quaternion[0] +
                         quaternion[1] * quaternion[1] + 
                         quaternion[2] * quaternion[2] + 
                         quaternion[3] * quaternion[3]); 
  for (int i = 0; i < 4; ++i)
  {
    quaternion[i] /= magnitude;
  }

  double xx = quaternion[0] * quaternion[0], xy = quaternion[0] * quaternion[1],
         xz = quaternion[0] * quaternion[2], xw = quaternion[0] * quaternion[3];
  double yy = quaternion[1] * quaternion[1], yz = quaternion[1] * quaternion[2],
         yw = quaternion[1] * quaternion[3];
  double zz = quaternion[2] * quaternion[2], zw = quaternion[2] * quaternion[3];

  // Column major order
  rotation[0] = 1.0f - 2.0f * (yy + zz);
  rotation[1] = 2.0f * (xy - zw);
  rotation[2] = 2.0f * (xz + yw); 
  rotation[3] = 0; 

  rotation[4] = 2.0f * (xy + zw);
  rotation[5] = 1.0f - 2.0f * (xx + zz);
  rotation[6] = 2.0f * (yz - xw);
  rotation[7] = 0; 

  rotation[8] = 2.0f * (xz - yw);
  rotation[9] = 2.0f * (yz + xw);
  rotation[10] = 1.0f - 2.0f * (xx + yy);
  rotation[11] = 0; 

  rotation[12] = 0; 
  rotation[13] = 0; 
  rotation[14] = 0; 
  rotation[15] = 1; 
}

然后在绘图调用中使用旋转矩阵:

static void draw()
{
  // Get IMU quaternion
  float* quaternion = tracker.getTrackingData();
  if (quaternion != NULL)
  {
    quaternionToRotation(quaternion);
  }

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();

  glPushMatrix();
  // TODO: Multiply initialRotation quaternion with IMU quaternion
  glMultMatrixf(initialRotation); // Initial rotation to point forward
  glMultMatrixf(rotation); // Rotation based on IMU

  glEnable(GL_TEXTURE_2D);
  glBindTexture(GL_TEXTURE_2D, texture);

  gluSphere(quad, 0.1, 50, 50);

  glBindTexture(GL_TEXTURE_2D, 0);
  glPopMatrix();

  glFlush();
  glutSwapBuffers();
}

我试图将四元数中除了一个字段之外的所有字段都设置为0,我注意到它们都是单独工作的,除了交换滚动和音高。我尝试交换X和Y,但这似乎没有帮助。

任何帮助都会非常感激。如果您有任何可以让我调试我的问题的步骤,请告诉我。谢谢!

0 个答案:

没有答案