i've been asked to recreate the to_track_quat function of mathutils to create a quaternion that looks from point a to point b, but so far i've been un successful.

I'm using in blender two objects, being their positions:

object.location = mathutils.Vector((0,0,3))

target.location = mathutils.Vector((2,4,4))

angle = look_at(object, target)

Here is my first function:

def look_at(u, v):
    dot = u.dot(v)
    cross = u.cross(v)
    q = mathutils.Quaternion()
    q.x = cross.x
    q.y = cross.y
    q.z = cross.z
    q.w = math.sqrt(u.length_squared*v.length_squared) + dot
    return q

Returns (w=0.9129, x=-0.3651, y=0.1826, z=0.0000)

The result is something like this:

enter image description here

I believe i'm missing an operation, but i'm not certainly sure what. Can someone guide me a bit on how to do it properly?

Another attempt that has been suggested:

def look_at(u, v):
    w = (v - u)/math.sqrt((v.x - u.x)**2 + (v.y - u.y)**2 + (v.z - u.z)**2)
    up = mathutils.Vector((0,-1,0))

    q = mathutils.Quaternion()
    cross1 = w.cross(up)
    dot1 = w.dot(up) 
    q.x = cross1.x
    q.y = cross1.y
    q.z = cross1.z
    q.w = math.sqrt(w.length_squared*up.length_squared) + dot1
    return q
  • $\begingroup$ In maths, a vector is not a point, even though we use the same data structure to store both. Normalising points (u and v) makes no sense. $\endgroup$
    – dr. Sybren
    Dec 8, 2016 at 0:47
  • $\begingroup$ I'm kind of aware since when i did put it in it made no difference, but i comment it in an out just in case to get some hope when i try new stuff. $\endgroup$ Dec 8, 2016 at 2:25
  • $\begingroup$ You have to compute w = (v - u)/|v - u|, and then compute the angle between the forward vector of the object and w to compute the correct rotation. $\endgroup$
    – dr. Sybren
    Dec 8, 2016 at 2:44
  • $\begingroup$ With that do you mean to subtract the two vectors and divide it by the module of the subtraction of the vectors? $\endgroup$ Dec 8, 2016 at 4:00
  • 2
    $\begingroup$ That's the mathematical notation of the normalised vector from u to v. $\endgroup$
    – dr. Sybren
    Dec 8, 2016 at 4:01

1 Answer 1


Based on this tutorial I wrote this function

def look_at(camera_position, target_position):
    """Returns model-view matrix from camera position to target.

    # Arguments
        camera_position: Numpy-array of length 3. Camera position.
        target_position: Numpy-array of length 3. Target position.
    camera_direction = camera_position - target_position
    camera_direction = camera_direction / np.linalg.norm(camera_direction)
    camera_right = np.cross(np.array([0.0, 0.0, 1.0]), camera_direction)
    camera_right = camera_right / np.linalg.norm(camera_right)
    camera_up = np.cross(camera_direction, camera_right)
    camera_up = camera_up / np.linalg.norm(camera_up)
    rotation_transform = np.zeros((4, 4))
    rotation_transform[0, :3] = camera_right
    rotation_transform[1, :3] = camera_up
    rotation_transform[2, :3] = camera_direction
    rotation_transform[-1, -1] = 1
    translation_transform = np.eye(4)
    translation_transform[:3, -1] = - camera_position
    look_at_transform = np.matmul(rotation_transform, translation_transform)
    return look_at_transform

You must log in to answer this question.

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