Rotation API Reference#

The rotation portion of the module provides methods for generating rotation matrices, as well as methods for handling the rotations.

The getMatrix* methods return a matrix based on specific rotation types: axis, Euler and from one reference frame to another.

The rotate* methods work similarly to the getMatrix* methods, but they handle deriving the necessary matrices and how to use them internally. This allows the most inexperienced user to safely rotate vectors between reference frames and keeps code clean and concise.

How Rotations Work#

Pure rotations work like a map from a vector space to itself. If the original reference frame is our normal x, y, z coordinate frame, a rotated vector is that original vector expressed with a differenct set of basis vectors.

Basis Vectors#

Simply speaking, basis vectors are the set of vectors that allow us to represent every vector in a vector space. For a Euclidean vector space these are usually the unit vectors pointing towards each positive axis, namely (1, 0, 0), (0, 1, 0) and (0, 0, 1), also called e1, e2 and e3 respectively. Any vector in our vector space then, can be written as a linear combination of our basis vectors: (a, b, c) = e1 * a + e2 * b + e3 * c. Other sets of basis vectors also exist, as well show shortly.

Rotation Matrix#

A rotation matrix is simply a mapping of vectors. When right multiplying a matrix by a vector, we create a new vector that is a linear combination of the columns of our matrix (called the column space). In essence, we can think of these column vectors as a basis for a rotated reference frame in the same vector space.

For a simple example, think of the identity matrix as a rotation. Of course we know this is a rotation of zero radians, since no vector will be changed by multiplying by the identity matrix. This can be demonstrated by looking at the identity matrix’s columns:

>>> Matrix.id
Matrix([1, 0, 0]
    [0, 1, 0]
    [0, 0, 1])

This first column, which represents where the x-axis is mapped to, is the x-axis (1, 0, 0). The second and third columns show the y and z axes also map to themselves, which is why each vector remains the same after being multiplied by the identity matrix.

A more complex example can be seen using the Euler rotation around the axes X, Y and Z, with angles 1.0, 2.0 and 3.0 radians. This yields the rotation matrix:

>>> getMatrixEuler(XYZ, Angles(1.0, 2.0, 3.0))
Matrix([0.411982, 0.0587266, 0.909297]
    [-0.681243, -0.642873, 0.350175]
    [0.605127, -0.763718, -0.224845])

Here the x-axis maps to the vector (0.411982, -0.681243, 0.605127). The y and z axes map to the second and third column vectors respectively. Because these vectors are only rotations of our original axis vectors, they remain orthogonal to each other, meaning they are linearly independent, and since there’s three of them in a 3-dimensional vector space, they form a basis.

The significance of this basis is it represents how the three axes of the reference frame defined by the Euler rotation are represented in our original basis. Therefore, by multiplying a vector from the rotated reference frame by our rotation matrix, we get a representation of that vector in the original basis. This is equivalent to rotating the vector from the rotated reference frame, to the original reference frame. Simply put, if we multiply our vectors on the right, the rotation matrix tells us how to move vectors from a rotated reference frame to the unrotated reference frame.

Overly simplifying a few things, the rotation matrix that describes how to move the other direction between reference frames is simply the inverse of the original rotation matrix. Luckily, the inverse of a pure rotation matrix is its transpose, which is simple to compute. Therefore, multiplying a vector from our original reference frame on the right by the transpose of our matrix from above, rotates said vector to the rotated reference frame.

Speeding Things Along#

As you may have already noticed, multiplying the transpose of a matrix on the right generates the same output as if we multiplied the original matrix on the left. This is good for us, because it means we don’t need to transpose our matrices, which otherwise would add more time to our computations. In summary, for an unrotated reference frame A, if we have a pure rotation matrix that describes a mapping to reference frame B, multiplying the matrix by a vector on the right rotates the vector from B to A. Multiplying the matrix by a vector on the left rotates the vector from A to B. Note the opposite is true if you inverse (transpose) the matrix.

If M is a matrix representing a rotation from reference frame A to reference frame B:

Mapping Direction

Matrix Form

Operation

A -> B

normal

vB = vA @ M

A -> B

transposed

vB = transpose(M) @ vA

B -> A

normal

vA = M @ vB

B -> A

transposed

vA = vB @ transpose(M)

While several reference frame mappings exist, as long as they are pure rotations (no offset origins) a single matrix is enough describe the mapping. This allows us to use the rules above to rotate any vector using the matrix returned by one of the getMatrix* methods. To simplify all of this, PyEVSpace implements a collection of methods to handle all of the above for you. The rotate*To and rotate*From methods remove all of the complexities of rotations, while also eliminating the need for you to create a matrix yourself. While you now know how to rotate vectors yourself, it is advised to use these methods for cleaner code, to reduce errors and faster execution of the rotation.

Generating Rotation Matrices#

The pyevspace module provides the following methods for generating rotation matrices.

Method

Rotation Type

Reference

getMatrixAxis()

Rotation around a single axis

Rotation Matrix

