两个四元数之间的差异 [英] Difference between the two quaternions

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

问题描述

我正在用引擎制作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.

要找到从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);

并以此方式计算翻译:

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

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

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