Déterminer si deux rectangles se chevauchent?


337

J'essaie d'écrire un programme C ++ qui prend les entrées suivantes de l'utilisateur pour construire des rectangles (entre 2 et 5): hauteur, largeur, x-pos, y-pos. Tous ces rectangles existeront parallèlement aux axes x et y, c'est-à-dire que toutes leurs arêtes auront des pentes de 0 ou infini.

J'ai essayé de mettre en œuvre ce qui est mentionné dans cette question mais je n'ai pas beaucoup de chance.

Mon implémentation actuelle fait ce qui suit:

// Gets all the vertices for Rectangle 1 and stores them in an array -> arrRect1
// point 1 x: arrRect1[0], point 1 y: arrRect1[1] and so on...
// Gets all the vertices for Rectangle 2 and stores them in an array -> arrRect2

// rotated edge of point a, rect 1
int rot_x, rot_y;
rot_x = -arrRect1[3];
rot_y = arrRect1[2];
// point on rotated edge
int pnt_x, pnt_y;
pnt_x = arrRect1[2]; 
pnt_y = arrRect1[3];
// test point, a from rect 2
int tst_x, tst_y;
tst_x = arrRect2[0];
tst_y = arrRect2[1];

int value;
value = (rot_x * (tst_x - pnt_x)) + (rot_y * (tst_y - pnt_y));
cout << "Value: " << value;  

Cependant, je ne sais pas trop si (a) j'ai correctement implémenté l'algorithme auquel j'ai lié, ou si j'ai fait exactement comment interpréter cela?

Aucune suggestion?


3
je pense que la solution à votre problème n'implique aucune multiplication.
Scott Evernden

Réponses:


708
if (RectA.Left < RectB.Right && RectA.Right > RectB.Left &&
     RectA.Top > RectB.Bottom && RectA.Bottom < RectB.Top ) 

ou, en utilisant des coordonnées cartésiennes

