# Calculating join angle of an armature

For a school project I need to calculate joint angle of an armature. I found some code that works with 2 bones, but I need to calculate the angle of every 2 adjacent bones (knees, elbows, back, etc). I'm not getting it to work for multiple bones. In a perfect situation I need a text output in the 3d viewer that shows a list of the angles.

#stock code
import bpy
import math  # we need this to get the anglein degrees
import numpy  # we need this for the Vector Math
cob = bpy.data.objects.get('Armature')

# remember, we are working on the Pose Bones in this example!
bones = cob.pose.bones

# get the bones
bone1 = bones['FirstBone']
bone2 = bones['LastBone']

# get the bone locations as Vectors in World Space
pointB = bone1.tail
pointC = bone2.tail

# find the two Vectors
# you retrieve the Vector by subtracting the intended Vector Root coordinate from the Tip coordinate
vecA = pointA - pointB
vecB = pointC - pointB

print(vecA, vecB)

# calculate the angle, formula taken from https://stackoverflow.com/questions/39497496/angle-between-two-vectors-3d-python
angle=numpy.arccos(numpy.dot(vecA,vecB)/(numpy.linalg.norm(vecA)*numpy.linalg.norm(vecB)))

# remember the angle is in RADIANS!
print(math.degrees(angle))

# remixed code
import bpy
import math  # we need this to get the anglein degrees
import numpy  # we need this for the Vector Math
cob = bpy.data.objects.get('Mannequin')

# remember, we are working on the Pose Bones in this example!
bones = cob.pose.bones

# get the bones
bone1 = bones['RightUpLeg']
bone2 = bones['RightLowLeg']
bone3 = bones['RightUpArm']
bone4 = bones['RightLowArm']

# get the bone locations as Vectors in World Space
pointB = bone1.tail
pointC = bone2.tail
pointE = bone3.tail
pointF = bone4.tail

# find the two Vectors
# you retrieve the Vector by subtracting the intended Vector Root coordinate from the Tip coordinate
vecA = pointA - pointB
vecB = pointC - pointB
vecD = pointD - pointE
vecE = pointF - pointE

print(vecA, vecB)
print(vecD, vecE)

# calculate the angle, formula taken from https://stackoverflow.com/questions/39497496/angle-between-two-vectors-3d-python
angle1=numpy.arccos(numpy.dot(vecA,vecB)/(numpy.linalg.norm(vecA)*numpy.linalg.norm(vecB)))
angle2=numpy.arccos(numpy.dot(vecD,vecE)/(numpy.linalg.norm(vecD)*numpy.linalg.norm(vecE)))

# remember the angle is in RADIANS!
print(math.degrees(angle1))
print(math.degrees(angle2))

# let's for the show assign the angle to a Text Object for display in the Viewport
bpy.data.objects.get('Output1').data.body = str(math.degrees(angle1))
bpy.data.objects.get('Output2').data.body = str(math.degrees(angle2))


Right now I got the code working for multiple joints but I can figure out how to loop the code so it runs on every frame.

• What's wrong with the remixed code? Can you provide an example Mannequin? I think you need a list of bone pairs for which you want to calculate the angles (or loop over the whole armature) and then do the calculations. Where are you stuck? Dec 14, 2022 at 13:57
• Right now I got the code working for multiple joints but I can figure out how to loop the code so it runs on every frame. Dec 15, 2022 at 9:46
• This is a very important detail that should be added to your question. To do the calculation for every frame have a look at the so-called Application Handlers Dec 15, 2022 at 13:32