Getting local rotation in python

I'm using blender to visualize data from an orientation sensor, and would like to display the current rotation, but about the local axis. I can get the local axis just fine, but what I'm interested in is the actual rotation quaternion associated with the local rotation (how much the object has rotated over each local axis). I don't want to actually rotate anything, just display what the current local rotation is.

Is there a proper way to do this with bpy or mathutils? Or will I have to come up with my own method of determining the local rotation?

• have you found a solution to calculate the local rotation? I am currently trying to simulate angular velocity for a rotating object in Blender... – shintobi Nov 26 '19 at 10:17

Blender's objects have three rotation values, rotation_euler, rotation_quaternion and rotation_axis_angle with the rotation_mode property defining which one is used.

If euler rotation is used and you want the quaternion rotation you can use to_quaternion() to convert it. Quaternion values also have to_axis_angle() and to_euler() if you need to convert the other way. The mathutils module contains some extras.

Note that euler values are stored as radians so you will want to use math.degrees() to get the degrees of each rotation. Both index and property access are available for euler and quaternion rotation values.

if 'Z' in bpy.data.objects['Cube'].rotation_mode:
r = bpy.data.objects['Cube'].rotation_euler
print(math.degrees(r[0])) # 0=X, 1=Y, 2=Z
print(math.degrees(r.x))

q = r.to_quaternion()
print(q[0]) # 0=W, 1=X, 2=Y, 3=Z

• That gives the global rotation, I am interested in the local rotation. I want how much the object has rotated around its local axis, not the global axis. – Matt May 10 '17 at 20:27
• There is no other "local" rotation. If you rotate an object 10 degrees on X then it's local YZ axes no longer align with the global axes. Using the objects local axis when performing a rotation is translated into global rotation values that are stored for the object. If you perform a rotation of the vertices in edit mode then you are using a rotational translation to move the vertices to a new location, which are relative to the objects origin. There is no internal rotation value used to define a vertices location. – sambler May 11 '17 at 5:39
• You've inadvertently answered my question, the answer being "Blender does not keep track of local rotation. I will need to calculate it myself" – Matt May 11 '17 at 22:03

I think this is very good question.I will answer them for those who will be looking for answers in the future.

• If you are using IMU or AHRS modeule it intrinsic rotation in ZYX (Yaw, Pitch, Roll). It mean that at first you rotate Z axis (local/global), then Y (local) and eventually X (local).
• The angles in the blender refer to extrinsic rotation. for example in XYZ convention at first you rotate Z axis (global), then Y (Global) and eventually X (Global).

To get real Yaw Pitch Roll you should use convention from intrinsic rotation to extrinsic rotation https://en.wikipedia.org/wiki/Euler_angles#Definition_by_extrinsic_rotations.

You can see that example rotation A) and B) gives the same result

1. intrinsic rotation,local axis (IMU Yaw Pitch Roll)

Local Z(90) ->Local Y(45)->Local X(30)

1. extrinsic_rotations, global axis Global X(30) ->Global Y(45) ->Global Z(90)

import numpy as np

matrix=bpy.data.objects['Test orientation'].matrix_world

e=np.degrees(np.array(matrix.to_euler('XYZ')[0:3]))
print('Yaw %.2f Pitch %.2f Roll %.2f'%(e[2],e[1],e[0]))


You should notice the e[2],e[1] reverse order.

• – batFINGER Nov 23 '19 at 12:03
bpy.objects['Cube'].rotation_euler


Euler((-1.8313435316085815, -0.2717221677303314, -1.0411337614059448), 'XYZ')

here s your pitch, yaw, roll, meaning your object is rotated by X(-1.83), then Y(-0.27), then Z(-1.04)