it-swarm.com.de

Java prüft, ob sich zwei Rechtecke an irgendeiner Stelle überlappen

Ich habe mehrere Rechtecke und ein spezielles Rechteck: das Auswahlrechteck . Ich möchte für jedes Rechteck prüfen, ob das Rechteck mindestens einen Punkt enthält, der sich innerhalb des Auswahlrechteckes befindet.

Selection example

17
user2190492

Dies wird feststellen, wenn das Rechteck ein anderes Rechteck überlappt:

public boolean overlaps (Rectangle r) {
    return x < r.x + r.width && x + width > r.x && y < r.y + r.height && y + height > r.y;
}
21
CodeCamper

Wir können ein Rechteck mit nur einer Diagonale bestimmen. 
Nehmen wir an, die Diagonale des linken Rechtecks ​​ist (x1, y1) bis (x2, y2). 
Und die Diagonale des rechten Rechtecks ​​ist (x3, y3) bis (x4, y4) 

 Sample

Wenn nun eine dieser 4 Bedingungen erfüllt ist, können Sie sagen, dass sich die Rechtecke nicht überlappen:

  1. x3> x2 (ODER)
  2. y3> y2 (ODER)
  3. x1> x4 (ODER)
  4. y1> y4  enter image description here

Alles andere als diese Bedingung bedeutet, dass sie sich überschneiden!

48
A-patel-guy

Ich würde Rechteckobjekte erstellen ( http://docs.Oracle.com/javase/8/docs/api/Java/awt/Rectangle.html ) und dann zur Ermittlung die Methoden Rectangle.intersects und Rectangle.contains verwenden wenn sie sich schneiden oder wenn einer den anderen enthält.

Da Sie ein großes Rechteck haben, das ist das Auswahlrechteck, ist dies noch einfacher als ich dachte. Führen Sie Rectangle.contains aus. Führen Sie für alle nicht enthaltenen Rechtecke Rectangle.intersects aus, und Sie haben das, wonach Sie suchen.

8

Hier ist eine andere einfachere Lösung:

    // 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;
5
A-patel-guy

Wenn der erste RectangularShape implementiert und der zweite ein Rectangle2D ist, können Sie einfach RectangularShape.intersects verwenden:

selectionRectangle.intersects(otherRectangle)

Testet, ob das Innere der Form das Innere eines angegebenen Rechtecks2D schneidet

Von den Oracle Java-Dokumenten

2
Supuhstar

Ich habe eine generische Implementierung für Polygone im gps-Koordinatensystem, die für Rechtecke (die einfache Polygone sind) ein wenig übertrieben sein kann. aber es wird funktionieren. Es sollte ziemlich einfach sein, den Ansatz an Ihre Anwendung anzupassen, wenn Sie AWT aus irgendeinem Grund nicht verwenden möchten.

https://github.com/jillesvangurp/geogeometry/blob/master/src/main/Java/com/jillesvangurp/geo/GeoGeometry.Java#L753 (Überlappungsmethode)

Was ich dort mache, ist einfach zu prüfen, ob die Polygone Punkte haben, die im anderen Polygon enthalten sind.

Für die Polygon-Einschließung von Punkten gibt es einen einfachen Algorithmus, der die Ränder des Polygons durchläuft, um zu überprüfen, ob sich der Punkt innerhalb oder außerhalb von O (n) befindet. Für Rechtecke sollte es billig sein, zu laufen.

Das Schöne an diesem Ansatz ist, dass es für beliebige Rechtecke und auch gedrehte Rechtecke oder komplexere Formen funktioniert. 

1
Jilles van Gurp

Zwei Rechtecke nicht überlappen sich, wenn eine der folgenden Bedingungen erfüllt ist.
1) Ein Rechteck befindet sich über der oberen Kante eines anderen Rechtecks.
2) Ein Rechteck befindet sich am linken Rand des anderen Rechtecks.

Beachten Sie, dass ein Rechteck durch zwei Koordinaten dargestellt werden kann, oben links und unten rechts. Wir bekommen also hauptsächlich vier Koordinaten.
l1: Oberste linke Koordinate des ersten Rechtecks.
r1: Unten rechte Koordinate des ersten Rechtecks.
l2: Oberste linke Koordinate des zweiten Rechtecks.
r2: Unten rechte Koordinate des zweiten Rechtecks. 

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;
}
1
JerryGoyal

Diese Klasse übernimmt den Bestellcode 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;        
}
}
0
Antinous