Recently I've had to implement collision detection between rotated rectangle. Following this algorithm, http://www.gamedev.net/page/resources/_/technical/game-programming/2d-rotated-rectangle-collision-r2604 (http://www.gamedev.net/page/resources/_/technical/game-programming/2d-rotated-rectangle-collision-r2604), I created a function to take the four corners of two rectangles and return a bool as to whether or not they collide. However, for some reason it registers collisions even when no collisions occur.
bool Game_State::RotatedRectCollision(sf::Vector2f UL1, sf::Vector2f UR1, sf::Vector2f LL1, sf::Vector2f LR1, sf::Vector2f UL2, sf::Vector2f UR2, sf::Vector2f LL2, sf::Vector2f LR2)
{
sf::Vector2f RectA[4];
sf::Vector2f RectB[4];
RectA[0] = UL1;
RectA[1] = UR1;
RectA[2] = LL1;
RectA[3] = LR1;
RectB[0] = UL2;
RectB[1] = UR2;
RectB[2] = LL2;
RectB[3] = LR2;
sf::Vector2f Axes[4];
Axes[0] = sf::Vector2f(UR1.x - UL1.x, UR1.y - UL1.y);
Axes[1] = sf::Vector2f(UR1.x - LR1.x, UR1.y - LR1.y);
Axes[2] = sf::Vector2f(UL2.x - LL2.x, UL2.y - LL2.y);
Axes[3] = sf::Vector2f(UL2.x - UR2.x, UL2.y - UR2.y);
float ScalarVal[8];
for(int i = 0; i < 4; i++)
{
sf::Vector2f Proj[8];
int curProj = 0;
for(int j = 0; j < 4; j++)
{
Proj[curProj].x = Axes[i].x * (RectA[j].x * Axes[i].x + RectA[j].y * Axes[i].y)/(Axes[i].x * Axes[i].x + Axes[i].y * Axes[i].y);
Proj[curProj].y = Axes[i].y * Proj[curProj].x / Axes[i].x;
curProj++;
Proj[curProj].x = Axes[i].x * (RectB[j].x * Axes[i].x + RectB[j].y * Axes[i].y)/(Axes[i].x * Axes[i].x + Axes[i].y * Axes[i].y);
Proj[curProj].y = Axes[i].y * Proj[curProj].x / Axes[i].x;
curProj++;
}
for(int j = 0; j < 8; j++)
{
ScalarVal[j] = Proj[j].x * Axes[i].x + Proj[j].y * Axes[i].y;
}
float min_a = ScalarVal[0];
float min_b = ScalarVal[4];
float max_a = ScalarVal[0];
float max_b = ScalarVal[4];
for(int j = 1; j < 4; j++)
{
min_a = std::min(min_a, ScalarVal[j]);
min_b = std::min(min_b, ScalarVal[j + 4]);
max_a = std::max(max_a, ScalarVal[j]);
max_b = std::max(max_b, ScalarVal[j + 4]);
}
if((min_b > min_a) && (max_b < min_a))
{
return false;
}
}
return true;
}