判断矩形相交以及求出相交区域

问题:给定两个矩形A和B,矩形A的左上角坐标为(Xa1,Ya1),右下角坐标为(Xa2,Ya2),矩形B的左上角坐标为(Xb1,Yb1),右下角坐标为(Xb2,Yb2)。
(1)设计一个算法,确定两个矩形是否相交(即有重叠区域)
(2)如果两个矩形相交,设计一个算法,求出相交的区域矩形

(1) 对于这个问题,一般的思路就是判断一个矩形的四个顶点是否在另一个矩形的区域内。这个思路最简单,但是效率不高,并且存在错误,错误在哪里,下面分析一下。

如上图,把矩形的相交(区域重叠)分成三种(可能也有其他划分),对于第三种情况,如图中的(3),两个矩形相交,但并不存在一个矩形的顶点在另一个矩形内部。所以那种思路存在一个错误,对于这种情况的相交则检查不出。

仔细观察上图,想到另一种思路,那就是判断两个矩形的中心坐标的水平和垂直距离,只要这两个值满足某种条件就可以相交。
矩形A的宽 Wa = Xa2-Xa1 高 Ha = Ya2-Ya1
矩形B的宽 Wb = Xb2-Xb1 高 Hb = Yb2-Yb1
矩形A的中心坐标 (Xa3,Ya3) = ( (Xa2+Xa1)/2 ,(Ya2+Ya1)/2 )
矩形B的中心坐标 (Xb3,Yb3) = ( (Xb2+Xb1)/2 ,(Yb2+Yb1)/2 )
所以只要同时满足下面两个式子,就可以说明两个矩形相交。
1) | Xb3-Xa3 | <= Wa/2 + Wb/2
2) | Yb3-Ya3 | <= Ha/2 + Hb/2
即:
| Xb2+Xb1-Xa2-Xa1 | <= Xa2-Xa1 + Xb2-Xb1
| Yb2+Yb1-Ya2-Ya1 | <=Y a2-Ya1 + Yb2-Yb1

(2) 对于这个问题,假设两个矩形相交,设相交之后的矩形为C,且矩形C的左上角坐标为(Xc1,Yc1),右下角坐标为(Xc2,Yc2),经过观察上图,很显然可以得到:
Xc1 = max(Xa1,Xb1)
Yc1 = max(Ya1,Yb1)
Xc2 = min(Xa2,Xb2)
Yc2 = min(Ya2,Yb2)
这样就求出了矩形的相交区域。
另外,注意到在不假设矩形相交的前提下,定义(Xc1,Yc1),(Xc2,Yc2),且Xc1,Yc1,Xc2,Yc2的值由上面四个式子得出。这样,可以依据Xc1,Yc1,Xc2,Yc2的值来判断矩形相交。
Xc1,Yc1,Xc2,Yc2只要同时满足下面两个式子,就可以说明两个矩形相交。
3) Xc1 <= Xc2
4) Yc1 <= Yc2
即:
max(Xa1,Xb1) <= min(Xa2,Xb2)
max(Ya1,Yb1) <= min(Ya2,Yb2)

参考:
[url]http://hi.baidu.com/hytjfxk/blog/item/32348c35c6637b8ca61e12c8.html[/url]
[url]http://www.cnblogs.com/nicolaszhao/archive/2011/01/24/1943276.html[/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
判断两个矩形是否相交可以使用以下方法: 1. 判断两个矩形的边界是否有交集,如果没有交集,那么两个矩形一定不相交。 2. 如果两个矩形的边界有交集,那么再判断两个矩形的重心是否在对方的内部,如果重心不在对方的内部,那么两个矩形也不相交求出两个相交矩形区域可以使用以下方法: 1. 判断两个矩形是否相交,如果不相交,则不存在相交区域。 2. 如果两个矩形相交,那么可以求出相交矩形的左上角和右下角的坐标,从而确定相交区域。 具体实现可以参考以下代码: ```java public class Rectangle { // 判断两个矩形是否相交 public static boolean isOverlap(int x1, int y1, int width1, int height1, int x2, int y2, int width2, int height2) { if (x1 + width1 <= x2 || x1 >= x2 + width2 || y1 + height1 <= y2 || y1 >= y2 + height2) { return false; } return true; } // 求出两个相交矩形区域 public static void getOverlapRegion(int x1, int y1, int width1, int height1, int x2, int y2, int width2, int height2) { if (!isOverlap(x1, y1, width1, height1, x2, y2, width2, height2)) { System.out.println("两个矩形相交"); return; } int x = Math.max(x1, x2); int y = Math.max(y1, y2); int width = Math.min(x1 + width1, x2 + width2) - x; int height = Math.min(y1 + height1, y2 + height2) - y; System.out.println("相交区域左上角坐标为 (" + x + ", " + y + ")"); System.out.println("相交区域右下角坐标为 (" + (x + width) + ", " + (y + height) + ")"); } public static void main(String[] args) { int x1 = 0, y1 = 0, width1 = 4, height1 = 4; int x2 = 2, y2 = 2, width2 = 4, height2 = 4; getOverlapRegion(x1, y1, width1, height1, x2, y2, width2, height2); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值