Подтвердить что ты не робот

Java проверяет, перекрываются ли два прямоугольника в любой точке

У меня есть несколько прямоугольников и один специальный прямоугольник: выбор rect. Я хочу проверить каждый прямоугольник, если прямоугольник содержит хотя бы одну точку, находящуюся внутри прямоугольника выделения. Вот изображение для ясности:

Selection example

4b9b3361

Ответ 1

Это найдет, если прямоугольник перекрывает другой прямоугольник:

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

Мы можем определить прямоугольник только с одной его диагональю.
Допустим, диагональ левого прямоугольника равна (x1, y1) - (x2, y2)
Диагональ прямоугольника справа от (x3, y3) до (x4, y4)

Sample

Теперь, если любое из этих 4 условий выполняется, вы можете сказать, что прямоугольники не перекрываются:

  1. х3> х2 (ИЛИ)
  2. y3> y2 (ИЛИ)
  3. x1> x4 (ИЛИ)
  4. y1> y4 enter image description here

Что-нибудь кроме этих условий означает, что они перекрываются!

Пример решения на Leetcode (подход 2): https://leetcode.com/problems/rectangle-overlap/discuss/141724/Clear-Java-Code-x-2

Ответ 3

Я бы создал объекты Rectangle, а затем использовал бы методы 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;

Ответ 6

У меня есть обобщенная реализация для полигонов в системе координат gps, которая может быть немного избыточной для прямоугольников (которые являются простыми многоугольниками); но он будет работать. Должно быть довольно просто адаптировать подход к вашему usecase, если по какой-либо причине вы не хотите использовать 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

Изменить Как упоминалось в принятом ответе, объект Rectangle AWT предоставляет эту функциональность с помощью метода 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.

Изменить: использовать <= и >= для сравнения совпадений.