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

时间:2016-10-26 18:48:47

标签: java math quaternions

我目前正在开发包含四元数的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正确地解决了它并返回-2.93146 + 0.523599i + 0.523599j + 0.523599k

这是我从维基百科中巧妙复制的公式: enter image description here

除了请帮助我之外,我没有什么可说的,维基百科无法做到。

1 个答案:

答案 0 :(得分:2)

我认为您应该在临时变量中存储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个操作将受到此更改的影响。