quaternion

Create a quaternion array

Description

A quaternion is a four-part hyper-complex number used in three-dimensional rotations and orientations.

A quaternion number is represented in the form a+bi+cj+dk, where a, b, c, and d parts are real numbers, and i, j, and k are the basis elements, satisfying the equation: i2 = j2 = k2 = ijk = −1.

The set of quaternions, denoted by H, is defined within a four-dimensional vector space over the real numbers, R4. Every element of H has a unique representation based on a linear combination of the basis elements, i, j, and k.

All rotations in 3-D can be described by an axis of rotation and angle about that axis. An advantage of quaternions over rotation matrices is that the axis and angle of rotation is easy to interpret. For example, consider a point in R3. To rotate the point, you define an axis of rotation and an angle of rotation.

The quaternion representation of the rotation may be expressed as q=cos(θ2)+sin(θ2)(ubi+ucj+udk), where θ is the angle of rotation and [ub, uc, and ud] is the axis of rotation.

Creation

Description

example

quat = quaternion() creates an empty quaternion.

example

quat = quaternion(A,B,C,D) creates a quaternion array where the four quaternion parts are taken from the arrays A, B, C, and D. All the inputs must have the same size and be of the same data type.

example

quat = quaternion(matrix) creates an N-by-1 quaternion array from an N-by-4 matrix, where each column becomes one part of the quaternion.

example

quat = quaternion(RV,'rotvec') creates an N-by-1 quaternion array from an N-by-3 matrix of rotation vectors, RV. Each row of RV represents a rotation vector in radians.

example

quat = quaternion(RV,'rotvecd') creates an N-by-1 quaternion array from an N-by-3 matrix of rotation vectors, RV. Each row of RV represents a rotation vector in degrees.

example

quat = quaternion(RM,'rotmat',PF) creates an N-by-1 quaternion array from the 3-by-3-by-N array of rotation matrices, RM. PF can be either 'point' if the Euler angles represent point rotations or 'frame' for frame rotations.

example

quat = quaternion(E,'euler',RS,PF) creates an N-by-1 quaternion array from the N-by-3 matrix, E. Each row of E represents a set of Euler angles in radians. The angles in E are rotations about the axes in sequence RS.

example

quat = quaternion(E,'eulerd',RS,PF) creates an N-by-1 quaternion array from the N-by-3 matrix, E. Each row of E represents a set of Euler angles in degrees. The angles in E are rotations about the axes in sequence RS.

Input Arguments

expand all

Parts of a quaternion, specified as four comma-separated scalars, matrices, or multi-dimensional arrays of the same size.

Example: quat = quaternion(1,2,3,4) creates a quaternion of the form 1 + 2i + 3j + 4k.

Example: quat = quaternion([1,5],[2,6],[3,7],[4,8]) creates a 1-by-2 quaternion array where quat(1,1) = 1 + 2i + 3j + 4k and quat(1,2) = 5 + 6i + 7j + 8k

Data Types: single | double

Matrix of quaternion parts, specified as an N-by-4 matrix. Each row represents a separate quaternion. Each column represents a separate quaternion part.

Example: quat = quaternion(rand(10,4)) creates a 10-by-1 quaternion array.

Data Types: single | double

Matrix of rotation vectors, specified as an N-by-3 matrix. Each row of RV represents the [X Y Z] elements of a rotation vector. A rotation vector is a unit vector representing the axis of rotation scaled by the angle of rotation in radians or degrees.

To use this syntax, specify the first argument as a matrix of rotation vectors and the second argument as the 'rotvec' or 'rotvecd'.

Example: quat = quaternion(rand(10,3),'rotvec') creates a 10-by-1 quaternion array.

Data Types: single | double

Array of rotation matrices, specified by a 3-by-3 matrix or 3-by-3-by-N array. Each page of the array represents a separate rotation matrix.

Example: quat = quaternion(rand(3),'rotmat','point')

Example: quat = quaternion(rand(3),'rotmat','frame')

Data Types: single | double

Type of rotation matrix, specified by 'point' or 'frame'.

Example: quat = quaternion(rand(3),'rotmat','point')

Example: quat = quaternion(rand(3),'rotmat','frame')

