# matrix_local from head, tail and roll

What is the algorithm for calculating Bone.matrix_local from Editbone.head, tail and roll?

The corresponding world matrix is enough; to get from there I just need to multiply with the parent’s inverse matrix_local. I make the ansatz

``````M = X(a) Z(c) Y(b)
M = Z(c) X(a) Y(b)
``````

where X, Y, Z are Euler matrices and a,b,c are Euler angles. I think that b is the roll angle. Moreover, let u be a unit vector pointing from head to tail. It should be an easy task to get a and c by solving

``````u = M e_y,
``````

(e_y = unit vector in y direction) but I don’t manage to get it right.

You might want to look here: http://stackoverflow.com/questions/7132018/how-to-convert-global-to-local-coordinates-in-blender-2-5

Thank you, but this was not really what I asked. Anyway, I figured out the answer myself: in the axis-angle representation, the rotation axis is perpendicular to both the world bone axis and the y-axis (= local bone axis), and the angle is given by cos(phi) = dot product. Here is a code excerpt, using transformations.py.

``````    def matrixLocalFromBone(self):

length = sqrt(u.dot(u))
if length &lt; 1e-3:
print("Zero-length bone %s. Removed" % self.name)
self.matrix_local = tm.identity(4)
return
u = u.div(length)

ey = Vector((0,1,0))
yu = ey.dot(u)
if abs(yu) &gt; 0.999:
axis = ey
if yu &gt; 0:
angle = 0
else:
angle = pi
else:
axis = ey.cross(u)
length = sqrt(axis.dot(axis))
axis = axis.div(length)
angle = acos(yu)

mat = tm.rotation_matrix(angle,axis)
matrix = Matrix(mat)
if self.parent:
pmat = self.parent.matrix_local.inverted()
self.matrix_local = matrix.mult(pmat)
else:
self.matrix_local = matrix