9.5.3. Extracting 3D angles using Kinetics Toolkit#

We already used the ktk.geometry.get_angles function to extract a 2D angle. This function can also accommodate any of these 24 variations of 3D rotation sequences, using the seq parameter which is 3 characters belonging to the set {‘X’, ‘Y’, ‘Z’} for intrinsic rotations (moving axes), or {‘x’, ‘y’, ‘z’} for extrinsic rotations (fixed axes).

For instance, lets create a 3d rotation defined by an extrinsic cardan sequence of 20° about the x axis, then -10° about the y axis, then 15° about the z axis:

\[ T = T_{15^\circ \text{around} z} ~~~ T_{-10^\circ \text{around} y} ~~~ T_{20^\circ \text{around} x} \]
import kineticstoolkit.lab as ktk


total_rotation = ktk.geometry.matmul(
    ktk.geometry.create_transforms(angles=[15], seq="z", degrees=True),
    ktk.geometry.matmul(
        ktk.geometry.create_transforms(angles=[-10], seq="y", degrees=True),
        ktk.geometry.create_transforms(angles=[20], seq="x", degrees=True),
    ),
)

total_rotation
array([[[ 0.95125124, -0.30057782, -0.0690945 ,  0.        ],
        [ 0.254887  ,  0.8923018 , -0.37259912,  0.        ],
        [ 0.17364818,  0.33682409,  0.92541658,  0.        ],
        [ 0.        ,  0.        ,  0.        ,  1.        ]]])

To extract these three angles back from this matrix, we would use a sequence of “xyz”, in lower case to denote extrinsic rotations:

angles = ktk.geometry.get_angles(total_rotation, seq="xyz", degrees=True)

angles
array([[ 20., -10.,  15.]])

Note that other combinations would give different and wrong angles:

print(ktk.geometry.get_angles(total_rotation, seq="XYZ", degrees=True))
print(ktk.geometry.get_angles(total_rotation, seq="xzy", degrees=True))
print(ktk.geometry.get_angles(total_rotation, seq="zyx", degrees=True))
print(ktk.geometry.get_angles(total_rotation, seq="ZXY", degrees=True))
[[21.93112279 -3.96197996 17.53557362]]
[[ 22.66398762  14.76688961 -10.34527005]]
[[17.53557362 -3.96197996 21.93112279]]
[[ 18.61644157  19.68349808 -10.62758414]]