I'm experimenting with OpenGL currently and I've come upon a situation where I want to find the 4x4 matrix x
where x * mat1 = mat2
(column major order, i think. where x * mat1
means apply the transformations in mat1
, then x
.).
Naturally, I thought that the solution might be x = mat2 / mat1
, so I tried it with glm. And it worked! The following snippet would output true
.
glm::mat4 mat1 = glm::translate(glm::vec3{1,2,3});
glm::mat4 mat2 = glm::scale(glm::vec3{-1,-2,-3});
glm::mat4 x = mat2 / mat1;
std::cout << ((x * mat1) == mat2) << std::endl;
But then, I realized that mat1 * x != x * mat1
!
How does this make any sense? mat2 / mat1
would be ambiguous! Is my solution of division satisfactory for finding x or are there any caveats? (Again, my goal is to have x * mat1 = mat2
)
I came across this discussion too: https://math.stackexchange.com/questions/228229/is-division-of-matrices-possible?newreg=c7fd79a48ae54ed694af1ee5f4646af7
There is no such thing as matrix division. However, scalar division is simply multiplying by the inverse of the scalar value. As such, one could (and GLM does) define "matrix division" to be the same thing: multiplying by the inverse.
So your mat2 / mat1
is really mat2 * glm::inverse(mat1)
.
As for commutativity, let's look at the algebra here. You start with this:
x * mat1 = mat2
And you want to solve for x
. You therefore multiply both sides by a value that removes mat1
from the left side of the equation. Namely, glm::inverse(mat1)
.
However, because matrix multiplication is not commutative, you know that doing glm::inverse(mat1) * (x * mat1)
does not actually get rid of the mat1
on the left of the equation. Therefore, you must right-multiply by the inverse to get rid of the mat1
.
And since algebraic transformations only work if you do the exact same operation to both sides, you must also right-multiply on the right side:
(x * mat1) * glm::inverse(mat1) = mat2 * glm::inverse(mat1)
So there is no ambiguity about the order; if you do them in the wrong order, you get the wrong answer.