# How to precisely rotate object to align with 3D cursor via Python script?

I would like to rotate my object, which is a simple rod, so it PRECISELY align with the 3D cursor. Here are some images showing what I mean:

I wish it to be precise so I asked for the python script, but showing me how to calculate this is also very helpful.

Any help appreciated.

You can use the Vector.angle function to find the angle between an arbitrary axis vector (like the Z axis "up" vector), and the 3D cursor. This will provide you the angle you need to rotate your object to align it with the cursor in that specific axis.

import bpy
from mathutils import Vector

curloc  = bpy.context.scene.cursor_location # Cursor location
up      = Vector((0,0,1)) # Positive Z axis
right   = Vector((1,0,0)) # Positive X axis
forward = Vector((0,1,0)) # Positive Y axis

o = bpy.context.object    # Active object

# Calculate angle between up and cursor vectors and set as Y rotation
o.rotation_euler.y = up.angle( curloc )


Notice that in the example above I'm aligning the object with the cursor on the Y axis specifically. You can change this by replacing the axis letter on o.rotation_euler, to align with a different axis.

• This looks a bit dodgy.. doubt this works for cursor locations in the -x quadrants or when there is a lot of "depth" on the 3d cursor.? – batFINGER Feb 5 '17 at 17:23
• You're right, it doesn't work properly with negative axis values. Could probably get around this by inverting the angle in these cases, but a more general solution is likely better. – TLousky Feb 6 '17 at 8:53

Do you want the 3d cursor to lie exactly on the z axis of your object, in which case can use methods outlined in this answer Align Object to Vector using python

import bpy
from mathutils import Matrix, Vector
from bpy import context

obj = context.object
scene = context.scene
loc, rot, scale = obj.matrix_world.decompose()
vec = scene.cursor_location - loc

# object axis to align with vector vec
z = Vector((0.0, 0.0, 1.0))

q = z.rotation_difference(vec)
obj.matrix_world = Matrix.Translation(loc) * q.to_matrix().to_4x4()
obj.scale = scale


If you want to rotate using the view ( equiv of bpy.ops.object.rotate(angle, axis, GLOBAL) ) give a hoy and will edit together.

Origin of the mesh and 3d cursor coordinates

First you have to know the x,y,z coordinates of the origin of the mesh and of the 3d cursor.

The coordinates of the 3d cursor you find:

THe coordinates of the origin of the mesh you find:

1. First shiftS, cursor to selected:

1. Read the coordinates in the same way as for the 3d cursor.

Mesh rotation

Next, onsider this schematic:

Angle theta can be calculated with arctan(dy/dx), where

• dy = abs(y_3dcursor - y_originmesh)
• dx = abs(x_3dcursor - x_originmesh)

1. Now add a plane (with the 3d cursor located on the origin of the mesh and re-enter the coordinates of the 3d cursor's original location
2. Change transform-orientation to normal:

1. Turn the plan around the z-axis theta degrees with R,Z and enter theta (correct negative or positive sign if necessary) such that either the red x-axis or green y-axis points to the 3d cursor:

1. In the right side toolbar of the 3d view, add new custom transform orientation (highlighted):

1. Select the new transfomation-orientation:

1. Select the mesh

1. Angle phi can be calculated with arctan(dz/r), where

• dz = abs(z_3dcursor - z_originmesh)
• r = sqrt(dx^2+dy^2)
2. With the mesh selected, then rotate the mesh around the axis that does not point to the 3d cursor which is the y-axis in this example, press R, twice Y and enter '90-phi':

1. Which results in the mesh rotated to the 3d cursor:

• I explained the mathematical way of calculation, but maybe this helps you with writing your script – Faceb Faceb Nov 30 '16 at 11:55