namespace Eigen { /** \page TutorialGeometry Tutorial 2/3 - Geometry \ingroup Tutorial
\ref index "Overview" | \ref TutorialCore "Core features" | \b Geometry | \ref TutorialAdvancedLinearAlgebra "Advanced linear algebra"
In this tutorial chapter we will shortly introduce the many possibilities offered by the \ref GeometryModule "geometry module", namely 2D and 3D rotations and affine transformations. \b Table \b of \b contents - \ref TutorialGeoElementaryTransformations - \ref TutorialGeoCommontransformationAPI - \ref TutorialGeoTransform - \ref TutorialGeoEulerAngles \section TutorialGeoElementaryTransformations Transformation types
Transformation typeTypical initialization code
2D rotation from an angle\code Rotation2D rot2(angle_in_radian);\endcode
3D rotation as an angle + axis\code AngleAxis aa(angle_in_radian, Vector3f(ax,ay,az));\endcode
3D rotation as a quaternion\code Quaternion q = AngleAxis(angle_in_radian, axis);\endcode
N-D Scaling\code Scaling(sx, sy) Scaling(sx, sy, sz) Scaling(s) Scaling(vecN)\endcode
N-D Translation\code Translation(tx, ty) Translation(tx, ty, tz) Translation(s) Translation(vecN)\endcode
N-D \ref TutorialGeoTransform "Affine transformation"\code Transform t = concatenation_of_any_transformations; Transform t = Translation3f(p) * AngleAxisf(a,axis) * Scaling3f(s);\endcode
N-D Linear transformations \n (pure rotations, \n scaling, etc.)\code Matrix t = concatenation_of_rotations_and_scalings; Matrix t = Rotation2Df(a) * Scaling2f(s); Matrix t = AngleAxisf(a,axis) * Scaling3f(s);\endcode
Notes on rotations\n To transform more than a single vector the preferred representations are rotation matrices, while for other usages Quaternion is the representation of choice as they are compact, fast and stable. Finally Rotation2D and AngleAxis are mainly convenient types to create other rotation objects. Notes on Translation and Scaling\n Likewise AngleAxis, these classes were designed to simplify the creation/initialization of linear (Matrix) and affine (Transform) transformations. Nevertheless, unlike AngleAxis which is inefficient to use, these classes might still be interesting to write generic and efficient algorithms taking as input any kind of transformations. Any of the above transformation types can be converted to any other types of the same nature, or to a more generic type. Here are come additional examples:
\code Rotation2Df r = Matrix2f(..); // assumes a pure rotation matrix AngleAxisf aa = Quaternionf(..); AngleAxisf aa = Matrix3f(..); // assumes a pure rotation matrix Matrix2f m = Rotation2Df(..); Matrix3f m = Quaternionf(..); Matrix3f m = Scaling3f(..); Transform3f m = AngleAxis3f(..); Transform3f m = Scaling3f(..); Transform3f m = Translation3f(..); Transform3f m = Matrix3f(..); \endcode
top\section TutorialGeoCommontransformationAPI Common API across transformation types To some extent, Eigen's \ref GeometryModule "geometry module" allows you to write generic algorithms working on any kind of transformation representations:
Concatenation of two transformations\code gen1 * gen2;\endcode
Apply the transformation to a vector\code vec2 = gen1 * vec1;\endcode
Get the inverse of the transformation\code gen2 = gen1.inverse();\endcode
Spherical interpolation \n (Rotation2D and Quaternion only)\code rot3 = rot1.slerp(alpha,rot2);\endcode
top\section TutorialGeoTransform Affine transformations Generic affine transformations are represented by the Transform class which internaly is a (Dim+1)^2 matrix. In Eigen we have chosen to not distinghish between points and vectors such that all points are actually represented by displacement vectors from the origin ( \f$ \mathbf{p} \equiv \mathbf{p}-0 \f$ ). With that in mind, real points and vector distinguish when the transformation is applied.
Apply the transformation to a \b point \code VectorNf p1, p2; p2 = t * p1;\endcode
Apply the transformation to a \b vector \code VectorNf vec1, vec2; vec2 = t.linear() * vec1;\endcode
Apply a \em general transformation \n to a \b normal \b vector (explanations)\code VectorNf n1, n2; MatrixNf normalMatrix = t.linear().inverse().transpose(); n2 = (normalMatrix * n1).normalized();\endcode
Apply a transformation with \em pure \em rotation \n to a \b normal \b vector (no scaling, no shear)\code n2 = t.linear() * n1;\endcode
OpenGL compatibility \b 3D \code glLoadMatrixf(t.data());\endcode
OpenGL compatibility \b 2D \code Transform3f aux(Transform3f::Identity); aux.linear().corner<2,2>(TopLeft) = t.linear(); aux.translation().start<2>() = t.translation(); glLoadMatrixf(aux.data());\endcode
\b Component \b accessors
full read-write access to the internal matrix\code t.matrix() = matN1xN1; // N1 means N+1 matN1xN1 = t.matrix(); \endcode
coefficient accessors\code t(i,j) = scalar; <=> t.matrix()(i,j) = scalar; scalar = t(i,j); <=> scalar = t.matrix()(i,j); \endcode
translation part\code t.translation() = vecN; vecN = t.translation(); \endcode
linear part\code t.linear() = matNxN; matNxN = t.linear(); \endcode
extract the rotation matrix\code matNxN = t.extractRotation(); \endcode
\b Transformation \b creation \n While transformation objects can be created and updated concatenating elementary transformations, the Transform class also features a procedural API:
\b procedurale \b API \b equivalent \b natural \b API
Translation\code t.translate(Vector_(tx,ty,..)); t.pretranslate(Vector_(tx,ty,..)); \endcode\code t *= Translation_(tx,ty,..); t = Translation_(tx,ty,..) * t; \endcode
\b Rotation \n In 2D, any_rotation can also \n be an angle in radian\code t.rotate(any_rotation); t.prerotate(any_rotation); \endcode\code t *= any_rotation; t = any_rotation * t; \endcode
Scaling\code t.scale(Vector_(sx,sy,..)); t.scale(s); t.prescale(Vector_(sx,sy,..)); t.prescale(s); \endcode\code t *= Scaling_(sx,sy,..); t *= Scaling_(s); t = Scaling_(sx,sy,..) * t; t = Scaling_(s) * t; \endcode
Shear transformation \n ( \b 2D \b only ! )\code t.shear(sx,sy); t.preshear(sx,sy); \endcode
Note that in both API, any many transformations can be concatenated in a single expression as shown in the two following equivalent examples:
\code t.pretranslate(..).rotate(..).translate(..).scale(..); \endcode
\code t = Translation_(..) * t * RotationType(..) * Translation_(..) * Scaling_(..); \endcode
top\section TutorialGeoEulerAngles Euler angles
Euler angles might be convenient to create rotation objects. On the other hand, since there exist 24 differents convensions,they are pretty confusing to use. This example shows how to create a rotation matrix according to the 2-1-2 convention.\code Matrix3f m; m = AngleAxisf(angle1, Vector3f::UnitZ()) * * AngleAxisf(angle2, Vector3f::UnitY()) * * AngleAxisf(angle3, Vector3f::UnitZ()); \endcode
*/ }