Jan Schultke - 1 year ago 59
Java Question

Invalid results when multiplying quaternions and no idea why

I am currently working on a 3D-library including quaternions. As every expert, I coded my methods based on what I found on Wikipedia and it doesn't work quite right.

This is the method for calculating the product between two quaternions:

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

And here is its implementation:

``````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;
}
``````

And here is a small test that I wrote:

``````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);
``````

Note that the
`create()`
method initializes quaternions with
`x`
,
`y`
,
`z`
,
`w`
.

Unfortunately, the tests yields results that don't make any sense despite my amazing skills of copying and pasting Wikipedia formulas:

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

For comparison, Wolfram solves it correctly and returns
`-2.93146 + 0.523599i + 0.523599j + 0.523599k`
.

Here's the formulas I so skillfully copied from Wikipedia:

I think you should store the current values of `x`, `y`, `z` and `w` in a temp variable before updating it with new values.

``````    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;
}
``````

In your code, when you use `this.w = w*rw - x*rx - y*ry - z*rz;`, you are override the current value o `w`, and the next 3 operations will be affect by this changes.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download