44B2_INLINE
int b2MinInt(
int a,
int b )
50B2_INLINE
int b2MaxInt(
int a,
int b )
56B2_INLINE
int b2AbsInt(
int a )
58 return a < 0 ? -a : a;
62B2_INLINE
int b2ClampInt(
int a,
int lower,
int upper )
64 return a < lower ? lower : ( a > upper ? upper : a );
68B2_INLINE
int b2CeilingInt(
int numerator,
int denominator )
70 B2_VALIDATE( denominator > 0 && numerator >= 0 );
71 return ( numerator + denominator - 1 ) / denominator;
75B2_INLINE
float b2MinFloat(
float a,
float b )
81B2_INLINE
float b2MaxFloat(
float a,
float b )
87B2_INLINE
float b2AbsFloat(
float a )
89 return a < 0 ? -a : a;
93B2_INLINE
float b2ClampFloat(
float a,
float lower,
float upper )
95 return a < lower ? lower : ( a > upper ? upper : a );
109 return a.
x * b.
x + a.y * b.y;
115 return a.
x * b.y - a.y * b.
x;
121 return B2_LITERAL(
b2Vec2 ){ s * v.y, -s * v.
x };
127 return B2_LITERAL(
b2Vec2 ){ -s * v.y, s * v.
x };
133 return B2_LITERAL(
b2Vec2 ){ -v.y, v.
x };
139 return B2_LITERAL(
b2Vec2 ){ v.y, -v.
x };
145 return B2_LITERAL(
b2Vec2 ){ a.
x + b.
x, a.y + b.y };
151 return B2_LITERAL(
b2Vec2 ){ a.
x - b.
x, a.y - b.y };
157 return B2_LITERAL(
b2Vec2 ){ -a.
x, -a.y };
164 return B2_LITERAL(
b2Vec2 ){ ( 1.0f - t ) * a.
x + t * b.
x, ( 1.0f - t ) * a.y + t * b.y };
170 return B2_LITERAL(
b2Vec2 ){ a.
x * b.
x, a.y * b.y };
176 return B2_LITERAL(
b2Vec2 ){ s * v.
x, s * v.y };
182 return B2_LITERAL(
b2Vec2 ){ a.
x + s * b.
x, a.y + s * b.y };
188 return B2_LITERAL(
b2Vec2 ){ a.
x - s * b.
x, a.y - s * b.y };
195 b.
x = b2AbsFloat( a.
x );
196 b.y = b2AbsFloat( a.y );
204 c.
x = b2MinFloat( a.
x, b.
x );
205 c.y = b2MinFloat( a.y, b.y );
213 c.
x = b2MaxFloat( a.
x, b.
x );
214 c.y = b2MaxFloat( a.y, b.y );
222 c.
x = b2ClampFloat( v.
x, a.
x, b.
x );
223 c.y = b2ClampFloat( v.y, a.y, b.y );
228B2_INLINE
float b2Length(
b2Vec2 v )
230 return sqrtf( v.
x * v.
x + v.y * v.y );
236 float dx = b.
x - a.
x;
237 float dy = b.y - a.y;
238 return sqrtf( dx * dx + dy * dy );
244 float lengthSquared = a.
x * a.
x + a.y * a.y;
245 if ( lengthSquared > 1000.0f * FLT_MIN )
247 float s = 1.0f / sqrtf( lengthSquared );
248 b2Vec2 u = { s * a.
x, s * a.y };
251 return B2_LITERAL(
b2Vec2 ){ 0.0f, 0.0f };
255B2_INLINE
bool b2IsNormalized(
b2Vec2 a )
257 float aa = b2Dot( a, a );
258 return b2AbsFloat( 1.0f - aa ) < 100.0f * FLT_EPSILON;
263B2_INLINE
b2Vec2 b2GetLengthAndNormalize(
float* length,
b2Vec2 a )
265 float lengthSquared = a.
x * a.
x + a.y * a.y;
266 if ( lengthSquared > 1000.0f * FLT_MIN )
268 *length = sqrtf( lengthSquared );
269 float s = 1.0f / *length;
270 b2Vec2 u = { s * a.
x, s * a.y };
275 return B2_LITERAL(
b2Vec2 ){ 0.0f, 0.0f };
281 float mag = sqrtf( q.s * q.s + q.
c * q.
c );
282 float invMag = mag > 0.0f ? 1.0f / mag : 0.0f;
283 b2Rot qn = { q.
c * invMag, q.s * invMag };
290B2_INLINE
b2Rot b2IntegrateRotation(
b2Rot q1,
float deltaAngle )
296 b2Rot q2 = { q1.
c - deltaAngle * q1.s, q1.s + deltaAngle * q1.
c };
297 float mag = sqrtf( q2.s * q2.s + q2.
c * q2.
c );
298 float invMag = mag > 0.0f ? 1.0f / mag : 0.0f;
299 b2Rot qn = { q2.
c * invMag, q2.s * invMag };
304B2_INLINE
float b2LengthSquared(
b2Vec2 v )
306 return v.
x * v.
x + v.y * v.y;
312 b2Vec2 c = { b.
x - a.
x, b.y - a.y };
313 return c.
x * c.
x + c.y * c.y;
317B2_INLINE
b2Rot b2MakeRot(
float radians )
324B2_INLINE
b2Rot b2MakeRotFromUnitVector(
b2Vec2 unitVector )
326 B2_ASSERT( b2IsNormalized( unitVector ) );
327 return B2_LITERAL(
b2Rot ){ unitVector.
x, unitVector.y };
334B2_INLINE
bool b2IsNormalizedRot(
b2Rot q )
337 float qq = q.s * q.s + q.
c * q.
c;
338 return 1.0f - 0.0006f < qq && qq < 1.0f + 0.0006f;
344 return B2_LITERAL(
b2Rot ){ a.
c, -a.s };
352 float omt = 1.0f - t;
354 omt * q1.
c + t * q2.
c,
355 omt * q1.s + t * q2.s,
358 float mag = sqrtf( q.s * q.s + q.
c * q.
c );
359 float invMag = mag > 0.0f ? 1.0f / mag : 0.0f;
360 b2Rot qn = { q.
c * invMag, q.s * invMag };
368B2_INLINE
float b2ComputeAngularVelocity(
b2Rot q1,
b2Rot q2,
float inv_h )
380 float omega = inv_h * ( q2.s * q1.
c - q2.
c * q1.s );
385B2_INLINE
float b2Rot_GetAngle(
b2Rot q )
412 qr.s = q.s * r.
c + q.
c * r.s;
413 qr.
c = q.
c * r.
c - q.s * r.s;
426 r.s = a.
c * b.s - a.s * b.
c;
427 r.
c = a.
c * b.
c + a.s * b.s;
432B2_INLINE
float b2RelativeAngle(
b2Rot a,
b2Rot b )
436 float s = a.
c * b.s - a.s * b.
c;
437 float c = a.
c * b.
c + a.s * b.s;
442B2_INLINE
float b2UnwindAngle(
float radians )
447 B2_VALIDATE( b2AbsFloat( radians ) < 1.0e4f );
448 float x = b2ClampFloat( radians, -1.0e6f, 1.0e6f );
452 double twoPi = 2.0f *
B2_PI;
453 double roundToNearest = 6755399441055744.0;
455 double k = ( a / twoPi + roundToNearest ) - roundToNearest;
456 return (
float)( a - k * twoPi );
462 return B2_LITERAL(
b2Vec2 ){ q.
c * v.
x - q.s * v.y, q.s * v.
x + q.
c * v.y };
468 return B2_LITERAL(
b2Vec2 ){ q.
c * v.
x + q.s * v.y, -q.s * v.
x + q.
c * v.y };
474 float x = ( t.q.
c * p.
x - t.q.s * p.y ) + t.p.
x;
475 float y = ( t.q.s * p.x + t.q.c * p.y ) + t.p.y;
477 return B2_LITERAL(
b2Vec2 ){ x, y };
483 float vx = p.
x - t.p.
x;
484 float vy = p.y - t.p.y;
485 return B2_LITERAL(
b2Vec2 ){ t.q.
c * vx + t.q.s * vy, -t.q.s * vx + t.q.
c * vy };
495 C.q = b2MulRot( A.q, B.q );
496 C.p = b2Add( b2RotateVector( A.q, B.p ), A.p );
506 C.q = b2InvMulRot( A.q, B.q );
507 C.p = b2InvRotateVector( A.q, b2Sub( B.p, A.p ) );
514 return B2_LITERAL(
b2Pos ){ v.
x, v.y };
520 return B2_LITERAL(
b2Vec2 ){ (float)p.
x, (
float)p.y };
527B2_INLINE
float b2RoundDownFloat(
double x )
529#if defined( BOX2D_DOUBLE_PRECISION )
531 return (
double)f > x ? nextafterf( f, -FLT_MAX ) : f;
538B2_INLINE
float b2RoundUpFloat(
double x )
540#if defined( BOX2D_DOUBLE_PRECISION )
542 return (
double)f < x ? nextafterf( f, FLT_MAX ) : f;
551 return B2_LITERAL(
b2Vec2 ){ (float)( a.
x - b.
x ), (float)( a.y - b.y ) };
557 return B2_LITERAL(
b2Pos ){ p.
x + d.
x, p.y + d.y };
563 return B2_LITERAL(
b2Pos ){ ( 1.0f - t ) * a.
x + t * b.
x, ( 1.0f - t ) * a.y + t * b.y };
569 float rx = t.q.
c * p.
x - t.q.s * p.y;
570 float ry = t.q.s * p.
x + t.q.
c * p.y;
571 return B2_LITERAL(
b2Pos ){ t.p.
x + rx, t.p.y + ry };
577 float vx = (float)( p.
x - t.p.
x );
578 float vy = (float)( p.y - t.p.y );
579 return B2_LITERAL(
b2Vec2 ){ t.q.
c * vx + t.q.s * vy, -t.q.s * vx + t.q.
c * vy };
586 C.q = b2InvMulRot( A.q, B.q );
587 b2Vec2 d = { (float)( B.p.
x - A.p.
x ), (float)( B.p.y - A.p.y ) };
588 C.p = b2InvRotateVector( A.q, d );
596 C.q = b2MulRot( A.q, B.q );
597 C.p = b2OffsetPos( A.p, b2RotateVector( A.q, B.p ) );
606 r.p = B2_LITERAL(
b2Vec2 ){ (float)( t.p.
x - base.
x ), (float)( t.p.y - base.y ) };
614 w.p = b2ToPos( t.p );
623 A.
cx.
x * v.
x + A.cy.
x * v.y,
624 A.
cx.y * v.
x + A.cy.y * v.y,
632 float a = A.
cx.
x, b = A.cy.
x, c = A.
cx.y, d = A.cy.y;
633 float det = a * d - b * c;
640 { det * d, -det * c },
641 { -det * b, det * a },
650 float a11 = A.
cx.
x, a12 = A.cy.
x, a21 = A.
cx.y, a22 = A.cy.y;
651 float det = a11 * a22 - a12 * a21;
656 b2Vec2 x = { det * ( a22 * b.
x - a12 * b.y ), det * ( a11 * b.y - a21 * b.
x ) };
664 s = s && a.lowerBound.
x <= b.lowerBound.
x;
665 s = s && a.lowerBound.y <= b.lowerBound.y;
666 s = s && b.upperBound.
x <= a.upperBound.
x;
667 s = s && b.upperBound.y <= a.upperBound.y;
674 b2Vec2 b = { 0.5f * ( a.lowerBound.
x + a.upperBound.
x ),
675 0.5f * ( a.lowerBound.y + a.upperBound.y ) };
682 b2Vec2 b = { 0.5f * ( a.upperBound.
x - a.lowerBound.
x ),
683 0.5f * ( a.upperBound.y - a.lowerBound.y ) };
691 c.lowerBound.
x = b2MinFloat( a.lowerBound.
x, b.lowerBound.
x );
692 c.lowerBound.y = b2MinFloat( a.lowerBound.y, b.lowerBound.y );
693 c.upperBound.
x = b2MaxFloat( a.upperBound.
x, b.upperBound.
x );
694 c.upperBound.y = b2MaxFloat( a.upperBound.y, b.upperBound.y );
701 return !( b.lowerBound.
x > a.upperBound.
x || b.lowerBound.y > a.upperBound.y ||
702 a.lowerBound.
x > b.upperBound.
x || a.lowerBound.y > b.upperBound.y );
706B2_INLINE
b2AABB b2MakeAABB(
const b2Vec2* points,
int count,
float radius )
708 B2_ASSERT( count > 0 );
709 b2AABB a = { points[0], points[0] };
710 for (
int i = 1; i < count; ++i )
712 a.lowerBound = b2Min( a.lowerBound, points[i] );
713 a.upperBound = b2Max( a.upperBound, points[i] );
716 b2Vec2 r = { radius, radius };
717 a.lowerBound = b2Sub( a.lowerBound, r );
718 a.upperBound = b2Add( a.upperBound, r );
724B2_INLINE
float b2PlaneSeparation(
b2Plane plane,
b2Vec2 point )
726 return b2Dot( plane.normal, point ) - plane.offset;
734B2_INLINE
float b2SpringDamper(
float hertz,
float dampingRatio,
float position,
float velocity,
737 float omega = 2.0f *
B2_PI * hertz;
738 float omegaH = omega * timeStep;
739 return ( velocity - omega * omegaH * position ) /
740 ( 1.0f + 2.0f * dampingRatio * omegaH + omegaH * omegaH );
787inline void operator*=(
b2Vec2& a,
float b )
796 return { -a.
x, -a.y };
802 return { a.
x + b.
x, a.y + b.y };
808 return { a.
x - b.
x, a.y - b.y };
814 return { a * b.
x, a * b.y };
820 return { a.
x * b, a.y * b };
826 return a.
x == b.
x && a.y == b.y;
832 return a.
x != b.
x || a.y != b.y;
835#if defined( BOX2D_DOUBLE_PRECISION )
840 return { a.
x + b.
x, a.y + b.y };
846 return { a.
x - b.
x, a.y - b.y };
852 return { (float)( a.
x - b.
x ), (float)( a.y - b.y ) };
float c
cosine and sine
Definition math_types.h:31
float x
coordinates
Definition math_types.h:16
b2Vec2 cx
columns
Definition math_types.h:72
float cosine
cosine and sine
Definition math_types.h:23
BOX2D_EXPORT float b2_lengthUnitsPerMeter
This value is exported for efficiency. Don't modify directly.
float b2GetLengthUnitsPerMeter(void)
Get the current length units per meter.
bool b2IsValidPlane(b2Plane a)
Is this a valid plane? Normal is a unit vector. Not NaN or infinity.
bool b2IsValidPos(b2Pos p)
Is this a valid world position? Not NaN or infinity.
float b2Atan2(float y, float x)
Compute an approximate arctangent in the range [-pi, pi] This is hand coded for cross-platform determ...
void b2SetLengthUnitsPerMeter(float lengthUnits)
Box2D bases all length units on meters, but you may need different units for your game.
bool b2IsValidVec2(b2Vec2 v)
Is this a valid vector? Not NaN or infinity.
bool b2IsValidFloat(float a)
Is this a valid number? Not NaN or infinity.
b2Vec2 b2Pos
Alias in single precision.
Definition math_types.h:61
bool b2IsValidRot(b2Rot q)
Is this a valid rotation? Not NaN or infinity. Is normalized.
b2Transform b2WorldTransform
Alias in single precision.
Definition math_types.h:64
b2CosSin b2ComputeCosSin(float radians)
Compute the cosine and sine of an angle in radians. Implemented for cross-platform determinism.
bool b2IsValidWorldTransform(b2WorldTransform t)
Is this a valid world transform? Not NaN or infinity. Rotation is normalized.
bool b2IsValidAABB(b2AABB aabb)
Is this a valid bounding box?
#define B2_PI
https://en.wikipedia.org/wiki/Pi
Definition math_types.h:90
bool b2IsValidTransform(b2Transform t)
Is this a valid transform? Not NaN or infinity. Rotation is normalized.
b2Rot b2ComputeRotationBetweenUnitVectors(b2Vec2 v1, b2Vec2 v2)
Compute the rotation between two unit vectors.
Axis-aligned bounding box.
Definition math_types.h:77
Cosine and sine pair This uses a custom implementation designed for cross-platform determinism.
Definition math_types.h:21
A 2-by-2 Matrix.
Definition math_types.h:70
separation = dot(normal, point) - offset
Definition math_types.h:84
2D rotation This is similar to using a complex number for rotation
Definition math_types.h:29
2D vector This can be used to represent a point or free vector
Definition math_types.h:14