#include "box2d/math_functions.h"
#include <float.h>
_Static_assert( sizeof( int32_t ) == sizeof( int ), "Box2D expects int32_t and int to be the same" );
bool b2IsValidFloat( float a )
{
if ( isnan( a ) )
{
return false;
}
if ( isinf( a ) )
{
return false;
}
return true;
}
bool b2IsValidVec2( b2Vec2 v )
{
if ( isnan( v.x ) || isnan( v.y ) )
{
return false;
}
if ( isinf( v.x ) || isinf( v.y ) )
{
return false;
}
return true;
}
bool b2IsValidRotation( b2Rot q )
{
if ( isnan( q.s ) || isnan( q.c ) )
{
return false;
}
if ( isinf( q.s ) || isinf( q.c ) )
{
return false;
}
return b2IsNormalizedRot( q );
}
bool b2IsValidTransform(b2Transform t)
{
if (b2IsValidVec2(t.p) == false)
{
return false;
}
return b2IsValidRotation( t.q );
}
bool b2IsValidPlane( b2Plane a )
{
return b2IsValidVec2( a.normal ) && b2IsNormalized( a.normal ) && b2IsValidFloat( a.offset );
}
float b2Atan2( float y, float x )
{
if (x == 0.0f && y == 0.0f)
{
return 0.0f;
}
float ax = b2AbsFloat( x );
float ay = b2AbsFloat( y );
float mx = b2MaxFloat( ay, ax );
float mn = b2MinFloat( ay, ax );
float a = mn / mx;
float s = a * a;
float c = s * a;
float q = s * s;
float r = 0.024840285f * q + 0.18681418f;
float t = -0.094097948f * q - 0.33213072f;
r = r * s + t;
r = r * c + a;
if ( ay > ax )
{
r = 1.57079637f - r;
}
if ( x < 0 )
{
r = 3.14159274f - r;
}
if ( y < 0 )
{
r = -r;
}
return r;
}
b2CosSin b2ComputeCosSin( float radians )
{
float x = b2UnwindAngle( radians );
float pi2 = B2_PI * B2_PI;
float c;
if ( x < -0.5f * B2_PI )
{
float y = x + B2_PI;
float y2 = y * y;
c = -( pi2 - 4.0f * y2 ) / ( pi2 + y2 );
}
else if ( x > 0.5f * B2_PI )
{
float y = x - B2_PI;
float y2 = y * y;
c = -( pi2 - 4.0f * y2 ) / ( pi2 + y2 );
}
else
{
float y2 = x * x;
c = ( pi2 - 4.0f * y2 ) / ( pi2 + y2 );
}
float s;
if ( x < 0.0f )
{
float y = x + B2_PI;
s = -16.0f * y * ( B2_PI - y ) / ( 5.0f * pi2 - 4.0f * y * ( B2_PI - y ) );
}
else
{
s = 16.0f * x * ( B2_PI - x ) / ( 5.0f * pi2 - 4.0f * x * ( B2_PI - x ) );
}
float mag = sqrtf( s * s + c * c );
float invMag = mag > 0.0f ? 1.0f / mag : 0.0f;
b2CosSin cs = { c * invMag, s * invMag };
return cs;
}
b2Rot b2ComputeRotationBetweenUnitVectors(b2Vec2 v1, b2Vec2 v2)
{
B2_ASSERT( b2AbsFloat( 1.0f - b2Length( v1 ) ) < 100.0f * FLT_EPSILON );
B2_ASSERT( b2AbsFloat( 1.0f - b2Length( v2 ) ) < 100.0f * FLT_EPSILON );
b2Rot rot;
rot.c = b2Dot( v1, v2 );
rot.s = b2Cross( v1, v2 );
return b2NormalizeRot( rot );
}