Data Types: char | string

Matrix of Euler angles, specified by an N-by-3 matrix. If using the 'euler' syntax, specify E in radians. If using the 'eulerd' syntax, specify E in degrees.

Example: quat = quaternion(E,'euler','YZY','point')

Example: quat = quaternion(E,'euler','XYZ','frame')

Data Types: single | double

Rotation sequence, specified as a three-element character vector:

  • 'YZY'

  • 'YXY'

  • 'ZYZ'

  • 'ZXZ'

  • 'XYX'

  • 'XZX'

  • 'XYZ'

  • 'YZX'

  • 'ZXY'

  • 'XZY'

  • 'ZYX'

  • 'YXZ'

Assume you want to determine the new coordinates of a point when its coordinate system is rotated using frame rotation. The point is defined in the original coordinate system as:

point = [sqrt(2)/2,sqrt(2)/2,0];
In this representation, the first column represents the x-axis, the second column represents the y-axis, and the third column represents the z-axis.

You want to rotate the point using the Euler angle representation [45,45,0]. Rotate the point using two different rotation sequences:

  • If you create a quaternion rotator and specify the 'ZYX' sequence, the frame is first rotated 45° around the z-axis, then 45° around the new y-axis.

    quatRotator = quaternion([45,45,0],'eulerd','ZYX','frame');
    newPointCoordinate = rotateframe(quatRotator,point)
    newPointCoordinate =
    
        0.7071   -0.0000    0.7071

  • If you create a quaternion rotator and specify the 'YZX' sequence, the frame is first rotated 45° around the y-axis, then 45° around the new z-axis.

    quatRotator = quaternion([45,45,0],'eulerd','YZX','frame');
    newPointCoordinate = rotateframe(quatRotator,point)
    newPointCoordinate =
    
        0.8536    0.1464    0.5000

Data Types: char | string

Object Functions

classUnderlyingClass of parts within quaternion
compactConvert quaternion array to N-by-4 matrix
conjComplex conjugate of quaternion
ctransposeComplex conjugate transpose of quaternion array
distAngular distance in radians
eulerConvert quaternion to Euler angles (radians)
eulerdConvert quaternion to Euler angles (degrees)
expExponential of quaternion array
logNatural logarithm of quaternion array
meanrotQuaternion mean rotation
minus, -Quaternion subtraction
mtimes, *Quaternion multiplication
normQuaternion norm
normalizeQuaternion normalization
onesCreate quaternion array with real parts set to one and imaginary parts set to zero
partsExtract quaternion parts
power, .^Element-wise quaternion power
prodProduct of a quaternion array
randrotUniformly distributed random rotations
rotateframeQuaternion frame rotation
rotatepointQuaternion point rotation
rotmatConvert quaternion to rotation matrix
rotvecConvert quaternion to rotation vector (radians)
rotvecdConvert quaternion to rotation vector (degrees)
slerpSpherical linear interpolation
times, .*Element-wise quaternion multiplication
rdivide, ./Element-wise quaternion right division
ldivide, .\Element-wise quaternion left division
transposeTranspose a quaternion array
uminus, -Quaternion unary minus
zerosCreate quaternion array with all parts set to zero

Examples

collapse all

quat = quaternion()
quat = 

  0x0 empty quaternion array

By default, the underlying class of the quaternion is a double.

classUnderlying(quat)
ans = 
'double'

You can create a quaternion array by specifying the four parts as comma-separated scalars, matrices, or multidimensional arrays of the same size.

Define quaternion parts as scalars.

A = 1.1;
B = 2.1;
C = 3.1;
D = 4.1;
quatScalar = quaternion(A,B,C,D)
quatScalar = quaternion
     1.1 + 2.1i + 3.1j + 4.1k

Define quaternion parts as column vectors.

A = [1.1;1.2];
B = [2.1;2.2];
C = [3.1;3.2];
D = [4.1;4.2];
quatVector = quaternion(A,B,C,D)
quatVector=2×1 object
     1.1 + 2.1i + 3.1j + 4.1k
     1.2 + 2.2i + 3.2j + 4.2k

Define quaternion parts as matrices.

A = [1.1,1.3; ...
     1.2,1.4];
