Пересечение двух прямоугольников
У меня есть два прямоугольника, каждый из которых характеризуется 4 значениями:
Левая позиция X
, верхняя позиция Y
ширина W
и высота H
:
X1, Y1, H1, W1
X2, Y2, H2, W2
Прямоугольники не вращаются, вот так:
+--------------------> X axis
|
| (X,Y) (X+W, Y)
| +--------------+
| | |
| | |
| | |
| +--------------+
v (X, Y+H) (X+W,Y+H)
Y axis
Как лучше всего определить, является ли пересечение двух прямоугольников пустым или нет?
9 ответов
if (X1+W1<X2 or X2+W2<X1 or Y1+H1<Y2 or Y2+H2<Y1):
Intersection = Empty
else:
Intersection = Not Empty
Если у вас есть четыре координаты - ((X,Y),(A,B))
а также ((X1,Y1),(A1,B1))
- а не два плюс ширина и высота, это будет выглядеть так:
if (A<X1 or A1<X or B<Y1 or B1<Y):
Intersection = Empty
else:
Intersection = Not Empty
Лучший пример..
/**
* Check if two rectangles collide
* x_1, y_1, width_1, and height_1 define the boundaries of the first rectangle
* x_2, y_2, width_2, and height_2 define the boundaries of the second rectangle
*/
boolean rectangle_collision(float x_1, float y_1, float width_1, float height_1, float x_2, float y_2, float width_2, float height_2)
{
return !(x_1 > x_2+width_2 || x_1+width_1 < x_2 || y_1 > y_2+height_2 || y_1+height_1 < y_2);
}
а также еще один способ увидеть эту ссылку... и закодировать его самостоятельно..
Если два прямоугольника имеют одинаковые размеры, вы можете сделать:
if (abs (x1 - x2) < w && abs (y1 - y2) < h) {
// overlaps
}
Круговой подход более прямолинеен. Я имею в виду, когда вы определяете круг как центральную точку и радиус. Здесь то же самое, за исключением того, что у вас есть горизонтальный радиус (ширина / 2) и вертикальный (высота / 2) и 2 условия для горизонтального и вертикального расстояния.
abs(cx1 – cx2) <= hr1 + hr2 && abs(cy1 - cy2) <= vr1 + vr2
Если вам нужно исключить случай с непересекающимися сторонами, отфильтруйте их с одним прямоугольником меньше по обоим измерениям и недостаточным расстоянием (между центрами) от большего, чтобы достичь одного из его краев.
abs(cx1 – cx2) <= hr1 + hr2 && abs(cy1 - cy2) <= vr1 + vr2 &&
!(abs(cx1 – cx2) < abs(hr1 - hr2) && abs(cy1 - cy2) < abs(vr1 - vr2) && sign(hr1 - hr2) == sign(vr1 – vr2))
Если координаты прямоугольников нижнего левого угла и верхнего правого угла:
(r1x1, r1y1), (r1x2, r1y2) для rect1 и
(r2x1, r2y1), (r2x2, r2y2) для rect2
(Python как код ниже)
intersect = False
for x in [r1x1, r1x2]:
if (r2x1<=x<=r2x2):
for y in [r1y1, r1y2]:
if (r2y1<=y<=r2y2):
intersect = True
return intersect
else:
for Y in [r2y1, r2y2]:
if (r1y1<=Y<=r1y2):
intersect = True
return intersect
else:
for X in [r2x1, r2x2]:
if (r1x1<=X<=r1x2):
for y in [r2y1, r2y2]:
if (r1y1<=y<=r1y2):
intersect = True
return intersect
else:
for Y in [r1y1, r1y2]:
if (r2y1<=Y<=r2y2):
intersect = True
return intersect
return intersect
Rectangle = namedtuple('Rectangle', 'x y w h')
def intersects(rect_a: Rectangle, rect_b: Rectangle):
if (rect_a.x + rect_a.w < rect_b.x) or (rect_a.x > rect_b.x + rect_b.w) or (rect_a.y + rect_a.h < rect_b.y) or (rect_a.y > rect_b.y + rect_b.h):
return False
else:
return True
Используя систему координат, где (0, 0) - левый верхний угол.
Я думал об этом с точки зрения вертикальных и горизонтальных раздвижных окон и придумал это:
(B.Bottom> A.Top && B.Top Что вы получите, если примените закон Деморгана к следующему: Нет (B.Bottom
Я только что попробовал с программой переменного тока и написал ниже.
#include<stdio.h>
int check(int i,int j,int i1,int j1, int a, int b,int a1,int b1){
return (\
(((i>a) && (i<a1)) && ((j>b)&&(j<b1))) ||\
(((a>i) && (a<i1)) && ((b>j)&&(b<j1))) ||\
(((i1>a) && (i1<a1)) && ((j1>b)&&(j1<b1))) ||\
(((a1>i) && (a1<i1)) && ((b1>j)&&(b1<j1)))\
);
}
int main(){
printf("intersection test:(0,0,100,100),(10,0,1000,1000) :is %s\n",check(0,0,100,100,10,0,1000,1000)?"intersecting":"Not intersecting");
printf("intersection test:(0,0,100,100),(101,101,1000,1000) :is %s\n",check(0,0,100,100,101,101,1000,1000)?"intersecting":"Not intersecting");
return 0;
}
Если ( X1<=X2+W2 && X2<=X1+W1 && Y1>=Y2-H2 && Y2>=Y1+H1) Пересекаются
В вопросе Y верхняя позиция..
Примечание. Это решение работает, только если прямоугольник выровнен по осям X / Y.