From 994629721a3e72e83b2df597d5f78d1dc9398c09 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Sun, 31 Aug 2008 17:30:09 +0000 Subject: update of the geometry tutorial --- doc/TutorialGeometry.dox | 230 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 doc/TutorialGeometry.dox (limited to 'doc/TutorialGeometry.dox') diff --git a/doc/TutorialGeometry.dox b/doc/TutorialGeometry.dox new file mode 100644 index 000000000..69ca78997 --- /dev/null +++ b/doc/TutorialGeometry.dox @@ -0,0 +1,230 @@ +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
+ +*/ + +} -- cgit v1.2.3