'is it legal to take acos of 1.0f or -1.0f?
I have a problem with my code where agents moving around suddenly disappear. This seems to be because their positions suddenly become 1.#INF000 in the x and y axis. I did a little research and someone said this can occur with acos if a value is over or under 1 and -1 respectively, but went on to say it could happen if the values were close too. I added an if statement to check to see if I'm ever taking acos of 1 or -1 and it does evaluate to 1 a few frame cycles before they disappear, however I don't really understand the problem to be able to fix it. Can anyone shed any light on this matter?
D3DXVECTOR3 D3DXVECTOR3Helper::RotToTarget2DPlane(D3DXVECTOR3 position, D3DXVECTOR3 target)//XY PLANE
{
//Create std::vector to target
D3DXVECTOR3 vectorToTarget = target - position;
D3DXVec3Normalize(&vectorToTarget, &vectorToTarget);
//creates a displacement std::vector of relative 0, 0, 0
D3DXVECTOR3 neutralDirectionalVector = D3DXVECTOR3(1, 0, 0);//set this to whatever direction your models are loaded facing
//Create the angle between them
if(D3DXVec3Dot(&vectorToTarget, &neutralDirectionalVector) >= 1.0f ||D3DXVec3Dot(&vectorToTarget, &neutralDirectionalVector) <= -1.0f)
{
float i = D3DXVec3Dot(&vectorToTarget, &neutralDirectionalVector);
float j = 0; //ADDED THIS IF STATEMENT
}
float angle = acos(D3DXVec3Dot(&vectorToTarget, &neutralDirectionalVector));
if (target.y > position.y)
{
return D3DXVECTOR3(0, 0, angle);
}
else
{
return D3DXVECTOR3(0, 0, -angle);
}
}//end VecRotateToTarget2DPlane()
Solution 1:[1]
man page for acos tells this :
On success, these functions return the arc cosine of x in radians; the return value is in the range [0, pi].
If x is a NaN, a NaN is returned.
If x is +1, +0 is returned.
If x is positive infinity or negative infinity, a domain error occurs, and a NaN is returned.
If x is outside the range [-1, 1], a domain error occurs, and a NaN is returned.
This means that for a value outside of the [-1,+1] range, the value is not a number. That also corresponds to how the acos is defined.
Solution 2:[2]
As mentioned above (by @TonyK) , acos is not defined outside the range [-1,+1].
First, you should check why the issue exists, aka: Why is my argument out of range? Maybe there is some issue with the calculation of your argument.
If you worked that out, you can use the SafeAcos proposed by TonyK.
As we do know that acos(-1.0) = ? and acos(1.0) = 0, I suggest a little modification (for performance reasons):
double SafeAcos (double x)
{
if (x <= -1.0)
return MATH_PI;
else if(x >= 1.0)
return 0;
else
return acos (x) ;
}
Where MATH_PI = 3.14...
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | BЈовић |
| Solution 2 |
