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 '16 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$ – Seyren Windsor Dec 8 '16 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 '16 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$ – Seyren Windsor Dec 8 '16 at 4:00
  • 2
    $\begingroup$ That's the mathematical notation of the normalised vector from u to v. $\endgroup$ – dr. Sybren Dec 8 '16 at 4:01

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

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.