Transformations
The moro.transformations module provides functions for rotations,
homogeneous transformations, Euler angles, axis-angle representations, and
Denavit-Hartenberg transformations.
Numython R&D, (c) 2026 Moro is a Python library for kinematic and dynamic modeling of serial robots. This library has been designed, mainly, for academic and research purposes, using SymPy as base library.
- moro.transformations.axa2rot(k, theta)[source]
Build a rotation matrix from an axis-angle representation.
- Parameters:
- klist, tuple or sympy Matrix
Rotation axis. Accepted formats are a 3-element list, a 3-element tuple, a column matrix of shape (3, 1), or a row matrix of shape (1, 3). The vector is normalized internally to a column matrix. The zero vector is rejected because it does not define a rotation axis.
- thetafloat, int or symbolic
Rotation angle in radians.
- Returns:
- Rsympy.matrices.dense.MutableDenseMatrix
Rotation matrix of shape (3, 3) computed with Rodrigues’ formula.
- moro.transformations.dh(a, alpha, d, theta)[source]
Compute the Denavit-Hartenberg homogeneous transformation matrix.
- Parameters:
- aint, float or symbolic
Link length (DH parameter).
- alphaint, float or symbolic
Link twist (DH parameter).
- dint, float or symbolic
Link offset (DH parameter).
- thetaint, float or symbolic
Joint angle (DH parameter).
- Returns:
- sympy.matrices.dense.MutableDenseMatrix
Denavit-Hartenberg homogeneous transformation matrix of shape (4, 4).
Examples
With numerical values:
>>> dh(100, pi/2, 50, pi/2) ⎡0 0 1 0 ⎤ ⎢ ⎥ ⎢1 0 0 100⎥ ⎢ ⎥ ⎢0 1 0 50 ⎥ ⎢ ⎥ ⎣0 0 0 1 ⎦
Using symbolic values:
>>> a = symbols("a") >>> t = symbols("t") >>> dh(a, 0, 0, t) ⎡cos(t) -sin(t) 0 a⋅cos(t)⎤ ⎢ ⎥ ⎢sin(t) cos(t) 0 a⋅sin(t)⎥ ⎢ ⎥ ⎢ 0 0 1 0 ⎥ ⎢ ⎥ ⎣ 0 0 0 1 ⎦
- moro.transformations.eul2rot(phi, theta, psi, seq='zxz', deg=False)[source]
Build a rotation matrix from proper Euler angles.
- Parameters:
- phiint, float or symbolic
First Euler angle.
- thetaint, float or symbolic
Intermediate Euler angle.
- psiint, float or symbolic
Third Euler angle.
- seqstr, optional
Proper Euler sequence. Supported sequences are
"xyx","xzx","yxy","yzy","zxz"and"zyz". Matching is case-insensitive. Tait-Bryan sequences such as"xyz"are not supported here.- degbool, optional
If True, the input angles are interpreted as degrees and converted to radians before constructing the matrix.
- Returns:
- sympy.matrices.dense.MutableDenseMatrix
Rotation matrix.
Notes
This function uses column vectors and active rotations. For a sequence
seq="abc", the convention is defined by the matrix productR = R_a(phi) @ R_b(theta) @ R_c(psi), where each elementary rotation is produced byrot(). For proper Euler sequences,a == c.Examples
>>> eul2rot(pi/2, pi/3, pi/4, seq="zxz") ⎡-√2 -√6 ⎤ ⎢──── ──── √3/2 ⎥ ⎢ 4 4 ⎥ ⎢ ⎥ ⎢-√2 √6 ⎥ ⎢──── ── -1/2 ⎥ ⎢ 4 4 ⎥ ⎢ ⎥ ⎢ √6 √2 ⎥ ⎢ ── ── 1/2 ⎥ ⎣ 4 4 ⎦
>>> eul2rot(pi/6, pi/4, pi/3, seq="xyx") ⎡√2 √2 ⎤ ⎢── √6/4 ── ⎥ ⎢2 4 ⎥ ⎢ ⎥ ⎢√2 3/8 + √3 1 3⋅√3 ⎥ ⎢── ──────── ─ - ──── ⎥ ⎢4 4 8 8 ⎥ ⎢ ⎥ ⎢-√6 1 3⋅√3 √3 3/8⎥ ⎢──── ─ + ──── ── - ───⎥ ⎣ 4 8 8 4 4 ⎦
- moro.transformations.htm2rot(T)[source]
Extract the rotation block from a homogeneous transformation matrix.
- Parameters:
- Tarray-like or sympy Matrix
Homogeneous transformation matrix. It is converted with
Matrix(T)and must have shape (4, 4). No full SE(3) membership validation is performed.
- Returns:
- sympy.matrices.dense.MutableDenseMatrix
Upper-left rotation block of shape (3, 3).
- moro.transformations.htm2tra(T)[source]
Extract the translation vector from a homogeneous transformation matrix.
- Parameters:
- Tarray-like or sympy Matrix
Homogeneous transformation matrix. It is converted with
Matrix(T)and must have shape (4, 4). No full SE(3) membership validation is performed.
- Returns:
- sympy.matrices.dense.MutableDenseMatrix
Translation column vector of shape (3, 1).
- moro.transformations.htmrot(theta, axis='z', deg=False)[source]
Return a homogeneous transformation matrix for a pure rotation.
- Parameters:
- thetafloat, int or symbolic
Rotation angle. By default, the value is interpreted in radians.
- axisstr
Rotation axis,
"x","y"or"z". Matching is case-insensitive. Default is"z".- degbool, optional
If True,
thetais interpreted as degrees. Default is False.
- Returns:
- H
sympy.matrices.dense.MutableDenseMatrix Homogeneous transformation matrix of shape (4, 4).
- H
Examples
>>> htmrot(pi/2) ⎡0 -1 0 0⎤ ⎢ ⎥ ⎢1 0 0 0⎥ ⎢ ⎥ ⎢0 0 1 0⎥ ⎢ ⎥ ⎣0 0 0 1⎦ >>> htmrot(pi/2, "x") ⎡1 0 0 0⎤ ⎢ ⎥ ⎢0 0 -1 0⎥ ⎢ ⎥ ⎢0 1 0 0⎥ ⎢ ⎥ ⎣0 0 0 1⎦ >>> htmrot(30, "y", True) ⎡0.866025403784439 0 0.5 0⎤ ⎢ ⎥ ⎢ 0 1 0 0⎥ ⎢ ⎥ ⎢ -0.5 0 0.866025403784439 0⎥ ⎢ ⎥ ⎣ 0 0 0 1⎦ >>> t = symbols("t") >>> htmrot(t, "x") ⎡1 0 0 0⎤ ⎢ ⎥ ⎢0 cos(t) -sin(t) 0⎥ ⎢ ⎥ ⎢0 sin(t) cos(t) 0⎥ ⎢ ⎥ ⎣0 0 0 1⎦
- moro.transformations.htmtra(x=0, y=0, z=0)[source]
Calculate the homogeneous transformation matrix of a translation.
- Parameters:
- xint, float or symbolic, optional
Translation along the x-axis. Default is 0.
- yint, float or symbolic, optional
Translation along the y-axis. Default is 0.
- zint, float or symbolic, optional
Translation along the z-axis. Default is 0.
- Returns:
- H
sympy.matrices.dense.MutableDenseMatrix Homogeneous transformation matrix
- H
Examples
>>> htmtra() ⎡1 0 0 0⎤ ⎢ ⎥ ⎢0 1 0 0⎥ ⎢ ⎥ ⎢0 0 1 0⎥ ⎢ ⎥ ⎣0 0 0 1⎦
>>> htmtra(10,-40,50) ⎡1 0 0 10 ⎤ ⎢ ⎥ ⎢0 1 0 -40⎥ ⎢ ⎥ ⎢0 0 1 50 ⎥ ⎢ ⎥ ⎣0 0 0 1 ⎦
>>> htmtra(z=100) ⎡1 0 0 0 ⎤ ⎢ ⎥ ⎢0 1 0 0 ⎥ ⎢ ⎥ ⎢0 0 1 100⎥ ⎢ ⎥ ⎣0 0 0 1 ⎦
>>> a,b,c = symbols("a,b,c") >>> htmtra(x=a, y=b, z=c) ⎡1 0 0 a⎤ ⎢ ⎥ ⎢0 1 0 b⎥ ⎢ ⎥ ⎢0 0 1 c⎥ ⎢ ⎥ ⎣0 0 0 1⎦
- moro.transformations.invhtm(T)[source]
Compute the structured inverse of a homogeneous transformation matrix.
- Parameters:
- Tarray-like or sympy Matrix
Homogeneous transformation matrix. It is converted with
Matrix(T)and must have shape (4, 4). No full SE(3) membership validation is performed.
- Returns:
- sympy.matrices.dense.MutableDenseMatrix
Inverse homogeneous transformation matrix computed from the rigid-body structure, using
R.Tand-R.T*pinstead of a general matrix inverse.
- moro.transformations.rot(theta, axis='z', deg=False)[source]
Return a rotation matrix that represents a rotation of
thetaaboutaxis.- Parameters:
- thetafloat, int or symbolic
Rotation angle. By default, the value is interpreted in radians.
- axisstr
Rotation axis,
"x","y"or"z". Matching is case-insensitive. Default is"z".- degbool, optional
If True,
thetais interpreted as degrees. Default is False.
- Returns:
- sympy.matrices.dense.MutableDenseMatrix
Rotation matrix of shape (3, 3).
- moro.transformations.rot2axa(R, deg=False, tol=1e-09)[source]
Return the axis-angle representation of a rotation matrix.
- Parameters:
- Rsympy Matrix
Rotation matrix in SO(3).
- degbool, optional
If True, the angle is returned in degrees. Default is False.
- tolfloat, optional
Positive tolerance used to validate numeric rotation matrices, classify angles close to 0, classify angles close to pi, and tolerate small floating-point errors in trigonometric quantities. Default is 1e-9.
- Returns:
- ksympy.matrices.dense.MutableDenseMatrix
Axis of rotation, a 3D vector.
- thetafloat, int or symbolic
Rotation angle in radians by default, or in degrees when
deg=True.
- moro.transformations.rot2eul(R, seq='zxz', deg=False, tol=1e-09)[source]
Calculate proper Euler angles from a rotation matrix.
- Parameters:
- Rmatrix-like, shape (3, 3)
Rotation matrix. The function validates only that the input has shape
(3, 3); it does not yet perform a full SO(3) membership check.- seqstr, optional
Proper Euler sequence. Supported sequences are
"xyx","xzx","yxy","yzy","zxz"and"zyz". Matching is case-insensitive.- degbool, optional
If True, returned angles are converted from radians to degrees.
- tolfloat, optional
Positive numerical tolerance used only for floating-point classification near the singularities
theta = 0andtheta = piand for clipping small numerical excursions ofcos(theta)outside[-1, 1].
- Returns:
- list of tuple
In the general case, returns two equivalent solutions
[(phi1, theta1, psi1), (phi2, theta2, psi2)]. In singular cases, returns a single representative solution withpsi = 0.
Notes
The convention matches
eul2rot(): column vectors, active rotations andR = R_a(phi) @ R_b(theta) @ R_a(psi)forseq="aba". Euler angle representations are not unique; both general-case solutions reconstruct the same matrix, the second solution may contain a negative intermediate angle, and no additional range normalization is applied. At singularities,phiandpsiare not independently determined; settingpsi = 0is only a representative convention.
- moro.transformations.rot2htm(R)[source]
Build a homogeneous transformation matrix from a rotation matrix.
- Parameters:
- Rarray-like or sympy Matrix
Rotation block. It is converted with
Matrix(R)and must have shape (3, 3). No full SO(3) membership validation is performed.
- Returns:
- sympy.matrices.dense.MutableDenseMatrix
Homogeneous transformation matrix with zero translation and shape (4, 4).
- moro.transformations.rotx(theta, deg=False)[source]
Calculates the rotation matrix about the x-axis
- Parameters:
- thetafloat, int or symbolic
Rotation angle (given in radians by default)
- degbool
If True, theta is interpreted as degrees. Default is False.
- Returns:
- sympy.matrices.dense.MutableDenseMatrix
Rotation matrix in SO(3).
Examples
>>> rotx(pi) ⎡1 0 0 ⎤ ⎢ ⎥ ⎢0 -1 0 ⎥ ⎢ ⎥ ⎣0 0 -1⎦ >>> rotx(60, deg=True) ⎡1 0 0 ⎤ ⎢ ⎥ ⎢0 0.5 -0.866025403784439⎥ ⎢ ⎥ ⎣0 0.866025403784439 0.5 ⎦
- moro.transformations.roty(theta, deg=False)[source]
Calculates the rotation matrix about the y-axis
- Parameters:
- thetafloat, int or symbolic
Rotation angle (given in radians by default)
- degbool
If True, theta is interpreted as degrees. Default is False.
- Returns:
- sympy.matrices.dense.MutableDenseMatrix
Rotation matrix in SO(3).
Examples
>>> roty(pi/3) ⎡ √3 ⎤ ⎢1/2 0 ── ⎥ ⎢ 2 ⎥ ⎢ ⎥ ⎢ 0 1 0 ⎥ ⎢ ⎥ ⎢-√3 ⎥ ⎢──── 0 1/2⎥ ⎣ 2 ⎦
>>> roty(30, deg=True) ⎡0.866025403784439 0 0.5 ⎤ ⎢ ⎥ ⎢ 0 1 0 ⎥ ⎢ ⎥ ⎣ -0.5 0 0.866025403784439⎦
- moro.transformations.rotz(theta, deg=False)[source]
Calculate the rotation matrix about the z-axis.
- Parameters:
- thetafloat, int or symbolic
Rotation angle. By default, the value is assumed to be given in radians.
- degbool, optional
If True, theta is interpreted as degrees. Default is False.
- Returns:
- sympy.matrices.dense.MutableDenseMatrix
Rotation matrix in SO(3).
Examples
Using angle in radians:
>>> rotz(pi/2) ⎡0 -1 0⎤ ⎢ ⎥ ⎢1 0 0⎥ ⎢ ⎥ ⎣0 0 1⎦
Using symbolic variables:
>>> x = symbols("x") >>> rotz(x) ⎡cos(x) -sin(x) 0⎤ ⎢ ⎥ ⎢sin(x) cos(x) 0⎥ ⎢ ⎥ ⎣ 0 0 1⎦
Using angles in degrees:
>>> rotz(45, deg=True) ⎡0.707106781186548 -0.707106781186547 0⎤ ⎢ ⎥ ⎢0.707106781186547 0.707106781186548 0⎥ ⎢ ⎥ ⎣ 0 0 1⎦
- moro.transformations.rt2htm(R, p)[source]
Build a homogeneous transformation matrix from rotation and translation.
- Parameters:
- Rarray-like or sympy Matrix
Rotation block. It is converted with
Matrix(R)and must have shape (3, 3). No full SO(3) membership validation is performed.- plist, tuple or sympy Matrix
Translation vector. Accepted formats are a 3-element list, a 3-element tuple, a column matrix of shape (3, 1), or a row matrix of shape (1, 3). The vector is normalized internally to a column matrix.
- Returns:
- sympy.matrices.dense.MutableDenseMatrix
Homogeneous transformation matrix of shape (4, 4).
- moro.transformations.skew(u)[source]
Return the skew-symmetric matrix associated with a 3D vector.
- Parameters:
- ulist, tuple or sympy Matrix
Vector. Accepted formats are a 3-element list, a 3-element tuple, a column matrix of shape (3, 1), or a row matrix of shape (1, 3). The vector is normalized internally to a column matrix.
- Returns:
- Ssympy.matrices.dense.MutableDenseMatrix
Skew-symmetric matrix of shape (3, 3).