Search code examples
javascriptalgorithmmathinverse-kinematics

2D Inverse kinematics angle constraint


I am writing a 2D game with inverse kinematics. I am using this simple algorithm:

let angleToParent = angleBetweenPoints(parent, child)
child.x = parent.x + distance*Math.cos(angleToParent)
child.y = parent.y + distance*Math.sin(angleToParent)
child.rotation = angleToParent

How to implement angle constraint for childs?

This code works wrong when rotation of parent cross 180 degrees:

let implementBound = (lowerBound, upperBound, input) => { 
    return Math.min(Math.max(lowerBound, input), upperBound)
}

let constraint = (Math.PI/180)*15 
let left = parent.rotation - constraint 
let right = parent.rotation + constraint 
angleToParent = implementBound(left, right, angleToParent)

Solution

  • You can do something like the following:

    if (input < lowerBound || input > upperBound)
    {
        //check which limit is closer
        while (Math.abs(upperBound - input ) > Math.PI)
            input += 2 * Math.PI * (input < upperBound ? 1.0f : -1.0f);
        double distance_to_upper = Math.abs(upperBound - input);
    
        while (Math.abs(lowerBound - input) > Math.PI)
            input += 2 * Math.PI * (input < lowerBound ? 1.0f : -1.0f);
        double distance_to_lower = Math.abs(lowerBound - input);
    
        if (distance_to_lower < distance_to_upper)
            return lowerBound;
        else
            return upperBound;
    }
    else
        return input;