在c ++中,如何根据最新的四元数旋转在3D空间中转换附加到另一个点的点

时间:2014-12-18 00:14:59

标签: c++ rotation quaternions

我有必要,p1和p2,p2附加到p1,不仅是p1的位置,还有它的旋转,所以q1是四元数,表示p1的旋转。 如果q1旋转,则p1的位置也必须相应地围绕p1旋转。 我只需要计算p2的位置,而不是它的旋转,我已经完成了旋转。 所以基本上是一个停靠在车站的太空船,我需要移动并旋转车站,船停靠在船上。 我该怎么做?

我为它编写的代码只要在对接期间没有旋转工作站就可以工作:

bool docked[100];
Quaternion quatTarget[100];
double distance_dock[100];

vector3 docking_position(int ship, int station)
{
    if (!docked[ship])
    {
        docked[ship] = true;
        distance_dock[ship] = distances(position[ship], position[station]);
        vector3 direcc = normalized(position[station] - position[ship]);
        quatTarget[ship] = vecToVecRotation(direcc, { 0, 0, 1 });
        QuaternionNormalize(&quatTarget[ship], &quatTarget[ship]);
    }

    Quaternion orientation = total_rotation[station] * quatTarget[ship];

    Matrix docking_place;

    MatrixRotationQuaternion(&docking_place, &orientation);

    vector3 axis_z = { docking_place(0, 2), docking_place(1, 2), docking_place(2, 2) };

    return position[station] + -axis_z * distance_dock[ship];
}

我在这里做的是在对接时从船到站的方向四元数,然后沿着方向的负z轴移动船“distance_dock”单位,因此船将始终相应地移动,但是不知何故,如果我在车站已经旋转时停靠船只,那么我的初始停靠位置会出错,尽管它仍然与车站一起完美旋转。

1 个答案:

答案 0 :(得分:0)

如果我理解正确,你有两个在它们之间有严格转换的对象。问题是你想要计算一个的姿势(位置+方向),给定另一个的姿势。

让我们说你有三个框架;车站框架" S",车辆框架" V"和全球框架" G" (我假设你的图形环境有一个全局3D笛卡尔框架)。 帧S和V之间的变换是完全已知的(平移和定向)和常数,并且表示为S_p_SV(车辆的位置,在车站框架中表示)和SV_q(车辆的四元数方向,表示为车站框架。)

如果您没有刚体力学经验,这将会令人困惑,在这种情况下,您应该阅读" Rigid-Body Mechanics" 的一些介绍性说明/幻灯片。 Google搜索结果很丰富。

我已经在LATEX中编写了表达式,但遗憾的是StackOverflow不支持它,因此我将其作为图像附加。可以找到原始LATEX here。 在下面的符号中,例如在第一行 Sp_SV 上,是 V ehicle w.r.t的 p S ,在 S 框架(旋转)中表示。 带前缀的上标表示旋转框架。例如,对于四元数 G_Sq ,这表示 G 圆框架中 S 框架的方向。

LATEX Of the 2-particle rigid transform

就在C ++中实现它而言,我不确定您为Quaternions使用的库,但是您需要以下函数:

  • 将Euler转换为四元数 - 如果您要手动指定旋转SV q (车辆w.r.t Station的旋转)
  • 将四元数转换为DCM - 对于LATEX中的第一个方法
  • Quaternion Multiply - 对于LATEX中的第二种方法
  • Quaternion Conjugate - 对于LATEX中的第二种方法