# Rotation around the cursor with low-level python (no bpy.ops)

In order to optimize my script, I would need some help to perform a rotation around the cursor
(see Rotate object around cursor with Python)

With low-level python, that means, without bpy.ops.* operations.

I have to admit that I didn't find a good overview on how to make rotation with python without bpy.ops. Do I have to perform matrix operations for a simple rotation around an axis Z located at the cursor position?

• I think you are better of using the bpy.ops. The functions in the module call on compiled C commands. This is a lot faster than doing it with python. Also optimizing a script by not using the built-ins blender provides is rather silly. This is just my opinion though – Vader Mar 7 '14 at 13:18
• The low level python api will call c-functions as well. See this post and this post for reasons to not use operators. – pink vertex Mar 7 '14 at 15:25

## Rotate a vector

import bpy
from math import pi
from mathutils import Vector, Euler, Matrix, Quaternion

v = Vector((1.0, 1.0, 1.0))
#point which will be rotated around the cursor

cursor_loc = bpy.context.scene.cursor_location

rot_mat = Matrix.Rotation(pi / 2.0, 3, 'Z')
v_new = rot_mat * (v - cursor_loc) + cursor_loc


There are further options available (see api docs):

You can construct a matrix, this is most efficient if you want to apply the same transformation on many points.

mat = (Matrix.Translation(cursor_loc) *
Matrix.Rotation(pi / 2.0, 4, 'Z') *
Matrix.Translation(-cursor_loc))
v_new = mat * v


You can use quaternions:

# using (axis, angle) constructor
q = Quaternion((0.0, 0.0, 1.0), pi / 2.0)
v_new = q * (v - cursor_loc) + cursor_loc


or eulers:

eu = Euler((0.0, 0.0, pi / 2.0), 'XYZ')
v_new = v - cursor_loc
v_new.rotate(eu)  # works for quat's and matrix types too
v_new += cursor_loc


## Rotate an object

mat = (Matrix.Translation(cursor_loc) *
Matrix.Rotation(pi / 2.0, 4, 'Z') *
Matrix.Translation(-cursor_loc))

obj.matrix_world = mat * obj.matrix_world


Euler and Quaternion both offer a method to convert them to a matrix:

q  = Quaternion()
eu = Euler()

mat =  q.to_matrix().to_4x4()
mat = eu.to_matrix().to_4x4()

• You can also do from math import radians and specify the rotation in degrees like radians(90) (equal to pi/2) – CodeManX Mar 7 '14 at 18:47
• Thanks pink vertex for the answer. I have difficulties to adapt your proposal for a single point (the vector v) to a whole object obj; could you adapt your script to make it run for an object obj that is a plan or a cube? Thanks. – Salvatore Mar 7 '14 at 23:26
• Added a section. – pink vertex Mar 8 '14 at 1:46
• great, it helped me a lot! I used the matrix_basis and not matrix_world but your answer provided me the information I needed to move ahead. Thanks! – Salvatore Mar 8 '14 at 23:51