是否可以仅使用四元数在 3D space 中旋转矢量?
Is it possible to rotate a vector in 3D space using quaternions only?
我想围绕原点旋转 3D 向量 space。
假设我有一个以原点为中心并垂直于 y 轴的多边形。
然后我想将这个多边形围绕某个任意轴旋转某个任意旋转量。
示例:绕Y轴旋转90度。视图沿 -Y 轴。
一种方法是创建一个旋转矩阵并将旋转应用到多边形的每个点。我现在已经可以做到这一点。
但是,我决定使用四元数来实现这一点。
尝试:绕Y轴旋转90度。视图沿 -Y 轴。
代码好像有问题。
为了尝试找出问题所在,我创建了函数 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 向量。
在我代码的其他部分,我目前确实在执行四元数-矩阵-向量转换,但我认为这似乎效率不高。
我读到可以单独使用四元数导出旋转点,并且使用了我的代码中建议的那些算法。我还认为结果不一定是垃圾,实际上代表了一些有用的东西,但我不知道是什么。
单靠四元数是不可能的吗?
您的函数以弧度为单位旋转角度,但您输入的角度为度数。您应该以弧度为单位输入角度,或者在函数顶部将角度转换为弧度。
我想围绕原点旋转 3D 向量 space。
假设我有一个以原点为中心并垂直于 y 轴的多边形。
然后我想将这个多边形围绕某个任意轴旋转某个任意旋转量。
示例:绕Y轴旋转90度。视图沿 -Y 轴。
一种方法是创建一个旋转矩阵并将旋转应用到多边形的每个点。我现在已经可以做到这一点。
但是,我决定使用四元数来实现这一点。
尝试:绕Y轴旋转90度。视图沿 -Y 轴。
代码好像有问题。
为了尝试找出问题所在,我创建了函数 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 向量。
在我代码的其他部分,我目前确实在执行四元数-矩阵-向量转换,但我认为这似乎效率不高。
我读到可以单独使用四元数导出旋转点,并且使用了我的代码中建议的那些算法。我还认为结果不一定是垃圾,实际上代表了一些有用的东西,但我不知道是什么。
单靠四元数是不可能的吗?
您的函数以弧度为单位旋转角度,但您输入的角度为度数。您应该以弧度为单位输入角度,或者在函数顶部将角度转换为弧度。