<br>thank you, I&#39;m putting versors on my list of things to look at.<br><br>cheers, Michael<br><br><div class="gmail_quote">On Tue, Mar 30, 2010 at 3:35 PM, Luis Ibanez <span dir="ltr">&lt;<a href="mailto:luis.ibanez@kitware.com">luis.ibanez@kitware.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Hi Michiel,<br>
<br>
This is actually the reason why using Euler angles is a bad idea.<br>
<br>
           The lack of a standard for the order of<br>
           application of the individual rotations.<br>
<br>
plus their vulnerability to the gimbal lock problem:<br>
<br>
             <a href="http://en.wikipedia.org/wiki/Gimbal_lock" target="_blank">http://en.wikipedia.org/wiki/Gimbal_lock</a><br>
<br>
<a href="http://en.wikipedia.org/wiki/Gimbal_lock#Loss_of_a_degree_of_freedom_with_Euler_angles" target="_blank">http://en.wikipedia.org/wiki/Gimbal_lock#Loss_of_a_degree_of_freedom_with_Euler_angles</a><br>
<br>
<br>
---<br>
<br>
I would strongly encourage you to use itk::Versors instead.<br>
<br>
Versors (Unit Quaternions) are an unambiguous representation of<br>
rotations.<br>
<br>
<br>
    Regards,<br>
<br>
<br>
          Luis<br>
