You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

obb2d.cpp 2.9 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. class OBB2D {
  2. private:
  3. /** Corners of the box, where 0 is the lower left. */
  4. Vector2 corner[4];
  5. /** Two edges of the box extended away from corner[0]. */
  6. Vector2 axis[2];
  7. /** origin[a] = corner[0].dot(axis[a]); */
  8. double origin[2];
  9. /** Returns true if other overlaps one dimension of this. */
  10. bool overlaps1Way(const OBB2D& other) const {
  11. for (int a = 0; a < 2; ++a) {
  12. double t = other.corner[0].dot(axis[a]);
  13. // Find the extent of box 2 on axis a
  14. double tMin = t;
  15. double tMax = t;
  16. for (int c = 1; c < 4; ++c) {
  17. t = other.corner[c].dot(axis[a]);
  18. if (t < tMin) {
  19. tMin = t;
  20. } else if (t > tMax) {
  21. tMax = t;
  22. }
  23. }
  24. // We have to subtract off the origin
  25. // See if [tMin, tMax] intersects [0, 1]
  26. if ((tMin > 1 + origin[a]) || (tMax < origin[a])) {
  27. // There was no intersection along this dimension;
  28. // the boxes cannot possibly overlap.
  29. return false;
  30. }
  31. }
  32. // There was no dimension along which there is no intersection.
  33. // Therefore the boxes overlap.
  34. return true;
  35. }
  36. /** Updates the axes after the corners move. Assumes the
  37. corners actually form a rectangle. */
  38. void computeAxes() {
  39. axis[0] = corner[1] - corner[0];
  40. axis[1] = corner[3] - corner[0];
  41. // Make the length of each axis 1/edge length so we know any
  42. // dot product must be less than 1 to fall within the edge.
  43. for (int a = 0; a < 2; ++a) {
  44. axis[a] /= axis[a].squaredLength();
  45. origin[a] = corner[0].dot(axis[a]);
  46. }
  47. }
  48. public:
  49. OBB2D(const Vector2& center, const double w, const double h, double angle)
  50. {
  51. Vector2 X( cos(angle), sin(angle));
  52. Vector2 Y(-sin(angle), cos(angle));
  53. X *= w / 2;
  54. Y *= h / 2;
  55. corner[0] = center - X - Y;
  56. corner[1] = center + X - Y;
  57. corner[2] = center + X + Y;
  58. corner[3] = center - X + Y;
  59. computeAxes();
  60. }
  61. /** For testing purposes. */
  62. void moveTo(const Vector2& center) {
  63. Vector2 centroid = (corner[0] + corner[1] + corner[2] + corner[3]) / 4;
  64. Vector2 translation = center - centroid;
  65. for (int c = 0; c < 4; ++c) {
  66. corner[c] += translation;
  67. }
  68. computeAxes();
  69. }
  70. /** Returns true if the intersection of the boxes is non-empty. */
  71. bool overlaps(const OBB2D& other) const {
  72. return overlaps1Way(other) && other.overlaps1Way(*this);
  73. }
  74. void render() const {
  75. glBegin(GL_LINES);
  76. for (int c = 0; c < 5; ++c) {
  77. glVertex2fv(corner[c & 3]);
  78. }
  79. glEnd();
  80. }
  81. };