libreria - pasos para crear un componente en java
Comprobación de Java si dos rectángulos se superponen en cualquier punto (9)
Tengo múltiples rectángulos y un rectángulo especial: la selección rect. Quiero verificar cada rectángulo si el rectángulo contiene al menos un punto que está dentro del rectángulo de selección. Aquí hay una imagen para mayor claridad:
Me gustaría hacer objetos Rectangle ( http://docs.oracle.com/javase/8/docs/api/java/awt/Rectangle.html ) y luego usar los métodos Rectangle.intersects y Rectangle.contains para determinar si se cruzan o no si uno contiene el otro.
Como tienes un gran rectángulo, ese es el rectángulo de selección, esto es aún más fácil de lo que pensaba. Ejecute Rectangle.contains, y para todos los rectángulos que no estén contenidos, ejecute Rectangle.intersects, y tiene lo que está buscando.
Tengo una implementación genérica para polígonos en el sistema de coordenadas gps, que puede ser un poco exagerada para rectángulos (que son polígonos simples); pero funcionará Debería ser bastante sencillo adaptar el enfoque a su caso de uso si por algún motivo no desea utilizar AWT.
https://github.com/jillesvangurp/geogeometry/blob/master/src/main/java/com/jillesvangurp/geo/GeoGeometry.java#L753 (método de superposición)
Lo que hago allí es simplemente verificar si los polígonos tienen algún punto contenido por el otro polígono.
Para la contención de polígonos de puntos, tengo un algoritmo simple que recorre los bordes del polígono para verificar si el punto está dentro o fuera de O (n). Para rectángulos, debería ser barato ejecutarlo.
Lo bueno de este enfoque funcionará para cualquier rectángulo y también rectángulos girados o formas más complejas.
Editar Como se menciona en la respuesta aceptada, el objeto AWT Rectangle proporciona esta funcionalidad con el método intersects
. Si no desea usar AWT o por alguna otra razón, a continuación encontrará una solución alternativa.
Si quieres reinventar la rueda, aquí hay algunas cosas. Usando su imagen de ejemplo, esto probará que el rectángulo negro se superpone con el rectángulo azul. Además, esto supone que tocar no se superpone.
Cada rectángulo estará representado por dos pares de coordenadas: topLeft y bottomRight.
Esto supone que 0, 0 está en la esquina superior izquierda.
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;
}
}
El negro se superpone a Azul cuando ambas funciones devuelven verdadero.
Editar: use <= y> = para las comparaciones superpuestas.
Esto encontrará si el rectángulo se superpone a otro rectángulo:
public boolean overlaps (Rectangle r) {
return x < r.x + r.width && x + width > r.x && y < r.y + r.height && y + height > r.y;
}
Aquí hay otra solución más simple:
// 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;
Podemos determinar un rectángulo con solo una de sus diagonales.
Digamos que la diagonal del rectángulo izquierdo es (x1, y1) a (x2, y2)
Y la diagonal del rectángulo derecho es (x3, y3) a (x4, y4)
Ahora, si alguna de estas 4 condiciones es verdadera, puede decir que los rectángulos no se superponen:
¡Cualquier cosa aparte de estas condiciones significa que se superponen!
Si el primero implementa RectangularShape
y el segundo es un Rectangle2D
, simplemente puede usar RectangularShape.intersects
:
selectionRectangle.intersects(otherRectangle)
Comprueba si el interior de la forma se cruza con el interior de un Rectangle2D especificado
Dos rectángulos no se superponen si una de las siguientes condiciones es verdadera.
1) Un rectángulo está por encima del borde superior de otro rectángulo.
2) Un rectángulo está en el lado izquierdo del borde izquierdo de otro rectángulo.
Tenga en cuenta que un rectángulo se puede representar con dos coordenadas, arriba a la izquierda y abajo a la derecha. Entonces, principalmente nos dan las siguientes cuatro coordenadas.
l1: Coordenada superior izquierda del primer rectángulo.
r1: Coordenada inferior derecha del primer rectángulo.
l2: Coordenada superior izquierda del segundo rectángulo.
r2: Coordenada inferior derecha del segundo rectángulo.
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;
}
Esta clase asume que el ordenamiento 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;
}
}