Java-метод, чтобы найти прямоугольник, который является пересечением двух прямоугольников, используя только левую нижнюю точку, ширину и высоту?
Я нашел решение, но хотел, чтобы моя логика была наиболее эффективной. Я чувствую, что есть лучший способ. У меня есть координата (x, y) нижнего левого угла, высота и ширина 2 прямоугольника, и мне нужно вернуть третий прямоугольник, являющийся их пересечением. Я не хочу публиковать код, поскольку я чувствую, что он обманывает.
- Я считаю, что самый дальний слева и самый высокий на графике.
- Я проверяю, полностью ли перекрывается другой, и обратный, чтобы увидеть, полностью ли перекрывается первая на оси X.
- Я проверяю частичное пересечение по оси X.
- Я в основном повторяю шаги 2 и 3 для оси Y.
- Я делаю некоторую математику и получаю точки прямоугольника на основе этих условий.
Возможно, я об этом подумал и написал неэффективный код. Я уже включил рабочую программу, но хотел бы найти лучший способ для своих собственных знаний. Если кто-то может согласиться или указать мне в правильном направлении, это было бы здорово!
Ответы
Ответ 1
Почему бы вам не использовать JDK API для этого?
Rectangle rect1 = new Rectangle(100, 100, 200, 240);
Rectangle rect2 = new Rectangle(120, 80, 80, 120);
Rectangle intersection = rect1.intersection(rect2);
Чтобы использовать класс java.awt.Rectangle
, параметры конструктора: x, y, width, height, в которых x, y - верхний левый угол прямоугольника. Вы можете легко преобразовать нижнюю левую точку в верхнюю левую.
Я рекомендую выше, но если вы действительно хотите сделать это самостоятельно, вы можете выполнить следующие шаги:
say (x1, y1), (x2, y2)
- нижние левые и нижние правые углы Rect1 соответственно,
(x3, y3), (x4, y4)
- те из Rect2.
- найдите большую из
x1
, x3
и меньшую из x2
, x4
, скажем xL
,
xR
соответственно
- if
xL >= xR
, тогда не возвращайте никакое другое пересечение
- найдите большую из
y1
, y3
и меньшую из y2
, y4
, скажем yT
,
yB
соответственно
- if
yT >= yB
, тогда не возвращайте никакое другое пересечение
- return
(xL, yB, xR-xL, yB-yT)
.
Более похожий на Java псевдо-код:
// Two rectangles, assume the class name is `Rect`
Rect r1 = new Rect(x1, y2, w1, h1);
Rect r2 = new Rect(x3, y4, w2, h2);
// get the coordinates of other points needed later:
int x2 = x1 + w1;
int x4 = x3 + w2;
int y1 = y2 - h1;
int y3 = y4 - h2;
// find intersection:
int xL = Math.max(x1, x3);
int xR = Math.min(x2, x4);
if (xR <= xL)
return null;
else {
int yT = Math.max(y1, y3);
int yB = Math.min(y2, y4);
if (yB <= yT)
return null;
else
return new Rect(xL, yB, xR-xL, yB-yT);
}
Как вы видите, если ваш прямоугольник был первоначально определен двумя диагональными углами, это будет проще, вам нужно только сделать часть // find intersection
.
Ответ 2
Принятый ответ неверен. Вот моя версия, которая правильна.
Не используйте принятый ответ.
//returns true when intersection is found, false otherwise.
//when returning true, rectangle 'out' holds the intersection of r1 and r2.
private static boolean intersection2(Rectangle r1, Rectangle r2,
Rectangle out) {
float xmin = Math.max(r1.x, r2.x);
float xmax1 = r1.x + r1.width;
float xmax2 = r2.x + r2.width;
float xmax = Math.min(xmax1, xmax2);
if (xmax > xmin) {
float ymin = Math.max(r1.y, r2.y);
float ymax1 = r1.y + r1.height;
float ymax2 = r2.y + r2.height;
float ymax = Math.min(ymax1, ymax2);
if (ymax > ymin) {
out.x = xmin;
out.y = ymin;
out.width = xmax - xmin;
out.height = ymax - ymin;
return true;
}
}
return false;
}
Ответ 3
Вы также можете использовать исходный код Rectangle для сравнения с вашим собственным алгоритмом:
/**
* Computes the intersection of this <code>Rectangle</code> with the
* specified <code>Rectangle</code>. Returns a new <code>Rectangle</code>
* that represents the intersection of the two rectangles.
* If the two rectangles do not intersect, the result will be
* an empty rectangle.
*
* @param r the specified <code>Rectangle</code>
* @return the largest <code>Rectangle</code> contained in both the
* specified <code>Rectangle</code> and in
* this <code>Rectangle</code>; or if the rectangles
* do not intersect, an empty rectangle.
*/
public Rectangle intersection(Rectangle r) {
int tx1 = this.x;
int ty1 = this.y;
int rx1 = r.x;
int ry1 = r.y;
long tx2 = tx1; tx2 += this.width;
long ty2 = ty1; ty2 += this.height;
long rx2 = rx1; rx2 += r.width;
long ry2 = ry1; ry2 += r.height;
if (tx1 < rx1) tx1 = rx1;
if (ty1 < ry1) ty1 = ry1;
if (tx2 > rx2) tx2 = rx2;
if (ty2 > ry2) ty2 = ry2;
tx2 -= tx1;
ty2 -= ty1;
// tx2,ty2 will never overflow (they will never be
// larger than the smallest of the two source w,h)
// they might underflow, though...
if (tx2 < Integer.MIN_VALUE) tx2 = Integer.MIN_VALUE;
if (ty2 < Integer.MIN_VALUE) ty2 = Integer.MIN_VALUE;
return new Rectangle(tx1, ty1, (int) tx2, (int) ty2);
}
Ответ 4
был ханнин бой бой.........................