/** \eigenManualPage TutorialGeometry Space transformations
In this page, we will introduce the many possibilities offered by the \ref Geometry_Module "geometry module" to deal with 2D and 3D rotations and projective or affine transformations.
\eigenAutoToc
Eigen's Geometry module provides two different kinds of geometric transformations:
- Abstract transformations, such as rotations (represented by \ref AngleAxis "angle and axis" or by a \ref Quaternion "quaternion"), \ref Translation "translations", \ref Scaling "scalings". These transformations are NOT represented as matrices, but you can nevertheless mix them with matrices and vectors in expressions, and convert them to matrices if you wish.
- Projective or affine transformation matrices: see the Transform class. These are really matrices.
\note If you are working with OpenGL 4x4 matrices then Affine3f and Affine3d are what you want. Since Eigen defaults to column-major storage, you can directly use the Transform::data() method to pass your transformation matrix to OpenGL.
You can construct a Transform from an abstract transformation, like this:
\code
Transform t(AngleAxis(angle,axis));
\endcode
or like this:
\code
Transform t;
t = AngleAxis(angle,axis);
\endcode
But note that unfortunately, because of how C++ works, you can \b not do this:
\code
Transform t = AngleAxis(angle,axis);
\endcode
<span class="note">\b Explanation: In the C++ language, this would require Transform to have a non-explicit conversion constructor from AngleAxis, but we really don't want to allow implicit casting here.
<tr><td colspan="2">(See subject 5.27 of this <a href="http://www.faqs.org/faqs/graphics/algorithms-faq">faq</a> for the explanations)</td></tr>
<tr class="alt"><td>
Apply a transformation with \em pure \em rotation \n to a \b normal \b vector
(no scaling, no shear)</td><td>\code
n2 = t.linear() * n1;\endcode</td></tr>
<tr><td>
OpenGL compatibility \b 3D </td><td>\code
glLoadMatrixf(t.data());\endcode</td></tr>
<tr class="alt"><td>
OpenGL compatibility \b 2D </td><td>\code
Affine3f aux(Affine3f::Identity());
aux.linear().topLeftCorner<2,2>() = t.linear();
aux.translation().start<2>() = t.translation();
glLoadMatrixf(aux.data());\endcode</td></tr>
</table>
\b Component \b accessors
<table class="manual">
<tr><td>
full read-write access to the internal matrix</td><td>\code
t.matrix() = matN1xN1; // N1 means N+1
matN1xN1 = t.matrix();
\endcode</td></tr>
<tr class="alt"><td>
coefficient accessors</td><td>\code
t(i,j) = scalar; <=> t.matrix()(i,j) = scalar;
scalar = t(i,j); <=> scalar = t.matrix()(i,j);
\endcode</td></tr>
<tr><td>
translation part</td><td>\code
t.translation() = vecN;
vecN = t.translation();
\endcode</td></tr>
<tr class="alt"><td>
linear part</td><td>\code
t.linear() = matNxN;
matNxN = t.linear();
\endcode</td></tr>
<tr><td>
extract the rotation matrix</td><td>\code
matNxN = t.rotation();
\endcode</td></tr>
</table>
\b Transformation \b creation \n
While transformation objects can be created and updated concatenating elementary transformations,
the Transform class also features a procedural API:
<table class="manual">
<tr><th></th><th>procedural API</th><th>equivalent natural API </th></tr>
<tr><td>Translation</td><td>\code
t.translate(Vector_(tx,ty,..));
t.pretranslate(Vector_(tx,ty,..));
\endcode</td><td>\code
t *= Translation_(tx,ty,..);
t = Translation_(tx,ty,..) * t;
\endcode</td></tr>
<tr class="alt"><td>\b Rotation \n <em class="note">In 2D and for the procedural API, any_rotation can also \n be an angle in radian</em></td><td>\code