如何仅反转四元数的一个轴?

时间:2019-07-15 11:37:14

标签: unity3d axis quaternions

我在Unity3D中创建了两个对象,分别代表一个上臂(父级)和一个下臂(子级),并通过字符关节进行连接。这些对象的旋转由2个四元数驱动,我从位于上臂和下臂的IMU收集它们。我校准两个四元数。我的目标是可视化肘部弯曲/伸展。

名称中的

Q表示它是四元数。 QImu表示它是来自IMU的四元数。 Qstart表示它是IMU的初始启动方向。

// upperarm script attached to upperarm object
if (Input.GetKeyDown(KeyCode.Space))
        {
            QstartUpperArm = QimuUpperArm;
        }

        transform.localRotation = QstartUpperArm * Quaternion.Inverse(QimuUpperArm);
// lowerarm script attached to lowerarm object
if (Input.GetKeyDown(KeyCode.Space))
        {
            QstartLowerArm = QimuLowerArm;
        }

        QimuLowerArm = QstartLowerArm * Quaternion.Inverse(QimuLowerArm);
transform.localrotation = Quaternion.Inverse(Qstart2 * Quaternion.Inverse(Qimu2)) * Qimu1new;

Upperarm对象正在完全按预期旋转。但是,下臂对象的y轴反转了一个。所有其他轴都可以。如何使用四元数更改一个轴的符号?

1 个答案:

答案 0 :(得分:0)

您不应该直接在Quaternion中执行此操作。听起来您似乎将Quaternion(具有4个成分x,y,z,w)与x,y,z中的Euler空间表示相混淆。

您可以尝试使用类似的东西

var invertedRotation = Quaternion.Euler(Vector3.Scale(QimuLowerArm.eulerAngles, Vector3.up * -1));

取决于要反转的旋转角度(在代码中没有清楚看到这一点)。

  • eulerAngles返回Quaternion

  • 的Euler表示
  • Vector3.Scale乘以Vector3的分量。在这种情况下,Vector3.up * -1 == new Vector3(0, -1, 0);

  • Quaternion.Euler为给定的Euler角旋转生成Quaternion。这里必须要注意的是,旋转顺序依次为x然后z然后y,但是由于您要反转后者,所以应该没问题。


另一种afaik(不太确定)是

  • 取反相应的轴分量
  • 否定w组件

我仍然不会直接在四元数中这样做,因为顺序很重要,但是确实如此。

var invertedRotation = new Quaternion (QimuLowerArm.x, - QimuLowerArm.y, QimuLowerArm.z, -QimuLowerArm.w);