发一个面试题:如何判断两个矩形有相交的部分?

若鱼1919 2011-06-17 02:05:21

假设两个矩形都是平行于坐标轴的,如何判断两个矩形有相交的部分?

当时没没有思路,就放弃了,看看大家是不是有好的实现方法
...全文
1383 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
此余生安 2014-02-11
  • 打赏
  • 举报
回复
引用 6 楼 alexandertech 的回复:
如果不用现成的相交API的话,思路可以这样: 新建一个包含2个矩形的最小矩形 新矩形的两个边长如果都大于2个旧矩形的边长之和,则不相交
应该说,新矩形只要有一个边长大于2个旧矩性之和,就不相交
此余生安 2014-02-11
  • 打赏
  • 举报
回复
引用 6 楼 alexandertech 的回复:
如果不用现成的相交API的话,思路可以这样: 新建一个包含2个矩形的最小矩形 新矩形的两个边长如果都大于2个旧矩形的边长之和,则不相交
零零玲 2014-01-03
  • 打赏
  • 举报
回复
若是两个矩形大小嵌套, ( 两个矩形的x轴上的中心距离 > 两个矩形的长度之和的一半 || 两个矩形的y轴上的中心距离 > 两个矩形的高度之和的一半 ) 结果为依然为1,判断相交。矩阵的相交类型 还得具体再判断。
涡轮5 2013-11-09
  • 打赏
  • 举报
回复
引用 27 楼 mrlmrlmrl 的回复:
经分析, 两个矩形的x轴上的中心距离 > 两个矩形的长度之和的一半 两个矩形的y轴上的中心距离 > 两个矩形的高度之和的一半 以上是 || 的关系,则两矩阵不相交,反之相交 这个方法比较简单,而且考虑全面
若是两个矩形大小嵌套了呢?中心重合呢?
ssxtim 2012-12-08
  • 打赏
  • 举报
回复
可以用类似判断两个圆是否相交的方法
antiMight 2012-05-23
  • 打赏
  • 举报
回复
不过拿来做游戏的话,貌似只有7楼的方法可行,因为这个考虑了旋转,虽然会出现28楼所说十字交叉情况,但只要保证一开始两个矩形是分开的,那么运动起来后只要一直满足任一顶点不被另一矩形个包含就肯定不会出现十字交叉的情况了。
antiMight 2012-05-23
  • 打赏
  • 举报
回复
如果两个矩形都可以任意旋转呢?上面的方法都失效了吧
lewishuangym 2012-01-02
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 alexandertech 的回复:]

楼主你上面贴的还是有问题
只判断矩形A的4个顶点在不在矩形B中还不够
还要反过来再判断下矩形B的4个顶点在不在矩形A中
[/Quote]
这个错了吧兄弟,一个矩形如果从另一个矩形中穿过去。。想十字架。。
零零玲 2011-07-22
  • 打赏
  • 举报
回复
经分析,
两个矩形的x轴上的中心距离 > 两个矩形的长度之和的一半
两个矩形的y轴上的中心距离 > 两个矩形的高度之和的一半
以上是 || 的关系,则两矩阵不相交,反之相交
这个方法比较简单,而且考虑全面


飞跃颠峰 2011-06-18
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 goldenfish1919 的回复:]

Java code

