İki dikdörtgenin birbiriyle çakışıp çakışmadığını belirleyin


337

Yükseklik, genişlik, x-pos, y-pos: Dikdörtgenler (2 ve 5 arasında) oluşturmak için kullanıcıdan aşağıdaki girişleri alan bir C ++ programı yazmaya çalışıyorum. Bu dikdörtgenlerin tümü x ve y eksenine paralel olarak var olacak, yani tüm kenarları 0 veya sonsuz eğimlere sahip olacak.

Bu soruda belirtilenleri uygulamaya çalıştım ama çok şansım yok.

Mevcut uygulamam şunları yapıyor:

// 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;  

Ancak (a) Bağlandığım algoritmayı doğru bir şekilde uyguladığımdan mı yoksa tam olarak nasıl yorumladığımdan emin değilim?

Herhangi bir öneri?


3
senin sorunun çözümü herhangi bir çarpma içermez düşünürdüm .
Scott Evernden

Yanıtlar:


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

veya Kartezyen koordinatlar kullanarak

(X1 sol koordinat, X2 sağ koordinat, soldan sağa ve Y1 Üst koordinat ve Y2 Alt koordinat olacak şekilde , aşağıdan yukarıya doğru artar . Koordinat sisteminiz böyle değilse [örneğin çoğu bilgisayar Y yönü ters çevrilmiş], aşağıdaki karşılaştırmaları değiştirin ) ...

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

Diyelim ki Rect A ve Rect B'ye sahipsiniz. İspat çelişkilidir. Dört koşuldan herhangi biri, çakışma olmayacağını garanti eder :

  • Koşul1. A'nın sol kenarı B'nin sağ kenarının sağındaysa, - A, Tamamen B'nin sağındadır
  • Cond2. A'nın sağ kenarı B'nin sol kenarının solundaysa, - A, Tamamen B'nin soludur
  • Cond3. A'nın üst kenarı B'nin alt kenarının altındaysa, - o zaman A Tamamen B'nin altındadır
  • Cond4. A'nın alt kenarı B'nin üst kenarının üzerindeyse - - A, Tamamen B'nin üzerindedir

Çakışmayan durum

Çakışmayan => Cond1 veya Cond2 veya Cond3 veya Cond4

Bu nedenle, Çakışma için yeterli bir koşul tersidir.

Çakışma => DEĞİL (Cond1 veya Cond2 veya Cond3 veya Cond4)

De Morgan'ın yasası, De Morgan'ı kullanmakla
Not (A or B or C or D)aynı şey diyorNot A And Not B And Not C And Not D

Cond1 değil Cond2 değil Cond3 değil Cond4 değil

Bu şuna eşittir:

  • A'nın Sol Kenarı B'nin sağ kenarının solunda, [ RectA.Left < RectB.Right] ve
  • A'nın sağ kenarı B'nin sol kenarının sağından [ RectA.Right > RectB.Left] ve
  • A'nın B'nin altından üstü, [ RectA.Top > RectB.Bottom] ve
  • A'nın alt kısmı B'nin Üstü [ RectA.Bottom < RectB.Top]

Not 1 : Bu aynı ilkenin herhangi bir sayıda boyuta genişletilebileceği açıktır.
Not 2 : Yalnızca bir pikselin çakışmalarını saymak, <ve / veya >bu sınırdaki açıklığı a <=veya a olarak değiştirmek de oldukça açık olmalıdır >=.
Not 3 : Bu cevap, Kartezyen koordinatları (X, Y) kullanırken standart cebirsel Kartezyen koordinatlarına dayanır (x soldan sağa ve Y aşağıdan yukarıya artar). Bir bilgisayar sisteminin ekran koordinatlarını farklı şekilde mekanize edebileceği açıksa (örneğin, Y'yi yukarıdan aşağıya veya X'i sağdan sola doğru) sözdiziminin buna göre ayarlanması gerekecektir /


489
Neden çalıştığını görselleştirmekte zorlanıyorsanız , silentmatt.com/intersection.html adresinde dikdörtgenleri sürükleyip karşılaştırmaları görebileceğiniz bir örnek sayfa hazırladım .
Matthew Crumley

4
zor kısıtlamaları kullandığını düşünmüyor musun? iki dikdörtgen tam olarak o kenarda üst üste gelirse ne olur? <=,> = ??
Nawshad Farruque

6
@Y1 <B.Y2 ve A.Y2> B.Y1 için @MatthewCrumley, bağlantınızdaki gt & lt işaretleri tersine çevrilmemeli mi?
NikT

15
Çalışması için son iki karşılaştırmada <ve> takas etmek zorunda kaldım
DataGreed

17
Hayır, cevap belirtildiği gibi doğrudur. Standart Kartezyen koordinatların kullanımına dayanır. Farklı bir sistem kullanıyorsanız (Y yukarıdan aşağı doğru artar), uygun ayarlamaları yapın.
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
En basit ve en temiz cevap.
ldog

1
@ e.James Sanırım son B.heightolmalıA.height
mat_boy