(Avec X1 étant la coordonnée gauche, X2 étant la coordonnée droite, augmentant de gauche à droite et Y1 étant la coordonnée supérieure, et Y2 étant la coordonnée inférieure, augmentant de bas en haut - si ce n'est pas ainsi que votre système de coordonnées [par exemple, la plupart des ordinateurs ont le Direction Y inversée], permutez les comparaisons ci-dessous ) ...

if (RectA.X1 < RectB.X2 && RectA.X2 > RectB.X1 &&
    RectA.Y1 > RectB.Y2 && RectA.Y2 < RectB.Y1) 

Disons que vous avez Rect A et Rect B. La preuve est par contradiction. L'une des quatre conditions garantit qu'aucun chevauchement ne peut exister :

  • Cond1. Si le bord gauche de A est à droite du bord droit de B, - alors A est totalement à droite de B
  • Cond2. Si le bord droit de A est à gauche du bord gauche de B, - alors A est totalement à gauche de B
  • Cond3. Si le bord supérieur de A est inférieur au bord inférieur de B, - alors A est totalement inférieur à B
  • Cond4. Si le bord inférieur de A est au-dessus du bord supérieur de B, - alors A est totalement au-dessus de B

La condition de non-chevauchement est donc

NON-Overlap => Cond1 ou Cond2 ou Cond3 ou Cond4

Par conséquent, une condition suffisante pour Overlap est le contraire.

Chevauchement => NON (Cond1 ou Cond2 ou Cond3 ou Cond4)

La loi de De Morgan dit que
Not (A or B or C or D)c'est la même chose qu'en Not A And Not B And Not C And Not D
utilisant De Morgan, nous avons

Pas Cond1 et pas Cond2 et pas Cond3 et pas Cond4

Cela équivaut à:

  • Bord gauche de A à gauche du bord droit de B, [ RectA.Left < RectB.Right] et
  • Le bord droit de A à droite du bord gauche de B, [ RectA.Right > RectB.Left] et
  • Le haut de A au-dessus du bas de B, [ RectA.Top > RectB.Bottom] et
  • Le bas de A sous le haut de B [ RectA.Bottom < RectB.Top]

Note 1 : Il est assez évident que ce même principe peut être étendu à n'importe quel nombre de dimensions.
Note 2 : Il devrait également être assez évident de compter les chevauchements d'un seul pixel, de changer le <et / ou le >sur cette frontière en a <=ou a >=.
Remarque 3 : Cette réponse, lorsque vous utilisez des coordonnées cartésiennes (X, Y), est basée sur des coordonnées cartésiennes algébriques standard (x augmente de gauche à droite et Y augmente de bas en haut). De toute évidence, lorsqu'un système informatique peut mécaniser les coordonnées de l'écran différemment (par exemple, en augmentant Y de haut en bas ou X de droite à gauche), la syntaxe devra être ajustée en conséquence /


489
Si vous avez du mal à visualiser pourquoi cela fonctionne, j'ai créé une page d'exemple sur silentmatt.com/intersection.html où vous pouvez faire glisser des rectangles et voir les comparaisons.
Matthew Crumley

4
ne pensez-vous pas que vous utilisez les contraintes dures? que faire si les deux rectangles se chevauchent exactement sur ce bord? ne devriez-vous pas considérer <=,> = ??
Nawshad Farruque

6
@MatthewCrumley pour A.Y1 <B.Y2 et A.Y2> B.Y1 sur votre lien, les signes gt & lt ne devraient-ils pas être inversés?
NikT

15
J'ai dû échanger <et> dans les deux dernières comparaisons pour le faire fonctionner
DataGreed

17
Non, la réponse est correcte comme indiqué. Il est basé sur l'utilisation de coordonnées cartésiennes standard. Si vous utilisez un système différent (Y augmentant de haut en bas), effectuez les réglages appropriés.
Charles Bretana

115
struct rect
{
    int x;
    int y;
    int width;
    int height;
};

bool valueInRange(int value, int min, int max)
{ return (value >= min) && (value <= max); }

bool rectOverlap(rect A, rect B)
{
    bool xOverlap = valueInRange(A.x, B.x, B.x + B.width) ||
                    valueInRange(B.x, A.x, A.x + A.width);

    bool yOverlap = valueInRange(A.y, B.y, B.y + B.height) ||
                    valueInRange(B.y, A.y, A.y + A.height);

    return xOverlap && yOverlap;
}

15
Réponse la plus simple et la plus propre.
ldog

1
@ e.James Je suppose que le dernier B.heightdevrait êtreA.height
mat_boy

'min' et 'max' sont des mots clés réservés dans <windows.h>. vous pouvez le corriger en faisant #undef minet #undef max, ou en utilisant différents noms de paramètres.
mchiasson

Si vous utilisez beaucoup, vous pouvez échanger valueInRange contre un#define BETWEEN(value,min,max) \ (\ value > max ? max : ( value < min ? min : value )\ )
Ratata Tata

@Nemo En fait, la vérification xOverlapest en une dimension; rectOverlapest à deux dimensions. Il peut être étendu à N dimensions à l'aide d'une boucle.
Justme0

27
struct Rect
{
    Rect(int x1, int x2, int y1, int y2)
    : x1(x1), x2(x2), y1(y1), y2(y2)
    {
        assert(x1 < x2);
        assert(y1 < y2);
    }

    int x1, x2, y1, y2;
};

bool
overlap(const Rect &r1, const Rect &r2)
{
    // The rectangles don't overlap if
    // one rectangle's minimum in some dimension 
    // is greater than the other's maximum in
    // that dimension.

    bool noOverlap = r1.x1 > r2.x2 ||
                     r2.x1 > r1.x2 ||
                     r1.y1 > r2.y2 ||
                     r2.y1 > r1.y2;

    return !noOverlap;
}

Joli! En appliquant la loi De Morgans, obtenez: r1.x1 <= r2.x2 && r2.x1 <= r1.x2 && r1.y1 <= r2.y2 && r2.y1 <= r1.y2.
Borzh

23

Il est plus facile de vérifier si un rectangle est complètement en dehors de l'autre, donc s'il est soit

sur la gauche...

(r1.x + r1.width < r2.x)

ou à droite ...

(r1.x > r2.x + r2.width)

ou en haut ...

(r1.y + r1.height < r2.y)

ou en bas ...

(r1.y > r2.y + r2.height)

du deuxième rectangle, il ne peut pas entrer en collision avec lui. Donc, pour avoir une fonction qui renvoie un dicton booléen lorsque les rectangles entrent en collision, nous combinons simplement les conditions par des OU logiques et annulons le résultat:

function checkOverlap(r1, r2) : Boolean
{ 
    return !(r1.x + r1.width < r2.x || r1.y + r1.height < r2.y || r1.x > r2.x + r2.width || r1.y > r2.y + r2.height);
}

Pour recevoir déjà un résultat positif en touchant seulement, nous pouvons changer le "<" et ">" par "<=" et "> =".


3
Et appliquez-lui la loi de Morgan.
Borzh

6

Posez-vous la question opposée: comment puis-je déterminer si deux rectangles ne se croisent pas du tout? De toute évidence, un rectangle A complètement à gauche du rectangle B ne se coupe pas. Aussi si A est complètement à droite. Et de même si A est complètement au-dessus de B ou complètement en dessous de B. Dans tous les autres cas, A et B se croisent.

Ce qui suit peut avoir des bugs, mais je suis assez confiant sur l'algorithme:

struct Rectangle { int x; int y; int width; int height; };

bool is_left_of(Rectangle const & a, Rectangle const & b) {
   if (a.x + a.width <= b.x) return true;
   return false;
}
bool is_right_of(Rectangle const & a, Rectangle const & b) {
   return is_left_of(b, a);
}

bool not_intersect( Rectangle const & a, Rectangle const & b) {
   if (is_left_of(a, b)) return true;
   if (is_right_of(a, b)) return true;
   // Do the same for top/bottom...
 }

bool intersect(Rectangle const & a, Rectangle const & b) {
  return !not_intersect(a, b);
}

6

Supposons que vous ayez défini les positions et les tailles des rectangles comme ceci:

entrez la description de l'image ici

Mon implémentation C ++ est comme ceci:

class Vector2D
{
    public:
        Vector2D(int x, int y) : x(x), y(y) {}
        ~Vector2D(){}
        int x, y;
};

bool DoRectanglesOverlap(   const Vector2D & Pos1,
                            const Vector2D & Size1,
                            const Vector2D & Pos2,
                            const Vector2D & Size2)
{
    if ((Pos1.x < Pos2.x + Size2.x) &&
        (Pos1.y < Pos2.y + Size2.y) &&
        (Pos2.x < Pos1.x + Size1.x) &&
        (Pos2.y < Pos1.y + Size1.y))
    {
        return true;
    }
    return false;
}

Un exemple d'appel de fonction selon la figure ci-dessus:

DoRectanglesOverlap(Vector2D(3, 7),
                    Vector2D(8, 5),
                    Vector2D(6, 4),
                    Vector2D(9, 4));

Les comparaisons à l'intérieur du ifbloc ressembleront à ci-dessous:

if ((Pos1.x < Pos2.x + Size2.x) &&
    (Pos1.y < Pos2.y + Size2.y) &&
    (Pos2.x < Pos1.x + Size1.x) &&
    (Pos2.y < Pos1.y + Size1.y))
                   
if ((   3   <    6   +   9    ) &&
    (   7   <    4   +   4    ) &&
    (   6   <    3   +   8    ) &&
    (   4   <    7   +   5    ))

3

Voici comment cela se fait dans l'API Java:

public boolean intersects(Rectangle r) {
    int tw = this.width;
    int th = this.height;
    int rw = r.width;
    int rh = r.height;
    if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) {
        return false;
    }
    int tx = this.x;
    int ty = this.y;
    int rx = r.x;
    int ry = r.y;
    rw += rx;
    rh += ry;
    tw += tx;
    th += ty;
    //      overflow || intersect
    return ((rw < rx || rw > tx) &&
            (rh < ry || rh > ty) &&
            (tw < tx || tw > rx) &&
            (th < ty || th > ry));
}

