Определите, перекрывают ли два прямоугольника друг друга?

Независимо от того, что вы делаете в конечном итоге, убедитесь, что вы проверяете, что ваш вход еще не был искажен magic_quotes или каким-то другим благонамеренным мусором, и, если необходимо, запустите его через stripslashes или что-то еще, чтобы его дезинфицировать .

320
задан Community 23 May 2017 в 00:31
поделиться

9 ответов

if (RectA.Left < RectB.Right && RectA.Right > RectB.Left &&
     RectA.Top > RectB.Bottom && RectA.Bottom < RectB.Top ) 

или, с помощью Декартовых координат

(С X1, оставляемым coord, X2, являющийся правильным coord, увеличиваясь слева направо и Y1, являющимся Вершиной coord и Y2, являющимся Нижней частью coord, увеличиваясь от нижней части до вершины)...

if (RectA.X1 < RectB.X2 && RectA.X2 > RectB.X1 &&
    RectA.Y1 > RectB.Y2 && RectA.Y2 < RectB.Y1) 

ПРИМЕЧАНИЕ: КО ВСЕМ ТАК ПОЛЬЗОВАТЕЛИ С ПОЛНОМОЧИЯМИ РЕДАКТИРОВАНИЯ. ПРЕКРАТИТЕ ИГРАТЬ С ЭТИМ.

Говорят, что у Вас есть Rect A, и Rect B. Proof противоречием. Любое из четырех условий гарантирует, что никакое перекрытие не может существовать :

  • Cond1. Если левый край A направо от правого края B, - тогда A Полностью направо от B
  • Cond2. Если правый край A налево от левого края B, - тогда A Полностью налево от B
  • Cond3. Если главный край A ниже базового края B, - тогда A Полностью ниже B
  • Cond4. Если базовый край A выше края вершины B, - тогда A Полностью выше B

, Таким образом, условие для Неперекрытия

Cond1 Or Cond2 Or Cond3 Or Cond4

Поэтому, достаточное условие для Перекрытия является противоположным.

Not (Cond1 Or Cond2 Or Cond3 Or Cond4)

в законе De Morgan говорится
Not (A or B or C or D), совпадает с Not A And Not B And Not C And Not D
настолько использующий De Morgan, мы имеем

Not Cond1 And Not Cond2 And Not Cond3 And Not Cond4

, Это эквивалентно:

  • Левый край А налево от правого края B, [RectA.Left < RectB.Right], и
  • правый край А направо от левого края B, [RectA.Right > RectB.Left], и
  • вершина А выше нижней части B, [RectA.Top > RectB.Bottom], и
  • нижняя часть А ниже Вершины B [RectA.Bottom < RectB.Top]

Примечание 1 : довольно очевидно, что этот тот же принцип может быть расширен на любое количество размеров.
Примечание 2 : должно также быть довольно очевидно считать перекрытия всего одного пикселя, измениться < и/или > на той границе к <= или >=.
Примечание 3 : Этот ответ, при использовании Декартовых координат (X, Y) основан на стандартных алгебраических Декартовых координатах (x увеличения слева направо и нижняя часть увеличений Y к вершине). Очевидно, где компьютерная система могла бы механизировать координаты экрана по-другому, (например, увеличиваясь Y сверху донизу, или X Справа налево), синтаксис должен будет быть скорректирован соответственно /

680
ответ дан hellow 23 November 2019 в 00:58
поделиться

Я реализовал версию C#, она легко преобразовывается в C++.

public bool Intersects ( Rectangle rect )
{
  float ulx = Math.Max ( x, rect.x );
  float uly = Math.Max ( y, rect.y );
  float lrx = Math.Min ( x + width, rect.x + rect.width );
  float lry = Math.Min ( y + height, rect.y + rect.height );

  return ulx <= lrx && uly <= lry;
}
0
ответ дан baretta 23 November 2019 в 00:58
поделиться

Не думайте о координатах как об указании, где пиксели. Думайте о них как являющийся между пикселями. Тем путем область 2x2 прямоугольник должна быть 4, не 9.

bool bOverlap = !((A.Left >= B.Right || B.Left >= A.Right)
               && (A.Bottom >= B.Top || B.Bottom >= A.Top));
1
ответ дан Mike Dunlavey 23 November 2019 в 00:58
поделиться
struct Rect
{
   Rect(int x1, int x2, int y1, int y2)
   : x1(x1), x2(x2), y1(y1), y2(y2)
   {
       assert(x1 < x2);
       assert(y1 < y2);
   }

   int x1, x2, y1, y2;
};

//some area of the r1 overlaps r2
bool overlap(const Rect &r1, const Rect &r2)
{
    return r1.x1 < r2.x2 && r2.x1 < r1.x2 &&
           r1.y1 < r2.y2 && r2.x1 < r1.y2;
}

