Defining Rotations edit page

A reference frame is the coordinate system in which data are expressed. A rotation moves a geometric object within a fixed reference frame. In MTEX, rot * v is the active rotation that moves the direction v. This is different from a frame change, which describes the same object in another reference frame without moving it. Orientations use rotations as coordinate mappings, as explained in Crystal Orientation as Coordinate Transformation.

This page assumes the three-dimensional directions introduced in Defining Three-Dimensional Vectors and basic matrix algebra.

MTEX can build a rotation from Euler angles, an axis and angle, a matrix, or the action on directions. Every constructor returns a rotation array. MTEX stores its proper part internally as a unit quaternion.

plottingConvention.default('y↑→x');

Euler Angles

Euler angles describe a rotation by three successive angular steps. The axes, their order, and the direction of the mapping belong to the convention. Three numbers without that convention are therefore ambiguous.

Texture analysis commonly uses the following names:

  • Bunge \((\varphi_1,\Phi,\varphi_2)\), with the ZXZ axis sequence
  • Matthies \((\alpha,\beta,\gamma)\), with the ZYZ axis sequence
  • Roe \((\Psi,\Theta,\Phi)\)
  • Kocks \((\Psi,\Theta,\varphi)\)
  • Canova \((\omega,\Theta,\varphi)\)

A new MTEX installation uses Bunge as its preference. Reusable code should name the convention so that a user's preference cannot change the input.

rotBunge = rotation.byEuler(30*degree,50*degree,10*degree,'Bunge');
rotRoe = rotation.byEuler(30*degree,50*degree,10*degree,'Roe');

angle(rotBunge,rotRoe) ./ degree
ans =
   69.5509

The nonzero angle confirms that equal triplets in different conventions need not describe the same rotation. Angles are radians throughout MTEX, which is why values in degrees are multiplied by degree.

The convention used to display an existing rotation can also be named. The rotation constructed with the Roe triplet above reads

Euler(rotRoe,'Roe')
Roe Euler angles in degree
  Psi Theta   Phi
   30    50    10
Euler(rotRoe,'Bunge')
Bunge Euler angles in degree
  phi1  Phi phi2
   120   50  280

These are two descriptions of the same rotation. The separate question of which way an orientation maps coordinates is covered in MTEX vs. Bunge Convention.

For interactive work, setMTEXpref changes the session's default Euler convention. Explicit conventions remain safer in files that must be reproducible.

Euler Angles Are Not Unique

Even after the convention is fixed, Euler angles are not always unique. In the Bunge convention, when the middle angle \(\Phi\) is zero, only the sum of the first and third angles is determined. These two triplets therefore describe the same rotation.

rotA = rotation.byEuler(10*degree,0,20*degree,'Bunge');
rotB = rotation.byEuler(15*degree,0,15*degree,'Bunge');

angle(rotA,rotB) ./ degree
ans =
     0

The zero angular difference is the Euler-angle singularity. It is a property of the representation, not an additional physical freedom of the rotation.

Axis and Angle

Every non-identity proper rotation in three dimensions turns about an axis. MTEX reports an angle between \(0\) and \(180^\circ\). The identity has no unique axis. At \(180^\circ\), the two signs of the axis describe the same rotation.

rot = rotation.byAxisAngle(vector3d.X,30*degree);

The axis and angle can be read from any rotation, however it was defined.

rot.axis
ans = vector3d (y↑→x)
  x y z
  1 0 0
rot.angle ./ degree
ans =
   30.0000

The following figure draws the axis in blue, a direction before the rotation in grey, and the rotated direction in red.

v = normalize(vector3d(0.2,0.3,1));

arrow3d(1.5*rot.axis,'faceColor','blue')
hold on
arrow3d(1.2*v,'faceColor',[.45 .45 .45])
arrow3d(1.2*(rot*v),'faceColor','red')
hold off
axis off

Notice that the blue axis stays fixed while the red direction has turned around it. This fixed direction is the defining axis of the rotation.

Rodrigues--Frank Vector

The Rodrigues--Frank vector packs axis and angle into one vector. It is the rotation axis scaled by \(\tan(\omega/2)\).

R = rot.Rodrigues
R = vector3d (y↑→x)
      x     y     z
  0.268     0     0

Its length recovers the rotation angle.

2 * atan(norm(R)) ./ degree
ans =
   30.0000

Constructing a rotation from the vector returns the original rotation, as shown by their zero angular difference.

rotFromR = rotation.byRodrigues(R);
angle(rot,rotFromR) ./ degree
ans =
     0

Rotation Matrix

A proper rotation is also represented by an orthogonal \(3 \times 3\) matrix with determinant \(+1\).

M = rot.matrix
M =
    1.0000         0         0
         0    0.8660   -0.5000
         0    0.5000    0.8660

Its columns are the rotated basis directions X, Y, and Z. Rotating Y gives the second column of M.

rot * vector3d.Y
ans = vector3d (y↑→x)
  x     y     z
  0 0.866   0.5