Notez qu'en C ++, ces tests de débordement ne fonctionneront pas, car le débordement d'entier signé n'est pas défini.
Ben Voigt

2

Dans la question, vous établissez un lien avec les mathématiques lorsque les rectangles ont des angles de rotation arbitraires. Cependant, si je comprends un peu les angles de la question, j'interprète que tous les rectangles sont perpendiculaires les uns aux autres.

Un général connaissant la zone de formule de chevauchement est:

En utilisant l'exemple:

   1 2 3 4 5 6

1 + --- + --- +
   | |   
2 + A + --- + --- +
   | | B |
3 + + + --- + --- +
   | | | | |
4 + --- + --- + --- + --- + +
               | |
5 + C +
               | |
6 + --- + --- +

1) rassemblez toutes les coordonnées x (à gauche et à droite) dans une liste, puis triez-la et supprimez les doublons

1 3 4 5 6

2) rassemblez toutes les coordonnées y (en haut et en bas) dans une liste, puis triez-la et supprimez les doublons

1 2 3 4 6

3) créer un tableau 2D par nombre d'espaces entre les coordonnées x uniques * nombre d'espaces entre les coordonnées y uniques.

4 * 4

4) peignez tous les rectangles dans cette grille, en incrémentant le nombre de chaque cellule sur laquelle elle se produit:

   1 3 4 5 6

