自定义 C++ 四元数旋转无法正常工作
Custom C++ Quaternion Rotation Not Working Correctly
在我的代码中,我有一个四元数用于为玩家旋转相机。旋转本身似乎工作正常,但我用于移动和旋转的方向向量没有正确旋转。
四元数乘法:
Quaternion Quaternion::operator*(Vector3 other) const
{
float x_ = w * other.x + y * other.z - z * other.y;
float y_ = w * other.y + z * other.x - x * other.z;
float z_ = w * other.z + x * other.y - y * other.x;
float w_ = -x * other.x - y * other.y - z * other.z;
return Quaternion(x_, y_, z_, w_);
}
Quaternion Quaternion::operator*(Quaternion other) const
{
Vector4 r = other.getValues();
float x_ = x * r.w + w * r.x + y * r.z - z * r.y;
float y_ = y * r.w + w * r.y + z * r.x - x * r.z;
float z_ = z * r.w + w * r.z + x * r.y - y * r.x;
float w_ = w * r.w - x * r.x - y * r.y - z * r.z;
return Quaternion(x_, y_, z_, w_);
}
共轭函数
Quaternion Quaternion::conjugate() const
{
return Quaternion(-x, -y, -z, w);
}
矢量旋转:
void Vector3::rotate(Quaternion rotation)
{
Quaternion rotated = rotation * *this * rotation.conjugate();
x = rotated.getValues().x;
y = rotated.getValues().y;
z = rotated.getValues().z;
}
示例方向向量:
Vector3 Quaternion::getRight() const
{
Vector3 right(1.0f, 0.0f, 0.0f);
right.rotate(*this);
return right;
}
如果我让相机绕 y 轴精确旋转 90 度,然后打印出右向量的值,则 x 为 0.000796229,y 为 0,z 为 -1。在这种情况下,x 应为 0,z 应为正数 1。
过去几天我一直在浏览 Google 和其他人的代码,试图找出我做错了什么,但我找不到任何错误。
更新:
我最终决定将 GLM 合并到我的数学中 类,经过一些改变后,一切都按预期进行。
在矢量旋转中将第一行替换为
Quaternion rotated = rotation * Quaternion(this->x, this->y, this->z, 0) *
rotation.conjugate();
解释:四元数乘法不可交换,这意味着 Q * v 不等于 v * Q,其中 v 是 w=0 的四元数。
我最终决定将 GLM 合并到我的数学中类,经过一些改变后,一切都按预期进行。
在我的代码中,我有一个四元数用于为玩家旋转相机。旋转本身似乎工作正常,但我用于移动和旋转的方向向量没有正确旋转。
四元数乘法:
Quaternion Quaternion::operator*(Vector3 other) const
{
float x_ = w * other.x + y * other.z - z * other.y;
float y_ = w * other.y + z * other.x - x * other.z;
float z_ = w * other.z + x * other.y - y * other.x;
float w_ = -x * other.x - y * other.y - z * other.z;
return Quaternion(x_, y_, z_, w_);
}
Quaternion Quaternion::operator*(Quaternion other) const
{
Vector4 r = other.getValues();
float x_ = x * r.w + w * r.x + y * r.z - z * r.y;
float y_ = y * r.w + w * r.y + z * r.x - x * r.z;
float z_ = z * r.w + w * r.z + x * r.y - y * r.x;
float w_ = w * r.w - x * r.x - y * r.y - z * r.z;
return Quaternion(x_, y_, z_, w_);
}
共轭函数
Quaternion Quaternion::conjugate() const
{
return Quaternion(-x, -y, -z, w);
}
矢量旋转:
void Vector3::rotate(Quaternion rotation)
{
Quaternion rotated = rotation * *this * rotation.conjugate();
x = rotated.getValues().x;
y = rotated.getValues().y;
z = rotated.getValues().z;
}
示例方向向量:
Vector3 Quaternion::getRight() const
{
Vector3 right(1.0f, 0.0f, 0.0f);
right.rotate(*this);
return right;
}
如果我让相机绕 y 轴精确旋转 90 度,然后打印出右向量的值,则 x 为 0.000796229,y 为 0,z 为 -1。在这种情况下,x 应为 0,z 应为正数 1。
过去几天我一直在浏览 Google 和其他人的代码,试图找出我做错了什么,但我找不到任何错误。
更新:
我最终决定将 GLM 合并到我的数学中 类,经过一些改变后,一切都按预期进行。
在矢量旋转中将第一行替换为
Quaternion rotated = rotation * Quaternion(this->x, this->y, this->z, 0) *
rotation.conjugate();
解释:四元数乘法不可交换,这意味着 Q * v 不等于 v * Q,其中 v 是 w=0 的四元数。
我最终决定将 GLM 合并到我的数学中类,经过一些改变后,一切都按预期进行。