# Python move object on local axis

Read through a lot of questions but I didn't find a simple answer.

How do I move an object on it's local axis using a vector? I don't want to use bpy.ops.transform.translate, because it's slow.

Given an object that is rotated and an example vector (1,2,3). How can I do a translation on the local axis, so the object is moved 1 on it's local x-axis, 2 on the local y-axis, 3 on the local z-axis. Just like in the viewport, when you move an object pressing "g" and then pressing the x-axis key (or y / z) twice.

EDIT: So from a C++ post I understand the math behind it, still I'm unable to reproduce it in Blender. For the local translation T you have to do the translation first, then multiply it with the rotation matrix R. So (pseudocode)

myobject.location = T(1,2,3) * R


Problems: 1.) How do I get R of the object that is already rotated. 2.) Can I just multiply a vector with that matrix? 3.) What about the location that the object had before? Just add it?

This seems to work the inverse of the world matrix is used to align the translation vector to the local axis:

import bpy
import mathutils

cube = bpy.data.objects["Cube"]
# one blender unit in x-direction
vec = mathutils.Vector((1.0, 0.0, 0.0))
inv = cube.matrix_world.copy()
inv.invert()
# vec aligned to local axis
vec_rot = vec * inv
cube.location = cube.location + vec_rot

• Thanks you Sir! For completeness, this works also in a condensed form: cube.location += vec * inv. – bortran Mar 9 '15 at 11:02
• This fails if the object is scaled. Using cube.rotation_euler.to_matrix() as invmatrix seems to be better – florian h Oct 3 '18 at 16:34

In order to make it faster you could also assign the values directly to the location property:

import bpy
import mathutils

# get the object
obj = bpy.data.objects["Object"]

# store the current location
loc = obj.location

(x,y,z) = (1.0,2.0,3.0)

obj.location = loc + mathutils.Vector((x,y,z))


Assigning and adding the values in one line:

bpy.data.objects["Object"].location = bpy.data.objects['Object'].location + Vector((x,y,z))


bpy.data.objects["Object"].location.x += 1.0
bpy.data.objects["Object"].location.y += 2.0
bpy.data.objects["Object"].location.z += 3.0

• But that's a global translation. – bortran Mar 9 '15 at 9:05
• It's not a global translation. An object with ob.location = (0, 0, 0) can be placed anywhere in the scene using constraints or parenting. There is only one global origin. – batFINGER Nov 15 at 11:41

So I made this now, but I don't know if it's correct.

import bpy
import mathutils
from mathutils import Vector, Matrix

myobject = bpy.context.active_object
rotMat = myobject.rotation_euler.to_matrix()
pos = myobject.location
newPos = Vector([1, 2, 3])
myobject.location = newPos * rotMat + pos


Try this blender 2.8 script to displace all cylinders in a scene, with respect to their axis in the -ve Z direction:

        if obj.name.startswith('Cylinder'):

# print(obj.location)

# one blender unit in x-direction
distz = mathutils.Vector((0.0, 0.0, -0.001))
rotationMAT = obj.rotation_euler.to_matrix()
rotationMAT.invert()
# project the vector to the world using the rotation matrix
zVector = distz @ rotationMAT
obj.location = obj.location + zVector