I have my custom axis XYZ vectors (Yellow color in the screenshot below). They are normalized. I need to rotate an object according to these vectors. Is it possible to do this with the python API?

custom axis

  • 1
    $\begingroup$ If these are direction vectors, you can find the rotation_difference between them via the Vector function of the same name: blender.org/api/blender_python_api_current/… $\endgroup$ – TLousky Dec 20 '16 at 10:56
  • $\begingroup$ I tried it but had no luck. If you could make an example? $\endgroup$ – mifth Dec 20 '16 at 12:42

If you want to change the basis you need to set up a transformation matrix. For standard Cartesian coordinates the x (1, 0, 0) , y (0, 1, 0) and z (0, 0, 1) axis vectors make up the columns of the 3 x 3 Indentity matrix.

To make up your basis matrix use the three orthogonal vectors that make up your axis vectors to build a transform matrix.

m = [vx, vy, vz]

which for all extents and purposes is a 3 x 3 rotation matrix.

To rotate your monkey simply multiply its matrix_world by this matrix.

To have translation in your change of coordinates would need a 4 x 4 matrix.

Is all this starting to sound familiar?, it should do as it's pretty much making the cube in image below a child of the empty, and using the empties local space as our new coordinate space.

enter image description here

Using the empty as an example to show the 3 orthogonal vectors that make up its local space.

>>> for v in C.object.matrix_world.to_3x3():
...     print(v)
<Vector (0.8496, -0.4064, -0.3362)>
<Vector (0.1958, 0.8349, -0.5144)>
<Vector (0.4897, 0.3712, 0.7889)>
# orthogonal ?
>>> degrees(Vector((0.8496, -0.4064, -0.3362)).angle(Vector((0.1958, 0.8349, -0.5144))))
90.00059673093595 # close enough

enter image description here

You can use the rotation_difference method of the mathutils.Vector object to calculate the 3 axis angle difference between two vectors.

This function is used as follows:

# Calculate the angle between two vectors. Returns a Quaternion object.
vector1.rotation_difference( vector2 )

Here's some sample code that uses this function:

import bpy
from mathutils import Vector
from math import degrees

v0 = Vector(( 0,0,0 ))
v1 = Vector((-0.792312741279602, 0.6056182980537415, -0.0739390179514885))

rot = v1.rotation_difference( v0 ).to_euler()
print( [ degrees( a ) for a in rot ] )

Output is (angle rotation in each axis):

[ -77.31130736634618, -146.788879528308, -40.89379056097038 ]

Now if you want to rotate an object according to this rotation difference, all you need to do is to assign the value of rot to the object's rotation_euler property:

obj.rotation_euler = rot

Note: the image can be a bit misleading since the cube and corresponding empty's location is not the value of V1 at all. V1 represents the rotation / direction values only, with respect to the zero vector (V0).

  • $\begingroup$ What would happen if you exchange v0 and v1 above? $\endgroup$ – batFINGER Dec 20 '16 at 15:56
  • $\begingroup$ @batFINGER that would give you the inverse transformation form v1 to v0 $\endgroup$ – Ajay Feb 12 at 0:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.