是否可以仅使用四元数在 3D space 中旋转矢量?

Is it possible to rotate a vector in 3D space using quaternions only?

我想围绕原点旋转 3D 向量 space。

假设我有一个以原点为中心并垂直于 y 轴的多边形。

然后我想将这个多边形围绕某个任意轴旋转某个任意旋转量。

示例:绕Y轴旋转90度。视图沿 -Y 轴。

Rotate by 90 degrees

一种方法是创建一个旋转矩阵并将旋转应用到多边形的每个点。我现在已经可以做到这一点。

但是,我决定使用四元数来实现这一点。

尝试:绕Y轴旋转90度。视图沿 -Y 轴。

Failure

代码好像有问题。

为了尝试找出问题所在,我创建了函数 qRotate,它应该围绕原点旋转单个点(或矢量)。为了检查我的数学是否正确,我使用两种不同的方法得出了最终的旋转。但是,这两种方法都会产生完全错误的结果。

void qRotate(glm::vec3 point, glm::vec3 rotate)
{
  printf("\n\n%f %f %f around point %f %f %f", 
          rotate.x, rotate.y, rotate.z, point.x, point.y, point.z);

  //Create quaternion.
  glm::quat orientation = glm::quat(rotate);

  //Normalize
  orientation = glm::normalize(orientation);

  /*Method 1 - pure vector quaternion.*/
  //Create the 'pure' vector quaternion
  glm::quat pure = glm::quat(0.0, point.x, point.y, point.z);
  glm::quat qpq = orientation * pure * (glm::conjugate(orientation));
  //Form the result
  glm::vec3 result = glm::vec3(qpq.x, qpq.y, qpq.z);
  printf("\nResult1 = %f %f %f", result.x, result.y, result.z);

  /*Method 2 - just apply the orientation to the point.*/
  glm::vec3 alpha = orientation * point;
  printf("\nResult2 = %f %f %f", alpha.x, alpha.y, alpha.z);
}

一些示例输入和输出:

qRotate(glm::vec3(10.0, 0.0, 0.0), glm::vec3(0.0, 45.0, 0.0));

0.000000 45.000000 0.000000 around point 10.000000 0.000000 0.000000
Result1 = 5.253221 0.000000 -8.509035
Result2 = 5.253221 0.000000 -8.509035

(预期结果 - 接近 7.5、0.0、7.5)

qRotate(glm::vec3(10.0, 0.0, 0.0), glm::vec3(0.0, 90.0, 0.0));

0.000000 90.000000 0.000000 around point 10.000000 0.000000 0.000000
Result1 = -4.480736 0.000000 -8.939966
Result2 = -4.480736 0.000000 -8.939966

(预期结果 - 0.00000、0.00000、10.00000)

qRotate(glm::vec3(10.0, 0.0, 0.0), glm::vec3(0.0, 180.0, 0.0));
Result1 = -5.984600 0.000000 8.011526
Result2 = -5.984600 0.000000 8.011526

(预期结果 - -10.00000、0.00000、0.0000)


据我了解,数学是正确的,因此,我尝试使用它的方式一定有问题。我已经看到许多资源采用旋转四元数(方向)并将其转换为 4x4 矩阵,然后将旋转应用于向量,并将矩阵转换回(旋转的)3d 向量。

在我代码的其他部分,我目前确实在执行四元数-矩阵-向量转换,但我认为这似乎效率不高。

我读到可以单独使用四元数导出旋转点,并且使用了我的代码中建议的那些算法。我还认为结果不一定是垃圾,实际上代表了一些有用的东西,但我不知道是什么。

单靠四元数是不可能的吗?

您的函数以弧度为单位旋转角度,但您输入的角度为度数。您应该以弧度为单位输入角度,或者在函数顶部将角度转换为弧度。