getMatrixEuler()

Three axis Euler rotation

Euler Rotation

getMatrixFromTo()

From one reference frame to another

Rotating Vectors#

The following methods are used to rotate vectors without needing to generate a rotation matrix yourself. Each method ‘type’ refers to a rotation type, and has two related methods, a ‘from’ and a ‘to’ method.

Note

An inertial reference frame refers to an un-rotated and constant reference frame. In theory, this need not be exactly true, only true relative to the derived reference frame rotating from or to. In most cases, the corresponding rotation matrix for the inertial reference frame is the identity matrix: Matrix.id.

Method

From Reference Frame

To Reference Frame

rotateAxisFrom()

The axis and angle specified

An inertial reference frame

rotateAxisTo()

An inertial reference frame

The axis and angle specified

rotateEulerFrom()

The frame resulting from the order and angles specified

An inertial reference frame

rotateEulerTo()

An inertial reference frame

The frame resulting from the order and angles specified

rotateMatrixFrom()

The frame described by the matrix

An inertial reference frame

rotateMatrixTo()

An inertial reference frame

The frame described by the matrix

rotateOffsetFrom()

The offset frame specified

An inertial reference frame

rotateOffsetTo()

An inertial reference frame

The offset frame specified

Rotation Types#

Enumerated Axes#

A few types are needed to help describe an Euler rotation. An Euler rotation consists of an order of axes about which consecutive axis rotations occur, and the angles by which they’re rotated.

To specify an axis around which a rotation occurs, there are three enumerated constants.

pyevspace.X_AXIS#

Enumerated constant to specify the X_AXIS.

Type:

int

Value:

0

pyevspace.Y_AXIS#

Enumerated constant to specify the Y_AXIS.

Type:

int

Value:

1

pyevspace.Z_AXIS#

Enumerated constant to specify the Z_AXIS.

Type:

int

Value:

2

Order#

There are 12 unique Euler rotation orders, which are already defined, so it is unlikely to need to instantiate another Order object, however the class is still documented below.

class pyevspace.Order(firstAxis, secondAxis, thirdAxis)#

A class that specifies the order of axes in an Euler rotation. The axis arguments are technically int values, but the enumerated axis values should be used to avoid confusion and made code cleaner and easier to read.

Parameters:
  • firstAxis (int) – the first axis of an Euler rotation

  • secondAxis (int) – the second axis of an Euler rotation

  • thirdAxis (int) – the third axis of an Euler rotation

Attributes#

Order.first#

The first axis of the rotation order.

Type:

int

Order.second#

The second axis of the rotation order.

Type:

int

Order.third#

The third axis of the rotation order.

Type:

int

Instance Methods#

Order.__len__()#

Returns the length of the order for sequencing.

Returns:

always returns 3

Return type:

int

Order.__getitem__(index)#

Returns the indexed axis.

Parameters:

index (int) – the index of the order to get

Raises:
  • TypeError – if index is not an int type

  • IndexError – if index is not in [0, 2]

Returns:

the indexed axis

Return type:

int

Order.__setitem__(index, value)#

to be removed?

Order.__repr__()#

Converts the order to a string representation, representative of a constructor call.

Returns:

a string representation of the order

Return type:

str

Order.__str__()#

Converts the order to a string representation.

Returns:

a string representation of the order

Return type:

str

Order.__reduce__()#

Returns a tuple of objects capable of reconstructing an order object for copying and pickling.

Returns:

a tuple with the constructor and rotations

Return type:

tuple

Angles#

class pyevspace.Angles(alpha, beta, gamma)#

A class to hold the angles that correspond to the axes in the Order type. The angle corresponds to the respective axis in its associated order object.

Parameters:
  • alpha (float) – the angle in radians around the first axis

  • beta (float) – the angle in radians around the second axis

  • gamma (float) – the angle in radians around the third axis

Attributes#

Angles.alpha#

The first angle of a rotation.

Angles.beta#

The second angle of a rotation.

Angles.gamma#

The third angle of a rotation.

Instance Methods#

Angles.__len__()#

Returns the lengh of the angles for sequencing.

Returns:

always returns 3

Return type:

int

Angles.__getitem__(index)#

Returns the indexed angle.

Parameters:

index (int) – the index of the angle to get

Raises:
  • TypeError – if index is not an int type

  • IndexError – if index is not in [0, 2]

Returns:

the indexed angle

Return type:

float

Angles.__setitem__(index, value)#

Sets the indexed angle to value.

Parameters:
  • index (int) – the index of the angle to get

  • value (float) – the value to set the angle in radians

Raises:
  • TypeError – if index is not an int type or value is not a numeric type

  • IndexError – if index is not in [0, 2]

Angles.__repr__()#

Converts the angles to a string representation, representative of a constructor call.

Returns:

a string representation of the angles

Return type:

str

Angles.__str__()#

Converts the angles to a string representation.

Returns:

a string representation of the angles

Return type:

str

Angles.__reduce__()#

