Calculating with Rotations edit page

This page assumes the directions introduced in Defining Three-Dimensional Vectors and the active rotations introduced in Defining Rotations.

A reference frame is the coordinate system in which data are expressed. The rotations below move objects within one reference frame. They do not perform a frame change, which re-expresses the same physical object in a different reference frame without moving it.

The examples use proper rotations. Reflections and inversions are covered in Improper Rotations.

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

Rotating a Direction

The product rot * v actively turns the direction v by rot.

rot = rotation.byEuler(90*degree,90*degree,0*degree,'Bunge');
v = rot * vector3d.X
v = vector3d (y↑→x)
  x y z
  0 1 0

The grey arrows are the specimen axes. The black arrow is X before the rotation, and the red arrow is its image.

arrow3d(1.2*[vector3d.X,vector3d.Y,vector3d.Z],...
  'faceColor',[.75 .75 .75])
hold on
arrow3d(1.05*vector3d.X,'faceColor','black')
arrow3d(1.05*v,'faceColor','red')
hold off
axis off

The red arrow coincides with Y, so this rotation sends X to Y. \\ applies the inverse rotation and returns the direction to X.

rot \ v
ans = vector3d (y↑→x)
  x y z
  1 0 0

Composing Rotations

Multiplication composes rotations. The rotation on the right acts first, just as it does in matrix multiplication.

rot1 = rotation.byEuler(90*degree,0,0,'Bunge');
rot2 = rotation.byEuler(0,60*degree,0,'Bunge');

rot = rot2 * rot1;

The order matters. == tests rotation equality within an angular tolerance, rather than comparing printed Euler angles. Reversing these two rotations does not give the same result.

rot2 * rot1 == rot1 * rot2
ans =
  logical
   0

Their angular separation is 82.8192 degrees.

angle(rot2*rot1,rot1*rot2) ./ degree
ans =
   82.8192

The black arrow below is one starting direction. The red arrow results from rot1 followed by rot2, while the blue arrow shows the reverse order.

startDirection = normalize(vector3d(1,1,1));
forwardDirection = rot2 * (rot1 * startDirection);
reverseDirection = rot1 * (rot2 * startDirection);

figure;
arrow3d(1.2*[vector3d.X,vector3d.Y,vector3d.Z],...
  'faceColor',[.75 .75 .75])
hold on
arrow3d(1.05*startDirection,'faceColor','black')
arrow3d(1.05*forwardDirection,'faceColor','red')
arrow3d(1.05*reverseDirection,'faceColor','blue')
hold off
axis off

The separated red and blue arrows make the noncommutativity visible. Parentheses are useful whenever the intended order might otherwise be misread.

Axis and Angle

angle and axis read the axis--angle description from the composed rotation, however it was built.

rot.angle ./ degree
ans =
  104.4775
rot.axis
ans = vector3d (y↑→x)
      x      y      z
  0.447 -0.447  0.775

The composite is a 104.4775 degree turn about the displayed axis. This is not the sum of the two input angles because rotations about different axes do not add like vectors.

The Inverse Rotation

inv reverses a rotation. For a nonzero turn below 180 degrees, the inverse has the opposite axis and the same canonical, nonnegative angle.

invRot = inv(rot);

[rot.axis,invRot.axis]
ans = vector3d (y↑→x)
 size: 1 × 2
       x      y      z
   0.447 -0.447  0.775
  -0.447  0.447 -0.775
[rot.angle,invRot.angle] ./ degree
ans =
  104.4775  104.4775

A rotation multiplied by its inverse is the identity. This is why rot \ v is the same operation as inv(rot) * v.

rot * invRot
ans = rotation
 
  Bunge Euler angles in degree
  phi1  Phi phi2
     0    0    0

The Angle Between Two Rotations

The relative rotation below acts after rot1 and carries its result to the result of rot. Its principal angle is the angular distance between the two rotations.

relativeRot = rot * inv(rot1);

[relativeRot.angle,angle(rot,rot1)] ./ degree
ans =
   60.0000   60.0000

Both entries are 60 degrees. The second is the direct angle(rot,rot1) call, so there is usually no need to construct the relative rotation explicitly.

This angular distance is used throughout MTEX to compare a fit with a measurement and to quantify orientation variation. For orientations it additionally minimizes over symmetry-equivalent descriptions, as explained in Orientation Symmetry.

Lists of Rotations

MTEX objects are vectorized. If both operands are non-scalar, .* pairs corresponding entries while * forms every combination. A scalar operand is applied to the whole list with either operator.

rotations = rotation.byAxisAngle(vector3d.Z,[0 30 60]*degree);
directions = [vector3d.X,vector3d.Y,vector3d.Z];

size(rotations .* directions)
ans =
     1     3

The elementwise result has size 1-by-3: one output for each pair.

size(rotations * directions)
ans =
     3     3

The outer result has size 3-by-3: every rotation was applied to every direction. The same distinction applies when two rotation lists are composed.

Reading Other Parametrisations

A rotation can be inspected in any representation, regardless of how it was constructed.

Euler(rot)

the three Euler angles

Rodrigues(rot)

the Rodrigues--Frank vector

matrix(rot)

the rotation matrix

homochoric(rot)

the homochoric vector

cubochoric(rot)

the cubochoric vector

axis(rot), angle(rot)

axis and angle

Euler angles depend on a convention. Naming Matthies here makes the result independent of the user's display preference.

[alpha,beta,gamma] = Euler(rot,'Matthies');

[alpha,beta,gamma] ./ degree
ans =
  270.0000   60.0000  180.0000

The displayed 270, 60, 180 degree triplet is the Matthies description of the same composite rotation. See Rotation Representations before comparing coordinates produced by different programs.

The Maths Behind the Angular Distance

For rotations \(r_1\) and \(r_2\), MTEX uses the principal angle of a relative rotation:

\[ d(r_1,r_2) = \mathop{\rm angle}(r_2 r_1^{-1}) = \mathop{\rm angle}(r_1^{-1}r_2). \]

The two relative rotations generally have different axes, but they have the same angle. The distance is unchanged if the same rotation is composed onto both inputs from the left or from the right. This invariance is why the 60 degree result above does not depend on the starting orientation rot1.

References

Next

Sets of rotations are drawn in Plotting. A rotation that maps crystal coordinates into specimen coordinates and carries crystal symmetry is 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/RotationOperations.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.