//either the rectangles overlap or the edges touch
bool touch(const Rect &r1, const Rect &r2)
{
    return r1.x1 <= r2.x2 && r2.x1 <= r1.x2 &&
           r1.y1 <= r2.y2 && r2.x1 <= r1.y2;
}
2
ответ дан Adam Tegen 23 November 2019 в 00:58
поделиться

В вопросе Вы связываетесь с математикой для того, когда прямоугольники в произвольных углах вращения. Если я понимаю бит об углах в вопросе однако, я интерпретирую это все, прямоугольники перпендикулярны друг другу.

А общее знание области формулы перекрытия:

Используя пример:

   1   2   3   4   5   6

1  +---+---+
   |       |   
2  +   A   +---+---+
   |       | B     |
3  +       +   +---+---+
   |       |   |   |   |
4  +---+---+---+---+   +
               |       |
5              +   C   +
               |       |
6              +---+---+

1) собирают все координаты x (оба левые и правые) в список, затем сортируют его и удаляют дубликаты

1 3 4 5 6

, 2) собирают все координаты y (и вершина и нижняя часть) в список, затем сортируют его и удаляют дубликаты

1 2 3 4 6

, 3) создают 2D массив количеством разрывов между уникальными координатами x * количество разрывов между уникальными координатами y.

4 * 4

4) краска все прямоугольники в эту сетку, увеличивая количество каждой ячейки это происходит:

   1   3   4   5   6

1  +---+
   | 1 | 0   0   0
2  +---+---+---+
   | 1 | 1 | 1 | 0
3  +---+---+---+---+
   | 1 | 1 | 2 | 1 |
4  +---+---+---+---+
     0   0 | 1 | 1 |
6          +---+---+

5), Поскольку Вы красите прямоугольники, его легкое для прерывания перекрытий.

2
ответ дан Will 23 November 2019 в 00:58
поделиться

Задайте себе противоположный вопрос: Как я могу определить, не пересекаются ли два прямоугольника вообще? Очевидно, прямоугольник полностью налево от прямоугольника B не пересекается. Также, если A полностью направо. И так же если A полностью выше B или полностью ниже B. В любом другом случае пересекаются A и B.

то, Что следует, может иметь ошибки, но я довольно уверен в алгоритме:

struct Rectangle { int x; int y; int width; int height; };

bool is_left_of(Rectangle const & a, Rectangle const & b) {
   if (a.x + a.width <= b.x) return true;
   return false;
}
bool is_right_of(Rectangle const & a, Rectangle const & b) {
   return is_left_of(b, a);
}

bool not_intersect( Rectangle const & a, Rectangle const & b) {
   if (is_left_of(a, b)) return true;
   if (is_right_of(a, b)) return true;
   // Do the same for top/bottom...
 }

bool intersect(Rectangle const & a, Rectangle const & b) {
  return !not_intersect(a, b);
}
6
ответ дан bstpierre 23 November 2019 в 00:58
поделиться
struct Rect
{
    Rect(int x1, int x2, int y1, int y2)
    : x1(x1), x2(x2), y1(y1), y2(y2)
    {
        assert(x1 < x2);
        assert(y1 < y2);
    }

    int x1, x2, y1, y2;
};

bool
overlap(const Rect &r1, const Rect &r2)
{
    // The rectangles don't overlap if
    // one rectangle's minimum in some dimension 
    // is greater than the other's maximum in
    // that dimension.

    bool noOverlap = r1.x1 > r2.x2 ||
                     r2.x1 > r1.x2 ||
                     r1.y1 > r2.y2 ||
                     r2.y1 > r1.y2;

    return !noOverlap;
}
26
ответ дан David Norman 23 November 2019 в 00:58
поделиться
struct rect
{
    int x;
    int y;
    int width;
    int height;
};

bool valueInRange(int value, int min, int max)
{ return (value >= min) && (value <= max); }

bool rectOverlap(rect A, rect B)
{
    bool xOverlap = valueInRange(A.x, B.x, B.x + B.width) ||
                    valueInRange(B.x, A.x, A.x + A.width);

    bool yOverlap = valueInRange(A.y, B.y, B.y + B.height) ||
                    valueInRange(B.y, A.y, A.y + A.height);

    return xOverlap && yOverlap;
}
113
ответ дан e.James 23 November 2019 в 00:58
поделиться

Этот ответ должен быть верхним:

Если прямоугольники перекрываются, площадь перекрытия будет больше нуля. Теперь давайте найдем область перекрытия:

Если они перекрываются, то левый край перекрытия-прямоугольника будет max (r1.x1, r2.x1) и правый край будет min (r1.x2, r2.x2) . Таким образом, длина перекрытия будет min (r1.x2, r2.x2) - max (r1.x1, r2.x1)

Таким образом, площадь будет:

area = (max(r1.x1, r2.x1) - min(r1.x2, r2.x2)) * (max(r1.y1, r2.y1) - min(r1.y2, r2.y2))

Если area = 0 , то они не перекрываются.

Все просто?

0
ответ дан 23 November 2019 в 00:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: