判斷兩個矩形是否相交

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 plain copy
  1. <pre name="code" class="cpp">bool CPreprocess::crossAlgorithm1(CvRect r1,CvRect r2)  
  2. {  
  3.     int nMaxLeft = 0;  
  4.     int nMaxTop = 0;  
  5.     int nMinRight = 0;  
  6.     int nMinBottom = 0;  
  7.   
  8.     //計算兩矩形可能的相交矩形的邊界  
  9.     nMaxLeft = r1.x >= r2.x ? r1.x : r2.x;  
  10.     nMaxTop = r1.y >= r2.y ? r1.y : r2.y;  
  11.     nMinRight = (r1.x + r1.width) <= (r2.x + r2.width) ? (r1.x + r1.width) : (r2.x + r2.width);  
  12.     nMinBottom = (r1.y + r1.height) <= (r2.y + r2.height) ? (r1.y + r1.height) : (r2.y + r2.height);  
  13.     // 判斷是否相交  
  14.     if (nMaxLeft > nMinRight || nMaxTop > nMinBottom)  
  15.     {  
  16.         return false;  
  17.     }  
  18.     else  
  19.     {  
  20.         return true;  
  21.     }  
  22. }</pre>  
  23. <pre></pre>  
方法二:如果兩個矩形相交,則必然存在線條交叉,而能交叉的線條只有橫線和豎線,兩根橫線或兩根豎線都不可能交叉。所以,這個問題就轉化成尋找是否存在交叉的橫線與豎線。
[cpp]  view plain copy
  1. //判斷兩個矩形是否相交  
  2. bool CPreprocess::crossAlgorithm2(CvRect r1,CvRect r2)  
  3. {  
  4.     //判斷兩個矩形是否相交,  
  5.     //從一個矩形中取出一條橫線,與另一矩形中的一條豎線判斷是否交叉  
  6.     return crossLine(r1.x, r1.x + r1.width, r1.y, r2.y, r2.y + r2.height, r2.x)  
  7.         || crossLine(r1.x, r1.x + r1.width, r1.y, r2.y, r2.y + r2.height, r2.x + r2.width)  
  8.           || crossLine(r1.x, r1.x + r1.width, r1.y + r1.height, r2.y, r2.y + r2.height, r2.x)  
  9.             || crossLine(r1.x, r1.x + r1.width, r1.y + r1.height, r2.y, r2.y + r2.height, r2.x r2.width)  
  10.               || crossLine(r2.x, r2.x + r2.width, r2.y, r1.y, r1.y + r1.height, r1.x)  
  11.                 || crossLine(r2.x, r2.x + r2.width, r2.y, r1.y, r1.y + r1.height, r1.x + r1.width)  
  12.                   || crossLine(r2.x, r2.x + r2.width, r2.y + r2.height, r1.y, r1.y + r1.height, r1.x)  
  13.                     || crossLine(r2.x, r2.x + r2.width, r2.y r2.height, r1.y + r1.height, r1.y + r1.height, r1.x r1.width);  
  14. }  
  15. //判斷直線是否相交  
  16. bool CPreprocess::crossLine(int left,int right,int x,int top,int bottom,int y)  
  17. {  
  18.     return (top < y) && (bottom > y) && (left < x) && (right > x);  
  19. }  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值