'min' ve 'max' <windows.h> içindeki ayrılmış anahtar kelimelerdir. Eğer yaparak düzeltebilirsiniz #undef minve #undef maxya farklı parametre adları kullanılarak.
mchiasson

Eğer yoğun olarak kullanırsanız, bir değer için ticaret yapabilirsiniz#define BETWEEN(value,min,max) \ (\ value > max ? max : ( value < min ? min : value )\ )
Ratata Tata

@Nemo Aslında, kontrol xOverlaptek boyutludur; rectOverlapiki boyutludur. Bir döngü kullanılarak N boyutuna kadar genişletilebilir.
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;
}

Güzel bir! De Morgans yasasını uygulayarak şunları elde edin: r1.x1 <= r2.x2 && r2.x1 <= r1.x2 && r1.y1 <= r2.y2 && r2.y1 <= r1.y2.
Borzh

23

Bir dikdörtgenin tamamen diğerinin dışında olup olmadığını kontrol etmek daha kolaydır, bu yüzden ya

soldaki...

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

veya sağda ...

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

veya üstünde ...

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

veya altta ...

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

ikinci dikdörtgenin, muhtemelen onunla çarpışamaz. Bu nedenle, dikdörtgenlerin çarpıştığı bir Boole ifadesini döndüren bir işleve sahip olmak için, koşulları mantıklı OR'ler ile birleştirir ve sonucu reddederiz:

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

Yalnızca dokunurken zaten olumlu bir sonuç almak için "<" ve ">" öğelerini "<=" ve "> =" ile değiştirebiliriz.


3
Ve de de morgan yasasını uygulayın.
Borzh

6

Kendinize zıt soruyu sorun: İki dikdörtgenin hiç kesişmediğini nasıl belirleyebilirim? Açıkçası, dikdörtgen B'nin tamamen solundaki bir dikdörtgen A kesişmiyor. Ayrıca A tamamen sağda ise. Ve benzer şekilde A tamamen B'nin üzerinde veya B'nin tamamen altındaysa. Başka bir durumda A ve B kesişir.

Aşağıdaki hatalar olabilir, ama algoritma hakkında oldukça eminim:

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

Dikdörtgenlerin konumlarını ve boyutlarını şu şekilde tanımladığınızı varsayalım:

resim açıklamasını buraya girin

Benim C ++ uygulaması şöyle:

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

Yukarıdaki şekle göre bir örnek fonksiyon çağrısı:

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

ifBlok içindeki karşılaştırmalar aşağıdaki gibi görünecektir:

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

Java API'sında şu şekilde yapılır:

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

İmzalı tamsayı taşması tanımlanmadığından, C ++ 'da taşma testlerinin çalışmadığını unutmayın.
Ben Voigt

2

Soruda, dikdörtgenlerin gelişigüzel dönüş açılarında olduğu zaman matematiğe bağlanırsınız. Ancak sorudaki açılarla ilgili biraz anlıyorsam, tüm dikdörtgenlerin birbirine dik olduğunu yorumluyorum.

Çakışma formülü alanını bilen bir genel:

Örneği kullanarak:

   1 2 3 4 5 6

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

1) tüm x koordinatlarını (hem sol hem de sağ) bir liste halinde toplayın, ardından sıralayın ve kopyaları kaldırın

1 3 4 5 6

2) tüm y koordinatlarını (hem üst hem de alt) bir liste halinde toplayın, sonra sıralayın ve kopyaları kaldırın

1 2 3 4 6

3) benzersiz x koordinatları arasındaki boşluk sayısına göre bir 2D dizi oluşturun * benzersiz y koordinatları arasındaki boşluk sayısı.

4 * 4

4) tüm dikdörtgenleri bu ızgaraya boyayın, üzerinde gerçekleşen her hücrenin sayısını arttırın:

   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) Dikdörtgenleri boyadığınızda, örtüşmeleri yakalamak kolaydır.


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

Koordinatları piksellerin nerede olduğunu gösteren olarak düşünmeyin. Bunları pikseller arasında olduğunu düşünün. Bu şekilde, 2x2'lik bir dikdörtgenin alanı 9 değil 4 olmalıdır.

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

1

En kolay yol

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

her şeyden önce, bilgisayarlarda koordinat sisteminin baş aşağı olduğunu aklınıza getirin. x ekseni matematiktekiyle aynıdır, ancak y ekseni aşağı doğru artar ve yukarı doğru gittikçe azalır. Dikdörtgen merkezden çizilirse. x1 koordinatları x2'den büyükse artı genişliğinin yarısı. o zaman yarısı gitmek birbirlerine değecek demektir. ve aynı şekilde boyunun + yarısının altına iniyor. çarpışacak ..


1

İki dikdörtgenin dikdörtgen A ve dikdörtgen B olduğunu söyleyelim. Merkezleri A1 ve B1 olsun (A1 ve B1 koordinatları kolayca bulunabilir), yüksekliklerin Ha ve Hb olmasına izin verin, genişlik Wa ve Wb olsun, dx A1 ve B1 arasındaki genişlik (x) mesafesi ve dy, A1 ve B1 arasındaki yükseklik (y) mesafesi olmalıdır.

