Lets break it down a bit:
Code:
BOOL Sprite::HorizontalCollision(const RECT& rcTest)
{
return m_rcCollision.left <= rcTest.right &&
rcTest.left <= m_rcCollision.right;
}
BOOL Sprite::VerticalCollision(const RECT& rcTest)
{
return m_rcCollision.top <= rcTest.bottom &&
rcTest.top <= m_rcCollision.bottom;
}
BOOL Sprite::TestCollision(Sprite* pTestSprite)
{
RECT& rcTest = pTestSprite->GetCollision();
return HorizontalCollision(rcTest) &&
VerticalCollision(rcTest);
}
With me so far? The rectangles might overlap horizontally but one is below the other, or they might overlap vertically but one is to the right of the other, thus both conditions need to be satisfied (hence the && in TestCollision).
Given the vertical and horizontal tests are the same (just different variable names) lets look at just HorizontalCollision.
Forget thinking about where they do overlap and think about the two cases where they don't overlap, for a moment. There may be four ways that they do overlap, but there are only two ways that they do not overlap. Either one rectangle has both of its edges to the left of the other rectangle or it has both edges to the right of it. Here's how those two cases look, left-to-right:
Code:
m_rcCollision.Left m_rcCollision.Right rcTest.Left rcText.Right //case 1
rcTest.Left rcText.Right m_rcCollision.Left m_rcCollision.Right //case 2
We know any rectangle has its left edge and right edge the correct way around, so to detect the above cases all we need to check is the middle two items of the four:
Code:
is m_rcCollision.Right < rcTest.Left //case 1
or
is rcText.Right < m_rcCollision.Left // case 2
Now remember that we want the opposite case, where it does overlap, not where it doesn't. So we apply DeMorgan's Law:
A or B <==> !(!A and !B)
In other words, negate both expressions, and toggle the operator beteen 'or' and 'and'.
Starting with:
Code:
m_rcCollision.Right < rcTest.Left || (rcText.Right < m_rcCollision.Left)
this becomes:
Code:
!(m_rcCollision.Right < rcTest.Left) && !(rcText.Right < m_rcCollision.Left)
Simplify to remove the negation... !(A<B) is the same as A >= B:
Code:
m_rcCollision.Right >= rcTest.Left && rcText.Right >= m_rcCollision.Left
Flip the expresions over (since B>=A is the same as A<=B):
Code:
m_rcCollision.left <= rcTest.right && rcTest.left <= m_rcCollision.right
And there we have it!
I guess you could say that the function looks for the absense of ways in which the rectangles do not overlap, rather than looking for the presence of ways in which they do overlap.