zoukankan      html  css  js  c++  java
  • 判断两个矩形是否相交的4个方法

    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   
    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>  
    方法二:如果兩個矩形相交,則必然存在線條交叉,而能交叉的線條只有橫線和豎線,兩根橫線或兩根豎線都不可能交叉。所以,這個問題就轉化成尋找是否存在交叉的橫線與豎線。
    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. }  

    方法三:

    朋友面试的时候碰到这样的问题. 


    一句代码, 判断两个矩形是否相交.

    我想了想, 写了下面的代码. 

    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/


    方法四:

    第二种方法

    两个矩形相交的条件:两个矩形的重心距离在XY轴上都小于两个矩形长或宽的一半之和.这样,分两次判断一下就行了.

    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
  • 相关阅读:
    摄像头调试
    OpenGL学习记录
    Ubuntu使用操作记录/笔记
    ROS学习材料/链接
    ubuntu14 16使用libusb过程中遇到的问题及解决方法
    nodejs: 版本常识
    JS:Html事件处理程序 vs DOM0级事件处理程序 vs DOM2级事件处理程序
    网站性能优化(一)
    Css布局:左边固定,右边自适应
    css实现显示隐藏的5种方法
  • 原文地址:https://www.cnblogs.com/xieyuan/p/3787290.html
Copyright © 2011-2022 走看看