Returns a tuple of objects capable of reconstructing an angles object for copying and pickling.

Returns:

a tuple with the constructor and angles

Return type:

tuple

Matrix Generator Methods#

pyevspace.getMatrixAxis(axis, angle)#

Creates a matrix that describes a rotation around an axis by an angle.

Parameters:
  • axis (int) – axis of rotation, should be one of the defined enumerated axes

  • angle (numeric) – angle of rotation in radians

Raises:
  • TypeError – if axis is not an int or angle is not a numeric type

  • ValueError – if axis is not in [0-2]

Returns:

the rotation matrix

Return type:

Matrix

pyevspace.getMatrixEuler(order, angles)#

Creates a matrix that describes an Euler rotation by its order and the associated angles.

Parameters:
  • order (Order) – the Euler order of rotation

  • angles (Angles) – the angles associated with the order axes

Raises:

TypeError – if order is not an Order type or angles is not an Angles type

Returns:

the rotation matrix

Return type:

Matrix

pyevspace.getMatrixFromTo(orderFrom, anglesFrom, orderTo, anglesTo)#

Creates a matrix that describes a rotation between two reference frames, where each frame is defined as an Euler rotation.

Parameters:
  • orderFrom (Order) – the Euler order of the reference frame moving from

  • anglesFrom (Angles) – the angles for the reference frame moving from

  • orderTo (Order) – the Euler order of the reference frame moving to

  • anglesTo (Angles) – the angles for the reference frame moving to

Raises:

TypeError – if orderFrom or orderTo are not Order types, or anglesFrom or anglesTo are not Angles types

Returns:

the rotation matrix

Return type:

Matrix

Rotation Methods#

pyevspace.rotateAxisFrom(axis, angle, vector)#

Rotates a vector from a reference frame defined by an axis rotation.

Parameters:
  • axis (int) – axis of rotation, should be one of the defined enumerated axes

  • angle (float) – angle of rotation in radians

  • vector (Vector) – vector to rotate

Raises:
  • TypeError – if axis is not an int, angle is not a float or vector is not a Vector type

  • ValueError – if axis is not in [0, 2]

Returns:

the rotated vector

Return type:

Vector

pyevspace.rotateAxisTo(axis, angle, vector)#

Rotates a vector to a reference frame defined by an axis rotation.

Parameters:
  • axis (int) – axis of rotation, should be one of the defined enumerated axes

  • angle (float) – angle of rotation in radians

  • vector (Vector) – vector to rotate

Raises:
  • TypeError – if axis is not an int, angle is not a float or vector is not a Vector type

  • ValueError – if axis is not in [0, 2]

Returns:

the rotated vector

Return type:

Vector

pyevspace.rotateEulerFrom(order, angles, vector)#

Rotates a vector from a reference frame defined by an Euler rotation.

Parameters:
  • order (Order) – the Euler order of rotation

  • angles (Angles) – the angles associated with the order axes

  • vector (Vector) – the vector to rotate

Raises:

TypeError – if order is not an Order type, angles are not an Angles type or vector is not a Vector type

Returns:

the rotated vector

Return type:

Vector

pyevspace.rotateEulerTo(order, angles, vector)#

Rotates a vector to a reference frame defined by an Euler rotation.

Parameters:
  • order (Order) – the Euler order of rotation

  • angles (Angles) – the angles associated with the order axes

  • vector (Vector) – the vector to rotate

Raises:

TypeError – if order is not an Order type, angles are not an Angles type or vector is not a Vector type

Returns:

the rotated vector

Return type:

Vector

pyevspace.rotateMatrixFrom(matrix, vector)#

Rotates a vector from a reference frame defined by a rotation matrix.

Parameters:
  • matrix (Matrix) – the rotation matrix

  • vector (Vector) – the vector to rotate

Raises:

TypeError – if matrix is not a Matrix type or vector is not a Vector type

Returns:

the rotated vector

Return type:

Vector

pyevspace.rotateMatrixTo(matrix, vector)#

Rotates a vector to a reference frame defined by a rotation matrix.

Parameters:
  • matrix (Matrix) – the rotation matrix

  • vector (Vector) – the vector to rotate

Raises:

TypeError – if matrix is not a Matrix type or vector is not a Vector type

Returns:

the rotated vector

Return type:

Vector

pyevspace.rotateOffsetFrom(matrix, offset, vector)#

Rotates a vector from an offset reference frame.

Parameters:
  • matrix (Matrix) – the rotation matrix

  • vector (Vector) – the vector to rotate

Raises:

TypeError – if matrix is not a Matrix type or offset and vector are not Vector types

Returns:

the rotated vector:

Return type:

Vector

pyevspace.rotateOffsetTo(matrix, offset, vector)#

Rotates a vector to an offset reference frame.

Parameters:
  • matrix (Matrix) – the rotation matrix

  • vector (Vector) – the vector to rotate

Raises:

TypeError – if matrix is not a Matrix type or offset and vector are not Vector types

Returns:

the rotated vector:

Return type:

Vector