Jump to content

  • Log In with Google      Sign In   
  • Create Account

#ActualServant of the Lord

Posted 07 February 2014 - 01:47 PM

Here's how I calculate whether a rect is overlapping in C++:
//Returns true if the two rects overlap each other (either by intersecting, or one containing the other).
bool cRect::Overlaps(const cRect &other)
{
	if(this->Right() < other.Left())
		return false;
	if(this->Left() > other.Right())
		return false;
	if(this->Bottom() < other.Top())
		return false;
	if(this->Top() > other.Bottom())
		return false;
	
	return true;
}
Where Top() returns 'y' pos, Bottom() returns (y + height), Left() returns 'x' pos, Right() rights (x + width).
Normally I just use 'x' and 'y' directly, being public members, but I like to use Left() and Top() for code readability and self-documentation of intent, when I'm also using Right() and Bottom().

Here's how I calculate what the overlapping portion is:

//Resizes the rect to contain just the portion of both rects that overlap.
//Basically, the AND'd portion of the two rects. If they aren't overlapping anything, this rect becomes empty.
void cRect::Intersect(const cRect &other)
{
    if(!this->Overlaps(other))
    {
        this->Clear();
        return;
    }
    
    int left = std::max(this->Left(), other.Left());
    int right = std::min(this->Right(), other.Right());
    
    int top = std::max(this->Top(), other.Top());
    int bottom = std::min(this->Bottom(), other.Bottom());
    
    //Recreate this rect from the new positions.
    this->FromCorners({left, top}, {right, bottom});
}
As @ultramailman says, if you have a list of 100+ rectangles, you might want to figure out which ones are near each other before doing a huge amount of more-accurate tests. But if you just a few rectangles, doing it brute-force is better. Even if you do have hundreds or thousands of rectangles, you should do it brute-force first to make sure you got it working before you try to optimize it.

#1Servant of the Lord

Posted 07 February 2014 - 01:43 PM

Here's how I calculate whether a rect is overlapping in C++:

//Returns true if the two rects overlap each other (either by intersecting, or one containing the other).
bool cRect::Overlaps(const cRect &other)
{
	if(this->Right() < other.Left())
		return false;
	if(this->Left() > other.Right())
		return false;
	if(this->Bottom() < other.Top())
		return false;
	if(this->Top() > other.Bottom())
		return false;
	
	return true;
}

Where Top() returns 'y' pos, Bottom() returns (y + height), Left() returns 'x' pos, Right() rights (x + width).
Normally I just use 'x' and 'y' directly, being public members, but I like to use Left() and Top() for code readability and self-documentation of intent, when I'm also using Right() and Bottom().

Here's how I calculate what the overlapping portion is:

//Resizes the rect to contain just the portion of both rects that overlap.
//Basically, the AND'd portion of the two rects. If they aren't overlapping anything, this rect becomes empty.
void cRect::Intersect(const cRect &other)
{
    if(!this->Overlaps(other))
    {
        this->Clear();
        return;
    }
    
    int left = std::max(this->Left(), other.Left());
    int right = std::min(this->Right(), other.Right());
    
    int top = std::max(this->Top(), other.Top());
    int bottom = std::min(this->Bottom(), other.Bottom());
    
    //Recreate this rect from the new positions.
    this->FromCorners({left, top}, {right, bottom});
}

PARTNERS