py3dframe.Frame#

class py3dframe.Frame(*, origin: ndarray | None = None, axes: ndarray | None = None, x_axis: ndarray | None = None, y_axis: ndarray | None = None, z_axis: ndarray | None = None, translation: ndarray | None = None, rotation: Rotation | None = None, rotation_matrix: ndarray | None = None, quaternion: ndarray | None = None, euler_angles: ndarray | None = None, rotation_vector: ndarray | None = None, parent: Frame | None = None, setup_only: bool = False, convention: int | None = 0)[source]#

A Frame object represents a frame of reference of \(\mathbb{R}^3\) (only orthogonal and right-handed frames are supported).

A frame of reference is defined by its origin and its basis vectors in the global frame coordinates. The origin is a 3-element vector. The basis vectors can be given in 3 different 3-element vectors or in a 3x3 matrix with the basis vectors as columns.

import numpy
from py3dframe import Frame
e1 = [1, 0, 0]
e2 = [0, 1, 0]
e3 = [0, 0, 1]
origin = [1, 2, 3]
frame = Frame(origin=origin, x_axis=e1, y_axis=e2, z_axis=e3)
frame = Frame(origin=origin, axes=numpy.column_stack((e1, e2, e3)))

Sometimes the user wants to define a frame relatively to another frame. For example, if we consider a person in a train, the person is defined in the train frame and the train frame is defined in the global frame. When the parent frame changes, the child frame changes too but the transformation between the frames remains the same. In this case, the user must provide the parent frame (parent parameter) and the origin and the basis vectors of the frame in the parent frame coordinates.

An other way to define a frame is to use the transformation between the parent frame and the frame. Lets note \(E\) the parent frame (or the global frame) and \(F\) the frame to define. The transformation between the frame \(E\) and the frame \(F\) is defined by a rotation matrix \(R\) and a translation vector \(T\). Several conventions can be used to define the transformation between the frames.

Index

Formula

0

\(\mathbf{X}_E = \mathbf{R} \mathbf{X}_F + \mathbf{T}\)

1

\(\mathbf{X}_E = \mathbf{R} \mathbf{X}_F - \mathbf{T}\)

2

\(\mathbf{X}_E = \mathbf{R} (\mathbf{X}_F + \mathbf{T})\)

3

\(\mathbf{X}_E = \mathbf{R} (\mathbf{X}_F - \mathbf{T})\)

4

\(\mathbf{X}_F = \mathbf{R} \mathbf{X}_E + \mathbf{T}\)

5

\(\mathbf{X}_F = \mathbf{R} \mathbf{X}_E - \mathbf{T}\)

6

\(\mathbf{X}_F = \mathbf{R} (\mathbf{X}_E + \mathbf{T})\)

7

\(\mathbf{X}_F = \mathbf{R} (\mathbf{X}_E - \mathbf{T})\)

Note

If a parent is given to the frame, the frame will be defined relative to the parent frame. A change in the parent frame will affect the frame but the transformation between the frames will remain the same. If you want use the parent frame only to define the frame and not to link the frames, set the parameter setup_only to True (the parent attribute will be seted to None after the frame is created).

Note

If the axes are provided, the class will normalize the basis vectors to get an orthonormal matrix.

See also

  • class py3dframe.Transform to represent a transformation between two frames of reference and convert points between the frames.

  • function py3dframe.matrix.O3_project() to project a 3x3 matrix to the orthogonal group O(3) before using it as a rotation matrix.

Parameters:
  • origin (array_like, optional) – The coordinates of the origin of the frame in the parent frame coordinates. Default is the zero vector.

  • axes (array_like, optional) – The basis vectors of the frame in the parent frame coordinates. Default is the identity matrix.

  • x_axis (array_like, optional) – The x-axis of the frame in the parent frame coordinates. Default is the x-axis of the parent frame.

  • y_axis (array_like, optional) – The y-axis of the frame in the parent frame coordinates. Default is the y-axis of the parent frame.

  • z_axis (array_like, optional) – The z-axis of the frame in the parent frame coordinates. Default is the z-axis of the parent frame.

  • translation (array_like, optional) – The translation vector in the convention used to define the frame. Default is the zero vector. The translation vector is a 3-element vector.

  • rotation (scipy.spatial.transform.Rotation, optional) – The rotation in the convention used to define the frame. Default is the identity rotation.

  • rotation_matrix (array_like, optional) – The rotation matrix in the convention used to define the frame. Default is the identity matrix. The rotation matrix is a 3x3 matrix.

  • quaternion (array_like, optional) – The quaternion in the convention used to define the frame. Default is the identity quaternion. The quaternion is a 4-element vector [w, x, y, z] (scalar first convention).

  • euler_angles (array_like, optional) – The euler angles in the convention used to define the frame. Default is the zero vector. The euler angles are a 3-element vector with xyz convention in radians.

  • rotation_vector (array_like, optional) – The rotation vector in the convention used to define the frame. Default is the zero vector. The rotation vector is a 3-element vector with the angle in radians.

  • parent (Optional[Frame], optional) – The parent frame of the frame. Default is None - the global frame.

  • setup_only (bool, optional) – If True, the parent frame will be used only to define the frame and not to link the frames. Default is False.

  • convention (int, optional) – The convention to express the transformation. It can be an integer between 0 and 7 or a string corresponding to the conventions. Default is 0. This parameter is used only if the axes are not defined by the axes parameter.

