0
$\begingroup$

As far as I understand, Euler angles and quaternions are two approaches for rotation. So I suppose that if the directions of two objects are set by the same quaternion then their Euler angles are automatically the same:

def foo(a, b):
  a.rotation_quaternion = b.rotation_quaternion
  print(f"a: {a.rotation_euler}\nb: {b.rotation_euler}")

But I received:

a: <Euler (x=0.0000, y=0.0000, z=0.0000), order='XYZ'>
b: <Euler (x=1.1093, y=0.0000, z=0.8149), order='XYZ'>

Why are the Euler rotations of a and b different?

$\endgroup$
2
  • $\begingroup$ It is normal result, it is not update the Euler rotation value when you change the quaternion. $\endgroup$
    – X Y
    Commented Mar 29 at 11:28
  • $\begingroup$ Thank you. But if it's the case then how Blender deals with incoherent information about the direction of the object? $\endgroup$ Commented Mar 29 at 13:53

1 Answer 1

1
$\begingroup$

When you want to use quaternion to change the rotation, you need make sure the object rotation mode is QUATERNION.

import bpy

# set quaternion

cube = bpy.data.objects["Cube"]
print(cube.matrix_world)
cube.rotation_mode = "QUATERNION"
cube.rotation_quaternion = 1, 1, 1, 2
print(cube.matrix_world)

And you will see the matrix of the object not update immediately. If you want to access the correct matrix, you need run bpy.context.view_layer.update()

The same applies to other modes

import bpy

cube = bpy.data.objects["Cube"]
print(cube.matrix_world)
cube.rotation_mode = "AXIS_ANGLE"
cube.rotation_axis_angle = 1, 1, 1, 2
bpy.context.view_layer.update()
print(cube.matrix_world)

The attribute rotation_euler only works when the rotation mode is a specific value. For example, if there is a keyframe on rotation_euler[0], then the keyframe will not work after changing the rotation mode to QUATERNION.

There are several ways to obtain Euler rotations from quaternions, one way is

import bpy

# need rotation_mode == "QUATERNION"
q = bpy.context.object.rotation_quaternion
print(q.to_euler("XYZ"))

Get quaternion from matrix:

import bpy

loc, rot, sca = bpy.context.object.matrix_world.decompose()
print(rot)
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .