# Get the signed angle between 2 two Vector3

Hi everybody,

currently i’m working on an IK-Solver based on the FABRIK Algorithm (described in [here][1]).

As for the rotation-limits i need to compare angles between Vectors - for the case where the target is not reachable everything is working:

``````    void axis_limit()
{
for (int i = 0; i < (bones.Length - 1); i++)
{
axis_lambda = distances <em>/ Vector3.Distance(axis_target.position, bones*.position);*</em>
``````

axis_newVec = ((1 - axis_lambda) * bones.position + axis_lambda * axis_target.position);

if (!useRotationLimits )
{
bones[i + 1].position = axis_newVec;
continue;
}

if (bones*.GetComponent())*
{
rotationLimitAxis rotationScript = bones*.GetComponent();*

// returns Vector3.up, right or forward depending on the rotations limit axis
cur_direction = getDirectionFromAxis(bones*, rotationScript.axisX, rotationScript.axisY, rotationScript.axisZ);*

if (SignedVectorAngle(axis_newVec.normalized, rotationScript.angleVec.normalized, cur_direction, bones*.position) <= 0)
_{
bones[i + 1].position = rotationScript.angleVec;
continue;
}_

if (SignedVectorAngle(axis_newVec.normalized, rotationScript.limitVec.normalized, cur_direction, bones.position) >= 0)
_{
bones[i + 1].position = rotationScript.limitVec;
continue;
}
}
bones[i + 1].position = axis_newVec;
}
}*

And the SignedVectorAngle function:_

//From Math3D - http://wiki.unity3d.com/index.php/3d_Math_functions
public static float SignedVectorAngle(Vector3 referenceVector, Vector3 otherVector, Vector3 normal)
{
Vector3 perpVector;
float angle;

//Use the geometry object normal and one of the input vectors to calculate the perpendicular vector
perpVector = Vector3.Cross(normal, referenceVector);

//Now calculate the dot product between the perpendicular vector (perpVector) and the other input vector
angle = Vector3.Angle(referenceVector, otherVector);
angle *= Mathf.Sign(Vector3.Dot(perpVector, otherVector));

return angle;
}

The backwards-reaching function is basicaly the same as the axis_limit with only those differences:
axis_lambda = distances / Vector3.Distance(bones*.position, bones[i + 1].position);*
axis_newVec = ((1 - axis_lambda) * bones_.position + lambda * bones[i+1].position);
If i try to get the angle in the forward and backward reaching loop SignedVectorAngle won’t return the correct angle between both Vectors.
As far as i understand it and according to a few other posts about Vector angles, the SignedVectorAngle function seems to be the right approach to retrive the angle i need.
Am i totally wrong with my approach or just to blind to find the solution?
Does someone solved sth. like this and can give me a hint how to find the right angle?
Here are some pictures to maybe visualize my problem:
black = angle limits
green = angle limits normalized
red = target vector
The axis_limit limited to a certain angle (magnitude is wrong - but doesn’t matter right now)
[32262-axis_limit_02_solved.jpg
|32262]
forward-backward reaching
[32263-axis_fwd_bwd_02.jpg*|32263]
there seems to be a problem with the normalized angle-vectors or something but i can’t find the solution.
I hope someone can punch me in the right direction to understand what’s going on here and how to solve this.
Thank you for your time
Martin
[1]: http://andreasaristidou.com/publications/FABRIK.pdf*_
*
*

A bit of sleep and distance by doing other stuff made me finally find the soultion.

The problem was created by the angle-limitations Vector e.g. “rotationScript.angleVec”.
This Vector is constructed by the transforms position owning the limitiation-script (blue cone).

So if i’m right - to calculate the correct angle between two Vectors they need to have the same origin. This just simply means i have to substract the transforms position from the rotationScript.angleVec.

Right now this is working for me and i hope i’m right and not writing nonsense here ; -)

Here’s the complete code for the backwards reaching (forward reaching is working with negated limit vectors)

``````    void axis_backward()
{
for (int i = 0; i < bones.Length - 1; i++)
{
axis_lambda = distances _/ Vector3.Distance(bones*.position, bones[i + 1].position);*_
``````

axis_newVec = (1 - axis_lambda) * bones.position + axis_lambda * bones[i + 1].position;

if (!useRotationLimits)
{
bones[i + 1].position = axis_newVec;
continue;
}

if (bones*.GetComponent())*
{
rotationLimitAxis rotationScript = bones*.GetComponent();*

cur_direction = getDirectionFromAxis(bones*, rotationScript.axisX, rotationScript.axisY, rotationScript.axisZ);*

Vector3 normedAxis_newVec = axis_newVec - bones*.position;
_Vector3 normedAngleVec = rotationScript.angleVec - bones.position;_
_Vector3 normedLimitVec = rotationScript.limitVec - bones.position;*_

if (SignedVectorAngle(normedAxis_newVec.normalized, normedAngleVec.normalized, cur_direction) < 0)
{
bones[i + 1].position = bones.position + (rotationScript.angleVec - bones_.position).normalized * distances*;
continue;
}
if (SignedVectorAngle(normedAxis_newVec.normalized, normedLimitVec.normalized, cur_direction) > 0)
{
bones[i + 1].position = bones.position + (rotationScript.limitVec - bones.position).normalized * distances;
continue;
}
}
bones[i + 1].position = axis_newVec;
}
}*_