B = [2.1,2.3; ...
     2.2,2.4];
C = [3.1,3.3; ...
     3.2,3.4];
D = [4.1,4.3; ...
     4.2,4.4];
quatMatrix = quaternion(A,B,C,D)
quatMatrix=2×2 object
     1.1 + 2.1i + 3.1j + 4.1k     1.3 + 2.3i + 3.3j + 4.3k
     1.2 + 2.2i + 3.2j + 4.2k     1.4 + 2.4i + 3.4j + 4.4k

Define quaternion parts as three dimensional arrays.

A = randn(2,2,2);
B = zeros(2,2,2);
C = zeros(2,2,2);
D = zeros(2,2,2);
quatMultiDimArray = quaternion(A,B,C,D)
quatMultiDimArray = 2x2x2 quaternion array
quatMultiDimArray(:,:,1) = 

     0.53767 +       0i +       0j +       0k     -2.2588 +       0i +       0j +       0k
      1.8339 +       0i +       0j +       0k     0.86217 +       0i +       0j +       0k


quatMultiDimArray(:,:,2) = 

     0.31877 +       0i +       0j +       0k    -0.43359 +       0i +       0j +       0k
     -1.3077 +       0i +       0j +       0k     0.34262 +       0i +       0j +       0k

You can create a scalar or column vector of quaternions by specify an N-by-4 matrix of quaternion parts, where columns correspond to the quaternion parts A, B, C, and D.

Create a column vector of random quaternions.

quatParts = rand(3,4)
quatParts = 3×4

    0.8147    0.9134    0.2785    0.9649
    0.9058    0.6324    0.5469    0.1576
    0.1270    0.0975    0.9575    0.9706

quat = quaternion(quatParts)
quat=3×1 object
     0.81472 + 0.91338i +  0.2785j + 0.96489k
     0.90579 + 0.63236i + 0.54688j + 0.15761k
     0.12699 + 0.09754i + 0.95751j + 0.97059k

To retrieve the quatParts matrix from quaternion representation, use compact.

retrievedquatParts = compact(quat)
retrievedquatParts = 3×4

    0.8147    0.9134    0.2785    0.9649
    0.9058    0.6324    0.5469    0.1576
    0.1270    0.0975    0.9575    0.9706

You can create an N-by-1 quaternion array by specifying an N-by-3 matrix of rotation vectors in radians or degrees. Rotation vectors are compact spatial representations that have a one-to-one relationship with normalized quaternions.

Rotation Vectors in Radians

Create a scalar quaternion using a rotation vector and verify the resulting quaternion is normalized.

rotationVector = [0.3491,0.6283,0.3491];
quat = quaternion(rotationVector,'rotvec')
quat = quaternion
     0.92124 + 0.16994i + 0.30586j + 0.16994k

norm(quat)
ans = 1.0000

You can convert from quaternions to rotation vectors in radians using the rotvec function. Recover the rotationVector from the quaternion, quat.

rotvec(quat)
ans = 1×3

    0.3491    0.6283    0.3491

Rotation Vectors in Degrees

Create a scalar quaternion using a rotation vector and verify the resulting quaternion is normalized.

rotationVector = [20,36,20];
quat = quaternion(rotationVector,'rotvecd')
quat = quaternion
     0.92125 + 0.16993i + 0.30587j + 0.16993k

norm(quat)
ans = 1

You can convert from quaternions to rotation vectors in degrees using the rotvecd function. Recover the rotationVector from the quaternion, quat.

rotvecd(quat)
ans = 1×3

   20.0000   36.0000   20.0000

You can create an N-by-1 quaternion array by specifying a 3-by-3-by-N array of rotation matrices. Each page of the rotation matrix array corresponds to one element of the quaternion array.

Create a scalar quaternion using a 3-by-3 rotation matrix. Specify whether the rotation matrix should be interpreted as a frame or point rotation.

rotationMatrix = [1 0         0; ...
                  0 sqrt(3)/2 0.5; ...
                  0 -0.5      sqrt(3)/2];
quat = quaternion(rotationMatrix,'rotmat','frame')
quat = quaternion
     0.96593 + 0.25882i +       0j +       0k