rotation.byMatrix reconstructs the rotation.

rotFromM = rotation.byMatrix(M);
angle(rot,rotFromM) ./ degree
ans =
     0

The constructor assumes that its input is orthogonal; it does not validate a matrix imported from another program. A matrix with determinant \(-1\) is accepted and stored as an improper rotation, as discussed in Improper Rotations.

Defined by What It Does

Often the rotation is known only through the directions it must map. Two non-collinear pairs determine exactly one rotation when the angle within the first pair equals the angle within the second pair.

u1 = vector3d.X; v1 = vector3d.Y;
u2 = vector3d.Z; v2 = vector3d.Z;

rot = rotation.map(u1,v1,u2,v2);
[rot*u1,rot*u2]
ans = vector3d (y↑→x)
 size: 1 × 2
  x y z
  0 1 0
  0 0 1

The output reproduces the two target directions Y and Z. MTEX raises an error if the angles within the pairs disagree or if the input directions are collinear.

One pair leaves a rotation about the target direction undetermined. rotation.map then returns the smallest-angle rotation taking the first direction to the second.

rot = rotation.map(vector3d.Z,vector3d.Y);
rot * vector3d.Z
ans = vector3d (y↑→x)
  x y z
  0 1 0

For opposite directions this smallest angle is \(180^\circ\), but its axis is not unique. Supply a second pair when the particular half turn matters.

Fitting Measured Directions

More than two measured pairs will usually not agree exactly. The least-squares solution from rotation.fit makes rotFit * left as close as possible to right.

left = vector3d.rand(5);
right = rot * left + 0.1 * vector3d.rand(1,5);

rotFit = rotation.fit(left,right);
angle(rot,rotFit) ./ degree
ans =
    4.5269

The nonzero error comes from the added perturbations. By default, rotation.fit uses Horn's unit-quaternion method. The option 'method','kabsch' selects the Kabsch matrix method.

Random Rotations

rotation.rand samples the uniform, or Haar, distribution on the rotation group. Its size arguments create an array of rotations, just as size arguments do for MATLAB numeric arrays.

rotations = rotation.rand(100);
length(rotations)
ans =
   100

The output confirms that the array contains 100 rotations. The 'maxAngle' option restricts samples to a ball around the identity. Sampling from a nonuniform distribution is covered in Random Sampling.

Quaternions

A proper rotation is defined by the four coordinates of a unit quaternion. The quaternion and its negative encode the same rotation.

q = quaternion(0.5,0.5,0.5,0.5);
norm(q)
ans =
     1

The norm is one, so q can be passed to the rotation constructor.

rotQ = rotation(q);
rotMinusQ = rotation(-q);

angle(rotQ,rotMinusQ) ./ degree
ans =
     0

The zero difference demonstrates the double representation directly. Rotation Representations explains the geometry and numerical trade-offs of quaternions and rotation vectors.

Constructor Index

The constructors above cover the usual inputs. The complete set also includes generated, imported, and improper rotations.

input

constructor

Euler angles

rotation.byEuler

axis and angle

rotation.byAxisAngle

matrix

rotation.byMatrix

Rodrigues--Frank vector

rotation.byRodrigues

homochoric vector

rotation.byHomochoric

unit quaternion

rotation(q)

exact direction pairs

rotation.map

noisy direction pairs

rotation.fit

identity, random, or missing

rotation.id , rotation.rand , rotation.nan

file

rotation.load

distribution

odf.discreteSample

inversion or reflection

rotation.inversion , reflection

References

Next

Representations compares the coordinate descriptions of rotation space. Improper Rotations then treats inversion and reflection, and Operations composes, inverts, and applies rotations. A rotation carrying crystal and specimen symmetry becomes an orientation.

Citing this page. This page is part of the documentation of MTEX, a free and open source MATLAB toolbox for analyzing and modeling crystallographic textures. It was written by The MTEX Developers and is published at https://mtex-toolbox.github.io/RotationDefinition.html. If you use MTEX, or reuse text or figures from this page, in your research, please cite

F. Bachmann, R. Hielscher, H. Schaeben: Texture Analysis with MTEX - Free and Open Source Software Toolbox, Solid State Phenomena 160 (2010), 63-68. 10.4028/www.scientific.net/SSP.160.63

BibTeX
@article{bachmann2010mtex,
  author  = {F. Bachmann and R. Hielscher and H. Schaeben},
  title   = {Texture Analysis with MTEX - Free and Open Source Software Toolbox},
  journal = {Solid State Phenomena},
  volume  = {160},
  pages   = {63-68},
  year    = {2010},
  doi     = {10.4028/www.scientific.net/SSP.160.63},
  url     = {https://doi.org/10.4028/www.scientific.net/SSP.160.63}
}

Other papers describing specific MTEX methods are listed under Publications — please cite the one that best fits your application. The MTEX source code is licensed under the GNU General Public License v2.0; the text and figures of this documentation are licensed under CC BY 4.0, which permits reuse — including by automated systems — provided The MTEX Developers and this page are credited.