Java检查两个矩形是否在任何点重叠

时间:2014-04-25 20:45:48

标签: java math selection shapes contain

我有多个矩形和一个特殊矩形:选择矩形。 如果矩形包含至少一个位于选择矩形内的点,我想检查每个矩形。 为清晰起见,这是一张图片:

Selection example

10 个答案:

答案 0 :(得分:53)

我们可以确定一个只有一个对角线的矩形。
假设左方矩形的对角线是(x1,y1)到(x2,y2)
右边矩形的对角线是(x3,y3)到(x4,y4)

Sample

现在,如果这4个条件中的任何一个为真,则可以说矩形不重叠:

  1. x3> x2(OR)
  2. y3> y2(OR)
  3. x1> x4(OR)
  4. y1> Y4 enter image description here
  5. 除了这些条件之外的任何东西都意味着它们重叠!

答案 1 :(得分:24)

这将查找矩形是否与另一个矩形重叠:

public boolean overlaps (Rectangle r) {
    return x < r.x + r.width && x + width > r.x && y < r.y + r.height && y + height > r.y;
}

答案 2 :(得分:8)

我会创建Rectangle对象(http://docs.oracle.com/javase/8/docs/api/java/awt/Rectangle.html)然后使用Rectangle.intersects和Rectangle.contains方法来确定它们是否相交或者是否包含另一个。

由于你有一个大矩形,即选择矩形,这比我想象的要容易。运行Rectangle.contains,对于所有未包含的矩形,运行Rectangle.intersects,你就可以得到你想要的东西。

答案 3 :(得分:5)

这是另一个更简单的解决方案:

    // 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;

答案 4 :(得分:2)

如果第一个实现RectangularShape而第二个实现Rectangle2D,则只需使用RectangularShape.intersects

selectionRectangle.intersects(otherRectangle)
  

测试Shape的内部是否与指定的Rectangle2D

的内部相交

来自the Oracle Java docs

答案 5 :(得分:1)

我对gps坐标系中的多边形有一个通用的实现,对于矩形(简单的多边形)来说可能有点过分;但它会奏效。如果出于任何原因您不想使用AWT,那么将该方法适用于您的用例应该相当简单。

https://github.com/jillesvangurp/geogeometry/blob/master/src/main/java/com/jillesvangurp/geo/GeoGeometry.java#L753(重叠方法)

我在那里做的只是检查多边形是否有其他多边形包含的任何点。

对于点的多边形包含,我有一个简单的算法,它遍历多边形的边缘以检查该点是在O(n)的内部还是外部。对于矩形,运行起来应该很便宜。

这种方法的好处在于它适用于任何矩形以及旋转的矩形或更复杂的形状。

答案 6 :(得分:1)

如果满足下列条件之一,则两个矩形不会重叠 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;
}

答案 7 :(得分:0)

此课程假定排序left<=righttop<=bottomx1<=x2y1<=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;        
}
}

答案 8 :(得分:0)

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

答案 9 :(得分:-2)

编辑如接受的答案中所述,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时,黑色重叠蓝色。

编辑:使用&lt; =和&gt; =进行重叠比较。