Şimdi A ve B'nin çakıştığını söyleyebiliriz: ne zaman

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

0

Bir C # sürümü uyguladım, kolayca C ++ dönüştürülür.

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
Eğitimli göz için bunun Dikdörtgen için bir uzantı sınıfı olması gerektiği açıktı, ancak bunu yapmak için herhangi bir sınırlama veya kod sağlamadınız. Bunu yapsaydınız ya da yönteminizin nasıl kullanıldığını açıklarsanız iyi olur ve değişkenleriniz aslında takip eden herkesin amaçlarını / niyetlerini anlamaları için yeterince açıklayıcı isimlere sahipse bonus puanları olur.
tpartee

0

Çok kolay bir çözümüm var

x1, y1 x2, y2, l1, b1, l2, sırasıyla kordinatlar ve uzunlukları ve genişlikleri olsun

koşulu düşün ((x2

şimdi bu dikdörtgenin üst üste binmesinin tek yolu, x1'e çapraz nokta, y1 diğer dikdörtgenin içinde ya da benzer şekilde x2'ye çapraz nokta, y2 diğer dikdörtgenin içinde yatar. ki bu yukarıdaki koşulun ima ettiği anlamına gelir.


0

A ve B iki dikdörtgendir. C onların dikdörtgeni olabilir.

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) 

Olası tüm vakaları halleder.


0

Bu, Java Programlama - Kapsamlı Sürüme Giriş kitabının 3.28. Kod, iki dikdörtgenin girintili olup olmadığını, birinin diğerinin içinde olup olmadığını ve birinin diğerinin dışında olup olmadığını test eder. Bu koşulların hiçbiri karşılanmazsa, bu ikisi birbiriyle çakışır.

** 3.28 (Geometri: iki dikdörtgen) Kullanıcıdan iki dikdörtgenin merkezini x-, y-koordinatlarını, genişliğini ve yüksekliğini girmesini isteyen ve ikinci dikdörtgenin ilk içinde mi yoksa birinci dikdörtgenle mi çakıştığını belirleyen bir program yazın, Şekil 3.9'da gösterildiği gibi. Programınızı tüm durumları kapsayacak şekilde test edin. İşte örnek çalışmalar:

R1'in merkez x-, y-koordinatlarını, genişliğini ve yüksekliğini girin: 2.5 4 2.5 43 r2'nin merkez x-, y-koordinatlarını, genişliğini ve yüksekliğini girin: 1.5 5 0.5 3 r2 r1'in içinde

R1'in orta x-, y-koordinatlarını, genişliğini ve yüksekliğini girin: 1 2 3 5.5 r2'nin orta x-, y-koordinatlarını, genişliğini ve yüksekliğini girin: 3 4 4.5 5 r2 r1 ile çakışıyor

R1'in orta x-, y-koordinatlarını, genişliğini ve yüksekliğini girin: 1 2 3 3 r2'nin orta x-, y-koordinatlarını, genişliğini ve yüksekliğini girin: 40 45 3 2 r2 r1 ile çakışmaz

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

Dikdörtgen verileri için x, y, w, h veya x0, y0, x1, x1 yerine dikdörtgen noktaları için merkez noktaları ve yarım boyutlar kullananlarınız için bunu nasıl yapabilirsiniz:

#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

Dikdörtgenler üst üste biniyorsa, üst üste binme alanı sıfırdan büyük olacaktır. Şimdi örtüşme alanını bulalım:

Eğer üst üste biniyorlarsa, üst üste binme-rektinin sol kenarı max(r1.x1, r2.x1)ve sağ kenarı olacaktır min(r1.x2, r2.x2). Böylece örtüşmenin uzunluğumin(r1.x2, r2.x2) - max(r1.x1, r2.x1)

Böylece alan şöyle olacaktır:

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

Eğer area = 0öyleyse örtüşmezler.

Basit değil mi?


3
Bu üst üste binme için çalışır (soru budur), ancak bir köşede tam olarak kesiştiği takdirde işe yaramayacağı için kavşak için çalışmaz.
Lance Roberts

Bu kodu denedim ve hiç çalışmıyor. Hiç çakışmasalar bile pozitif sayılar alıyorum.
Brett

@Brett: Evet, çünkü iki negatif sayının çarpımı olumlu.
Ben Voigt

@BenVoigt, sorun, çakışma olmadığında işlevin 0 döndürmediğiydi. Yorumumdan çok emin değildim, ama evet, sadece bu fonksiyondan alan> 0 aldım.
Brett

Kayan nokta sayılarıyla çalışıyorsanız, herhangi bir sayı karşılaştırmasından önce çıkarma ve diğer aritmetik şeyleri kullanmak genellikle çok kötü bir fikirdir. Özellikle tam bir değerle karşılaştırmanız gerekiyorsa - bu durumda sıfır. Teoride çalışır, ancak pratikte değildir.
maja


-1

Dikdörtgenlerin birbiriyle temas edip etmediğini veya üst üste bindiğini anlamak için Java kodu

...

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

...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.