mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-03-25 18:50:40 +08:00
update of the geometry tutorial
This commit is contained in:
parent
d74916e4fe
commit
994629721a
@ -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"
|
||||
|
230
doc/TutorialGeometry.dox
Normal file
230
doc/TutorialGeometry.dox
Normal file
@ -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>
|
||||
|
||||
*/
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user