00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef B2_MATH_H
00020 #define B2_MATH_H
00021
00022 #include <Box2D/Common/b2Settings.h>
00023
00024 #include <cmath>
00025 #include <cfloat>
00026 #include <cstddef>
00027 #include <limits>
00028
00031 inline bool b2IsValid(float32 x)
00032 {
00033 if (x != x)
00034 {
00035
00036 return false;
00037 }
00038
00039 float32 infinity = std::numeric_limits<float32>::infinity();
00040 return -infinity < x && x < infinity;
00041 }
00042
00044 inline float32 b2InvSqrt(float32 x)
00045 {
00046 union
00047 {
00048 float32 x;
00049 int32 i;
00050 } convert;
00051
00052 convert.x = x;
00053 float32 xhalf = 0.5f * x;
00054 convert.i = 0x5f3759df - (convert.i >> 1);
00055 x = convert.x;
00056 x = x * (1.5f - xhalf * x * x);
00057 return x;
00058 }
00059
00060 #define b2Sqrt(x) sqrtf(x)
00061 #define b2Atan2(y, x) atan2f(y, x)
00062
00063 inline float32 b2Abs(float32 a)
00064 {
00065 return a > 0.0f ? a : -a;
00066 }
00067
00069 struct b2Vec2
00070 {
00072 b2Vec2() {}
00073
00075 b2Vec2(float32 x, float32 y) : x(x), y(y) {}
00076
00078 void SetZero() { x = 0.0f; y = 0.0f; }
00079
00081 void Set(float32 x_, float32 y_) { x = x_; y = y_; }
00082
00084 b2Vec2 operator -() const { b2Vec2 v; v.Set(-x, -y); return v; }
00085
00087 float32 operator () (int32 i) const
00088 {
00089 return (&x)[i];
00090 }
00091
00093 float32& operator () (int32 i)
00094 {
00095 return (&x)[i];
00096 }
00097
00099 void operator += (const b2Vec2& v)
00100 {
00101 x += v.x; y += v.y;
00102 }
00103
00105 void operator -= (const b2Vec2& v)
00106 {
00107 x -= v.x; y -= v.y;
00108 }
00109
00111 void operator *= (float32 a)
00112 {
00113 x *= a; y *= a;
00114 }
00115
00117 float32 Length() const
00118 {
00119 return b2Sqrt(x * x + y * y);
00120 }
00121
00124 float32 LengthSquared() const
00125 {
00126 return x * x + y * y;
00127 }
00128
00130 float32 Normalize()
00131 {
00132 float32 length = Length();
00133 if (length < b2_epsilon)
00134 {
00135 return 0.0f;
00136 }
00137 float32 invLength = 1.0f / length;
00138 x *= invLength;
00139 y *= invLength;
00140
00141 return length;
00142 }
00143
00145 bool IsValid() const
00146 {
00147 return b2IsValid(x) && b2IsValid(y);
00148 }
00149
00150 float32 x, y;
00151 };
00152
00154 struct b2Vec3
00155 {
00157 b2Vec3() {}
00158
00160 b2Vec3(float32 x, float32 y, float32 z) : x(x), y(y), z(z) {}
00161
00163 void SetZero() { x = 0.0f; y = 0.0f; z = 0.0f; }
00164
00166 void Set(float32 x_, float32 y_, float32 z_) { x = x_; y = y_; z = z_; }
00167
00169 b2Vec3 operator -() const { b2Vec3 v; v.Set(-x, -y, -z); return v; }
00170
00172 void operator += (const b2Vec3& v)
00173 {
00174 x += v.x; y += v.y; z += v.z;
00175 }
00176
00178 void operator -= (const b2Vec3& v)
00179 {
00180 x -= v.x; y -= v.y; z -= v.z;
00181 }
00182
00184 void operator *= (float32 s)
00185 {
00186 x *= s; y *= s; z *= s;
00187 }
00188
00189 float32 x, y, z;
00190 };
00191
00193 struct b2Mat22
00194 {
00196 b2Mat22() {}
00197
00199 b2Mat22(const b2Vec2& c1, const b2Vec2& c2)
00200 {
00201 col1 = c1;
00202 col2 = c2;
00203 }
00204
00206 b2Mat22(float32 a11, float32 a12, float32 a21, float32 a22)
00207 {
00208 col1.x = a11; col1.y = a21;
00209 col2.x = a12; col2.y = a22;
00210 }
00211
00214 explicit b2Mat22(float32 angle)
00215 {
00216
00217 float32 c = cosf(angle), s = sinf(angle);
00218 col1.x = c; col2.x = -s;
00219 col1.y = s; col2.y = c;
00220 }
00221
00223 void Set(const b2Vec2& c1, const b2Vec2& c2)
00224 {
00225 col1 = c1;
00226 col2 = c2;
00227 }
00228
00231 void Set(float32 angle)
00232 {
00233 float32 c = cosf(angle), s = sinf(angle);
00234 col1.x = c; col2.x = -s;
00235 col1.y = s; col2.y = c;
00236 }
00237
00239 void SetIdentity()
00240 {
00241 col1.x = 1.0f; col2.x = 0.0f;
00242 col1.y = 0.0f; col2.y = 1.0f;
00243 }
00244
00246 void SetZero()
00247 {
00248 col1.x = 0.0f; col2.x = 0.0f;
00249 col1.y = 0.0f; col2.y = 0.0f;
00250 }
00251
00254 float32 GetAngle() const
00255 {
00256 return b2Atan2(col1.y, col1.x);
00257 }
00258
00259 b2Mat22 GetInverse() const
00260 {
00261 float32 a = col1.x, b = col2.x, c = col1.y, d = col2.y;
00262 b2Mat22 B;
00263 float32 det = a * d - b * c;
00264 if (det != 0.0f)
00265 {
00266 det = 1.0f / det;
00267 }
00268 B.col1.x = det * d; B.col2.x = -det * b;
00269 B.col1.y = -det * c; B.col2.y = det * a;
00270 return B;
00271 }
00272
00275 b2Vec2 Solve(const b2Vec2& b) const
00276 {
00277 float32 a11 = col1.x, a12 = col2.x, a21 = col1.y, a22 = col2.y;
00278 float32 det = a11 * a22 - a12 * a21;
00279 if (det != 0.0f)
00280 {
00281 det = 1.0f / det;
00282 }
00283 b2Vec2 x;
00284 x.x = det * (a22 * b.x - a12 * b.y);
00285 x.y = det * (a11 * b.y - a21 * b.x);
00286 return x;
00287 }
00288
00289 b2Vec2 col1, col2;
00290 };
00291
00293 struct b2Mat33
00294 {
00296 b2Mat33() {}
00297
00299 b2Mat33(const b2Vec3& c1, const b2Vec3& c2, const b2Vec3& c3)
00300 {
00301 col1 = c1;
00302 col2 = c2;
00303 col3 = c3;
00304 }
00305
00307 void SetZero()
00308 {
00309 col1.SetZero();
00310 col2.SetZero();
00311 col3.SetZero();
00312 }
00313
00316 b2Vec3 Solve33(const b2Vec3& b) const;
00317
00321 b2Vec2 Solve22(const b2Vec2& b) const;
00322
00323 b2Vec3 col1, col2, col3;
00324 };
00325
00328 struct b2Transform
00329 {
00331 b2Transform() {}
00332
00334 b2Transform(const b2Vec2& position, const b2Mat22& R) : position(position), R(R) {}
00335
00337 void SetIdentity()
00338 {
00339 position.SetZero();
00340 R.SetIdentity();
00341 }
00342
00344 void Set(const b2Vec2& p, float32 angle)
00345 {
00346 position = p;
00347 R.Set(angle);
00348 }
00349
00351 float32 GetAngle() const
00352 {
00353 return b2Atan2(R.col1.y, R.col1.x);
00354 }
00355
00356 b2Vec2 position;
00357 b2Mat22 R;
00358 };
00359
00364 struct b2Sweep
00365 {
00368 void GetTransform(b2Transform* xf, float32 alpha) const;
00369
00372 void Advance(float32 t);
00373
00374 b2Vec2 localCenter;
00375 b2Vec2 c0, c;
00376 float32 a0, a;
00377 };
00378
00379
00380 extern const b2Vec2 b2Vec2_zero;
00381 extern const b2Mat22 b2Mat22_identity;
00382 extern const b2Transform b2Transform_identity;
00383
00385 inline float32 b2Dot(const b2Vec2& a, const b2Vec2& b)
00386 {
00387 return a.x * b.x + a.y * b.y;
00388 }
00389
00391 inline float32 b2Cross(const b2Vec2& a, const b2Vec2& b)
00392 {
00393 return a.x * b.y - a.y * b.x;
00394 }
00395
00398 inline b2Vec2 b2Cross(const b2Vec2& a, float32 s)
00399 {
00400 return b2Vec2(s * a.y, -s * a.x);
00401 }
00402
00405 inline b2Vec2 b2Cross(float32 s, const b2Vec2& a)
00406 {
00407 return b2Vec2(-s * a.y, s * a.x);
00408 }
00409
00412 inline b2Vec2 b2Mul(const b2Mat22& A, const b2Vec2& v)
00413 {
00414 return b2Vec2(A.col1.x * v.x + A.col2.x * v.y, A.col1.y * v.x + A.col2.y * v.y);
00415 }
00416
00419 inline b2Vec2 b2MulT(const b2Mat22& A, const b2Vec2& v)
00420 {
00421 return b2Vec2(b2Dot(v, A.col1), b2Dot(v, A.col2));
00422 }
00423
00425 inline b2Vec2 operator + (const b2Vec2& a, const b2Vec2& b)
00426 {
00427 return b2Vec2(a.x + b.x, a.y + b.y);
00428 }
00429
00431 inline b2Vec2 operator - (const b2Vec2& a, const b2Vec2& b)
00432 {
00433 return b2Vec2(a.x - b.x, a.y - b.y);
00434 }
00435
00436 inline b2Vec2 operator * (float32 s, const b2Vec2& a)
00437 {
00438 return b2Vec2(s * a.x, s * a.y);
00439 }
00440
00441 inline bool operator == (const b2Vec2& a, const b2Vec2& b)
00442 {
00443 return a.x == b.x && a.y == b.y;
00444 }
00445
00446 inline float32 b2Distance(const b2Vec2& a, const b2Vec2& b)
00447 {
00448 b2Vec2 c = a - b;
00449 return c.Length();
00450 }
00451
00452 inline float32 b2DistanceSquared(const b2Vec2& a, const b2Vec2& b)
00453 {
00454 b2Vec2 c = a - b;
00455 return b2Dot(c, c);
00456 }
00457
00458 inline b2Vec3 operator * (float32 s, const b2Vec3& a)
00459 {
00460 return b2Vec3(s * a.x, s * a.y, s * a.z);
00461 }
00462
00464 inline b2Vec3 operator + (const b2Vec3& a, const b2Vec3& b)
00465 {
00466 return b2Vec3(a.x + b.x, a.y + b.y, a.z + b.z);
00467 }
00468
00470 inline b2Vec3 operator - (const b2Vec3& a, const b2Vec3& b)
00471 {
00472 return b2Vec3(a.x - b.x, a.y - b.y, a.z - b.z);
00473 }
00474
00476 inline float32 b2Dot(const b2Vec3& a, const b2Vec3& b)
00477 {
00478 return a.x * b.x + a.y * b.y + a.z * b.z;
00479 }
00480
00482 inline b2Vec3 b2Cross(const b2Vec3& a, const b2Vec3& b)
00483 {
00484 return b2Vec3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
00485 }
00486
00487 inline b2Mat22 operator + (const b2Mat22& A, const b2Mat22& B)
00488 {
00489 return b2Mat22(A.col1 + B.col1, A.col2 + B.col2);
00490 }
00491
00492
00493 inline b2Mat22 b2Mul(const b2Mat22& A, const b2Mat22& B)
00494 {
00495 return b2Mat22(b2Mul(A, B.col1), b2Mul(A, B.col2));
00496 }
00497
00498
00499 inline b2Mat22 b2MulT(const b2Mat22& A, const b2Mat22& B)
00500 {
00501 b2Vec2 c1(b2Dot(A.col1, B.col1), b2Dot(A.col2, B.col1));
00502 b2Vec2 c2(b2Dot(A.col1, B.col2), b2Dot(A.col2, B.col2));
00503 return b2Mat22(c1, c2);
00504 }
00505
00507 inline b2Vec3 b2Mul(const b2Mat33& A, const b2Vec3& v)
00508 {
00509 return v.x * A.col1 + v.y * A.col2 + v.z * A.col3;
00510 }
00511
00512 inline b2Vec2 b2Mul(const b2Transform& T, const b2Vec2& v)
00513 {
00514 float32 x = T.position.x + T.R.col1.x * v.x + T.R.col2.x * v.y;
00515 float32 y = T.position.y + T.R.col1.y * v.x + T.R.col2.y * v.y;
00516
00517 return b2Vec2(x, y);
00518 }
00519
00520 inline b2Vec2 b2MulT(const b2Transform& T, const b2Vec2& v)
00521 {
00522 return b2MulT(T.R, v - T.position);
00523 }
00524
00525 inline b2Vec2 b2Abs(const b2Vec2& a)
00526 {
00527 return b2Vec2(b2Abs(a.x), b2Abs(a.y));
00528 }
00529
00530 inline b2Mat22 b2Abs(const b2Mat22& A)
00531 {
00532 return b2Mat22(b2Abs(A.col1), b2Abs(A.col2));
00533 }
00534
00535 template <typename T>
00536 inline T b2Min(T a, T b)
00537 {
00538 return a < b ? a : b;
00539 }
00540
00541 inline b2Vec2 b2Min(const b2Vec2& a, const b2Vec2& b)
00542 {
00543 return b2Vec2(b2Min(a.x, b.x), b2Min(a.y, b.y));
00544 }
00545
00546 template <typename T>
00547 inline T b2Max(T a, T b)
00548 {
00549 return a > b ? a : b;
00550 }
00551
00552 inline b2Vec2 b2Max(const b2Vec2& a, const b2Vec2& b)
00553 {
00554 return b2Vec2(b2Max(a.x, b.x), b2Max(a.y, b.y));
00555 }
00556
00557 template <typename T>
00558 inline T b2Clamp(T a, T low, T high)
00559 {
00560 return b2Max(low, b2Min(a, high));
00561 }
00562
00563 inline b2Vec2 b2Clamp(const b2Vec2& a, const b2Vec2& low, const b2Vec2& high)
00564 {
00565 return b2Max(low, b2Min(a, high));
00566 }
00567
00568 template<typename T> inline void b2Swap(T& a, T& b)
00569 {
00570 T tmp = a;
00571 a = b;
00572 b = tmp;
00573 }
00574
00580 inline uint32 b2NextPowerOfTwo(uint32 x)
00581 {
00582 x |= (x >> 1);
00583 x |= (x >> 2);
00584 x |= (x >> 4);
00585 x |= (x >> 8);
00586 x |= (x >> 16);
00587 return x + 1;
00588 }
00589
00590 inline bool b2IsPowerOfTwo(uint32 x)
00591 {
00592 bool result = x > 0 && (x & (x - 1)) == 0;
00593 return result;
00594 }
00595
00596 inline void b2Sweep::GetTransform(b2Transform* xf, float32 alpha) const
00597 {
00598 xf->position = (1.0f - alpha) * c0 + alpha * c;
00599 float32 angle = (1.0f - alpha) * a0 + alpha * a;
00600 xf->R.Set(angle);
00601
00602
00603 xf->position -= b2Mul(xf->R, localCenter);
00604 }
00605
00606 inline void b2Sweep::Advance(float32 t)
00607 {
00608 c0 = (1.0f - t) * c0 + t * c;
00609 a0 = (1.0f - t) * a0 + t * a;
00610 }
00611
00612 #endif