四元数相乘时结果无效,不知道为什么

Invalid results when multiplying quaternions and no idea why

我目前正在开发一个包含四元数的 3D 库。作为每一位专家,我都根据我在维基百科上找到的内容编写了我的方法,但它并不是很正确。

这是计算两个四元数乘积的方法:

public static Quaternion product(Quaternion a, Quaternion b) {
    return a.clone().multiply(b);
}

这是它的实现:

public Quaternion multiply(Quaternion q) {
    float rx = q.getX(), ry = q.getY(), rz = q.getZ(), rw = q.getW();

    this.w = w*rw - x*rx - y*ry - z*rz;
    this.x = w*rx + x*rw + y*rz - z*ry;
    this.y = w*ry - x*rz + y*rw + z*rx;
    this.z = w*rz + x*ry - y*rx + z*rw;
    return this;
}

这是我写的一个小测试:

Quaternion a = Quaternion.create(1, 1, 1, Spatium.DEG_TO_RAD *  15);
Quaternion b = Quaternion.create(1, 1, 1, Spatium.DEG_TO_RAD *  15);
Quaternion c = Quaternion.product(a, b);
System.out.println(a + " * " + b + " = " + c);

请注意,create() 方法使用 xyzw

初始化四元数

不幸的是,尽管我具有惊人的复制和粘贴维基百科公式的技能,但测试产生的结果没有任何意义:

(0.2617994 + 1.0i + 1.0j + 1.0k) * (0.2617994 + 1.0i + 1.0j + 1.0k) = (-2.931461 + -2.6696618i + 1.0j + -6.3393235k)

为了比较,Wolfram 解得正确 returns -2.93146 + 0.523599i + 0.523599j + 0.523599k.

以下是我巧妙地从维基百科复制的公式:

除了请帮助我,我真的没有什么可说的,维基百科不能。

我认为您应该先将 xyzw 的当前值存储在一个临时变量中,然后再用新值对其进行更新。

    public Quaternion multiply(Quaternion q) {
        float rx = q.getX(), ry = q.getY(), rz = q.getZ(), rw = q.getW();

        float cx = x; // cx = current X
        float cy = y;
        float cz = z;
        float cw = w;

        this.w = cw*rw - cx*rx - cy*ry - cz*rz;
        this.x = cw*rx + cx*rw + cy*rz - cz*ry;
        this.y = cw*ry - cx*rz + cy*rw + cz*rx;
        this.z = cw*rz + cx*ry - cy*rx + cz*rw;
        return this;
    }

在您的代码中,当您使用 this.w = w*rw - x*rx - y*ry - z*rz; 时,您将覆盖 w 的当前值,接下来的 3 个操作将受到此更改的影响。