7
\$\begingroup\$

How can I get the new position of my vertex given a 4x4 transform matrix or simply 9 floats (positionX, positionY, positionZ, rotationH, rotationP, rotationR, scaleX, scaleY, scaleZ)? Usually I can assign the matrix to my final mesh (or "node", or "object", or "geom"), but right now I need to do it manually.

\$\endgroup\$

2 Answers 2

5
\$\begingroup\$

In order to apply a general 4x4 transformation matrix to a vertex represented as a 3 dimensional vector, you need to:

  1. Expand the vector into the 4th dimension by adding a 1 as the w component:

    (x, y, z) => (x, y, z, 1)

  2. Multiply the transformation matrix by the 4 dimensional vector above. The result will be another 4 dimensional vector:

    ( 4x4 matrix ) * (x, y, z, 1) => (tx, ty, tz, w)

    The general formula for multiplying a 4x4 matrix by a 4x1 vector is (if I didn't mess up):

    [ m11 m12 m13 m14 ][ x ]   [ m11 * x + m12 * y + m13 * z + m14 * w ]
    [ m21 m22 m23 m24 ][ y ]   [ m21 * x + m22 * y + m23 * z + m24 * w ]
    [ m31 m32 m33 m34 ][ z ] = [ m31 * x + m32 * y + m33 * z + m34 * w ]
    [ m41 m42 m43 m44 ][ w ]   [ m41 * x + m42 * y + m43 * z + m44 * w ]
    

    Or if you consider the usual configuration of a transformation matrix:

    [ m11 m12 m13 px ][ x ]   [ m11 * x + m12 * y + m13 * z + px ]
    [ m21 m22 m23 py ][ y ]   [ m21 * x + m22 * y + m23 * z + py ]
    [ m31 m32 m33 pz ][ z ] = [ m31 * x + m32 * y + m33 * z + pz ]
    [ 0   0   0   1  ][ 1 ]   [ 1 ]
    
  3. Convert it back into the 3rd dimension by homogenizing the vector, i.e. dividing everything by the fourth component w:

    (tx, ty, tz, w) => (tx/w, ty/w, tz/w)

    The thing is that if your transformation matrix only does a simple translation / rotation / scale, the value of w will be 1 and you can just drop the fourth component since that will be the same as dividing by 1.

    But it's good to remember that dropping w component does not work for every case, e.g. with projection matrices you must remember to do this third step.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ It won't hurt if you add that this is how you multiply for a point represented as a column, for a row you first write the vector then the matrix, also if you want to multiply multiple matrices you arrange it in a way so that in the equation the matrix that's closest to the vector gets applied first, it's just always good to say this because some libraries treat points as rows and some as columns and you have to distinguish that so that you apply matrices properly, also if you're going to go from column to row representation you have to transpose the transformation matrix \$\endgroup\$
    – dreta
    Apr 29, 2012 at 9:02
  • 1
    \$\begingroup\$ @dreta I did ponder about some of those points. I could add it but I think your comment already does a great job at covering all the bases, so I upvoted it instead :P \$\endgroup\$ Apr 29, 2012 at 9:17
1
\$\begingroup\$

Matrix-vector multiplication:

[ rxx rxy rxz px ] [ vx ]   [ vx' ]
[ ryx ryy ryz py ] [ vy ]   [ vy' ]
[ ryx ryy ryz pz ] [ vz ] = [ vz' ]
[   0   0   0  1 ] [  1 ]   [  1  ]

See the page on wikipedia for more

\$\endgroup\$
4
  • \$\begingroup\$ So multiply each vector component with the corresponding matrix column and ignore the last row? \$\endgroup\$
    – ioa
    Apr 29, 2012 at 8:19
  • \$\begingroup\$ No, you do matrix multiplication just as in math. For example the vx' term is computed like this vx' = rxx * vx + rxy * vy + rxz * vz + px \$\endgroup\$ Apr 29, 2012 at 8:22
  • \$\begingroup\$ Okay. I hope you don't mind me accepting the above answer. I think it will be more informative for others as well. \$\endgroup\$
    – ioa
    Apr 29, 2012 at 8:31
  • \$\begingroup\$ Of course, it's more cleanly written, it deserves it :) \$\endgroup\$ Apr 29, 2012 at 8:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .