A question came up in IRC where a fellow wanted to calculate a position/orientation matrix based on 3 points.

Let's say that v1 should be the origin of the local coordinate space. The line from v1 to v2 should be the X axis, and v1,v2,v3 should all be in the XY plane. How do we use blender python to calculate a matrix usable as an object's transform matrix?


The following python code from orientation-matrix.py illustrates how to convert 3 coordinates into a transformation matrix:

import bpy
from mathutils import *

def make_matrix(v1, v2, v3):
    a = v2-v1
    b = v3-v1

    c = a.cross(b)
    if c.magnitude>0:
        c = c.normalized()
        raise BaseException("A B C are colinear")

    b2 = c.cross(a).normalized()
    a2 = a.normalized()
    m = Matrix([a2, b2, c]).transposed()
    s = a.magnitude
    m = Matrix.Translation(v1) * Matrix.Scale(s,4) * m.to_4x4()

    return m


obj = bpy.context.active_object
obj.matrix_world = make_matrix(Vector([1,1,1]), Vector([1,2.5,1]), Vector([0.5,1,1.5]) )

The Matrix.Scale is just thrown in for completeness and you can leave it out if you are content with scale=1. The order of the matrices in that multiplication is pretty important (I did not get it perfect on the first try).

  • $\begingroup$ Based on a question in IRC: if you are unhappy with the polarity of the Y and Z axes, you could use c=b.cross(a) instead. $\endgroup$ – Mutant Bob Dec 31 '15 at 19:08

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.