Eigen
3.2.8

In this page, we will introduce the many possibilities offered by the geometry module to deal with 2D and 3D rotations and projective or affine transformations.
Eigen's Geometry module provides two different kinds of geometric transformations:
You can construct a Transform from an abstract transformation, like this:
or like this:
But note that unfortunately, because of how C++ works, you can not do this:
Explanation: In the C++ language, this would require Transform to have a nonexplicit conversion constructor from AngleAxis, but we really don't want to allow implicit casting here.
Transformation type  Typical initialization code 

2D rotation from an angle  Rotation2D<float> rot2(angle_in_radian);

3D rotation as an angle + axis  AngleAxis<float> aa(angle_in_radian, Vector3f(ax,ay,az));

3D rotation as a quaternion  Quaternion<float> q; q = AngleAxis<float>(angle_in_radian, axis);

ND Scaling  
ND Translation  Translation<float,2>(tx, ty)
Translation<float,3>(tx, ty, tz)
Translation<float,N>(s)
Translation<float,N>(vecN)

ND Affine transformation  Transform<float,N,Affine> t = concatenation_of_any_transformations;
Transform<float,3,Affine> t = Translation3f(p) * AngleAxisf(a,axis) * Scaling(s);

ND Linear transformations (pure rotations, scaling, etc.)  Matrix<float,N> t = concatenation_of_rotations_and_scalings;
Matrix<float,2> t = Rotation2Df(a) * Scaling(s);
Matrix<float,3> t = AngleAxisf(a,axis) * Scaling(s);

Notes on rotations
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
Like 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 some additional examples:
AngleAxisf aa; aa = Quaternionf(..);
Matrix2f m; m = Rotation2Df(..);

To some extent, Eigen's geometry module allows you to write generic algorithms working on any kind of transformation representations:
Concatenation of two transformations  gen1 * gen2;

Apply the transformation to a vector  vec2 = gen1 * vec1;

Get the inverse of the transformation  gen2 = gen1.inverse();

Spherical interpolation (Rotation2D and Quaternion only)  rot3 = rot1.slerp(alpha,rot2);

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 ( ). With that in mind, real points and vector distinguish when the transformation is applied.
Apply the transformation to a point  VectorNf p1, p2;
p2 = t * p1;

Apply the transformation to a vector  VectorNf vec1, vec2;
vec2 = t.linear() * vec1;

Apply a general transformation to a normal vector (explanations)  VectorNf n1, n2;
MatrixNf normalMatrix = t.linear().inverse().transpose();
n2 = (normalMatrix * n1).normalized();

Apply a transformation with pure rotation to a normal vector (no scaling, no shear)  n2 = t.linear() * n1;

OpenGL compatibility 3D  glLoadMatrixf(t.data());

OpenGL compatibility 2D  Affine3f aux(Affine3f::Identity());
aux.linear().topLeftCorner<2,2>() = t.linear();
aux.translation().start<2>() = t.translation();
glLoadMatrixf(aux.data());

Component accessors
full readwrite access to the internal matrix  t.matrix() = matN1xN1; // N1 means N+1
matN1xN1 = t.matrix();

coefficient accessors  t(i,j) = scalar; <=> t.matrix()(i,j) = scalar;
scalar = t(i,j); <=> scalar = t.matrix()(i,j);

translation part  t.translation() = vecN;
vecN = t.translation();

linear part  t.linear() = matNxN;
matNxN = t.linear();

extract the rotation matrix  matNxN = t.rotation();

Transformation creation
While transformation objects can be created and updated concatenating elementary transformations, the Transform class also features a procedural API:
procedural API  equivalent natural API  

Translation  t.translate(Vector_(tx,ty,..));
t.pretranslate(Vector_(tx,ty,..));
 t *= Translation_(tx,ty,..);
t = Translation_(tx,ty,..) * t;

Rotation In 2D and for the procedural API, any_rotation can also be an angle in radian  t.rotate(any_rotation);
t.prerotate(any_rotation);
 t *= any_rotation;
t = any_rotation * t;

Scaling  t.scale(Vector_(sx,sy,..));
t.scale(s);
t.prescale(Vector_(sx,sy,..));
t.prescale(s);
 
Shear transformation ( 2D only ! )  t.shear(sx,sy);
t.preshear(sx,sy);

Note that in both API, any many transformations can be concatenated in a single expression as shown in the two following equivalent examples:
t.pretranslate(..).rotate(..).translate(..).scale(..);

t = Translation_(..) * t * RotationType(..) * Translation_(..) * Scaling(..);

Euler angles might be convenient to create rotation objects. On the other hand, since there exist 24 different conventions, they are pretty confusing to use. This example shows how to create a rotation matrix according to the 212 convention.  Matrix3f m;
m = AngleAxisf(angle1, Vector3f::UnitZ())
* * AngleAxisf(angle2, Vector3f::UnitY())
* * AngleAxisf(angle3, Vector3f::UnitZ());
