|
- class OBB2D {
- private:
- /** Corners of the box, where 0 is the lower left. */
- Vector2 corner[4];
-
- /** Two edges of the box extended away from corner[0]. */
- Vector2 axis[2];
-
- /** origin[a] = corner[0].dot(axis[a]); */
- double origin[2];
-
- /** Returns true if other overlaps one dimension of this. */
- bool overlaps1Way(const OBB2D& other) const {
- for (int a = 0; a < 2; ++a) {
-
- double t = other.corner[0].dot(axis[a]);
-
- // Find the extent of box 2 on axis a
- double tMin = t;
- double tMax = t;
-
- for (int c = 1; c < 4; ++c) {
- t = other.corner[c].dot(axis[a]);
-
- if (t < tMin) {
- tMin = t;
- } else if (t > tMax) {
- tMax = t;
- }
- }
-
- // We have to subtract off the origin
-
- // See if [tMin, tMax] intersects [0, 1]
- if ((tMin > 1 + origin[a]) || (tMax < origin[a])) {
- // There was no intersection along this dimension;
- // the boxes cannot possibly overlap.
- return false;
- }
- }
-
- // There was no dimension along which there is no intersection.
- // Therefore the boxes overlap.
- return true;
- }
-
-
- /** Updates the axes after the corners move. Assumes the
- corners actually form a rectangle. */
- void computeAxes() {
- axis[0] = corner[1] - corner[0];
- axis[1] = corner[3] - corner[0];
-
- // Make the length of each axis 1/edge length so we know any
- // dot product must be less than 1 to fall within the edge.
-
- for (int a = 0; a < 2; ++a) {
- axis[a] /= axis[a].squaredLength();
- origin[a] = corner[0].dot(axis[a]);
- }
- }
-
- public:
-
- OBB2D(const Vector2& center, const double w, const double h, double angle)
- {
- Vector2 X( cos(angle), sin(angle));
- Vector2 Y(-sin(angle), cos(angle));
-
- X *= w / 2;
- Y *= h / 2;
-
- corner[0] = center - X - Y;
- corner[1] = center + X - Y;
- corner[2] = center + X + Y;
- corner[3] = center - X + Y;
-
- computeAxes();
- }
-
-
- /** For testing purposes. */
- void moveTo(const Vector2& center) {
- Vector2 centroid = (corner[0] + corner[1] + corner[2] + corner[3]) / 4;
-
- Vector2 translation = center - centroid;
-
- for (int c = 0; c < 4; ++c) {
- corner[c] += translation;
- }
-
- computeAxes();
- }
-
- /** Returns true if the intersection of the boxes is non-empty. */
- bool overlaps(const OBB2D& other) const {
- return overlaps1Way(other) && other.overlaps1Way(*this);
- }
-
- void render() const {
- glBegin(GL_LINES);
- for (int c = 0; c < 5; ++c) {
- glVertex2fv(corner[c & 3]);
- }
- glEnd();
- }
- };
|