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.
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);
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 don't really have anything to say other than please help me, Wikipedia couldn't.
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 overridind the current value of w
, and the next 3 operations will be affected by this changes.