判断两个矩形是否相交的4个方法
2014-02-21 16:48
453 查看
http://blog.csdn.net/cxf7394373/article/details/7535105
最近在用opencv寫一個文本定位的程序,獲取到字符輪廓之後需要進行合並,涉及到判斷矩形是否相交的問題,記得去年去三星通信研究院面試同樣問到了這個問題,如何判斷兩條線段是否相交,如何判斷兩個矩形是否相交。以前寫過一篇如何判斷線段相交的問題,上網查了一些方法,在這裡做一下後一個問題的總結:
方法一:假定矩形是用一對點表達的(minx,miny)(maxx, maxy) ,那麼兩個矩形rect1{(minx1,miny1)(maxx1, maxy1)}, rect2{(minx2,miny2)(maxx2, maxy2)} 相交的結果一定是個矩形,構成這個相交矩形rect{(minx,miny)(maxx,
maxy)}的點對坐標是:
minx = max(minx1, minx2)
miny = max(miny1, miny2)
maxx = min(maxx1, maxx2)
maxy = min(maxy1, maxy2)
如果兩個矩形不相交,那麼計算得到的點對坐標必然滿足
minx > maxx 或者 miny > maxy
[cpp] view
plaincopy
<pre name="code" class="cpp">bool CPreprocess::crossAlgorithm1(CvRect r1,CvRect r2)
{
int nMaxLeft = 0;
int nMaxTop = 0;
int nMinRight = 0;
int nMinBottom = 0;
//計算兩矩形可能的相交矩形的邊界
nMaxLeft = r1.x >= r2.x ? r1.x : r2.x;
nMaxTop = r1.y >= r2.y ? r1.y : r2.y;
nMinRight = (r1.x + r1.width) <= (r2.x + r2.width) ? (r1.x + r1.width) : (r2.x + r2.width);
nMinBottom = (r1.y + r1.height) <= (r2.y + r2.height) ? (r1.y + r1.height) : (r2.y + r2.height);
// 判斷是否相交
if (nMaxLeft > nMinRight || nMaxTop > nMinBottom)
{
return false;
}
else
{
return true;
}
}</pre>
<pre></pre>
方法二:如果兩個矩形相交,則必然存在線條交叉,而能交叉的線條只有橫線和豎線,兩根橫線或兩根豎線都不可能交叉。所以,這個問題就轉化成尋找是否存在交叉的橫線與豎線。
[cpp] view
plaincopy
//判斷兩個矩形是否相交
bool CPreprocess::crossAlgorithm2(CvRect r1,CvRect r2)
{
//判斷兩個矩形是否相交,
//從一個矩形中取出一條橫線,與另一矩形中的一條豎線判斷是否交叉
return crossLine(r1.x, r1.x + r1.width, r1.y, r2.y, r2.y + r2.height, r2.x)
|| crossLine(r1.x, r1.x + r1.width, r1.y, r2.y, r2.y + r2.height, r2.x + r2.width)
|| crossLine(r1.x, r1.x + r1.width, r1.y + r1.height, r2.y, r2.y + r2.height, r2.x)
|| crossLine(r1.x, r1.x + r1.width, r1.y + r1.height, r2.y, r2.y + r2.height, r2.x r2.width)
|| crossLine(r2.x, r2.x + r2.width, r2.y, r1.y, r1.y + r1.height, r1.x)
|| crossLine(r2.x, r2.x + r2.width, r2.y, r1.y, r1.y + r1.height, r1.x + r1.width)
|| crossLine(r2.x, r2.x + r2.width, r2.y + r2.height, r1.y, r1.y + r1.height, r1.x)
|| crossLine(r2.x, r2.x + r2.width, r2.y r2.height, r1.y + r1.height, r1.y + r1.height, r1.x r1.width);
}
//判斷直線是否相交
bool CPreprocess::crossLine(int left,int right,int x,int top,int bottom,int y)
{
return (top < y) && (bottom > y) && (left < x) && (right > x);
}
方法三:
朋友面试的时候碰到这样的问题.
一句代码, 判断两个矩形是否相交.
我想了想, 写了下面的代码.
typedef struct
{
int left;
int right;
int top;
int bottom;
}RECT;
bool isRectOverlap(const RECT& r1, const RECT& r2)
{
return !(r1.left > r2.right || r1.top > r2.bottom || r2.left > r1.right || r2.top > r1.bottom);
}
运用逆向思维考虑这个问题或许会好一点.
1. 判断 r1 的左上角是否在 r2 的右下角的下面或者右面
2. 判断 r2 的左上角是否在 r1 的右下角的下面或者右面
3. 结果求反.
http://opengl2009.blog.163.com/blog/static/15032767620103774031630/
方法四:
第二种方法
两个矩形相交的条件:两个矩形的重心距离在X和Y轴上都小于两个矩形长或宽的一半之和.这样,分两次判断一下就行了.
bool CrossLine(Rect r1,RECT r2)
{
if(abs((r1.x1+r1.x2)/2-(r2.x1+r2.x2)/2)<((r1.x2+r2.x2-r1.x1-r2.x1)/2) && abs((r1.y1+r1.y2)/2-(r2.y1+r2.y2)/2)<((r1.y2+r2.y2-r1.y1-r2.y1)/2))
return true;
return false;
}
http://www.cnblogs.com/0001/archive/2010/05/04/1726905.html
最近在用opencv寫一個文本定位的程序,獲取到字符輪廓之後需要進行合並,涉及到判斷矩形是否相交的問題,記得去年去三星通信研究院面試同樣問到了這個問題,如何判斷兩條線段是否相交,如何判斷兩個矩形是否相交。以前寫過一篇如何判斷線段相交的問題,上網查了一些方法,在這裡做一下後一個問題的總結:
方法一:假定矩形是用一對點表達的(minx,miny)(maxx, maxy) ,那麼兩個矩形rect1{(minx1,miny1)(maxx1, maxy1)}, rect2{(minx2,miny2)(maxx2, maxy2)} 相交的結果一定是個矩形,構成這個相交矩形rect{(minx,miny)(maxx,
maxy)}的點對坐標是:
minx = max(minx1, minx2)
miny = max(miny1, miny2)
maxx = min(maxx1, maxx2)
maxy = min(maxy1, maxy2)
如果兩個矩形不相交,那麼計算得到的點對坐標必然滿足
minx > maxx 或者 miny > maxy
[cpp] view
plaincopy
<pre name="code" class="cpp">bool CPreprocess::crossAlgorithm1(CvRect r1,CvRect r2)
{
int nMaxLeft = 0;
int nMaxTop = 0;
int nMinRight = 0;
int nMinBottom = 0;
//計算兩矩形可能的相交矩形的邊界
nMaxLeft = r1.x >= r2.x ? r1.x : r2.x;
nMaxTop = r1.y >= r2.y ? r1.y : r2.y;
nMinRight = (r1.x + r1.width) <= (r2.x + r2.width) ? (r1.x + r1.width) : (r2.x + r2.width);
nMinBottom = (r1.y + r1.height) <= (r2.y + r2.height) ? (r1.y + r1.height) : (r2.y + r2.height);
// 判斷是否相交
if (nMaxLeft > nMinRight || nMaxTop > nMinBottom)
{
return false;
}
else
{
return true;
}
}</pre>
<pre></pre>
方法二:如果兩個矩形相交,則必然存在線條交叉,而能交叉的線條只有橫線和豎線,兩根橫線或兩根豎線都不可能交叉。所以,這個問題就轉化成尋找是否存在交叉的橫線與豎線。
[cpp] view
plaincopy
//判斷兩個矩形是否相交
bool CPreprocess::crossAlgorithm2(CvRect r1,CvRect r2)
{
//判斷兩個矩形是否相交,
//從一個矩形中取出一條橫線,與另一矩形中的一條豎線判斷是否交叉
return crossLine(r1.x, r1.x + r1.width, r1.y, r2.y, r2.y + r2.height, r2.x)
|| crossLine(r1.x, r1.x + r1.width, r1.y, r2.y, r2.y + r2.height, r2.x + r2.width)
|| crossLine(r1.x, r1.x + r1.width, r1.y + r1.height, r2.y, r2.y + r2.height, r2.x)
|| crossLine(r1.x, r1.x + r1.width, r1.y + r1.height, r2.y, r2.y + r2.height, r2.x r2.width)
|| crossLine(r2.x, r2.x + r2.width, r2.y, r1.y, r1.y + r1.height, r1.x)
|| crossLine(r2.x, r2.x + r2.width, r2.y, r1.y, r1.y + r1.height, r1.x + r1.width)
|| crossLine(r2.x, r2.x + r2.width, r2.y + r2.height, r1.y, r1.y + r1.height, r1.x)
|| crossLine(r2.x, r2.x + r2.width, r2.y r2.height, r1.y + r1.height, r1.y + r1.height, r1.x r1.width);
}
//判斷直線是否相交
bool CPreprocess::crossLine(int left,int right,int x,int top,int bottom,int y)
{
return (top < y) && (bottom > y) && (left < x) && (right > x);
}
方法三:
朋友面试的时候碰到这样的问题.
一句代码, 判断两个矩形是否相交.
我想了想, 写了下面的代码.
typedef struct
{
int left;
int right;
int top;
int bottom;
}RECT;
bool isRectOverlap(const RECT& r1, const RECT& r2)
{
return !(r1.left > r2.right || r1.top > r2.bottom || r2.left > r1.right || r2.top > r1.bottom);
}
运用逆向思维考虑这个问题或许会好一点.
1. 判断 r1 的左上角是否在 r2 的右下角的下面或者右面
2. 判断 r2 的左上角是否在 r1 的右下角的下面或者右面
3. 结果求反.
http://opengl2009.blog.163.com/blog/static/15032767620103774031630/
方法四:
第二种方法
两个矩形相交的条件:两个矩形的重心距离在X和Y轴上都小于两个矩形长或宽的一半之和.这样,分两次判断一下就行了.
bool CrossLine(Rect r1,RECT r2)
{
if(abs((r1.x1+r1.x2)/2-(r2.x1+r2.x2)/2)<((r1.x2+r2.x2-r1.x1-r2.x1)/2) && abs((r1.y1+r1.y2)/2-(r2.y1+r2.y2)/2)<((r1.y2+r2.y2-r1.y1-r2.y1)/2))
return true;
return false;
}
http://www.cnblogs.com/0001/archive/2010/05/04/1726905.html
相关文章推荐
- 也谈Android中的Context(1)
- http协议头
- python实现360的字符显示界面
- WPF 动画特效--翻牌
- android 电子书源码,翻页效果
- 名词王国里的死刑
- PowerDesigner 学习
- java Date Calendar 区别
- 判断两个矩形是否相交的4个方法
- SharePoint2013安装组件时AppFabric时出现1603错误,解决方法:
- 简单的一些数据库语句
- Android 开发性能优化之SparseArray(三)
- C#读写文件总结
- oracle 帐号
- Jquery实现倒计后可操作
- python实现360皮肤按钮控件示例
- 关于ios分享(ShareSDK)
- 杂
- http数据返回值
- 结构体中字符串赋值