Java检查两个矩形是不是在任何点重叠
Posted
技术标签:
【中文标题】Java检查两个矩形是不是在任何点重叠【英文标题】:Java check if two rectangles overlap at any pointJava检查两个矩形是否在任何点重叠 【发布时间】:2014-06-11 17:36:08 【问题描述】:我有多个矩形和一个特殊矩形:选择矩形。 我想检查每个矩形是否包含至少一个位于选择矩形内的点。 为了清楚起见,这是一张图片:
【问题讨论】:
Rectangle::intersects
对你有用。
javarevisited.blogspot.com/2016/10/…
【参考方案1】:
背景:
一个矩形只能由它的对角线之一定义。 假设第一个矩形的对角线是 (x1, y1) 到 (x2, y2) 而另一个矩形的对角线是 (x3, y3) 到 (x4, y4)
进行:
现在,如果这 4 个条件中的任何一个为真,我们可以断定矩形不重叠:
-
x3 > x2(或)
y3 > y2(或)
x1 > x4(或)
y1 > y4
否则,它们会重叠!
或者:
如果矩形重叠
(x1 < x4) && (x3 < x2) && (y1 < y4) && (y3 < y2)
Leetcode 上的示例解决方案: https://leetcode.com/problems/rectangle-overlap/discuss/468548/Java-check-if-two-rectangles-overlap-at-any-point
【讨论】:
这个肯定比公认的答案有更好的解释! 这可以通过一个代码示例来使其成为一个很好的答案【参考方案2】:这将确定矩形是否与另一个矩形重叠:
public boolean overlaps (Rectangle r)
return x < r.x + r.width && x + width > r.x && y < r.y + r.height && y + height > r.y;
【讨论】:
@ahitt6345 是的,确实如此。唯一的问题是如果您尝试旋转矩形,在这种情况下您将需要多边形重叠方法。 虽然解决方案是正确的 - 我推荐this answer down below 以获得更好的理解。【参考方案3】:我会创建Rectangle objects,然后使用Rectangle.intersects
和Rectangle.contains
方法来确定它们是否相交或一个是否包含另一个。
既然你有一个大矩形,那就是选择矩形,这比我想象的还要容易。运行 Rectangle.contains,对于所有不包含的矩形,运行 Rectangle.intersects,你就会得到你想要的。
【讨论】:
【参考方案4】:这是另一个更简单的解决方案:
// Left x
int leftX = Math.max(x1, x3);
// Right x
int rightX = Math.min(x2, x4);
// Bottom y
int botY = Math.max(y1, y3);
// TopY
int topY = Math.min(y2, y4);
if (rightX > leftX && topY > botY)
return true;
【讨论】:
【参考方案5】:如果第一个实现RectangularShape
,第二个是Rectangle2D
,你可以简单地使用RectangularShape.intersects
:
selectionRectangle.intersects(otherRectangle)
测试 Shape 的内部是否与指定的 Rectangle2D 的内部相交
来自the Oracle Java docs
【讨论】:
【参考方案6】:我对 gps 坐标系中的多边形有一个通用的实现,这对于矩形(简单的多边形)可能有点矫枉过正;但它会起作用。如果您出于某种原因不想使用 AWT,那么根据您的用例调整该方法应该相当简单。
https://github.com/jillesvangurp/geogeometry/blob/master/src/main/java/com/jillesvangurp/geo/GeoGeometry.java#L753(重叠法)
我所做的只是检查多边形是否有其他多边形包含的任何点。
对于点的多边形包含,我有一个简单的算法可以遍历多边形的边缘以检查该点是在 O(n) 内部还是外部。对于矩形,运行起来应该很便宜。
这种方法的好处是它适用于任何矩形以及旋转的矩形或更复杂的形状。
【讨论】:
【参考方案7】:如果以下条件之一为真,则两个矩形不重叠。 1) 一个矩形在另一个矩形的顶部边缘之上。 2) 一个矩形在另一个矩形的左边。
请注意,一个矩形可以用两个坐标表示,左上角和右下角。所以主要是给我们以下四个坐标。 l1:第一个矩形的左上角坐标。 r1:第一个矩形的右下坐标。 l2:第二个矩形的左上角坐标。 r2:第二个矩形的右下坐标。
class Point
int x, y;
;
// Returns true if two rectangles (l1, r1) and (l2, r2) overlap
bool doOverlap(Point l1, Point r1, Point l2, Point r2)
// If one rectangle is on left side of other
if (l1.x > r2.x || l2.x > r1.x)
return false;
// If one rectangle is above other
if (l1.y < r2.y || l2.y < r1.y)
return false;
return true;
【讨论】:
【参考方案8】:这个类假定顺序为left<=right
、top<=bottom
、x1<=x2
、y1<=y2
:
public class Rect
int left, right, bottom, top;
Rect(int left, int top, int right, int bottom)
this.left = left;
this.right = right;
this.top = top;
this.bottom = bottom;
boolean overlap(int x1, int y1, int x2, int y2)
// if one rectangle is to the left or right, then there can be no overlap
if(x2 < left || right < x1)
return false;
// the x values overlap, but the y values may still lie outside the rectangle
// if one rectangle is above or below, then there can be no overlap
if(y2 < top || bottom < y1)
return false;
// otherwise we must overlap !
return true;
【讨论】:
【参考方案9】:java.awt.Rectangle
有一个内置的 intersects
方法。
import java.awt.Rectangle;
// ...
Rectangle r1 = new Rectangle(
0 /* top left x */, 0 /* top left y */,
5 /* width */, 7 /* height */
);
Rectangle r2 = new Rectangle(4, 5, 3, 3);
System.out.println(r1.intersects(r2)); // true
【讨论】:
【参考方案10】:编辑 正如接受的答案中所述,AWT Rectangle 对象通过intersects
方法提供此功能。如果您不想使用 AWT 或出于其他原因,下面是一个变体解决方案。
如果您想重新发明***,那么这里有一些东西。 使用您的示例图像,这将测试黑色矩形与蓝色矩形重叠。此外,这假设触摸没有重叠。
每个矩形将由两个坐标对表示:topLeft 和 bottomRight。
这里假设0,0在左上角。
Function xOverlapCheck(black, blue)
// black left side overlaps.
if ((black.topLeft.x <= blue.bottomRight.x) &&
(black.topLeft.x >= blue.topLeft.x))
return true;
// black right side overlaps.
if ((black.bottomRight.x <= blue.bottomRight.x) &&
(black.bottomRight.x >= blue.topLeft.x))
return true;
// black fully contains blue.
if ((black.bottomRight.x >= blue.bottomRight.x) &&
(black.topLeft.x <= blue.topLeft.x))
return true;
Function yOverlapCheck(black, blue)
// black top side overlaps.
if ((black.topLeft.y >= blue.topLeft.y) &&
(black.topLeft.y <= blue.bottomRight.y))
return true;
// black bottom side overlaps.
if ((black.bottomRight.y >= blue.topLeft.y) &&
(black.bottomRight.y <= blue.bottomRight.y))
return true;
// black fully contains blue.
if ((black.bottomRight.y >= blue.bottomRight.y) &&
(black.topLeft.y <= blue.topLeft.y))
return true;
当两个函数都返回 true 时,黑色与蓝色重叠。
编辑:使用 = 进行重叠比较。
【讨论】:
伙计,你让我进行了数小时毫无意义的调试,你的方法有缺陷——由于某些原因,它不包括仅移动一个像素的矩形。对我来说Rect.intersection(new Rect(0, 5, 5, 0), new Rect(0, 6, 5, 1))
返回错误。但是,如果我增加矩形之间的距离,它就开始起作用了。以上是关于Java检查两个矩形是不是在任何点重叠的主要内容,如果未能解决你的问题,请参考以下文章