blob: 5a1a3e06efaf624a82c1449c16f3d9021e8b811b [file] [log] [blame]
Gael Guennebaud99462972008-08-31 17:30:09 +00001namespace Eigen {
2
3/** \page TutorialGeometry Tutorial 2/3 - Geometry
4 \ingroup Tutorial
5
6<div class="eimainmenu">\ref index "Overview"
7 | \ref TutorialCore "Core features"
8 | \b Geometry
9 | \ref TutorialAdvancedLinearAlgebra "Advanced linear algebra"
10</div>
11
12In this tutorial chapter we will shortly introduce the many possibilities offered by the \ref GeometryModule "geometry module",
13namely 2D and 3D rotations and affine transformations.
14
15\b Table \b of \b contents
16 - \ref TutorialGeoElementaryTransformations
17 - \ref TutorialGeoCommontransformationAPI
18 - \ref TutorialGeoTransform
19 - \ref TutorialGeoEulerAngles
20
21\section TutorialGeoElementaryTransformations Transformation types
22
23<table class="tutorial_code">
24<tr><td>Transformation type</td><td>Typical initialization code</td></tr>
25<tr><td>
Gael Guennebaud6825c8d2008-09-01 06:33:19 +000026\ref Rotation2D "2D rotation" from an angle</td><td>\code
Gael Guennebaud99462972008-08-31 17:30:09 +000027Rotation2D<float> rot2(angle_in_radian);\endcode</td></tr>
28<tr><td>
Gael Guennebaud6825c8d2008-09-01 06:33:19 +0000293D rotation as an \ref AngleAxis "angle + axis"</td><td>\code
Gael Guennebaud99462972008-08-31 17:30:09 +000030AngleAxis<float> aa(angle_in_radian, Vector3f(ax,ay,az));\endcode</td></tr>
31<tr><td>
Gael Guennebaud6825c8d2008-09-01 06:33:19 +0000323D rotation as a \ref Quaternion "quaternion"</td><td>\code
Gael Guennebaud99462972008-08-31 17:30:09 +000033Quaternion<float> q = AngleAxis<float>(angle_in_radian, axis);\endcode</td></tr>
34<tr><td>
35N-D Scaling</td><td>\code
36Scaling<float,2>(sx, sy)
37Scaling<float,3>(sx, sy, sz)
38Scaling<float,N>(s)
39Scaling<float,N>(vecN)\endcode</td></tr>
40<tr><td>
41N-D Translation</td><td>\code
42Translation<float,2>(tx, ty)
43Translation<float,3>(tx, ty, tz)
44Translation<float,N>(s)
45Translation<float,N>(vecN)\endcode</td></tr>
46<tr><td>
47N-D \ref TutorialGeoTransform "Affine transformation"</td><td>\code
48Transform<float,N> t = concatenation_of_any_transformations;
49Transform<float,3> t = Translation3f(p) * AngleAxisf(a,axis) * Scaling3f(s);\endcode</td></tr>
50<tr><td>
51N-D Linear transformations \n
52<em class=note>(pure rotations, \n scaling, etc.)</em></td><td>\code
53Matrix<float,N> t = concatenation_of_rotations_and_scalings;
54Matrix<float,2> t = Rotation2Df(a) * Scaling2f(s);
55Matrix<float,3> t = AngleAxisf(a,axis) * Scaling3f(s);\endcode</td></tr>
56</table>
57
58<strong>Notes on rotations</strong>\n To transform more than a single vector the preferred
59representations are rotation matrices, while for other usages Quaternion is the
60representation of choice as they are compact, fast and stable. Finally Rotation2D and
61AngleAxis are mainly convenient types to create other rotation objects.
62
63<strong>Notes on Translation and Scaling</strong>\n Likewise AngleAxis, these classes were
64designed to simplify the creation/initialization of linear (Matrix) and affine (Transform)
65transformations. Nevertheless, unlike AngleAxis which is inefficient to use, these classes
66might still be interesting to write generic and efficient algorithms taking as input any
67kind of transformations.
68
69Any of the above transformation types can be converted to any other types of the same nature,
Gael Guennebaud582c1f92008-11-22 19:51:05 +000070or to a more generic type. Here are some additional examples:
Gael Guennebaud99462972008-08-31 17:30:09 +000071<table class="tutorial_code">
72<tr><td>\code
73Rotation2Df r = Matrix2f(..); // assumes a pure rotation matrix
74AngleAxisf aa = Quaternionf(..);
75AngleAxisf aa = Matrix3f(..); // assumes a pure rotation matrix
76Matrix2f m = Rotation2Df(..);
77Matrix3f m = Quaternionf(..); Matrix3f m = Scaling3f(..);
78Transform3f m = AngleAxis3f(..); Transform3f m = Scaling3f(..);
79Transform3f m = Translation3f(..); Transform3f m = Matrix3f(..);
80\endcode</td></tr>
81</table>
82
83
84<a href="#" class="top">top</a>\section TutorialGeoCommontransformationAPI Common API across transformation types
85
86To some extent, Eigen's \ref GeometryModule "geometry module" allows you to write
87generic algorithms working on any kind of transformation representations:
88<table class="tutorial_code">
89<tr><td>
90Concatenation of two transformations</td><td>\code
91gen1 * gen2;\endcode</td></tr>
92<tr><td>Apply the transformation to a vector</td><td>\code
93vec2 = gen1 * vec1;\endcode</td></tr>
94<tr><td>Get the inverse of the transformation</td><td>\code
95gen2 = gen1.inverse();\endcode</td></tr>
96<tr><td>Spherical interpolation \n (Rotation2D and Quaternion only)</td><td>\code
97rot3 = rot1.slerp(alpha,rot2);\endcode</td></tr>
98</table>
99
100
101
102<a href="#" class="top">top</a>\section TutorialGeoTransform Affine transformations
103Generic affine transformations are represented by the Transform class which internaly
104is a (Dim+1)^2 matrix. In Eigen we have chosen to not distinghish between points and
105vectors such that all points are actually represented by displacement vectors from the
106origin ( \f$ \mathbf{p} \equiv \mathbf{p}-0 \f$ ). With that in mind, real points and
107vector distinguish when the transformation is applied.
108<table class="tutorial_code">
109<tr><td>
110Apply the transformation to a \b point </td><td>\code
111VectorNf p1, p2;
112p2 = t * p1;\endcode</td></tr>
113<tr><td>
114Apply the transformation to a \b vector </td><td>\code
115VectorNf vec1, vec2;
116vec2 = t.linear() * vec1;\endcode</td></tr>
117<tr><td>
118Apply a \em general transformation \n to a \b normal \b vector
119(<a href="http://www.cgafaq.info/wiki/Transforming_normals">explanations</a>)</td><td>\code
120VectorNf n1, n2;
121MatrixNf normalMatrix = t.linear().inverse().transpose();
122n2 = (normalMatrix * n1).normalized();\endcode</td></tr>
123<tr><td>
124Apply a transformation with \em pure \em rotation \n to a \b normal \b vector
125(no scaling, no shear)</td><td>\code
126n2 = t.linear() * n1;\endcode</td></tr>
127<tr><td>
128OpenGL compatibility \b 3D </td><td>\code
129glLoadMatrixf(t.data());\endcode</td></tr>
130<tr><td>
131OpenGL compatibility \b 2D </td><td>\code
132Transform3f aux(Transform3f::Identity);
133aux.linear().corner<2,2>(TopLeft) = t.linear();
134aux.translation().start<2>() = t.translation();
135glLoadMatrixf(aux.data());\endcode</td></tr>
136</table>
137
138\b Component \b accessors</td></tr>
139<table class="tutorial_code">
140<tr><td>
141full read-write access to the internal matrix</td><td>\code
142t.matrix() = matN1xN1; // N1 means N+1
143matN1xN1 = t.matrix();
144\endcode</td></tr>
145<tr><td>
146coefficient accessors</td><td>\code
147t(i,j) = scalar; <=> t.matrix()(i,j) = scalar;
148scalar = t(i,j); <=> scalar = t.matrix()(i,j);
149\endcode</td></tr>
150<tr><td>
151translation part</td><td>\code
152t.translation() = vecN;
153vecN = t.translation();
154\endcode</td></tr>
155<tr><td>
156linear part</td><td>\code
157t.linear() = matNxN;
158matNxN = t.linear();
159\endcode</td></tr>
160<tr><td>
161extract the rotation matrix</td><td>\code
162matNxN = t.extractRotation();
163\endcode</td></tr>
164</table>
165
166
167\b Transformation \b creation \n
168While transformation objects can be created and updated concatenating elementary transformations,
169the Transform class also features a procedural API:
170<table class="tutorial_code">
171<tr><td></td><td>\b procedurale \b API </td><td>\b equivalent \b natural \b API </td></tr>
172<tr><td>Translation</td><td>\code
173t.translate(Vector_(tx,ty,..));
174t.pretranslate(Vector_(tx,ty,..));
175\endcode</td><td>\code
176t *= Translation_(tx,ty,..);
177t = Translation_(tx,ty,..) * t;
178\endcode</td></tr>
Gael Guennebaud582c1f92008-11-22 19:51:05 +0000179<tr><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
Gael Guennebaud99462972008-08-31 17:30:09 +0000180t.rotate(any_rotation);
181t.prerotate(any_rotation);
182\endcode</td><td>\code
183t *= any_rotation;
184t = any_rotation * t;
185\endcode</td></tr>
186<tr><td>Scaling</td><td>\code
187t.scale(Vector_(sx,sy,..));
188t.scale(s);
189t.prescale(Vector_(sx,sy,..));
190t.prescale(s);
191\endcode</td><td>\code
192t *= Scaling_(sx,sy,..);
193t *= Scaling_(s);
194t = Scaling_(sx,sy,..) * t;
195t = Scaling_(s) * t;
196\endcode</td></tr>
197<tr><td>Shear transformation \n ( \b 2D \b only ! )</td><td>\code
198t.shear(sx,sy);
199t.preshear(sx,sy);
200\endcode</td><td></td></tr>
201</table>
202
203Note that in both API, any many transformations can be concatenated in a single expression as shown in the two following equivalent examples:
204<table class="tutorial_code">
205<tr><td>\code
206t.pretranslate(..).rotate(..).translate(..).scale(..);
207\endcode</td></tr>
208<tr><td>\code
209t = Translation_(..) * t * RotationType(..) * Translation_(..) * Scaling_(..);
210\endcode</td></tr>
211</table>
212
213
214
215<a href="#" class="top">top</a>\section TutorialGeoEulerAngles Euler angles
216<table class="tutorial_code">
217<tr><td style="max-width:30em;">
218Euler angles might be convenient to create rotation objects.
Gael Guennebaud582c1f92008-11-22 19:51:05 +0000219On the other hand, since there exist 24 differents convension,they are pretty confusing to use. This example shows how
Gael Guennebaud99462972008-08-31 17:30:09 +0000220to create a rotation matrix according to the 2-1-2 convention.</td><td>\code
221Matrix3f m;
222m = AngleAxisf(angle1, Vector3f::UnitZ())
223* * AngleAxisf(angle2, Vector3f::UnitY())
224* * AngleAxisf(angle3, Vector3f::UnitZ());
225\endcode</td></tr>
226</table>
227
228*/
229
230}