【问题标题】:Is it possible to rotate a vector in 3D space using quaternions only?是否可以仅使用四元数在 3D 空间中旋转矢量?
【发布时间】:2015-06-19 02:29:49
【问题描述】:

我想在 3D 空间中围绕原点旋转一个矢量。

假设我有一个以原点为中心并垂直于 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 向量。

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

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

难道不能单独使用四元数吗?

【问题讨论】:

  • 我不知道 glm,但据我所知,您的代码看起来正确...。我确实有一个问题:glm 中的角度是度数还是弧度?也许尝试在函数开始时将角度从度数转换为弧度?
  • 解决了这个问题。我假设 glm::quat(vec3) 转换为弧度。非常感谢您的帮助!不知道我怎样才能让你的评论成为“接受的答案”,但这就是我想做的!
  • 您能否提交您的评论作为答案,以便我将其标记为已接受的答案并关闭此问题?谢谢!
  • okie dokie 我提交了答案。

标签: c++ rotation


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2021-07-31
    • 2020-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多