# Inverse Kinematics with more than 2 segments

I'm building a 2D inverse kinematics system and can't figure out how to find all the joint positions. I have the math to make a typical IK set up with a single bend (e.g. arm, leg), but I get stuck when adding another bend.

How do I find the position of all joints for an inverse kinematic chain that is longer than 2 segments?

Here's an example of the planar solution I'm looking for: https://youtu.be/3sqd_CZNq7s?t=6s

I'm building this in Adobe After Effects so using an existing IK solver isn't going to work.

Here's my visual setup for reference: What I'm aiming for is that when the blue box is moved (target) joints 2 and 3 bend appropriately to maintain their length. Joint 1 is static and doesn't move.

To make this work, I need x,y coordinates to be calculated in real time. No need to render anything on screen—just the position values for each joint.

Here's my javascript so far:

var angle1, angle2, angle3, theta1, theta2, theta3, targetSqrDist;

// joints
var joint1 = thisComp.layer("joint 1");
var joint2 = thisComp.layer("joint 2");
var joint3 = thisComp.layer("joint 3");
var joint4 = thisComp.layer("joint 4");

// segment lengths
var segment1Len = length(joint2.transform.position, joint1.transform.position);
var segment2Len = length(joint3.transform.position, joint2.transform.position);
var segment3Len = length(joint4.transform.position, joint3.transform.position);

// target position
var target = thisComp.layer("target");
var ix = target.transform.position - joint1.transform.position;
var iy = target.transform.position - joint1.transform.position;

// target square distance
targetSqrDist = ix * ix + iy * iy;

// Segment 1
angle1 = Math.max(-1, Math.min( 1,
(targetSqrDist + (segment1Len*segment1Len) - (segment2Len*segment2Len)) / (2 * segment1Len * Math.sqrt(targetSqrDist))
));

theta1 = Math.atan2(iy, ix) - Math.acos(angle1);

var s1X = joint1.transform.position + segment1Len * Math.cos(theta1);
var s1Y = joint1.transform.position + segment1Len * Math.sin(theta1);

// Segment 2
angle2 = Math.max(-1, Math.min( 1,
(targetSqrDist - (segment1Len*segment1Len) - (segment2Len*segment2Len)) / (2 * segment1Len * segment2Len)
));

theta2 = Math.acos(angle2);

var s2X = s1X + segment2Len * Math.cos(theta2 + theta1);
var s2Y = s1Y + segment2Len * Math.sin(theta2 + theta1);

// Segment 3
angle3 = Math.max(-1, Math.min( 1,
(targetSqrDist - (segment2Len*segment2Len) - (segment3Len*segment3Len)) / (2 * segment2Len * segment3Len)
));

theta3 = Math.acos(angle3);

var s3X = s2X + segment3Len * Math.cos(theta3 + theta2);
var s3Y = s2Y + segment3Len * Math.sin(theta3 + theta2);


This code would be applied to each joint with a unique position value assigned to it, depending on the joint's location.

• To be honest, I didn't read the code. Can you first clarify your question? – StinkySkunk Feb 28 '17 at 11:49
• Sorry, things got muddled while writing. How do I find the position of all joints for an inverse kinematic chain that is longer than 2 segments? – Greg Gunn Feb 28 '17 at 18:14
• I think you can perhaps find explicit formulas here courses.csail.mit.edu/6.141/spring2011/pub/lectures/… starting on slide 32. Tell me if it's not what you're looking for. – StinkySkunk Feb 28 '17 at 19:41
• It's close, but not exactly it. These formulas illustrate a typical 3 joint IK solve (e.g. arm, leg) with a single bend. I'm looking for the formula that factors in additional joints and bends in the IK solve (e.g. 4 joints with 2 bends). – Greg Gunn Mar 1 '17 at 2:18

What you have here is an underconstrained problem*. To solve this problem you do what you do to any other underconstrained system. This is also why you mostly only see the 2 joint version as it is not underconstrained in the planar solution, and in any case the preregistration is trivial.

Basically you have 2 options:

• Deal with the freedom

Adding more constraints to the system reduces the degrees of freedom. For example if you only permit one of the joints to rotate about its z axis and the another around its x axis then y then you have reduced the problem to the same 2 member problem. Another way to constrain it is to force the orientation of the last link. This also reduces it to the same case as 2 links. But there are other meaningful ways to reduce complexity that depend on your application. Image 1: Constraining one member reduces the problem to a 2 member problem. In the planar case that means 2 solutions (other in blue).

Dealing with the freedom just means that your answer is going to be a family of answers. Then you develop a way to choose the solution from that family. Letting the user adjust the parameter is equivalent to adding one more constraint. But there are other methods such as least squares, or energy methods that yield different results. Sky is the limit here. For example I have worked with robot controllers that decided the parameter based on what was the least amount of rotation on joints. The problem was that this wasn't entirely deterministic so over time the robot ended up doing things differently...

* This is more suited to Engineering.SE but since IK is a common graphics problem lets deal with it here.

• Do you mean underconstrained? – StinkySkunk Mar 1 '17 at 12:25
• @StinkySkunk oh yes – joojaa Mar 1 '17 at 12:46
• To be honest, I'm not sure which option I'm searching for. What I do know is that I'm after a planar solution that moves like this: youtu.be/3sqd_CZNq7s?t=6s It's short, but I'm looking at the part where the color chain is red-orange-yellow-blue. – Greg Gunn Mar 1 '17 at 18:12
• That does not seem very useful @GregGunn It does not even seem to solve any ik. Atleast we do not know if it is because we cant see the target. It looks more like a system that moves the links based on proxility which is more like hbrid fk/ik. the only reason we even suspect its ik is because the title says so... Titles lie. – joojaa Mar 1 '17 at 19:00
• @joojaa If that reference is my goal—regardless of it's IK or not—how would you suggest I build something that moves like that? – Greg Gunn Mar 1 '17 at 19:30