1 + --- +
   | 1 | 0 0 0
2 + --- + --- + --- +
   | 1 | 1 | 1 | 0
3 + --- + --- + --- + --- +
   | 1 | 1 | 2 | 1 |
4 + --- + --- + --- + --- +
     0 0 | 1 | 1 |
6 + --- + --- +

5) Lorsque vous peignez les rectangles, il est facile d'intercepter les chevauchements.


2
struct Rect
{
   Rect(int x1, int x2, int y1, int y2)
   : x1(x1), x2(x2), y1(y1), y2(y2)
   {
       assert(x1 < x2);
       assert(y1 < y2);
   }

   int x1, x2, y1, y2;
};

//some area of the r1 overlaps r2
bool overlap(const Rect &r1, const Rect &r2)
{
    return r1.x1 < r2.x2 && r2.x1 < r1.x2 &&
           r1.y1 < r2.y2 && r2.x1 < r1.y2;
}

//either the rectangles overlap or the edges touch
bool touch(const Rect &r1, const Rect &r2)
{
    return r1.x1 <= r2.x2 && r2.x1 <= r1.x2 &&
           r1.y1 <= r2.y2 && r2.x1 <= r1.y2;
}

1

Ne pensez pas aux coordonnées comme indiquant où se trouvent les pixels. Considérez-les comme étant entre les pixels. De cette façon, l'aire d'un rectangle 2x2 doit être 4, pas 9.

bool bOverlap = !((A.Left >= B.Right || B.Left >= A.Right)
               && (A.Bottom >= B.Top || B.Bottom >= A.Top));

1

Le moyen le plus simple est

