四元数旋转错误
Quaternion Rotation errors
最近,我正在使用源对我的 3D 模型进行旋转。但是调用函数的时候出现了问题:
RotationBetweenVectors,定义在教程 17(
link:http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/)。
我想使用四元数方法将向量 _from 旋转到向量 _to 。
两个向量定义如下,并计算它们之间的四元数。
vec3 _from(0, -0.150401f, 0.93125f), _to(-0.383022f, -0.413672f, 1.24691f);
quat _rot = RotationBetweenVectors(_from, _to);
vec3 _to1 = _rot * _from;
vec3 _to2 = _rot * _from * inverse(_rot);
然后我使用这个 quat _rot 乘以向量 _from 。不幸的是,结果 _to1 和 _to2 都不相等到矢量 _to.
_rot gives {x=0.0775952041 y=-0.140000001 z=-0.0226106234 w=0.986847401}
_to1 gives {x=-0.264032304 y=-0.285160601 z=0.859544873 }
_to2 gives {x=-0.500465572 y=-0.390112638 z=0.697992325 }
请问有哪位朋友能帮我解决这个问题吗?
非常感谢!
我在这里看到两个问题。
首先,如果您希望向量 v1 旋转并在向量 v2 的相同位置精确结束,它们必须具有相同的长度。
在您的例子中,_to
的长度与 _from
不同。我建议你将它们归一化:
_to = normalize(_to);
_from = normalize(_from);
其次,正如您所提示的,通过四元数进行旋转是由该运算符完成的:
v1 = quat * Pin * inverse(quat);
问题是 Pin 也必须是四元数,而不是向量(您已将 _from
定义为 vec3)。请注意,在您的原始运算符中,它可以重写为:
vec3 _to2 = (_rot * _from) * inverse(_rot);
其中内部括号生成乘以 inverse(_rot)
的 vec3。
所以,要解决这个问题,这意味着您的运算符必须是这样的(四元数乘法):
quat Pin = {0, _from};
quat result = _rot * Pin * inverse(_rot);
现在,您只需要将这个四元数再次转换为vec3即可:
_to2 = axis(result);
我相信,您不能像下面那样将 vec3
乘以 quat
:
vec3 _to1 = _rot * _from;
您必须通过在第四处添加 1
将 _from
从 vec3
转换为 vec4
,即
vec4 _from2 = vec4(_from, 1);
此外,将 _rot
从 quat
转换为 4x4 矩阵,例如 _rot2
。您参考的教程提到可以使用:
mat4 RotationMatrix = quaternion::toMat4(quaternion);
那么你应该能够将 _from2
乘以 _rot2
得到 _to
向量。
最近,我正在使用源对我的 3D 模型进行旋转。但是调用函数的时候出现了问题: RotationBetweenVectors,定义在教程 17( link:http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/)。 我想使用四元数方法将向量 _from 旋转到向量 _to 。 两个向量定义如下,并计算它们之间的四元数。
vec3 _from(0, -0.150401f, 0.93125f), _to(-0.383022f, -0.413672f, 1.24691f);
quat _rot = RotationBetweenVectors(_from, _to);
vec3 _to1 = _rot * _from;
vec3 _to2 = _rot * _from * inverse(_rot);
然后我使用这个 quat _rot 乘以向量 _from 。不幸的是,结果 _to1 和 _to2 都不相等到矢量 _to.
_rot gives {x=0.0775952041 y=-0.140000001 z=-0.0226106234 w=0.986847401}
_to1 gives {x=-0.264032304 y=-0.285160601 z=0.859544873 }
_to2 gives {x=-0.500465572 y=-0.390112638 z=0.697992325 }
请问有哪位朋友能帮我解决这个问题吗? 非常感谢!
我在这里看到两个问题。
首先,如果您希望向量 v1 旋转并在向量 v2 的相同位置精确结束,它们必须具有相同的长度。
在您的例子中,_to
的长度与 _from
不同。我建议你将它们归一化:
_to = normalize(_to);
_from = normalize(_from);
其次,正如您所提示的,通过四元数进行旋转是由该运算符完成的:
v1 = quat * Pin * inverse(quat);
问题是 Pin 也必须是四元数,而不是向量(您已将 _from
定义为 vec3)。请注意,在您的原始运算符中,它可以重写为:
vec3 _to2 = (_rot * _from) * inverse(_rot);
其中内部括号生成乘以 inverse(_rot)
的 vec3。
所以,要解决这个问题,这意味着您的运算符必须是这样的(四元数乘法):
quat Pin = {0, _from};
quat result = _rot * Pin * inverse(_rot);
现在,您只需要将这个四元数再次转换为vec3即可:
_to2 = axis(result);
我相信,您不能像下面那样将 vec3
乘以 quat
:
vec3 _to1 = _rot * _from;
您必须通过在第四处添加 1
将 _from
从 vec3
转换为 vec4
,即
vec4 _from2 = vec4(_from, 1);
此外,将 _rot
从 quat
转换为 4x4 矩阵,例如 _rot2
。您参考的教程提到可以使用:
mat4 RotationMatrix = quaternion::toMat4(quaternion);
那么你应该能够将 _from2
乘以 _rot2
得到 _to
向量。