Blender#
Rotation formalisms#
See Rotation formalisms in three dimensions. Blender’s user interface only allows for rotations to be entered as as Quaternions, Euler rotations, or an Euler axis-angle. If you have a rotation in some other form, how do you enter it in Blender? See Rotation — SciPy Manual:
import numpy as np
from scipy.spatial.transform import Rotation as R
def show_rot(rot: R):
print('Matrix:')
display(rot.as_matrix())
print('\nBlender "Quaternion":')
display(rot.as_quat(canonical=True, scalar_first=True))
print('\nBlender "XYZ Euler":')
display(rot.as_euler('xyz', degrees=True))
print('\nBlender "Axis Angle":')
rot_vec = rot.as_rotvec(degrees=True)
norm = np.linalg.norm(rot_vec)
display(norm, rot_vec / norm)
show_rot(R.from_matrix([
[ 0.000, -0.643, -0.766],
[ 0.000, -0.766, 0.643],
[-1.000, 0.000, 0.000],]))
Matrix:
array([[-2.77555756e-17, -6.42962682e-01, -7.65897506e-01],
[ 0.00000000e+00, -7.65897506e-01, 6.42962682e-01],
[-1.00000000e+00, 0.00000000e+00, -2.77555756e-17]])
Blender "Quaternion":
array([ 0.2419207 , -0.66443538, 0.2419207 , 0.66443538])
Blender "XYZ Euler":
/opt/conda/lib/python3.12/site-packages/IPython/core/interactiveshell.py:3577: UserWarning: Gimbal lock detected. Setting third angle to zero since it is not possible to uniquely determine all angles.
exec(code_obj, self.user_global_ns, self.user_ns)
array([-139.98690433, 90. , 0. ])
Blender "Axis Angle":
np.float64(152.00014158445592)
array([-0.68477595, 0.24932669, 0.68477595])
show_rot(R.from_matrix([
[ 0.000, 0.000, 1.000],
[-1.000, 0.000, 0.000],
[ 0.000, -1.000, 0.000],]))
Matrix:
array([[ 0., 0., 1.],
[-1., 0., 0.],
[ 0., -1., 0.]])
Blender "Quaternion":
array([ 0.5, -0.5, 0.5, -0.5])
Blender "XYZ Euler":
array([-90., 0., -90.])
Blender "Axis Angle":
np.float64(119.99999999999999)
array([-0.57735027, 0.57735027, -0.57735027])
See also Rotation Modes - Blender 4.5 LTS Manual. Many Blender tutorials try to explain Gimbal lock, but the best references still seem to be Euler (gimbal lock) Explained - YouTube and Gimbal lock - Wikipedia.
In Eigen, quaternion-vector multiplication is just multiplication. In Eigen the coeffs command produces XYZW, but internally the data is XYZW. If you install the Eigen pretty printers, it’s explicit:
$1 = Eigen::Quaternion<double> (data ptr: 0x7fffffffd7d0) = {[x] = 0, [y] = 0.7071067811865841, [z] = 0, [w] = 0.70710678118651094}