2
$\begingroup$

Smart people in the past offered a solution to construct transformation matrix using 3 vertices:

How do I construct a transformation matrix from 3 vertices?

I tried to test it but I could not get it right. Please see attached code, screenshot, and blender file.

I would like to align Suzanne origin to K and align Suzanne's y axis to the normal of the plane defined by (k, i, j). I don't need (i, j) beyond defining the plane. My problem is my code doesn't do it. And I couldn't figure out why.

Thanks!

three random vertices

My goal: to align the monkey origin to "k"

# https://blender.stackexchange.com/questions/30808/how-do-i-construct-a-transformation-matrix-from-3-vertices

import bpy
from mathutils import *

# randomly selected 3 vertices
i = Vector((0.778421, 0.112746, 1.402834))
j = Vector((1.444566, 0.088229, 2.944015))
k = Vector((1.476759, 0.047526, 1.439882))

# to visualized the points
bpy.ops.mesh.primitive_uv_sphere_add(size=0.05, location=i)
bpy.ops.mesh.primitive_uv_sphere_add(size=0.05, location=j)
bpy.ops.mesh.primitive_uv_sphere_add(size=0.05, location=k)

a = i - k
b = j - k
c = a.cross(b).normalized() #y axis?
d = c.cross(a).normalized() #z axis?
e = c.cross(d).normalized() #x axis?

m = Matrix.Translation(k) * Matrix.Scale(1,4) * Matrix((e, c, d)).transposed().to_4x4()

obj = bpy.data.objects['Suzanne']
obj.matrix_world = m*obj.matrix_world

$\endgroup$
  • $\begingroup$ So if I understand correctly: K-> origin location, KJ -> rotation around x-axis, KI-> rotaion around y and z-axis ? $\endgroup$ – Bert VdB Nov 29 '17 at 10:39
  • 1
    $\begingroup$ Going by answer in link above, the three points make up a plane, the normal to the plane (ik.cross(jk)) is one axis, (both other axes lie on the plane) arbitrarily one of the vectors ik, or jk is chosen as another axis, and the third is their cross product. This will ensure the three axes are orthogonal. If the matrix, created from axes, is orthogonal its transpose is its inverse. (or use matrix.is_orthogonal to check) You have to decide which two local axes of suzanne will be the planes normal, and the other on the plane.. $\endgroup$ – batFINGER Nov 29 '17 at 12:21
  • $\begingroup$ I would like to align Suzanne origin to K and align Suzanne's y axis to the normal of the plane defined by (k, i, j). I don't need (i, j) beyond defining the plane. My problem is the code above doesn't do it. And I couldn't figure out why. $\endgroup$ – John Nov 30 '17 at 15:59
  • 1
    $\begingroup$ Only thing I would change is last line to obj.matrix_world = m otherwise you only get result you are after when suzanne's matrix world is identity. $\endgroup$ – batFINGER Dec 1 '17 at 22:56
0
$\begingroup$

As answered by batfinger in the comment. Just change the last line to

obj.matrix_wolrd = m

everything works well now. Thanks!

| improve this answer | |
$\endgroup$

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.