【发布时间】:2014-04-05 03:08:46
【问题描述】:
已解决
我正在我的引擎中制作一个 3D 门户系统(例如 Portal 游戏)。每个门户都有自己的方向保存在一个四元数中。要在其中一个门户中渲染虚拟场景,我需要计算两个四元数之间的差异,并将结果用于旋转虚拟场景。
当在左墙上创建第一个传送门,在右墙上创建第二个传送门时,从一个到另一个的旋转将仅在一个轴上发生,但例如当第一个传送门将在地板上创建时,以及右边墙上的第二个,从一个到另一个的旋转可能是在两个轴上,这就是问题,因为旋转出错了。
我认为问题的存在是因为例如 X 轴和 Z 轴的方向一起存储在一个四元数中,我需要分别手动乘以 X * Z (或 Z * @ 987654329@),但是如何只用一个四元数(差异四元数)呢?还是有其他方法来纠正旋转场景?
编辑:
这张图片上有两个传送门 P1 和 P2,箭头显示它们是如何旋转的。当我查看 P1 时,我会看到 P2 中的内容。为了找到我需要旋转主场景的旋转,就像这张图片中的虚拟场景一样,我正在执行以下操作:
- 从四元数 P2 到四元数 P1 的差异
- Y 轴旋转 180 度的结果(传送门的 UP)
- 使用结果旋转虚拟场景
仅当差异仅发生在一个轴上时,上述方法才有效。当一个门户在地板上或天花板上时,这将不起作用,因为差异四元数构建在多个轴上。正如建议的那样,我尝试将 P1 的四元数乘以 P2 的四元数,反之亦然,但这不起作用。
编辑 2:
要找出 P2 到 P1 的区别,我正在执行以下操作:
Quat q1 = P1->getOrientation();
Quat q2 = P2->getOrientation();
Quat diff = Quat::diff(q2, q1); // q2 * diff = q1 //
这是 Quat::diff 函数:
GE::Quat GE::Quat::diff(const Quat &a, const Quat &b)
{
Quat inv = a;
inv.inverse();
return inv * b;
}
逆向:
void GE::Quat::inverse()
{
Quat q = (*this);
q.conjugate();
(*this) = q / Quat::dot((*this), (*this));
}
共轭:
void GE::Quat::conjugate()
{
Quat q;
q.x = -this->x;
q.y = -this->y;
q.z = -this->z;
q.w = this->w;
(*this) = q;
}
点积:
float GE::Quat::dot(const Quat &q1, const Quat &q2)
{
return q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w;
}
操作员*:
const GE::Quat GE::Quat::operator* ( const Quat &q) const
{
Quat qu;
qu.x = this->w*q.x + this->x*q.w + this->y*q.z - this->z*q.y;
qu.y = this->w*q.y + this->y*q.w + this->z*q.x - this->x*q.z;
qu.z = this->w*q.z + this->z*q.w + this->x*q.y - this->y*q.x;
qu.w = this->w*q.w - this->x*q.x - this->y*q.y - this->z*q.z;
return qu;
}
操作员/:
const GE::Quat GE::Quat::operator/ (float s) const
{
Quat q = (*this);
return Quat(q.x / s, q.y / s, q.z / s, q.w / s);
}
所有这些东西都有效,因为我已经用GLM library 测试过它
【问题讨论】:
-
你如何计算 P2 和 P1 的四元数之间的差异?要找到将 q1 转换为 q2 的四元数 q',您必须找到 q1 的倒数,q1^'1 并左乘以 q2。 q' = q2*q1^-1 参考参考参考stackoverflow.com/questions/1755631/…
-
我按照你说的做。我已经编辑了我的问题,以展示寻找差异的整个过程。
标签: math rotation quaternions portal-system