[Insight-users] Get angle values from a 3D affine transform

Luis Ibanez luis.ibanez at kitware.com
Fri Aug 11 15:39:38 EDT 2006


Hi Yan,

A better method for extracting rotation information is
to compute the Polar decomposition of the Affine Matrix.

For background in this method, please look at:

Polar decomposition algorithm proposed by [Higham 86]
SIAM J. Sci. Stat. Comput. Vol. 7, Num. 4, October 1986.
"Computing the Polar Decomposition - with Applications"
by Nicholas Higham.

recommended by
Shoemake in the paper "Matrix Animation and Polar Decomposition".
http://citeseer.ist.psu.edu/shoemake92matrix.html



You can do this with the following code:



   typedef vnl_matrix<double> VnlMatrixType;

   VnlMatrixType M = initialAffine->GetMatrix().GetVnlMatrix();

   VnlMatrixType PQ = M;
   VnlMatrixType NQ = M;
   VnlMatrixType PQNQDiff;

   const unsigned int maximumIterations = 100;

   for(unsigned int ni = 0; ni < maximumIterations; ni++ )
     {
     // Average current Qi with its inverse transpose
     NQ = ( PQ + vnl_inverse_transpose( PQ ) ) / 2.0;
     PQNQDiff = NQ - PQ;
     if( PQNQDiff.frobenius_norm() < 1e-7 )
       {
       std::cout << "Polar decomposition used "
                 << ni << " iterations " << std::endl;
       break;
       }
     else
       {
       PQ = NQ;
       }
     }

   MatrixType QMatrix;

   QMatrix = NQ;

   std::cout << "Initial Matrix = " << std::endl << M << std::endl;
   std::cout << "Q Matrix = " << std::endl << QMatrix << std::endl;

   VersorType versor;
   versor.Set( QMatrix );

   std::cout << versor.GetAxis() << std::endl;
   std::cout << versor.GetAngle() << std::endl;



Note that Versors (=unit Quaternions) are a much better description
of rotations in 3D space than Euler angles. Euler angles are ambiguous
unles you specify the order in which the rotations are applied.

Note also that the components of a versor *are not* equivalent to
Euler angles.  For details on Quaternions you may want to look at
the ITK Tutorials:

       http://www.itk.org/HTML/Tutorials.htm

in particular to:

  http://www.itk.org/CourseWare/Training/QuaternionsI.pdf
  http://www.itk.org/CourseWare/Training/QuaternionsII.pdf



  Regards,


     Luis




---------------
Yan Yang wrote:
> Hi All,
>  
> Could you have a look at my method, I am not sure if it is correct. 
> Thanks in advance.
>  
> I am trying to extract angle information from a 3D affine transform, I 
> want to know if I can do as the following steps.
>  
> 1. Decompose the affine transform matrix (A) excluding translation using 
> SVD (vnl_svd), get A = UWV,
>     so the rotaiton matrix can be R = UV'.
>  
> 2. Create an euler transform (E) using the rotation matrix, 
> E->setMatrix( R ),
>  
> 3. Calculate the three angles around axes by
>     angleX = E->GetAngleX()
>     angleY = E->GetAngleY()
>     angleZ = E->GetAngleZ()
>  
> Am I right?
>  
> By the way, should the rotation matrix R be vnl_matrix type? Does 
> vnl_matrix support 3D?
>  
> Thanks,
>  
> Yan
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Insight-users mailing list
> Insight-users at itk.org
> http://www.itk.org/mailman/listinfo/insight-users




More information about the Insight-users mailing list