两个四元数的区别 [英] Difference between the two quaternions

查看:28
本文介绍了两个四元数的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在我的引擎中制作一个 3D 门户系统(例如 Portal 游戏).每个门户都有自己的方向保存在一个四元数中.要在其中一个门户中渲染虚拟场景,我需要计算两个四元数之间的差异,并将结果用于旋转虚拟场景.

I'm making a 3D portal system in my engine (like Portal game). Each of the portals has its own orientation saved in a quaternion. To render the virtual scene in one of the portals I need to calculate the difference between the two quaternions, and the result use to rotate the virtual scene.

当在左墙上创建第一个传送门,在右墙上创建第二个传送门时,从一个到另一个的旋转将仅在一个轴上发生,但例如当第一个传送门将在地板上创建时,以及第二个在右边墙上,从一个到另一个的旋转可能是在两个轴上,这就是问题所在,因为旋转出错了.

When creating the first portal on the left wall, and second one on the right wall, the rotation from one to another will take place in only one axis, but for example when the first portal will be created on the floor, and the second one on the right wall, the rotation from one to another could be in two axis, and that's the problem, because the rotation goes wrong.

我认为问题存在,因为例如 X 轴和 Z 轴的方向一起存储在一个四元数中,我需要单独手动乘以 X * Z(或Z * X),但是如何只用一个四元数(差异四元数)呢?还是有其他方法来纠正旋转场景?

I think the problem exists because the orientation for example X axis and Z axis are stored together in one quaternion and I need it separately to manualy multiply X * Z (or Z * X), but how to do it with only one quaternion, (the difference quaternion)? Or is there other way to correct rotate the scene?

这张图片上有两个传送门 P1 和 P2,箭头显示它们是如何旋转的.当我查看 P1 时,我会看到 P2 中的内容.为了找到我需要旋转主场景的旋转,就像这张图片中的虚拟场景一样,我正在执行以下操作:

Here on this picture are two portals P1 and P2, the arrows show how are they rotated. As I am looking into P1 I will see what sees P2. To find the rotation which I need to rotate the main scene to be like the virtual scene in this picture I'm doing following:

  1. 从四元数 P2 到四元数 P1 的区别
  2. Y 轴旋转 180 度的结果(传送门的 UP)
  3. 使用结果旋转虚拟场景

仅当差异仅发生在一个轴上时,上述方法才有效.当一个门户将在地板上或天花板上时,这将不起作用,因为差异四元数构建在多个轴上.正如建议的那样,我尝试将 P1 的四元数与 P2 的四元数相乘,反之亦然,但这不起作用.

This method above works only when the difference takes place in only one axis. When one portal will be on the floor, or on te ceiling, this will not work because the difference quaternion is build in more than one axis. As suggested I tried to multiply P1's quaternion to P2's quaternion, and inversely but this isn't working.

编辑 2:

要找出 P2 到 P1 的区别,我正在执行以下操作:

To find the difference from P2 to P1 I'm doing following:

Quat q1 = P1->getOrientation();
Quat q2 = P2->getOrientation();

Quat diff = Quat::diff(q2, q1);  // q2 * diff = q1 //

这是 Quat::diff 函数:

Here's the Quat::diff function:

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 对其进行了测试图书馆

All this stuff works, because I have tested it with GLM library

推荐答案

我解决了我的问题.事实证明,我不需要两次旋转之间的任何区别.只需将一个旋转乘以 180 度的旋转,然后以这种方式乘以第二个旋转的倒数(使用矩阵):

I solved my problem. As it turned out I don't need any difference between two rotations. Just multiply one rotation by rotation in 180 degrees, and then multiply by inverse of second rotation that way (using matrices):

Matrix m1 = p1->getOrientation().toMatrix();
Matrix m2 = p2->getOrientation().toMatrix();
Matrix model = m1 * Matrix::rotation(180, Vector3(0,1,0)) * Matrix::inverse(m2);

并以这种方式计算翻译:

and translation calculating this way:

Vector3 position = -p2->getPosition();
position = model * position + p1->getPosition();
model = Matrix::translation(position) * model;

这篇关于两个四元数的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