/**
 * 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);
}

tout d'abord, pensez à ce que, dans les ordinateurs, le système de coordonnées est à l'envers. L'axe des x est le même qu'en mathématiques, mais l'axe des y augmente vers le bas et diminue en montant vers le haut. si les coordonnées x1 sont supérieures à x2 plus sa moitié de largeur. alors cela signifie qu'en allant la moitié, ils se toucheront. et de la même manière en descendant + la moitié de sa hauteur. ça va entrer en collision ..


1

Disons que les deux rectangles sont le rectangle A et le rectangle B. Que leurs centres soient A1 et B1 (les coordonnées de A1 et B1 peuvent être facilement découvertes), que les hauteurs soient Ha et Hb, la largeur soit Wa et Wb, que dx soit le largeur (x) distance entre A1 et B1 et dy soit la hauteur (y) distance entre A1 et B1.

Maintenant, nous pouvons dire que nous pouvons dire que A et B se chevauchent: quand

if(!(dx > Wa+Wb)||!(dy > Ha+Hb)) returns true

0

J'ai implémenté une version C #, elle est facilement convertie en C ++.

public bool Intersects ( Rectangle rect )
{
  float ulx = Math.Max ( x, rect.x );
  float uly = Math.Max ( y, rect.y );
  float lrx = Math.Min ( x + width, rect.x + rect.width );
  float lry = Math.Min ( y + height, rect.y + rect.height );

  return ulx <= lrx && uly <= lry;
}

2
Pour l'œil averti, il est clair que vous vouliez que ce soit une classe d'extension pour Rectangle, mais vous n'avez fourni aucune limite ou code pour le faire. Ce serait bien si vous aviez fait cela ou expliqué que c'était ainsi que votre méthode devait être utilisée, et des points bonus si vos variables avaient en fait suffisamment de noms descriptifs pour que quiconque suivant puisse comprendre leur objectif / intention.
tpartee

0

J'ai une solution très simple

soit x1, y1 x2, y2, l1, b1, l2, soient respectivement leurs coordonnées et leurs longueurs et largeurs

considérer la condition ((x2

maintenant, la seule façon dont ces rectangles se chevauchent est si la diagonale du point à x1, y1 se trouve à l'intérieur de l'autre rectangle ou de la même manière la diagonale du point à x2, y2 se trouve à l'intérieur de l'autre rectangle. ce qui est exactement la condition ci-dessus implique.


0

A et B sont deux rectangles. C soit leur rectangle de couverture.

four points of A be (xAleft,yAtop),(xAleft,yAbottom),(xAright,yAtop),(xAright,yAbottom)
four points of A be (xBleft,yBtop),(xBleft,yBbottom),(xBright,yBtop),(xBright,yBbottom)

A.width = abs(xAleft-xAright);
A.height = abs(yAleft-yAright);
B.width = abs(xBleft-xBright);
B.height = abs(yBleft-yBright);

C.width = max(xAleft,xAright,xBleft,xBright)-min(xAleft,xAright,xBleft,xBright);
C.height = max(yAtop,yAbottom,yBtop,yBbottom)-min(yAtop,yAbottom,yBtop,yBbottom);

A and B does not overlap if
(C.width >= A.width + B.width )
OR
(C.height >= A.height + B.height) 

Il prend en charge tous les cas possibles.


0

Il s'agit de l'exercice 3.28 du livre Introduction to Java Programming- Comprehensive Edition. Le code teste si les deux rectangles sont indenticulaires, si l'un est à l'intérieur de l'autre et si l'un est à l'extérieur de l'autre. Si aucune de ces conditions n'est remplie, les deux se chevauchent.

** 3.28 (Géométrie: deux rectangles) Écrivez un programme qui invite l'utilisateur à entrer les coordonnées centrales x, y, la largeur et la hauteur de deux rectangles et détermine si le deuxième rectangle se trouve à l'intérieur du premier ou chevauche le premier, comme le montre la figure 3.9. Testez votre programme pour couvrir tous les cas. Voici les exemples d'exécutions:

Entrez les coordonnées x, y, centre et largeur de r1: 2,5 4 2,5 43 Entrez les coordonnées x, y, centre et largeur de r2: 1,5 5 0,5 3 r2 est à l'intérieur de r1

Entrez les coordonnées x, y, largeur et hauteur du centre de r1: 1 2 3 5.5 Saisissez les coordonnées x, y, largeur et hauteur du centre de r2: 3 4 4.5 5 r2 chevauche r1

Entrez les coordonnées x, y, largeur et hauteur du centre de r1: 1 2 3 3 Entrez les coordonnées x, y, largeur et hauteur du centre de r2: 40 45 3 2 r2 ne chevauche pas r1

import java.util.Scanner;

public class ProgrammingEx3_28 {
public static void main(String[] args) {
    Scanner input = new Scanner(System.in);

    System.out
            .print("Enter r1's center x-, y-coordinates, width, and height:");
    double x1 = input.nextDouble();
    double y1 = input.nextDouble();
    double w1 = input.nextDouble();
    double h1 = input.nextDouble();
    w1 = w1 / 2;
    h1 = h1 / 2;
    System.out
            .print("Enter r2's center x-, y-coordinates, width, and height:");
    double x2 = input.nextDouble();
    double y2 = input.nextDouble();
    double w2 = input.nextDouble();
    double h2 = input.nextDouble();
    w2 = w2 / 2;
    h2 = h2 / 2;

    // Calculating range of r1 and r2
    double x1max = x1 + w1;
    double y1max = y1 + h1;
    double x1min = x1 - w1;
    double y1min = y1 - h1;
    double x2max = x2 + w2;
    double y2max = y2 + h2;
    double x2min = x2 - w2;
    double y2min = y2 - h2;

    if (x1max == x2max && x1min == x2min && y1max == y2max
            && y1min == y2min) {
        // Check if the two are identicle
        System.out.print("r1 and r2 are indentical");

    } else if (x1max <= x2max && x1min >= x2min && y1max <= y2max
            && y1min >= y2min) {
        // Check if r1 is in r2
        System.out.print("r1 is inside r2");
    } else if (x2max <= x1max && x2min >= x1min && y2max <= y1max
            && y2min >= y1min) {
        // Check if r2 is in r1
        System.out.print("r2 is inside r1");
    } else if (x1max < x2min || x1min > x2max || y1max < y2min
            || y2min > y1max) {
        // Check if the two overlap
        System.out.print("r2 does not overlaps r1");
    } else {
        System.out.print("r2 overlaps r1");
    }

}
}

0
bool Square::IsOverlappig(Square &other)
{
    bool result1 = other.x >= x && other.y >= y && other.x <= (x + width) && other.y <= (y + height); // other's top left falls within this area
    bool result2 = other.x >= x && other.y <= y && other.x <= (x + width) && (other.y + other.height) <= (y + height); // other's bottom left falls within this area
    bool result3 = other.x <= x && other.y >= y && (other.x + other.width) <= (x + width) && other.y <= (y + height); // other's top right falls within this area
    bool result4 = other.x <= x && other.y <= y && (other.x + other.width) >= x && (other.y + other.height) >= y; // other's bottom right falls within this area
    return result1 | result2 | result3 | result4;
}

0

Pour ceux d'entre vous qui utilisent des points centraux et des demi-tailles pour leurs données rectangulaires, au lieu des x, y, w, h ou x0, y0, x1, x1 typiques, voici comment vous pouvez le faire:

#include <cmath> // for fabsf(float)

struct Rectangle
{
    float centerX, centerY, halfWidth, halfHeight;
};

bool isRectangleOverlapping(const Rectangle &a, const Rectangle &b)
{
    return (fabsf(a.centerX - b.centerX) <= (a.halfWidth + b.halfWidth)) &&
           (fabsf(a.centerY - b.centerY) <= (a.halfHeight + b.halfHeight)); 
}

0
struct point { int x, y; };

struct rect { point tl, br; }; // top left and bottom right points

// return true if rectangles overlap
bool overlap(const rect &a, const rect &b)
{
    return a.tl.x <= b.br.x && a.br.x >= b.tl.x && 
           a.tl.y >= b.br.y && a.br.y <= b.tl.y;
}

0

Si les rectangles se chevauchent, la zone de chevauchement sera supérieure à zéro. Maintenant, trouvons la zone de chevauchement:

S'ils se chevauchent, le bord gauche du chevauchement rect sera le max(r1.x1, r2.x1)bord droit et le sera min(r1.x2, r2.x2). Ainsi, la longueur du chevauchement seramin(r1.x2, r2.x2) - max(r1.x1, r2.x1)

La zone sera donc:

area = (max(r1.x1, r2.x1) - min(r1.x2, r2.x2)) * (max(r1.y1, r2.y1) - min(r1.y2, r2.y2))

Si area = 0alors ils ne se chevauchent pas.

C'est simple non?


3
Cela fonctionne pour le chevauchement (ce qui est la question) mais ne fonctionnera pas pour l'intersection, car cela ne fonctionnera pas s'ils se croisent exactement à un coin.
Lance Roberts

J'ai essayé ce code et cela ne fonctionne pas du tout. Je reçois juste des chiffres positifs même s'ils ne se chevauchent pas du tout.
Brett

@Brett: Oui, car le produit de deux nombres négatifs est positif.
Ben Voigt

@BenVoigt, le problème était que la fonction ne retournait pas 0 lorsqu'il n'y avait pas de chevauchement. Je n'étais pas très clair avec mon commentaire, mais oui, je n'ai reçu que la zone> 0 de cette fonction.
Brett

Si vous travaillez avec des nombres à virgule flottante, c'est généralement une très mauvaise idée d'utiliser des soustractions et d'autres éléments arithmétiques avant toute comparaison de nombres. Surtout si vous devez comparer avec une valeur exacte - dans ce cas, zéro. Cela fonctionne en théorie, mais pas en pratique.
maja


-1

Code Java pour déterminer si les rectangles se contactent ou se chevauchent

...

for ( int i = 0; i < n; i++ ) {
    for ( int j = 0; j < n; j++ ) {
        if ( i != j ) {
            Rectangle rectangle1 = rectangles.get(i);
            Rectangle rectangle2 = rectangles.get(j);

            int l1 = rectangle1.l; //left
            int r1 = rectangle1.r; //right
            int b1 = rectangle1.b; //bottom
            int t1 = rectangle1.t; //top

            int l2 = rectangle2.l;
            int r2 = rectangle2.r;
            int b2 = rectangle2.b;
            int t2 = rectangle2.t;

            boolean topOnBottom = t2 == b1;
            boolean bottomOnTop = b2 == t1;
            boolean topOrBottomContact = topOnBottom || bottomOnTop;

            boolean rightOnLeft = r2 == l1;
            boolean leftOnRight = l2 == r1;
            boolean rightOrLeftContact = leftOnRight || rightOnLeft;

            boolean leftPoll = l2 <= l1 && r2 >= l1;
            boolean rightPoll = l2 <= r1 && r2 >= r1;
            boolean leftRightInside = l2 >= l1 && r2 <= r1;
            boolean leftRightPossiblePlaces = leftPoll || rightPoll || leftRightInside;

            boolean bottomPoll = t2 >= b1 && b2 <= b1;
            boolean topPoll = b2 <= b1 && t2 >= b1;
            boolean topBottomInside = b2 >= b1 && t2 <= t1;
            boolean topBottomPossiblePlaces = bottomPoll || topPoll || topBottomInside;


            boolean topInBetween = t2 > b1 && t2 < t1;
            boolean bottomInBetween = b2 > b1 && b2 < t1;
            boolean topBottomInBetween = topInBetween || bottomInBetween;

            boolean leftInBetween = l2 > l1 && l2 < r1;
            boolean rightInBetween = r2 > l1 && r2 < r1;
            boolean leftRightInBetween = leftInBetween || rightInBetween;

            if ( (topOrBottomContact && leftRightPossiblePlaces) || (rightOrLeftContact && topBottomPossiblePlaces) ) {
                path[i][j] = true;
            }
        }
    }
}

...

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.