I am currently trying to make a robotic arm with inverse kinematics using the script below to calculate it. But there is an issue when you bring the arm into certain positions which I think is caused by the position from P1 to P2 being less than the distance to the midpoint.

I’ve scanned the devforum a bit but couldnt find a solution.

Oh, that’s very confusing for what it does. Just for my own understanding I simplified it a bit. This does the same thing with less CFrame math:

-- Returns the CFrame for the front/back end of `Segment` which is
-- closer to `point`
function FindEndpoint(Segment, point)
local halfLength = Segment.Size.Z / 2
local relative = Segment.CFrame:PointToObjectSpace(point)
if relative.Z > 0 then
return Segment.CFrame * Vector3.new(0, 0, halfLength)
else
return Segment.CFrame * Vector3.new(0, 0, -halfLength)
end
end

But that doesn’t matter anyway, because FindEndpoint is the problem.

You don’t want to decide which endpoint is closest to the joint. You already know which one it is.

In other words, your whole Solve function can just be:

Also, you didn’t ask, but you’ll have trouble if your IK rig is straight, and you move the target straight back.

You can fix this by checking if the arm is straight first, and jiggling the joint a bit if so (at the top of the Solve function):

-- quick check if things are colinear so we can jiggle it a bit
if math.abs(Segment1.CFrame.LookVector:Dot(Segment2.CFrame.LookVector)) > 0.999 then
joint = joint + Vector3.new(0, 0.001, 0)
end