You can convert from quaternions to rotation matrices using the rotmat function. Recover the rotationMatrix from the quaternion, quat.

rotmat(quat,'frame')
ans = 3×3

    1.0000         0         0
         0    0.8660    0.5000
         0   -0.5000    0.8660

You can create an N-by-1 quaternion array by specifying an N-by-3 array of Euler angles in radians or degrees.

Euler Angles in Radians

Use the euler syntax to create a scalar quaternion using a 1-by-3 vector of Euler angles in radians. Specify the rotation sequence of the Euler angles and whether the angles represent a frame or point rotation.

E = [pi/2,0,pi/4];
quat = quaternion(E,'euler','ZYX','frame')
quat = quaternion
     0.65328 +  0.2706i +  0.2706j + 0.65328k

You can convert from quaternions to Euler angles using the euler function. Recover the Euler angles, E, from the quaternion, quat.

euler(quat,'ZYX','frame')
ans = 1×3

    1.5708         0    0.7854

Euler Angles in Degrees

Use the eulerd syntax to create a scalar quaternion using a 1-by-3 vector of Euler angles in degrees. Specify the rotation sequence of the Euler angles and whether the angles represent a frame or point rotation.

E = [90,0,45];
quat = quaternion(E,'eulerd','ZYX','frame')
quat = quaternion
     0.65328 +  0.2706i +  0.2706j + 0.65328k

You can convert from quaternions to Euler angles in degrees using the eulerd function. Recover the Euler angles, E, from the quaternion, quat.

eulerd(quat,'ZYX','frame')
ans = 1×3

   90.0000         0   45.0000

Quaternions form a noncommutative associative algebra over the real numbers. This example illustrates the rules of quaternion algebra.

Addition and Subtraction

Quaternion addition and subtraction occur part-by-part, and are commutative:

Q1 = quaternion(1,2,3,4)
Q1 = quaternion
     1 + 2i + 3j + 4k

Q2 = quaternion(9,8,7,6)
Q2 = quaternion
     9 + 8i + 7j + 6k

Q1plusQ2 = Q1 + Q2
Q1plusQ2 = quaternion
     10 + 10i + 10j + 10k

Q2plusQ1 = Q2 + Q1
Q2plusQ1 = quaternion
     10 + 10i + 10j + 10k

Q1minusQ2 = Q1 - Q2
Q1minusQ2 = quaternion
    -8 - 6i - 4j - 2k

Q2minusQ1 = Q2 - Q1
Q2minusQ1 = quaternion
     8 + 6i + 4j + 2k

You can also perform addition and subtraction of real numbers and quaternions. The first part of a quaternion is referred to as the real part, while the second, third, and fourth parts are referred to as the vector. Addition and subtraction with real numbers affect only the real part of the quaternion.

Q1plusRealNumber = Q1 + 5
Q1plusRealNumber = quaternion
     6 + 2i + 3j + 4k

Q1minusRealNumber = Q1 - 5
Q1minusRealNumber = quaternion
    -4 + 2i + 3j + 4k

Multiplication

Quaternion multiplication is determined by the products of the basis elements and the distributive law. Recall that multiplication of the basis elements, i, j, and k, are not commutative, and therefore quaternion multiplication is not commutative.

Q1timesQ2 = Q1 * Q2
Q1timesQ2 = quaternion
    -52 + 16i + 54j + 32k

Q2timesQ1 = Q2 * Q1
Q2timesQ1 = quaternion
    -52 + 36i + 14j + 52k

isequal(Q1timesQ2,Q2timesQ1)
ans = logical
   0

You can also multiply a quaternion by a real number. If you multiply a quaternion by a real number, each part of the quaternion is multiplied by the real number individually:

Q1times5 = Q1*5
Q1times5 = quaternion
      5 + 10i + 15j + 20k

Multiplying a quaternion by a real number is commutative.

isequal(Q1*5,5*Q1)
ans = logical
   1

Conjugation

The complex conjugate of a quaternion is defined such that each element of the vector portion of the quaternion is negated.

Q1
Q1 = quaternion
     1 + 2i + 3j + 4k

conj(Q1)
ans = quaternion
     1 - 2i - 3j - 4k

Multiplication between a quaternion and its conjugate is commutative:

isequal(Q1*conj(Q1),conj(Q1)*Q1)
ans = logical
   1

You can organize quaternions into vectors, matrices, and multidimensional arrays. Built-in MATLAB® functions have been enhanced to work with quaternions.

Concatenate

Quaternions are treated as individual objects during concatenation and follow MATLAB rules for array manipulation.

Q1 = quaternion(1,2,3,4);
Q2 = quaternion(9,8,7,6);

qVector = [Q1,Q2]
qVector=1×2 object
     1 + 2i + 3j + 4k     9 + 8i + 7j + 6k

Q3 = quaternion(-1,-2,-3,-4);
Q4 = quaternion(-9,-8,-7,-6);

qMatrix = [qVector;Q3,Q4]
qMatrix=2×2 object
     1 + 2i + 3j + 4k     9 + 8i + 7j + 6k
    -1 - 2i - 3j - 4k    -9 - 8i - 7j - 6k

qMultiDimensionalArray(:,:,1) = qMatrix;
qMultiDimensionalArray(:,:,2) = qMatrix
qMultiDimensionalArray = 2x2x2 quaternion array
qMultiDimensionalArray(:,:,1) = 

     1 + 2i + 3j + 4k     9 + 8i + 7j + 6k
    -1 - 2i - 3j - 4k    -9 - 8i - 7j - 6k


qMultiDimensionalArray(:,:,2) = 

     1 + 2i + 3j + 4k     9 + 8i + 7j + 6k
    -1 - 2i - 3j - 4k    -9 - 8i - 7j - 6k

Indexing

To access or assign elements in a quaternion array, use indexing.

qLoc2 = qMultiDimensionalArray(2)
qLoc2 = quaternion
    -1 - 2i - 3j - 4k

Replace the quaternion at index two with a quaternion one.

qMultiDimensionalArray(2) = ones('quaternion')
qMultiDimensionalArray = 2x2x2 quaternion array
qMultiDimensionalArray(:,:,1) = 

     1 + 2i + 3j + 4k     9 + 8i + 7j + 6k
     1 + 0i + 0j + 0k    -9 - 8i - 7j - 6k


qMultiDimensionalArray(:,:,2) = 

     1 + 2i + 3j + 4k     9 + 8i + 7j + 6k
    -1 - 2i - 3j - 4k    -9 - 8i - 7j - 6k

Reshape

To reshape quaternion arrays, use the reshape function.

qMatReshaped = reshape(qMatrix,4,1)
qMatReshaped=4×1 object
     1 + 2i + 3j + 4k
    -1 - 2i - 3j - 4k
     9 + 8i + 7j + 6k
    -9 - 8i - 7j - 6k

Transpose

To transpose quaternion vectors and matrices, use the transpose function.

qMatTransposed = transpose(qMatrix)
qMatTransposed=2×2 object
     1 + 2i + 3j + 4k    -1 - 2i - 3j - 4k
     9 + 8i + 7j + 6k    -9 - 8i - 7j - 6k

Permute

To permute quaternion vectors, matrices, and multidimensional arrays, use the permute function.

qMultiDimensionalArray
qMultiDimensionalArray = 2x2x2 quaternion array
qMultiDimensionalArray(:,:,1) = 

     1 + 2i + 3j + 4k     9 + 8i + 7j + 6k
     1 + 0i + 0j + 0k    -9 - 8i - 7j - 6k


qMultiDimensionalArray(:,:,2) = 

     1 + 2i + 3j + 4k     9 + 8i + 7j + 6k
    -1 - 2i - 3j - 4k    -9 - 8i - 7j - 6k

qMatPermute = permute(qMultiDimensionalArray,[3,1,2])
qMatPermute = 2x2x2 quaternion array
qMatPermute(:,:,1) = 

     1 + 2i + 3j + 4k     1 + 0i + 0j + 0k
     1 + 2i + 3j + 4k    -1 - 2i - 3j - 4k


qMatPermute(:,:,2) = 

     9 + 8i + 7j + 6k    -9 - 8i - 7j - 6k
     9 + 8i + 7j + 6k    -9 - 8i - 7j - 6k

Extended Capabilities

C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.

Introduced in R2018a