bool Collision::AABB_vs_AABB(const AABB& a, const AABB& b, Vector *v) { const Vector a_upleft = a.upleft(); const Vector a_downright = a.downright(); const Vector b_upleft = b.upleft(); const Vector b_downright = b.downright(); bool c = !(a_downright.y < b_upleft.y || a_upleft.y > b_downright.y || a_downright.x < b_upleft.x || a_upleft.x > b_downright.x); if(c && v) { AABB ov = a.getOverlap(b); *v = ov.getCenter(); } return c; }
bool Collision::AABB_vs_Circle(const AABB& a, const Circle& c, Vector *v) { const Vector cpos = c.getPosition(); const Vector upleft = a.upleft(); const Vector downright = a.downright(); const bool leftside = cpos.x >= upleft.x; const bool rightside = cpos.x <= downright.x; const bool topside = cpos.y >= upleft.y; const bool bottomside = cpos.y <= downright.y; const bool inx = leftside && rightside; const bool iny = topside && bottomside; /* | | | (x) | ----+-------+---- |#######| (y)|#######|(y) |#######| ----+-------+---- | (x) | | | */ // First check: Center completely in AABB? [(#) region ] if(inx && iny) { if(v) *v = cpos; return true; } // Quick check: If AABBs are not intersecting, the circle is definitely out of reach. const AABB caabb = c.getAABB(); if(!AABB_vs_AABB(a, caabb, NULL)) return false; // AABBs intersecting. Now, if the circle center is contained in at least one axis, // they are intersecting. [ (x) or (y) region ] if(inx || iny) { if(v) { if(inx) { if(bottomside) *v = Vector(cpos.x, upleft.y); else if(topside) *v = Vector(cpos.x, downright.y); } else { if(leftside) *v = Vector(downright.x, cpos.y); else if(rightside) *v = Vector(upleft.x, cpos.y); } } return true; } // If we are here, the circle center must be in one of the corner regions. // Now we need to check if the circle contains the corresponding corner point of the AABB. Vector corner; // Above AABB? if(cpos.y <= upleft.y) { // Left of AABB? if(cpos.x <= upleft.x) { // Upper left corner = upleft; } else { // Upper right corner = Vector(downright.x, upleft.y); } } else if(cpos.y >= downright.y) { if(cpos.x <= upleft.x) { // Lower left corner = Vector(upleft.x, downright.y); } else { // Lower right. corner = downright; } } else { // Circle is too far away, done here. return false; } if(c.isPointInside(corner)) { if(v) *v = corner; return true; } return false; }