diff options
author | Gael Guennebaud <g.gael@free.fr> | 2008-08-31 17:30:09 +0000 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2008-08-31 17:30:09 +0000 |
commit | 994629721a3e72e83b2df597d5f78d1dc9398c09 (patch) | |
tree | 110769ae85411d5eaa6b1d85250d9bc4580058b9 | |
parent | d74916e4fe970030a1074fcf35328c3b49c1f899 (diff) |
update of the geometry tutorial
-rw-r--r-- | doc/QuickStartGuide.dox | 8 | ||||
-rw-r--r-- | doc/TutorialGeometry.dox | 230 | ||||
-rw-r--r-- | doc/eigendoxy.css | 2 | ||||
-rw-r--r-- | doc/examples/Tutorial_simple_example_dynamic_size.cpp | 9 | ||||
-rw-r--r-- | doc/examples/Tutorial_simple_example_fixed_size.cpp | 3 |
5 files changed, 242 insertions, 10 deletions
diff --git a/doc/QuickStartGuide.dox b/doc/QuickStartGuide.dox index b7cbf3046..96497073d 100644 --- a/doc/QuickStartGuide.dox +++ b/doc/QuickStartGuide.dox @@ -312,7 +312,7 @@ etc. </td></tr> <tr><td> \link Cwise::min min \endlink, \link Cwise::max max \endlink, \n -absolute value (\link Cwise::abs() abs \endlink, \link Cwise::abs2() abs2 \endlink +absolute value (\link Cwise::abs() abs \endlink, \link Cwise::abs2() abs2 \endlink) </td><td>\code mat3 = mat1.cwise().min(mat2); mat3 = mat1.cwise().max(mat2); @@ -410,8 +410,7 @@ Read-write access to sub-matrices: vec1 = mat1.diagonal(); mat1.diagonal() = vec1; \endcode - \link MatrixBase::diagonal() (more) \endlink</td></td> - <td></td> + \link MatrixBase::diagonal() (more) \endlink</td><td></td><td></td></tr> </table> @@ -442,7 +441,7 @@ vec1.normalize();\endcode </td></tr> <tr><td> \link MatrixBase::asDiagonal() make a diagonal matrix \endlink from a vector \n -\b Note: this product is automatically optimized !</td><td>\code +<em class="note">this product is automatically optimized !</em></td><td>\code mat3 = mat1 * vec2.asDiagonal();\endcode </td></tr> <tr><td> @@ -498,6 +497,7 @@ forces immediate evaluation of the transpose</td></tr> /** \page TutorialGeometry Tutorial 2/3 - Geometry \ingroup Tutorial + \internal <div class="eimainmenu">\ref index "Overview" | \ref TutorialCore "Core features" 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 + +<div class="eimainmenu">\ref index "Overview" + | \ref TutorialCore "Core features" + | \b Geometry + | \ref TutorialAdvancedLinearAlgebra "Advanced linear algebra" +</div> + +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 + +<table class="tutorial_code"> +<tr><td>Transformation type</td><td>Typical initialization code</td></tr> +<tr><td> +2D rotation from an angle</td><td>\code +Rotation2D<float> rot2(angle_in_radian);\endcode</td></tr> +<tr><td> +3D rotation as an angle + axis</td><td>\code +AngleAxis<float> aa(angle_in_radian, Vector3f(ax,ay,az));\endcode</td></tr> +<tr><td> +3D rotation as a quaternion</td><td>\code +Quaternion<float> q = AngleAxis<float>(angle_in_radian, axis);\endcode</td></tr> +<tr><td> +N-D Scaling</td><td>\code +Scaling<float,2>(sx, sy) +Scaling<float,3>(sx, sy, sz) +Scaling<float,N>(s) +Scaling<float,N>(vecN)\endcode</td></tr> +<tr><td> +N-D Translation</td><td>\code +Translation<float,2>(tx, ty) +Translation<float,3>(tx, ty, tz) +Translation<float,N>(s) +Translation<float,N>(vecN)\endcode</td></tr> +<tr><td> +N-D \ref TutorialGeoTransform "Affine transformation"</td><td>\code +Transform<float,N> t = concatenation_of_any_transformations; +Transform<float,3> t = Translation3f(p) * AngleAxisf(a,axis) * Scaling3f(s);\endcode</td></tr> +<tr><td> +N-D Linear transformations \n +<em class=note>(pure rotations, \n scaling, etc.)</em></td><td>\code +Matrix<float,N> t = concatenation_of_rotations_and_scalings; +Matrix<float,2> t = Rotation2Df(a) * Scaling2f(s); +Matrix<float,3> t = AngleAxisf(a,axis) * Scaling3f(s);\endcode</td></tr> +</table> + +<strong>Notes on rotations</strong>\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. + +<strong>Notes on Translation and Scaling</strong>\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: +<table class="tutorial_code"> +<tr><td>\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</td></tr> +</table> + + +<a href="#" class="top">top</a>\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: +<table class="tutorial_code"> +<tr><td> +Concatenation of two transformations</td><td>\code +gen1 * gen2;\endcode</td></tr> +<tr><td>Apply the transformation to a vector</td><td>\code +vec2 = gen1 * vec1;\endcode</td></tr> +<tr><td>Get the inverse of the transformation</td><td>\code +gen2 = gen1.inverse();\endcode</td></tr> +<tr><td>Spherical interpolation \n (Rotation2D and Quaternion only)</td><td>\code +rot3 = rot1.slerp(alpha,rot2);\endcode</td></tr> +</table> + + + +<a href="#" class="top">top</a>\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. +<table class="tutorial_code"> +<tr><td> +Apply the transformation to a \b point </td><td>\code +VectorNf p1, p2; +p2 = t * p1;\endcode</td></tr> +<tr><td> +Apply the transformation to a \b vector </td><td>\code +VectorNf vec1, vec2; +vec2 = t.linear() * vec1;\endcode</td></tr> +<tr><td> +Apply a \em general transformation \n to a \b normal \b vector +(<a href="http://www.cgafaq.info/wiki/Transforming_normals">explanations</a>)</td><td>\code +VectorNf n1, n2; +MatrixNf normalMatrix = t.linear().inverse().transpose(); +n2 = (normalMatrix * n1).normalized();\endcode</td></tr> +<tr><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><td> +OpenGL compatibility \b 2D </td><td>\code +Transform3f aux(Transform3f::Identity); +aux.linear().corner<2,2>(TopLeft) = t.linear(); +aux.translation().start<2>() = t.translation(); +glLoadMatrixf(aux.data());\endcode</td></tr> +</table> + +\b Component \b accessors</td></tr> +<table class="tutorial_code"> +<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><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><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.extractRotation(); +\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="tutorial_code"> +<tr><td></td><td>\b procedurale \b API </td><td>\b equivalent \b natural \b API </td></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><td>\b Rotation \n <em class="note">In 2D, any_rotation can also \n be an angle in radian</em></td><td>\code +t.rotate(any_rotation); +t.prerotate(any_rotation); +\endcode</td><td>\code +t *= any_rotation; +t = any_rotation * t; +\endcode</td></tr> +<tr><td>Scaling</td><td>\code +t.scale(Vector_(sx,sy,..)); +t.scale(s); +t.prescale(Vector_(sx,sy,..)); +t.prescale(s); +\endcode</td><td>\code +t *= Scaling_(sx,sy,..); +t *= Scaling_(s); +t = Scaling_(sx,sy,..) * t; +t = Scaling_(s) * t; +\endcode</td></tr> +<tr><td>Shear transformation \n ( \b 2D \b only ! )</td><td>\code +t.shear(sx,sy); +t.preshear(sx,sy); +\endcode</td><td></td></tr> +</table> + +Note that in both API, any many transformations can be concatenated in a single expression as shown in the two following equivalent examples: +<table class="tutorial_code"> +<tr><td>\code +t.pretranslate(..).rotate(..).translate(..).scale(..); +\endcode</td></tr> +<tr><td>\code +t = Translation_(..) * t * RotationType(..) * Translation_(..) * Scaling_(..); +\endcode</td></tr> +</table> + + + +<a href="#" class="top">top</a>\section TutorialGeoEulerAngles Euler angles +<table class="tutorial_code"> +<tr><td style="max-width:30em;"> +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.</td><td>\code +Matrix3f m; +m = AngleAxisf(angle1, Vector3f::UnitZ()) +* * AngleAxisf(angle2, Vector3f::UnitY()) +* * AngleAxisf(angle3, Vector3f::UnitZ()); +\endcode</td></tr> +</table> + +*/ + +} diff --git a/doc/eigendoxy.css b/doc/eigendoxy.css index 949a1368a..1e20503c5 100644 --- a/doc/eigendoxy.css +++ b/doc/eigendoxy.css @@ -451,7 +451,7 @@ A.top { A.top:hover, A.logo:hover { background-color: transparent;font-weight : bolder; } -SPAN.note { +.note { font-size: 8.5pt; } diff --git a/doc/examples/Tutorial_simple_example_dynamic_size.cpp b/doc/examples/Tutorial_simple_example_dynamic_size.cpp index 19cfa6af5..5aecc8746 100644 --- a/doc/examples/Tutorial_simple_example_dynamic_size.cpp +++ b/doc/examples/Tutorial_simple_example_dynamic_size.cpp @@ -7,10 +7,11 @@ int main(int, char *[]) { for (int size=1; size<=4; ++size) { - MatrixXi m(size,size+1); // creates a size x (size+1) matrix of int - for (int j=0; j<m.cols(); ++j) // loop over the columns - for (int i=0; i<m.rows(); ++i) // loop over the rows - m(i,j) = i+j*m.rows(); // to access matrix elements use operator (int,int) + MatrixXi m(size,size+1); // a size x (size+1) matrix of int + for (int j=0; j<m.cols(); ++j) // loop over the columns + for (int i=0; i<m.rows(); ++i) // loop over the rows + m(i,j) = i+j*m.rows(); // to access matrix elements + // use operator (int,int) std::cout << m << "\n\n"; } diff --git a/doc/examples/Tutorial_simple_example_fixed_size.cpp b/doc/examples/Tutorial_simple_example_fixed_size.cpp index 71bf1bafb..043a84831 100644 --- a/doc/examples/Tutorial_simple_example_fixed_size.cpp +++ b/doc/examples/Tutorial_simple_example_fixed_size.cpp @@ -10,5 +10,6 @@ int main(int, char *[]) Matrix4f m4 = Matrix4f::Identity(); Vector4i v4(1, 2, 3, 4); - std::cout << "m3\n" << m3 << "\nm4:\n" << m4 << "\nv4:\n" << v4 << std::endl; + std::cout << "m3\n" << m3 << "\nm4:\n" + << m4 << "\nv4:\n" << v4 << std::endl; } |