I am given a rotation matrix constant that is immutable and should not be modified with rotations of 30, 20, and 10 degrees about XYZ.
I need to create a matrix attempt that, when either pre or post multiplied with constant will create a matrix with rotations of 90, -20, and -10 degrees about XYZ and equal to target.
Matrix4d target = new Matrix4d()
.rotationXYZ(Math.toRadians(30 + 60), Math.toRadians(20 - 40), Math.toRadians(10 - 20)); // 90, -20, -10
System.out.println(new Vector3d(8.0).mulProject(target)); // Target * V = (5.973 -10.687 6.489)
Matrix4d constant = new Matrix4d()
.rotationXYZ(Math.toRadians(30), Math.toRadians(20), Math.toRadians(10)); // A
Matrix4d attempt = new Matrix4d()
.rotationXYZ(Math.toRadians(60), Math.toRadians(-40), Math.toRadians(-20)); // B
Matrix4d combined = constant.mulLocal(attempt, new Matrix4d()); // C = B * A
System.out.println(new Vector3d(8.0).mulProject(combined)); // Combined * V = (1.84 -10.747 8.55)
As shown above, the attempt matrix rotates by the extra amount required in each axis after the constant. This resulting combined matrix does not equal the target though.
Matrix4d attempt = new Matrix4d()
.rotationXYZ(Math.toRadians(90), Math.toRadians(-20), Math.toRadians(-10))
.mul(constant.invert(new Matrix4d()));
This second attempt works, but it requires that I inverse the work of constant first which is a waste of resources. I would like to find the correct rotation values to give to rotationXYZ or rotate with a quaternion without inversing the previous matrix.
First we must know precisely what rotateXYZ does. From https://joml-ci.github.io/JOML/apidocs/org/joml/Matrix4f.html#rotateXYZ(float,float,float,org.joml.Matrix4f)
So we can think of this as apply rotations Rx, Ry, Rz to our starting matrix M to give resulting matrix M'.
Now a very important point about matrix multiplication is that order of applying matrices is important, i.e. it is not commutative. So using a different order say
will in general be different to M'.
Here we have two matrices
and wish to find matrix
attemptsuch thatOr
target = attempt * Rz(10) * Ry(20) * Rx(10)
Now we can apply the inverse of the compentent rotations. Note that the inverse of a rotation matrix Rx(theta) is the rotation matrix Rx(-theta), (a clockwise rotation is the inverse of an anti-clockwise rotation).
So we apply the rotations applying the inverses on the right
Note the difference in order the last matrices are applied in the order Z, Y, X.
Now JOML has method for matrices in every possible order and the method we want is
So to find attempt we can take
Or more simply