//综合诸位大仙的结果如下:
public class Rectangle2Test {
private static final class Rectangle {
final int x, y;// 左下角的点的x和y坐标
final int w, h;// 矩形的宽度和高度
/* Y
*\……
[/Quote]

老大,如果我没看错,第二种方法应该是写错了
libralibra 2011-06-18
  • 打赏
  • 举报
回复
看这里,矩形相交合并分析
http://goo.gl/90FW
aotian16 2011-06-17
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 aotian16 的回复:]

以上是 || 的关系
[/Quote]
突然想到错了, 是&&, 汗颜
若鱼1919 2011-06-17
  • 打赏
  • 举报
回复

//综合诸位大仙的结果如下:
public class Rectangle2Test {
private static final class Rectangle {
final int x, y;// 左下角的点的x和y坐标
final int w, h;// 矩形的宽度和高度
/* Y
*\ /|\
* | 假设坐标系是这样:
* |
* |--------->X
* */
public Rectangle(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
/*
* 第一种方法
*/
public boolean intersects1(Rectangle r) {
// 两个矩形的水平与垂直区间都相交,两个矩形才相交
if ((interval(x, x + w, r.x) || interval(x, x + w, r.x + r.w))
&& (interval(y, y + h, r.y) || interval(y, y + h, r.y + r.h))) {
return true;
}
return false;
}
// 判断value是否在区间[start, end]之中
private static boolean interval(int start, int end, int value) {
if (start <= value && value <= end) {
return true;
}
return false;
}
/*
* 第二种方法
*/
public boolean intersects2(Rectangle r) {
// 只要保证: A的最左边坐标 <= B的最右边 && A的最右边坐标 >= B的最左边坐标
if ((x <= r.x + r.w && x + w >= r.x)
&& (y <= r.y + r.h && y + h >= r.y)) {
return true;
}
return false;
}
/*
* 第三种方法
*
* 假设矩形A和B分别有(p1, p2)和(p3,p4)确定(主对角线上的两个点),
* p1,p3分别是A、B的左下角点,p2、p4分别是A、B的右上角点
* 那么两个矩阵不相交的情况是:
* p2.y<p3.y(A在B的下方)或p4.x<p1.x(A在B的右边)或p4.y<p1.y(A在B的上方)或p2.x<p3.x(A在B的左边)
* 所以:
* 不相交:p2.y<p3.y || p4.x<p1.x || p4.y<p1.y || p2.x<p3.x
* 相交:!(p2.y<p3.y || p4.x<p1.x || p4.y<p1.y || p2.x<p3.x)
* 由德摩根定律知相交的情况是:
* p2.y>=p3.y && p4.x>=p1.x && p4.y>=p1.y && p2.x>=p3.x
* 所以:
*/
public boolean intersects3(Rectangle r) {
int x1 = this.x;
int y1 = this.y;
int x2 = x1 + w;
int y2 = x2 + h;
int x3 = r.x;
int y3 = r.y;
int x4 = x3 + r.w;
int y4 = y3 + r.h;
return y2 >= y3 && x4 >= x1 && y4 >= y1 && x2 >= x3;
}
}

public static void main(String[] args) {
Rectangle r1 = new Rectangle(0, 0, 5, 5);
Rectangle r2 = new Rectangle(2, 2, 2, 2);
Rectangle r3 = new Rectangle(6, 6, 2, 2);
Rectangle r4 = new Rectangle(-2, -2, 1, 2);

System.out.println(r1.intersects1(r2));
System.out.println(r1.intersects1(r3));
System.out.println(r1.intersects1(r4));

System.out.println(r1.intersects2(r2));
System.out.println(r1.intersects2(r3));
System.out.println(r1.intersects2(r4));

System.out.println(r1.intersects3(r2));
System.out.println(r1.intersects3(r3));
System.out.println(r1.intersects3(r4));
}
}
dreamhunter_lan 2011-06-17
  • 打赏
  • 举报
回复
假设矩形A和B分别有(p1, p2)和(p3, p4)确定(主对角线上的两个点),p1,p3分别是A、B的左上角点,p2、p4分别是A、B的右下角点

那么两个矩阵不相交的情况是:p1.y<p2.y(A在B的下方)或p1.x>p4.x(A在B的右边)或p2.y>p3.y(A在B的上方)或p2.x<p3.x(A在B的左边)
所以
不相交:p1.y<p2.y || p1.x>p4.x || p2.y>p3.y || p2.x<p3.x
相交:!(p1.y<p2.y || p1.x>p4.x || p2.y>p3.y || p2.x<p3.x)
由德摩根定律知相交的情况是:
p1.y>=p2.y && p1.x<=p4.x && p2.y<=p3.y && p2.x>=p3.x

所以:
boolean isIntersected(p1, p2, p3, p4) {
return p1.y>=p2.y && p1.x<=p4.x && p2.y<=p3.y && p2.x>=p3.x;
}
lliiqiang 2011-06-17
  • 打赏
  • 举报
回复
分别判断x轴和y轴方向是否都有公共部分

有公共部分一定满足任意一个小的在另外一个大的左边
aotian16 2011-06-17
  • 打赏
  • 举报
回复
以上是 || 的关系
aotian16 2011-06-17
  • 打赏
  • 举报
回复
两个矩形的x轴上的中心距离 > 两个矩形的长度之和的一半
两个矩形的y轴上的中心距离 > 两个矩形的高度之和的一半
Inhibitory 2011-06-17
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 java20087760445 的回复:]

假设这俩个矩形分别是A和B。只要保证 A的最右边坐标 > B的最左边坐标 && A的最左边坐标 < B 的最右边坐标。就可以了吧。
以前做过一个碰撞检测就是这样实现的。
[/Quote]
这个确实是最简单高效的:
    public boolean intersects(Rect r) {
// 只要保证: A的最左边坐标 <= B的最右边 && A的最右边坐标 >= B的最左边坐标
if ((x <= r.x + r.w && x + w >= r.x) && (y <= r.y + r.h && y + h >= r.y)) { return true; }
return false;
}
chenchenyangll 2011-06-17
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 java20087760445 的回复:]

假设这俩个矩形分别是A和B。只要保证 A的最右边坐标 > B的最左边坐标 && A的最左边坐标 < B 的最右边坐标。就可以了吧。
以前做过一个碰撞检测就是这样实现的。
[/Quote]

你不考虑y轴。。?
java20087760445 2011-06-17
  • 打赏
  • 举报
回复
假设这俩个矩形分别是A和B。只要保证 A的最右边坐标 > B的最左边坐标 && A的最左边坐标 < B 的最右边坐标。就可以了吧。
以前做过一个碰撞检测就是这样实现的。
加载更多回复(15)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