c++ - How do I invert an affine transformation with translation, rotation, and scaling? -


i have 4x4 matrix translation, rotation, , scaling components, no shear or other transformations. how find inverse? i'm using eigen library in c++.

this tricky right, since operations need performed in correct order:

template<class derived> matrix4f affineinverse(const eigen::matrixbase<derived>& mat) {     matrix3f rotsclinv = (         mat.block<3, 3>(0, 0).array().rowwise()         / mat.block<3, 3>(0, 0).colwise().squarednorm().array() //scaling         ).transpose(); //rotation     return (matrix4f(4,4) << rotsclinv         , -rotsclinv * mat.block<3, 1>(0, 3) //translation         , 0, 0, 0, 1).finished(); } 

as this answer states, inverse of top left 3x3 block can calculated separately:

inv ([ b ]) = [inv(a)  -inv(a)*b]     ([ 0 1 ])   [  0          1   ] 

the key insight top left block scaling , rotation equal orthogonal (rotation) matrix q times diagonal (scaling) matrix d: q*d. invert it, linear algebra:

  inv(q*d) = transp(transp(inv(q*d))) = transp(inv(transp(q*d))) = transp(inv(transp(d)*transp(q))) 

(see this proof), , since d diagonal , q orthogonal,

= transp(inv(d*inv(q))) = transp(q*inv(d))). 

q*inv(d) easy find: since in q*d each column column of q (which unit vector) times entry of d (which scalar), enough divide each column square of norm. first 3 lines of function do.

written out in linear algebra form:

inv ([ q*d b ]) = [transp(q*inv(d))  -transp(q*inv(d))*b]     ([ 0   1 ])   [       0                 1           ] 

Comments

Popular posts from this blog

Java 3D LWJGL collision -

spring - SubProtocolWebSocketHandler - No handlers -

methods - python can't use function in submodule -