Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient 4x4 matrix inverse (affine transform)

I was hoping someone can point out an efficient formula for 4x4 affine matrix transform. Currently my code uses cofactor expansion and it allocates a temporary array for each cofactor. It's easy to read, but it's slower than it should be.

Note, this isn't homework and I know how to work it out manually using 4x4 co-factor expansion, it's just a pain and not really an interesting problem for me. Also I've googled and came up with a few sites that give you the formula already (http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm). However this one could probably be optimized further by pre-computing some of the products. I'm sure someone came up with the "best" formula for this at one point or another?

like image 758
Budric Avatar asked Apr 12 '10 18:04

Budric


People also ask

How do you find the inverse affine transformation matrix?

The inverse of an affine transformation is also affine, assuming it exists. Proof: Let ¯q = A¯p+ t and assume A−1 exists, i.e. det(A) = 0. Then A¯p = ¯q− t, so ¯p = A−1 ¯q− A−1t.

Can a 4x4 matrix have an inverse?

How do you find the inverse of a 4x4 matrix? The inverse of a square matrix can be found through row reduction of the augmented matrix, created by attaching a copy of the identity matrix. If the matrix can be reduced to the identity, then in parallel the identity matrix will transform to the inverse matrix.

What is a 4x4 transformation matrix?

The 4 by 4 transformation matrix uses homogeneous coordinates, which allow to distinguish between points and vectors. Vectors have a direction and magnitude whereas points are positions specified by 3 coordinates with respect to the origin and three base vectors i, j and k that are stored in the first three columns.


1 Answers

You should be able to exploit the fact that the matrix is affine to speed things up over a full inverse. Namely, if your matrix looks like this

A = [ M   b  ]     [ 0   1  ] 

where A is 4x4, M is 3x3, b is 3x1, and the bottom row is (0,0,0,1), then

inv(A) = [ inv(M)   -inv(M) * b ]          [   0            1     ] 

Depending on your situation, it may be faster to compute the result of inv(A) * x instead of actually forming inv(A). In that case, things simplify to

inv(A) * [x] = [ inv(M) * (x - b) ]          [1] = [        1         ]  

where x is a 3x1 vector (usually a 3D point).

Lastly, if M represents a rotation (i.e. its columns are orthonormal), then you can use the fact that inv(M) = transpose(M). Then computing the inverse of A is just a matter of subtracting the translation component, and multiplying by the transpose of the 3x3 part.

Note that whether or not the matrix is orthonormal is something that you should know from the analysis of the problem. Checking it during runtime would be fairly expensive; although you might want to do it in debug builds to check that your assumptions hold.

Hope all of that is clear...

like image 156
celion Avatar answered Sep 24 '22 04:09

celion