5
$\begingroup$

I want to get the inverse of this homogeneous transformation matrix:

iab = {
 {1, 0, 0, 0},
 {0, 0, -1, 0},
 {0, 1, 0, 3},
 {0, 0, 0, 1}
      }

using the inverse function, but the problem is that I cannot directly use this function. Somehow I have to convert first the matrix to a transformation function.

iba = InverseFunction[iab] // MatrixForm

Using that I don't get any result. I can use TranslationTransform and RotationTransform to compute the inverse, but the problem with that approach is that I can only create a rotation matrix or a translation matrix, but not both in one transformation like in the above matrix I posted.

$\endgroup$
  • $\begingroup$ I'm confused: your matrix is not invertible. If it was, you could just use Inverse. Am I missing something? $\endgroup$ – march Feb 12 '16 at 23:45
  • $\begingroup$ Why my matrix is not invertible? I tried using Inverse and I got the following result: Inverse::sing: Matrix {{1,0,0,0},{0,0,-1,0},{0,1,0,3},{0,0,0,0}} is singular. >> $\endgroup$ – andrestoga Feb 12 '16 at 23:50
  • 1
    $\begingroup$ You can write a function which does the inversion. However, you cannot use the Inverse[] as inverse of transformation matrix is different than inverse of a general matrix. By inverse of transformation matrix we mean the matrix which takes back a rigid body to original orientation and position. $\endgroup$ – Saurav Feb 12 '16 at 23:50
  • $\begingroup$ By the way the (4,4) element in your transformation matrix should be $1$ or some scaling factor, not $0$. $\endgroup$ – Saurav Feb 12 '16 at 23:53
  • $\begingroup$ Your matrix is singular because the last row is all zeros. Or to put it another way: Det[{{1, 0, 0, 0}, {0, 0, -1, 0}, {0, 1, 0, 3}, {0, 0, 0, 0}}] returns zero. $\endgroup$ – m_goldberg Feb 12 '16 at 23:54
12
$\begingroup$

Here's a nice one-liner:

TransformationFunction[{{1, 0, 0, 0}, {0, 0, -1, 0}, {0, 1, 0, 3}, {0, 0, 0, 1}}]
// InverseFunction
   TransformationFunction[{{1, 0, 0, 0}, {0, 0, 1, -3}, {0, -1, 0, 0}, {0, 0, 0, 1}}]

Note that TransformationFunction[] is the head of the results returned by geometric *Transform functions, which take a homogeneous transformation matrix as an argument. Since you have the matrix already, you merely need to add the wrapper and then use InverseFunction[] to invert the transformation.


For future reference: Composition[] is a handy way to chain together more than one TransformationFunction:

Composition[TranslationTransform[{0, 0, 3}], RotationTransform[π/2, {1, 0, 0}]]

Alternatively, AffineTransform[] allows a direct construction:

AffineTransform[{RotationMatrix[π/2, {1, 0, 0}], {0, 0, 3}}]
$\endgroup$
11
$\begingroup$

If you have a homogenous transformation matrix of the form $$\begin{bmatrix} \mathrm{R_{3 \times 3}} & \mathrm{d}_{3 \times 1} \\ 0_{1\times 3} & 1_{1\times 1} \end{bmatrix}$$ Then the inverse is given by $$\begin{bmatrix} \mathrm{R}^{-1} & -\mathrm{R}^{-1}\mathrm{d} \\ 0 & 1 \end{bmatrix}$$

Therefore, if your homogeneous matrix is (I have added the 1 in the lower corner that I think should be there)

iab = {{1, 0, 0, 0},
       {0, 0, -1, 0},
       {0, 1, 0, 3},
       {0, 0, 0, 1}
      };

then the inverse can be written as (note that for rotation matrices, the inverse is the transpose)

homogeneousTransformationInverse[mat_] /; Dimensions[mat] == {4, 4} :=
  Module[{
     rot = Transpose[mat[[1 ;; 3, 1 ;; 3]]],
     vec = mat[[1 ;; 3, -1]],
     inv = mat
    },
   inv[[1 ;; 3, 1 ;; 3]] = rot;
   inv[[1 ;; 3, -1]] = -rot.vec;
   inv
  ]

enter image description here


I think the above is cleaner than the original version:

homogeneousTransformationInverse[mat_] /; Dimensions[mat] == {4, 4} :=
  Module[
   {rot = Transpose[mat[[1 ;; 3, 1 ;; 3]]], vec = mat[[1 ;; 3, -1]]},
   ArrayFlatten[{{rot, Map[List, -rot.vec]}, {{{0, 0, 0}}, {{mat[[-1, -1]]}}}}]
  ]
homogeneousTransformationInverse[iab] // MatrixForm
$\endgroup$
  • 1
    $\begingroup$ For rotation matrices, the transpose is same as inverse. Should use transpose as they are less expensive than inverse. $\endgroup$ – Saurav Feb 13 '16 at 0:25
  • $\begingroup$ @Saurav. True. Good recommendation. I will fix it. $\endgroup$ – march Feb 13 '16 at 0:26
  • $\begingroup$ I suppose you can mention about the transpose being equal to inverse in the answer. Else someone might end up getting confused as code does not match with the explanation. This should complete the answer. $\endgroup$ – Saurav Feb 13 '16 at 0:33
  • 1
    $\begingroup$ How I'd have done it: homogeneousTransformationInverse[mat_?SquareMatrixQ] /; Length[mat] == 4 := With[{rot = Take[mat, 3, 3]}, Transpose[ArrayFlatten[{{rot, 0}, {{-mat[[;; -2, -1]].rot}, 1}}]]]. Of course, if the appropriate part of the matrix is not orthogonal, Inverse[]/LinearSolve[] would be used instead. $\endgroup$ – J. M. is away Feb 13 '16 at 6:29
  • 1
    $\begingroup$ @J.M. I toyed with various things. Your way is cleaner (well, actually, your answer above is actually the best). I always have a hard time getting the correct nesting using ArrayFlatten, so once I found the way that works, I went with it. $\endgroup$ – march Feb 13 '16 at 6:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.