$begingroup$
Given the coordinates of two rectangles on a coordinate plane, what would be the easiest way to find the coordinates of the intersecting rectangle of the two?
I am trying to do this programatically.
asked Oct 20, 2010 at 21:23
serhatozgelserhatozgel
1711 gold badge1 silver badge4 bronze badges
$endgroup$
3
$begingroup$
Working from Zwarmapapa’s solution, you probably want to check that the rectangles actually overlap, and optionally that the overlap has a non-zero area.
When there is no overlap, the two coordinates will be reversed (top left will actually be bottom right and vice-versa).
If you want the rectangles with zero area (edge/corner intersection), change the two less than checks to less than or equal.
Rectangle r1 = rect1;
Rectangle r2 = rect2;
Rectangle intersectionRect = null;
int leftX = Math.max( r1.getX(), r2.getX() );
int rightX = Math.min( r1.getX() + r1.getWidth(), r2.getX() + r2.getWidth() );
int topY = Math.max( r1.getY(), r2.getY() );
int bottomY = Math.min( r1.getY() + r1.getHeight(), r2.getY() + r2.getHeight() );
if ( leftX < rightX && topY < bottomY ) {
intersectionRect = new Rectangle( leftX, topY, rightX-leftX, bottomY-topY );
} else {
// Rectangles do not overlap, or overlap has an area of zero (edge/corner overlap)
}
answered Oct 17, 2017 at 20:01
WillWill
511 silver badge2 bronze badges
$endgroup$
$begingroup$
Just think logically, draw it in mspaint or something. I got the answer in less than 15 minutes.
Rectangle r1 = rect1; Rectangle r2 = rect2; int leftX = Math.max( r1.getX(), r2.getX() ); int rightX = Math.min( r1.getX()+r1.getWidth(), r2.getX()+r2.getWidth() ); int topY = Math.max( r1.getY(), r2.getY() ); int bottomY = Math.min( r1.getY()+r1.getHeight(), r2.getY()+r2.getHeight() ); Rectangle intersectionRect = new Rectangle( leftX, topY, rightX-leftX, bottomY-topY );
answered Jul 14, 2012 at 16:47
$endgroup$
$begingroup$
In order to simplify the problem, I will assume that the rectangles are orientated “straight up and down.” By this I mean that each of the rectangles has an edge which is parallel to the x (or y) axis. Judging by the context, this should be a fair assumption. Let me know if this is not the case (in other words, what class is this for?) It might help to first graph the two rectangles whose coordinates are given. In the “simplest” case they will intersect in exactly two places.
The coordinates for some intersection will just be the point where “edge a” of “rectangle 1” intersects “edge x” of “rectangle 2.” That is, the intersection point will have the x value of (edge a or x), and the y value of the other edge (since these rectangles are parallel to the axis the x or y value of an edge will be constant across that edge.) You know the values of these edges by the coordinates given for the corners of your original rectangles.
After drawing the rectangles this should be a fairly easy and straight-forward process to work through. If you are trying to write a computer program to do this for you it is slightly more complicated but follows the same logic. Hope this helps!
answered Oct 20, 2010 at 22:21
jericsonjericson
8718 silver badges16 bronze badges
$endgroup$
1
You must log in to answer this question.
Not the answer you’re looking for? Browse other questions tagged
.
Not the answer you’re looking for? Browse other questions tagged
.
40 / 40 / 32 Регистрация: 24.11.2012 Сообщений: 200 |
|
1 |
|
Координаты пересечения двух прямоугольников14.02.2013, 15:38. Показов 16491. Ответов 2
здравствуйте. сегодня наткнулся на такую задачу: определить координаты левого верхнего и правого нижнего углов общей части 2-х прямоугольников, которые задаются так же координатами левого верхнего и правого нижнего углов. стороны прямоугольников параллельны координатным осям. случаев получается чуть больше чем дофига и как их все учесть? написать нужно на с++. может есть уже готовый алгоритм(знаю что есть для площади, а для координат что-то не видел).
0 |
dimon_91 10 / 10 / 4 Регистрация: 06.05.2009 Сообщений: 34 |
||||
15.02.2013, 11:38 |
2 |
|||
Сообщение было отмечено Agent Smith как решение РешениеПопробуйте так:
1 |
40 / 40 / 32 Регистрация: 24.11.2012 Сообщений: 200 |
|
27.02.2013, 16:30 [ТС] |
3 |
спасибо я чет посмотрел там много вариантов пересечения думал все придется просчитывать. сам себя испугался, что называется))))
0 |
Как найти площадь пересечения двух прямоугольников?
Есть два прямоугольника стороны, которых параллельны осям и они пересекаются. Нам известно:
(x1,y1) — левая нижняя точка первого прямоугольника
(x2,y2) — правая верхняя точка первого прямоугольника
(x3,y3) — левая нижняя точка второго прямоугольника
(x4,y4) — правая верхняя точка второго прямоугольника
И нужно найти площадь их пересечения. Но пересекатся они могут с разних сторон.
Хотя вопрос и простой, оставлю в качестве шпаргалки-сниппета:
Исходя из вопроса, полагаю, что координаты растут из нижнего левого угла (если же Y растет сверху вниз, то необходимо внести соответствующие поправки).
Идея простая, иллюстрируется на картинке (показано как определяется ширина общего прямоугольника, высота определяется аналогично):
Всё ещё ищете ответ? Посмотрите другие вопросы с метками c++ математика геометрия прямоугольники или задайте свой вопрос.
Site design / logo © 2022 Stack Exchange Inc; user contributions licensed under cc by-sa. rev 2022.6.10.42345
Нажимая «Принять все файлы cookie», вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
геометрия — Пересечение прямоугольников
Как вывести общую формулу для построения пересечения прямоугольников? Ведь бывает, что один прямоугольник находится внутри другого или координаты первого прямоугольника по х больше, чем у второго и при этом меньше по у, чем у второго. Как свести разные случаи в один?
задан 30 Май ’17 20:59
1 ответ
Задача для прямоугольников сводится к аналогичной задаче для отрезков. По каждой оси смотрим на пересечения отрезков, а потом берём получившийся прямоугольник (как декартово произведение). Если хотя одно пересечение отрезков окажется пустым, то и пересечение прямоугольников пусто.
По определению, отрезок [a,b] есть множество решений двойного неравенства a<=x<=b. Для двух отрезков имеем систему неравенств a<=x, c<=x, x<=b, x<=d. Она равносильна системе max(a,c)<=x, x<=min(b,d). То есть надо взять максимум левых концов и минимум правых. Получится отрезок [max(a,c),min(b,d)]. Если первое число больше второго, то это пустое множество.
отвечен 30 Май ’17 21:15
@falcao: Я уж сороковой год использую неравенство $%max(a,c)le min(b,d)$% в для проверки пересечения отрезков. Проверять пересечение прямоугольников не приходилось. Это я о программировании.
@EdwardTurJ: я вспомнил по ходу дела, что вопрос о прямоугольниках уже звучал здесь. Там площадь надо было найти. Наверное, на практике такое редко требуется, а в тренировочных задачах частенько встречается.
Получить точки пересечения из 2 прямоугольников
Допустим, у нас есть два прямоугольника, определенные их нижним левым и верхним правым углами. Например: rect1 (x1, y1) (x2, y2) а также rect2 (x3, y3) (x4, y4).
Я пытаюсь найти координаты (внизу слева и вверху справа) пересеченного прямоугольника.
Любые идеи, алгоритм, псевдокод, будет принята с благодарностью.
постскриптум Я нашел похожие вопросы, но они проверяют, только если 2 прямоугольника пересекаются.
Решение
Если входные прямоугольники нормализованы, то есть вы уже знаете, что x1 < x2 , y1 < y2 (и то же самое для второго прямоугольника), тогда все, что вам нужно сделать, это рассчитать
и это даст вам ваше пересечение в виде прямоугольника (x5, y5)-(x6, y6) , Если исходные прямоугольники не пересекаются, результатом будет «вырожденный» прямоугольник (с x5 >= x6 и / или y5 >= y6 ), который вы можете легко проверить.
Постскриптум Как обычно, мелкие детали будут зависеть от того, нужно ли учитывать трогательный прямоугольники как пересекающиеся.
Другие решения
Чтобы найти пересечение, вам нужно сделать несколько простых сравнений точек:
Итак, как мы можем видеть из изображения, если x3, y3 больше или равно x1, y1 и меньше или равно x2, y2, то оно находится внутри первого прямоугольника, аналогично вам нужно будет проверить, попадает ли x4, y4 внутрь диапазон от х1, у1 до х2, у2, а также.
если оба условия оказываются верными, то вы можете быть уверены, что второй прямоугольник полностью охватывается первым.
Вам нужно будет проверить и обратное, если узнаете, что внутри, что важно для вас.
Также необходимо, чтобы прямоугольники были выровнены по оси, иначе это не будет работать надежно.
Дайте мне знать, если вам нужно больше подробностей, хотя я думаю, что быстрый поиск в Google очень легко раскроет для вас более подробную информацию, но дайте мне знать, и я могу сделать учебник по столкновению с прямоугольником, если хотите.
Более подробно:
Чтобы выяснить, имеют ли прямоугольники пересечения, вы можете проверить координаты их определяющих точек, для наших целей мы будем использовать координаты верхнего левого и нижнего правого углов.
Мы можем использовать класс, чтобы сделать это проще для нас, и для максимального удобства использования кода мы можем использовать 2d Vector и 2d Point:
2dVectorPoint.h
Используемый код адаптирован из Вот чтобы сохранить мои пальцы.
Тогда мы можем использовать это, чтобы легко сравнить:
мы можем определить прямоугольник 1 как имеющий P1 и P2 как его границы и прямоугольник 2 как имеющий P3 и P4 как его границы, давая нам следующее сравнение:
Это вернет истинное значение для любого экземпляра пересечения или для прямоугольника 1, полностью охватывающего прямоугольник 2.
Чтобы проверить только пересечения, просто удалите проверку на равенство (возьмите все = из вышеприведенного уравнения), и вы будете проверять только на пересечения. Если у вас есть пересечение, вы можете использовать линейную алгебру для оценки точных координат.
Скажем, у блока есть радиус X и радиус Y (я знаю, что его нет, но этот термин здесь полезен).
Вы будете иметь:
Теперь, если прямоугольные средние точки находятся дальше, чем сумма их радиусов в соответствующем направлении — они не сталкиваются.
В противном случае они делают — этого намека должно хватить.
Теперь вы должны быть в состоянии выполнить задание.
ОБНОВИТЬ:
Хорошо — давайте решим это для 1D — позже вы решите это для 2D. Посмотрите на этот кусок … искусства
Вы видите 2 сегмента — теперь некоторые расчеты:
Теперь, как проверить, происходит ли столкновение? Как я уже сказал, если сумма «радиусов» меньше расстояния сегментов — столкновения нет:
Теперь ваша задача — вычислить пересечение / общую часть в 1D и 2D. Теперь все зависит от вас (вы можете прочитать ответ Андрея).
Здесь та же самая ситуация, но в 2D — две одномерные ситуации:
Вы можете иметь дело с x а также y Направление отдельно.
Предположим, что x1 <= x3 (первая коробка как минимум так же далеко, как и вторая). Тогда есть совпадение, если и только если x1 <= x3 <= x2 ,
Аналогично предположим y1 <= y3 (первая коробка, по крайней мере, так же далеко, как и вторая). Тогда есть совпадение, если и только если y1 <= y3 <= y2 ,
Если в обоих направлениях перекрытие, то перекрытие прямоугольника. Вы можете найти координаты, отсортировав x а также y координаты и выбрав два средних.
Допустим, у нас есть два прямоугольника, определенные их нижним левым и верхним правым углами. Например: rect1 (x1, y1) (x2, y2) а также rect2 (x3, y3) (x4, y4).
Я пытаюсь найти координаты (внизу слева и вверху справа) пересеченного прямоугольника.
Любые идеи, алгоритм, псевдокод, будет принята с благодарностью.
постскриптум Я нашел похожие вопросы, но они проверяют, только если 2 прямоугольника пересекаются.
23
Решение
Если входные прямоугольники нормализованы, то есть вы уже знаете, что x1 < x2
, y1 < y2
(и то же самое для второго прямоугольника), тогда все, что вам нужно сделать, это рассчитать
int x5 = max(x1, x3);
int y5 = max(y1, y3);
int x6 = min(x2, x4);
int y6 = min(y2, y4);
и это даст вам ваше пересечение в виде прямоугольника (x5, y5)-(x6, y6)
, Если исходные прямоугольники не пересекаются, результатом будет «вырожденный» прямоугольник (с x5 >= x6
и / или y5 >= y6
), который вы можете легко проверить.
Постскриптум Как обычно, мелкие детали будут зависеть от того, нужно ли учитывать трогательный прямоугольники как пересекающиеся.
50
Другие решения
Чтобы найти пересечение, вам нужно сделать несколько простых сравнений точек:
Итак, как мы можем видеть из изображения, если x3, y3 больше или равно x1, y1 и меньше или равно x2, y2, то оно находится внутри первого прямоугольника, аналогично вам нужно будет проверить, попадает ли x4, y4 внутрь диапазон от х1, у1 до х2, у2, а также.
если оба условия оказываются верными, то вы можете быть уверены, что второй прямоугольник полностью охватывается первым.
Вам нужно будет проверить и обратное, если узнаете, что внутри, что важно для вас.
Также необходимо, чтобы прямоугольники были выровнены по оси, иначе это не будет работать надежно.
Дайте мне знать, если вам нужно больше подробностей, хотя я думаю, что быстрый поиск в Google очень легко раскроет для вас более подробную информацию, но дайте мне знать, и я могу сделать учебник по столкновению с прямоугольником, если хотите.
Более подробно:
Чтобы выяснить, имеют ли прямоугольники пересечения, вы можете проверить координаты их определяющих точек, для наших целей мы будем использовать координаты верхнего левого и нижнего правого углов.
Мы можем использовать класс, чтобы сделать это проще для нас, и для максимального удобства использования кода мы можем использовать 2d Vector и 2d Point:
2dVectorPoint.h
#include <cmath>
class Vector2D
{
public:
float x;
float y;
Vector2D() {}
Vector2D(float inX, float inY)
{
x = inX;
y = inY;
}
Vector2D& Set(float inX, float inY)
{
x = inX;
y = inY;
return (*this);
}
float& operator [](long k) { return ((&x)[k]); }
const float& operator [](long k) const { return ((&x)[k]); }
Vector2D& operator +=(const Vector2D& v)
{
x += v.x;
y += v.y;
return (*this);
}
Vector2D& operator -=(const Vector2D& v)
{
x -= v.x;
y -= v.y;
return (*this);
}
Vector2D& operator *=(float t)
{
x *= t;
y *= t;
return (*this);
}
Vector2D& operator /=(float t)
{
float f = 1.0F / t;
x *= f;
y *= f;
return (*this);
}
Vector2D& operator &=(const Vector2D& v)
{
x *= v.x;
y *= v.y;
return (*this);
}
Vector2D operator -(void) const { return (Vector2D(-x, -y)); }
Vector2D operator +(const Vector2D& v) const { return (Vector2D(x + v.x, y + v.y)); }
Vector2D operator -(const Vector2D& v) const { return (Vector2D(x - v.x, y - v.y)); }
Vector2D operator *(float t) const { return (Vector2D(x * t, y * t)); }
Vector2D operator /(float t) const { float f = 1.0F / t; return (Vector2D(x * , y * f)); }
float operator *(const Vector2D& v) const { return (x * v.x + y * v.y); }
Vector2D operator &(const Vector2D& v) const { return (Vector2D(x * v.x, y * v.y)); }
bool operator ==(const Vector2D& v) const { return ((x == v.x) && (y == v.y)); }
bool operator !=(const Vector2D& v) const { return ((x != v.x) || (y != v.y)); }
Vector2D& Normalize(void) { return (*this /= sqrtf(x * x + y * y)); }
Vector2D& Rotate(float angle);
};class Point2D : public Vector2D
{
public:
Point2D() {}
Point2D(float r, float s) : Vector2D(r, s) {}
Point2D& operator =(const Vector2D& v)
{
x = v.x;
y = v.y;
return (*this);
}
Point2D& operator *=(float t)
{
x *= t;
y *= t;
return (*this);
}
Point2D& operator /=(float t)
{
float f = 1.0F / t;
x *= f;
y *= f;
return (*this);
}
Point2D operator -(void) const{ return (Point2D(-x, -y)); }
Point2D operator +(const Vector2D& v) const { return (Point2D(x + v.x, y + v.y)); }
Point2D operator -(const Vector2D& v) const { return (Point2D(x - v.x, y - v.y)); }
Vector2D operator -(const Point2D& p) const { return (Vector2D(x - p.x, y - p.y)); }
Point2D operator *(float t) const { return (Point2D(x * t, y * t)); }
Point2D operator /(float t) const
{
float f = 1.0F / t;
return (Point2D(x * f, y * f));
}
};inline Vector2D operator *(float t, const Vector2D& v){ return (Vector2D(t * v.x, t * v.y));}
inline Point2D operator *(float t, const Point2D& p){ return (Point2D(t * p.x, t * p.y));}
inline float Dot(const Vector2D& v1, const Vector2D& v2){ return (v1 * v2);}
inline float Magnitude(const Vector2D& v){ return (sqrtf(v.x * v.x + v.y * v.y));}
inline float InverseMag(const Vector2D& v){ return (1.0F / sqrtf(v.x * v.x + v.y * v.y));}
inline float SquaredMag(const Vector2D& v){ return (v.x * v.x + v.y * v.y);}
struct Origin2D_
{
const Point2D& operator +(const Vector2D& v) { return (static_cast<const Point2D&>(v)); }
Point2D operator -(const Vector2D& v) { return (Point2D(-v.x, -v.y)); }
};
2dVectorPoint.cpp
#include "2dVectorPoint.h"
Origin2D_ Origin2D;
Vector2D& Vector2D::Rotate(float angle)
{
float s = sinf(angle);
float c = cosf(angle);
float nx = c * x - s * y;
float ny = s * x + c * y;
x = nx;
y = ny;
return (*this);
}
extern Origin2D_ Origin2D;
Используемый код адаптирован из Вот чтобы сохранить мои пальцы.
Тогда мы можем использовать это, чтобы легко сравнить:
мы можем определить прямоугольник 1 как имеющий P1 и P2 как его границы и прямоугольник 2 как имеющий P3 и P4 как его границы, давая нам следующее сравнение:
if ( P2.y <= P3.y && P1.y >= P4.y && P2.x>= P3.x && P1.x <= P4.x )
{
return true;
}
Это вернет истинное значение для любого экземпляра пересечения или для прямоугольника 1, полностью охватывающего прямоугольник 2.
Чтобы проверить только пересечения, просто удалите проверку на равенство (возьмите все =
из вышеприведенного уравнения), и вы будете проверять только на пересечения. Если у вас есть пересечение, вы можете использовать линейную алгебру для оценки точных координат.
15
Скажем, у блока есть радиус X и радиус Y (я знаю, что его нет, но этот термин здесь полезен).
Вы будете иметь:
rect1_x_radius = (x2-x1)/2
rect1_y_radius = (y2-y1)/2
а также
rect2_x_radius = (x4-x3)/2
rect2_y_radius = (y4-y3)/2
Теперь, если прямоугольные средние точки находятся дальше, чем сумма их радиусов в соответствующем направлении — они не сталкиваются.
В противном случае они делают — этого намека должно хватить.
Теперь вы должны быть в состоянии выполнить задание.
ОБНОВИТЬ:
Хорошо — давайте решим это для 1D — позже вы решите это для 2D. Посмотрите на этот кусок … искусства 😉
Вы видите 2 сегмента — теперь некоторые расчеты:
rA = (maxA-minA) / 2
rB = (maxB-minB) / 2
midA = minA + rA
midB = minB + rB
mid_dist = |midA - midB|
Теперь, как проверить, происходит ли столкновение? Как я уже сказал, если сумма «радиусов» меньше расстояния сегментов — столкновения нет:
if ( mid_dist > fabs(rA+rB) )
{
// no intersection
}
else
{
// segments intersect
}
Теперь ваша задача — вычислить пересечение / общую часть в 1D и 2D. Теперь все зависит от вас (вы можете прочитать ответ Андрея).
Здесь та же самая ситуация, но в 2D — две одномерные ситуации:
7
Вы можете иметь дело с x
а также y
Направление отдельно.
Предположим, что x1 <= x3
(первая коробка как минимум так же далеко, как и вторая). Тогда есть совпадение, если и только если x1 <= x3 <= x2
,
Аналогично предположим y1 <= y3
(первая коробка, по крайней мере, так же далеко, как и вторая). Тогда есть совпадение, если и только если y1 <= y3 <= y2
,
Если в обоих направлениях перекрытие, то перекрытие прямоугольника. Вы можете найти координаты, отсортировав x
а также y
координаты и выбрав два средних.
В псевдокоде:
if (((x1 <= x3 && x3 <= x2) || (x3 <= x1 && x1 <= x4)) // x-overlap
&&
((y1 <= y3 && y3 <= y2) || (y3 <= y1 && y1 <= y4)) // y-overlap
) {
int[] xs = {x1, x2, x3, x4};
int[] ys = {y1, y2, y3, y4};
sort(xs);
sort(ys);
// bottom-left: xs[1], ys[1]
// top-right: xs[2], ys[2]
}
3
Как проверить, пересекаются ли два прямоугольника?
Александр
Гуру
(3871),
закрыт
11 лет назад
Стороны прямоугольников параллельны осям координат. Прямоугольник определяется двумя точками, левой верхней и правой нижней: (x1,y1) и (x2,y2). Ось Ox направлена направо, ось Oy направлена вниз (как на мониторе).
Jurii
Высший разум
(175122)
11 лет назад
Нарисуй на листочке бумаги:
– оси координат
– 2 прямоугольника, которые пересекаются (2-ой левее, правее, выше, ниже)
– прямоугольник, а в нём второй
– прямоугольники, которые не пересекаются
– обозначь на прямоугольниках точки (левую верхнюю и правую нижнюю)
И выведи нужные тебе условия!
+ случай когда координаты совпадают.
=Serge=
Просветленный
(35963)
11 лет назад
Элементарно. Вот фрагмент условий. Так как координаты уже упорядочены по возрастанию.
If b.x1 >a.x1 then
If b.x1>a.x2 then writeln(“Не входит”);
(иначе проверяем по y).
АлександрГуру (3871)
11 лет назад
У меня вышло вот так (при условии, что ширина и высота прямоугольника b не меньше чем i):
if ((i.x1>=b.x1) and (i.x1<=b.x2) and (i.y1>=b.y1) and (i.y1<=b.y2))
or ((i.x2>=b.x1) and (i.x2<=b.x2) and (i.y2>=b.y1) and (i.y2<=b.y2))
or ((i.x2>=b.x1) and (i.x2<=b.x2) and (i.y1>=b.y1) and (i.y1<=b.y2))
or ((i.x1>=b.x1) and (i.x1<=b.x2) and (i.y2>=b.y1) and (i.y2<=b.y2)) then
=Serge=
Просветленный
(35963)
Ты слишком усложняешь.Не вхождение проверяется проще,как я уже писал.И без всяких дополнительных условий.