Raises:
  • TypeError – If any of the parameters is wrong type.

  • ValueError – If the origin is not a 3-element vector. If the axes is not a 3x3 matrix. If the parent is not a Frame object. If axes is not an orthogonal matrix. If several parameters are provided to define the frame.

Examples

Lets \(E = (O_E, \mathbf{e}_1, \mathbf{e}_2, \mathbf{e}_3)\) be a frame of reference of \(\mathbb{R}^3\). To create the frame \(E\), the user must provide the origin and the basis vectors of the frame.

from py3dframe import Frame

origin = [1, 2, 3]
x_axis = [1, 1, 0]
y_axis = [1, -1, 0]
z_axis = [0, 0, 1]
frame_E = Frame(origin=origin, x_axis=x_axis, y_axis=y_axis, z_axis=z_axis, parent=None)

A frame can also be defined in another frame of reference (named the parent frame).

Lets consider a frame \(F = (O_F, \mathbf{f}_1, \mathbf{f}_2, \mathbf{f}_3)\) defined in the frame \(E\). The user must provide the origin and the basis vectors of the frame \(F\) in the frame \(E\).

from py3dframe import Frame

origin = [1, -2, 3]
x_axis = [1, 0, 1]
y_axis = [0, 1, 0]
z_axis = [-1, 0, 1]
frame_F = Frame(origin=origin, x_axis=x_axis, y_axis=y_axis, z_axis=z_axis, parent=frame_E)

In this case the frame \(F\) is defined relative to the frame \(E\). A change in the frame \(E\) will affect the frame \(F\) but the transformation between the frames will remain the same.

The user can access the origin and the basis vectors of the frame as follows:

# In the global frame
frame_F.global_origin
frame_F.global_x_axis
frame_F.global_y_axis
frame_F.gloabl_z_axis

# In the parent frame coordinates and relative to the parent frame
frame_F.origin
frame_F.x_axis
frame_F.y_axis
frame_F.z_axis

To finish, the user can define a frame using the transformation between the parent frame and the frame. Using the convention 0, the rotation matrix and the translation vector will exactly be the basis vectors and the origin of the frame.

from py3dframe import Frame

translation = [1, 2, 3]
rotation_matrix = np.array([[1, 1, 0], [1, -1, 0], [0, 0, 1]]).T # Equivalent to the column_stack((x_axis, y_axis, z_axis))
frame_E = Frame(translation=translation, rotation_matrix=rotation_matrix, parent=None, convention=0)

py3dframe.Frame.origin

Getter and setter for the origin of the frame in the parent frame coordinates.

py3dframe.Frame.axes

Getter and setter for the basis vectors of the frame in the parent frame coordinates.

py3dframe.Frame.x_axis

Getter for the x-axis of the frame in the parent frame coordinates.

py3dframe.Frame.y_axis

Getter for the y-axis of the frame in the parent frame coordinates.

py3dframe.Frame.z_axis

Getter for the z-axis of the frame in the parent frame coordinates.

py3dframe.Frame.convention

Getter and setter for the convention parameter.

py3dframe.Frame.parent

Getter and setter for the parent frame of the frame.

py3dframe.Frame.translation

Getter and setter for the translation vector between the parent frame and the frame in the convention of the frame.

py3dframe.Frame.get_translation(*[, convention])

Get the translation vector between the parent frame and the frame in the given convention.

py3dframe.Frame.set_translation(translation, *)

Set the translation vector between the parent frame and the frame in the given convention.

py3dframe.Frame.rotation

Getter and setter for the rotation between the parent frame and the frame in the convention of the frame.

py3dframe.Frame.get_rotation(*[, convention])

Get the rotation between the parent frame and the frame in the given convention.

py3dframe.Frame.set_rotation(rotation, *[, ...])

Set the rotation between the parent frame and the frame in the given convention.

py3dframe.Frame.rotation_matrix

Getter and setter for the rotation matrix between the parent frame and the frame in the convention of the frame.

py3dframe.Frame.get_rotation_matrix(*[, ...])

Get the rotation matrix between the parent frame and the frame in the given convention.

py3dframe.Frame.set_rotation_matrix(...[, ...])

Set the rotation matrix between the parent frame and the frame in the given convention.

py3dframe.Frame.quaternion

Getter and setter for the quaternion between the parent frame and the frame in the convention of the frame.

py3dframe.Frame.get_quaternion(*[, ...])

Get the quaternion between the parent frame and the frame in the given convention.

py3dframe.Frame.set_quaternion(quaternion, *)

Set the quaternion between the parent frame and the frame in the given convention.

py3dframe.Frame.euler_angles

Getter and setter for the Euler angles between the parent frame and the frame in the convention of the frame.

py3dframe.Frame.get_euler_angles(*[, ...])

Get the Euler angles between the parent frame and the frame in the given convention.

py3dframe.Frame.set_euler_angles(euler_angles, *)

Set the Euler angles between the parent frame and the frame in the given convention.

py3dframe.Frame.rotation_vector

Getter and setter for the rotation vector between the parent frame and the frame in the convention of the frame.

py3dframe.Frame.get_rotation_vector(*[, ...])

Get the rotation vector between the parent frame and the frame in the given convention.

py3dframe.Frame.set_rotation_vector(...[, ...])

Set the rotation vector between the parent frame and the frame in the given convention.

py3dframe.Frame.get_global_frame()

Get the Frame object between the global frame and the frame.

py3dframe.Frame.global_origin

Getter for the origin of the frame in the global frame coordinates.

py3dframe.Frame.global_axes

Getter and setter for the basis vectors of the frame in the global frame coordinates.

py3dframe.Frame.global_x_axis

Getter for the x-axis of the frame in the global frame coordinates.

py3dframe.Frame.global_y_axis

Getter for the y-axis of the frame in the global frame coordinates.

py3dframe.Frame.global_z_axis

Getter for the z-axis of the frame in the global frame coordinates.

py3dframe.Frame.global_translation

Getter and setter for the translation vector between the global frame and the frame in the convention of the frame.

py3dframe.Frame.get_global_translation(*[, ...])

Get the translation vector between the global frame and the frame in the given convention.

py3dframe.Frame.set_global_translation(...)

Set the translation vector between the global frame and the frame in the given convention.

py3dframe.Frame.global_rotation

Getter and setter for the rotation between the global frame and the frame in the convention of the frame.

py3dframe.Frame.get_global_rotation(*[, ...])

Get the rotation between the global frame and the frame in the given convention.

py3dframe.Frame.set_global_rotation(rotation, *)

Set the rotation between the global frame and the frame in the given convention.

py3dframe.Frame.global_rotation_matrix

Getter and setter for the rotation matrix between the global frame and the frame in the convention of the frame.

py3dframe.Frame.get_global_rotation_matrix(*)

Get the rotation matrix between the global frame and the frame in the given convention.

py3dframe.Frame.set_global_rotation_matrix(...)

Set the rotation matrix between the global frame and the frame in the given convention.

py3dframe.Frame.global_quaternion

Getter and setter for the quaternion between the global frame and the frame in the convention of the frame.

py3dframe.Frame.get_global_quaternion(*[, ...])

Get the quaternion between the global frame and the frame in the given convention.

py3dframe.Frame.set_global_quaternion(...[, ...])

Set the quaternion between the global frame and the frame in the given convention.

py3dframe.Frame.global_euler_angles

Getter and setter for the Euler angles between the global frame and the frame in the convention of the frame.

py3dframe.Frame.get_global_euler_angles(*[, ...])

Get the Euler angles between the global frame and the frame in the given convention.

py3dframe.Frame.set_global_euler_angles(...)

Set the Euler angles between the global frame and the frame in the given convention.

py3dframe.Frame.global_rotation_vector

Getter and setter for the rotation vector between the global frame and the frame in the convention of the frame.

py3dframe.Frame.get_global_rotation_vector(*)

Get the rotation vector between the global frame and the frame in the given convention.

py3dframe.Frame.set_global_rotation_vector(...)

Set the rotation vector between the global frame and the frame in the given convention.

py3dframe.Frame.draw(ax[, xcolor, ycolor, ...])

Draw the frame in the matplotlib axes (projection 3D).

py3dframe.Frame.__eq__(other)

Return the equality of the Frame object.

py3dframe.Frame.save_to_dict([method])

Save the Frame object to a dictionary.

py3dframe.Frame.load_from_dict(data)

Load the Frame object from a dictionary.

py3dframe.Frame.save_to_json(filename)

Save the Frame object to a JSON file.

py3dframe.Frame.load_from_json(filename)

Load the Frame object from a JSON file.