<br>
<br>
------------------------------------------------------------------------<br>
On Tue, Mar 30, 2010 at 9:11 AM, michiel mentink<br>
<div><div></div><div class="h5">&lt;<a href="mailto:michael.mentink@st-hughs.ox.ac.uk">michael.mentink@st-hughs.ox.ac.uk</a>&gt; wrote:<br>
&gt; in<br>
&gt; /itkEuler3DTransform.txx<br>
&gt; the rotation is applied either in X Y Z order, or Z X Y order (standard),<br>
&gt; where Y rotation is applied first.<br>
&gt;<br>
&gt; Indeed, if I try different orders of rotation, I get different outcomes. I<br>
&gt; suppose this is due to round-off<br>
&gt; errors.<br>
&gt; Why is Z X Y chosen as the standard way of multiplication?<br>
&gt;<br>
&gt;<br>
&gt; Z Y X<br>
&gt; image-&gt;GetDirection():<br>
&gt;  0.999695   0.0171452 0.0177517<br>
&gt; -0.0174497  0.999701  0.0171452<br>
&gt; -0.0174524 -0.0174497 0.999695<br>
&gt;<br>
&gt; X Y Z<br>
&gt; image-&gt;GetDirection():<br>
&gt; 0.999695    0.0174497 0.0174524<br>
&gt; -0.0177543  0.99969   0.0174497<br>
&gt; -0.0171425 -0.0177543 0.999695<br>
&gt;<br>
&gt; Z X Y<br>
&gt; image-&gt;GetDirection():<br>
&gt;  0.99969    0.0174497 0.0177543<br>
&gt; -0.0177543  0.999695  0.0171425<br>
&gt; -0.0174497 -0.0174524 0.999695<br>
&gt;<br>
&gt; cheers,<br>
&gt;<br>
&gt; Michael<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; On Tue, Mar 30, 2010 at 12:18 PM, michiel mentink<br>
&gt; &lt;<a href="mailto:michael.mentink@st-hughs.ox.ac.uk">michael.mentink@st-hughs.ox.ac.uk</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; ah just after posting I found it (figures!)<br>
&gt;&gt;<br>
&gt;&gt; complete and correct code now:<br>
&gt;&gt;<br>
&gt;&gt;   const ImageType::DirectionType &amp; direction = image-&gt;GetDirection()<br>
&gt;&gt;   std::cout &lt;&lt; &quot;direction: &quot; &lt;&lt; std::endl &lt;&lt; direction &lt;&lt; std::endl &lt;&lt;<br>
&gt;&gt; std::endl;<br>
&gt;&gt;<br>
&gt;&gt;   float angleX, angleY, angleZ;<br>
&gt;&gt;   angleX = angleY = angleZ = 1  *   vnl_math::pi / 180.0;             //<br>
&gt;&gt; in this case: rotation = 1 degree<br>
&gt;&gt;<br>
&gt;&gt;   const double cx = vcl_cos(angleX);<br>
&gt;&gt;   const double sx = vcl_sin(angleX);<br>
&gt;&gt;<br>
&gt;&gt;   typedef itk::Matrix&lt;double,3,3&gt; Matrix;<br>
&gt;&gt;   Matrix RotationX;<br>
&gt;&gt;   Matrix FinalRotation = image-&gt;GetDirection();<br>
&gt;&gt;<br>
&gt;&gt;   std::cout &lt;&lt; &quot;sin: &quot; &lt;&lt; sx &lt;&lt; &quot; Cos: &quot; &lt;&lt; cx &lt;&lt; std::endl;<br>
&gt;&gt;<br>
&gt;&gt;   RotationX[0][0] = 1; RotationX[0][1] =   0; RotationX[0][2] = 0;<br>
&gt;&gt;   RotationX[1][0] = 0; RotationX[1][1] =  cx; RotationX[1][2] = sx;<br>
&gt;&gt;   RotationX[2][0] = 0; RotationX[2][1] = -sx; RotationX[2][2] = cx;<br>
&gt;&gt;<br>
&gt;&gt;   FinalRotation = direction*RotationX;<br>
&gt;&gt;<br>
&gt;&gt;   std::cout &lt;&lt; &quot;image-&gt;GetDirection(): &quot; &lt;&lt; std::endl &lt;&lt;<br>
&gt;&gt; image-&gt;GetDirection() &lt;&lt; std::endl;<br>
&gt;&gt;   std::cout &lt;&lt; &quot;RotationX: &quot; &lt;&lt; std::endl &lt;&lt; RotationX &lt;&lt; std::endl;<br>
&gt;&gt;   std::cout &lt;&lt; &quot;FinalRotation: &quot; &lt;&lt; std::endl &lt;&lt; FinalRotation &lt;&lt;<br>
&gt;&gt; std::endl;<br>
&gt;&gt;<br>
&gt;&gt;   image-&gt;SetDirection(FinalRotation);<br>
&gt;&gt;<br>
&gt;&gt;   std::cout &lt;&lt; &quot;image-&gt;GetDirection(): &quot; &lt;&lt; std::endl &lt;&lt;<br>
&gt;&gt; image-&gt;GetDirection() &lt;&lt; std::endl;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; cheers, Michael<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; On Tue, Mar 30, 2010 at 12:10 PM, michiel mentink<br>
&gt;&gt; &lt;<a href="mailto:michael.mentink@st-hughs.ox.ac.uk">michael.mentink@st-hughs.ox.ac.uk</a>&gt; wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Hello Frederic,<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; thanks for your suggestion.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; although my code was working, I tried your suggestion. Unfortunately, it<br>
&gt;&gt;&gt; produces<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; error: no match for ‘operator*’ in<br>
&gt;&gt;&gt; ‘image.itk::SmartPointer&lt;TObjectType&gt;::operator-&gt; [with TObjectType =<br>
&gt;&gt;&gt; itk::Image&lt;float, 3u&gt;]()-&gt;itk::ImageBase&lt;VImageDimension&gt;::GetDirection<br>
&gt;&gt;&gt; [with unsigned int VImageDimension = 3u] * RotationX’<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Anyway, I forgot to mention to use:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;   float angleX, angleY, angleZ;<br>
&gt;&gt;&gt;   angleX = angleY = angleZ = 1 * (3.14/180);<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; (multiply by pi and divide by 180 degrees, because ITK internally works<br>
&gt;&gt;&gt; with radians instead of degrees)<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Which leads me to the question: vnl has a pi constant, and I remember<br>
&gt;&gt;&gt; vaguely having seen it somewhere as vnl::PI or something.<br>
&gt;&gt;&gt; Does anyone know how to convince vnl to hand me pi constant?<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; cheers, Michael<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; On Tue, Mar 30, 2010 at 11:55 AM, Frederic Perez &lt;<a href="mailto:fredericpcx@gmail.com">fredericpcx@gmail.com</a>&gt;<br>
&gt;&gt;&gt; wrote:<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Hello Michiel,<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; perhaps you could use a const Matrix object after all, since it looks to<br>
&gt;&gt;&gt;&gt; me that FinalRotation is first built with image-&gt;GetDirection() but this<br>
&gt;&gt;&gt;&gt; value is not actually used, and that the signature of itk::Image&#39;s is<br>
&gt;&gt;&gt;&gt; SetDirection(const DirectionType direction).<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; So here you are, my quickly written proposal (caution, I haven&#39;t<br>
&gt;&gt;&gt;&gt; compiled it):<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;   float angleX, angleY, angleZ;<br>
&gt;&gt;&gt;&gt;   angleX = angleY = angleZ = 5;<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;   const double cx = vcl_cos(angleX);<br>
&gt;&gt;&gt;&gt;   const double sx = vcl_sin(angleX);<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;   typedef itk::Matrix&lt;double,3,3&gt; Matrix;<br>
&gt;&gt;&gt;&gt;   Matrix RotationX;<br>
&gt;&gt;&gt;&gt;   // Matrix FinalRotation = image-&gt;GetDirection(); -- Commented now<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;   RotationX[0][0] = 1; RotationX[0][1] =   0;  RotationX[0][2] = 0;<br>
&gt;&gt;&gt;&gt;   RotationX[1][0] = 0; RotationX[1][1] =  cx; RotationX[1][2] = sx;<br>
&gt;&gt;&gt;&gt;   RotationX[2][0] = 0; RotationX[2][1] = -sx; RotationX[2][2] = cx;<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;   const Matrix FinalRotation = direction*RotationX;<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;   std::cout &lt;&lt; &quot;image-&gt;GetDirection(): &quot; &lt;&lt; std::endl &lt;&lt;<br>
&gt;&gt;&gt;&gt; image-&gt;GetDirection() &lt;&lt; std::endl;<br>
&gt;&gt;&gt;&gt;   std::cout &lt;&lt; &quot;RotationX: &quot; &lt;&lt; std::endl &lt;&lt; RotationX &lt;&lt; std::endl;<br>
&gt;&gt;&gt;&gt;   std::cout &lt;&lt; &quot;FinalRotation: &quot; &lt;&lt; std::endl &lt;&lt; FinalRotation &lt;&lt;<br>
&gt;&gt;&gt;&gt; std::endl;<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;   image-&gt;SetDirection(FinalRotation);<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;   std::cout &lt;&lt; &quot;image-&gt;GetDirection(): &quot; &lt;&lt; std::endl &lt;&lt;<br>
&gt;&gt;&gt;&gt; image-&gt;GetDirection() &lt;&lt; std::endl;<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Cheers,<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Frederic<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;<br>
&gt;<br>
</div></div></blockquote></div><br>