同样,我们还是要将所有的情况列举出来,然后仔细分析和提取特征。下面是两个矩形并集的所有情况:
【两个矩形所有并集情况列举图】
结合前文提到的求交集的经验,进而在总结求并集也就轻松了许多。我们确定并集最小外包矩形的左上角和右下角,就是两个矩形的左上角xy最小的值的组合,右下角则是两个矩形右下角xy最大值的组合。其实换个角度再想想,求交集是尽可能往中间靠,就是左上角大,右下角小,而并集就是往外扩张,所以左上角要尽可能小,右下角尽可能大。这么一对比,规律非常好把握了。
如果是左上角和右下角没有被两个矩形覆盖到,我们为了好分析,就画了延长线相交来辅助分析。需要注意一点,求并集的最小外包矩形,不存在求不到外包矩形的。除非两个矩形本身就是空的。
既然道理都清楚了,那就写代码吧。封装的函数名为UnionRect_cjjjs,参数和返回值和UnionRect一样。代码如下:
bool UnionRect_cjjjs(LPRECT lpDstRect,const RECT* lpSrcRect1,const RECT* lpSrcRect2)
{
if (lpSrcRect1->left>=lpSrcRect1->right || lpSrcRect2->top>=lpSrcRect2->bottom)
{
SetRectEmpty(lpDstRect);
return false;
}
if (lpSrcRect1->left>lpSrcRect2->left)
{
lpDstRect->left=lpSrcRect2->left;
}
else
{
lpDstRect->left=lpSrcRect1->left;
}
if (lpSrcRect1->top>lpSrcRect2->top)
{
lpDstRect->top=lpSrcRect2->top;
}
else
{
lpDstRect->top=lpSrcRect1->top;
}
if (lpSrcRect1->right>lpSrcRect2->right)
{
lpDstRect->right=lpSrcRect1->right;
}
else
{
lpDstRect->right=lpSrcRect2->right;
}
if (lpSrcRect1->bottom>lpSrcRect2->bottom)
{
lpDstRect->bottom=lpSrcRect1->bottom;
}
else
{
lpDstRect->bottom=lpSrcRect2->bottom;
}
return true;
}
测试通过,效果和《UnionRect求取两个矩形的并集最小外包矩形图解》效果一样。你将这个函数放在使用UnionRect求取并集最小外包矩形的代码最前面,然后将UnionRect改为UnionRect_cjjjs即可。