निर्धारित करें कि क्या दो आयत एक दूसरे को ओवरलैप करते हैं?


337

मैं एक C ++ प्रोग्राम लिखने की कोशिश कर रहा हूं जो उपयोगकर्ता से आयतों (2 और 5 के बीच) के निर्माण के लिए निम्नलिखित इनपुट लेता है: ऊंचाई, चौड़ाई, एक्स-पॉज़, वाई-पॉज़। ये सभी आयतें x और y अक्ष के समानांतर मौजूद होंगी, उनके सभी किनारों में 0 या अनंत की ढलानें होंगी।

मैंने इस प्रश्न में जो उल्लेख किया है, उसे लागू करने की कोशिश की है, लेकिन मुझे बहुत ज्यादा भाग्य नहीं मिल रहा है।

मेरा वर्तमान कार्यान्वयन निम्न कार्य करता है:

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

हालाँकि, मुझे यकीन नहीं है कि (ए) मैंने जिस एल्गोरिथ्म को सही ढंग से जोड़ा है, उस पर अमल किया है, या अगर मैंने इसकी व्याख्या कैसे की है?

कोई सुझाव?


3
मुझे लगता है कि आपकी समस्या के समाधान में कोई गुणा शामिल नहीं है।
स्कॉट एवेरेन्डेन

जवाबों:


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

या, कार्टेशियन निर्देशांक का उपयोग कर

(एक्स 1 के बाएं कोऑर्डिनेशन होने के साथ, एक्स 2 के राइट कॉर्ड होने के कारण, बाएं से दाएं और वाई 1 से टॉप कोऑर्डिनेशन, और वाई 2 के बॉटम कोऑर्डिनेट होने के कारण, नीचे से ऊपर तक बढ़ते हुए - अगर ऐसा नहीं है तो आपका कोऑर्डिनेट सिस्टम [जैसे ज्यादातर कंप्यूटरों में है। Y दिशा उलट], नीचे तुलना स्वैप करें ) ...

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

कहते हैं कि आपके पास रेक्ट ए है, और रेक्ट बी प्रूफ विरोधाभास है। कोई भी चार शर्तों की गारंटी देता है कि कोई भी ओवरलैप मौजूद नहीं हो सकता है :

  • Cond1। यदि A का बायाँ किनारा B के दाएं किनारे के दाईं ओर है, तो A, B के दाईं ओर है
  • Cond2। यदि A का दायाँ छोर B के बायें किनारे के बायीं ओर है, तो A, B के बायें ओर है
  • Cond3। यदि A का शीर्ष किनारा B के निचले किनारे से नीचे है, तो A, B के नीचे पूरी तरह से है
  • Cond4। यदि A का निचला किनारा B के शीर्ष किनारे से ऊपर है, तो A, B के शीर्ष पर है

तो नॉन-ओवरलैप के लिए शर्त है

NON-Overlap => Cond1 या Cond2 या Cond3 या Cond4

इसलिए, ओवरलैप के लिए एक पर्याप्त स्थिति विपरीत है।

ओवरलैप => नहीं (Cond1 या Cond2 या Cond3 या Cond4)

डी मॉर्गन का नियम कहता
Not (A or B or C or D)है कि Not A And Not B And Not C And Not D
डी मॉर्गन का उपयोग करना हमारे लिए समान है

Cond1 और Cond2 नहीं और Cond3 नहीं और Cond4 नहीं

यह इसके बराबर है:

  • B के दाएं किनारे के बाईं ओर A का बायाँ छोर, [ RectA.Left < RectB.Right], और
  • बी के बाएं किनारे के दाईं ओर एक दाहिने किनारे, [ RectA.Right > RectB.Left], और
  • A का शीर्ष B के तल से ऊपर है, [ RectA.Top > RectB.Bottom], और
  • B के शीर्ष के नीचे एक तल [ RectA.Bottom < RectB.Top]

नोट 1 : यह स्पष्ट है कि इसी सिद्धांत को किसी भी संख्या में आयामों तक बढ़ाया जा सकता है।
नोट 2 : यह सिर्फ एक पिक्सेल के ओवरलैप को गिनने के लिए, <और / या >उस सीमा पर एक <=या एक के ओवरलैप को गिनने के लिए काफी स्पष्ट होना चाहिए >=
नोट 3 : यह उत्तर, जब कार्टेशियन निर्देशांक (एक्स, वाई) का उपयोग मानक बीजीय कार्टेसियन निर्देशांक पर आधारित है (एक्स दाएं से बाएं बढ़ता है, और वाई नीचे से ऊपर बढ़ता है)। जाहिर है, जहां एक कंप्यूटर सिस्टम स्क्रीन को अलग तरह से समन्वित कर सकता है, (जैसे, ऊपर से नीचे की ओर Y बढ़ाना, या X बाएं से दाएं), वाक्यविन्यास को तदनुसार समायोजित करना होगा /


489
यदि आपको यह देखने में कठिनाई हो रही है कि यह क्यों काम कर रहा है, तो मैंने silmatt.com/intersection.html पर एक उदाहरण पृष्ठ बनाया, जहाँ आप आयतों को चारों ओर खींच सकते हैं और तुलनाएँ देख सकते हैं।
मैथ्यू क्रुमले

4
क्या आपको नहीं लगता कि आप कठिन बाधाओं का उपयोग कर रहे हैं? क्या होगा अगर दोनों आयतें एक दूसरे को बिल्कुल किनारे पर ओवरलैप करती हैं? क्या आपको <=,> = पर विचार नहीं करना चाहिए?
नवांश फर्रुके

6
आपके लिंक पर A.Y1 <B.Y2 और A.Y2> B.Y1 के लिए @MatthewCrumley, क्या gt & lt के संकेत उलटे नहीं होने चाहिए?
निकोट

15
मुझे यह काम करने के लिए <और> अंतिम दो तुलनाओं में स्वैप करना पड़ा
डेटाग्रेड

17
नहीं, उत्तर सही है जैसा कि कहा गया है। यह मानक कार्टेशियन निर्देशांक के उपयोग पर आधारित है। यदि आप एक अलग प्रणाली का उपयोग कर रहे हैं, (वाई ऊपर से नीचे की ओर बढ़ रहा है), तो उचित समायोजन करें।
चार्ल्स ब्रेटाना

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
सबसे सरल और साफ जवाब।
ldog

1
@ e.James मुझे लगता है आखिरी B.heightहोना चाहिएA.height
mat_boy

<windows.h> में 'min' और 'max' आरक्षित कीवर्ड हैं। आप इसे कर सकते हैं #undef minऔर #undef maxविभिन्न पैरामीटर नामों का उपयोग करके इसे ठीक कर सकते हैं ।
मोचीसन

यदि आप बड़े पैमाने पर उपयोग करते हैं, तो आप एक मूल्य के लिए इनरेंज व्यापार कर सकते हैं#define BETWEEN(value,min,max) \ (\ value > max ? max : ( value < min ? min : value )\ )
टाटा टाटा

@ नीमो दरअसल, चेकिंग xOverlapएक आयाम में है; rectOverlapदो आयाम है। यह लूप का उपयोग करके एन आयामों तक बढ़ाया जा सकता है।
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;
}

अच्छा है! डी मॉर्गन्स कानून लागू करना: r1.x1 <= r2.x2 && r2.x1 <= r1.x2 && r1.y1 <= r2.y2 && r2.y1 = # r1.y2।
बोरझ

23

यह जांचना आसान है कि क्या एक आयत पूरी तरह से दूसरे के बाहर है, इसलिए यदि यह या तो है

बाईं तरफ...

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

या दाईं ओर ...

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

या शीर्ष पर ...

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

या तल पर ...

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

दूसरी आयत के, यह संभवतः इसके साथ नहीं टकरा सकता है। तो एक ऐसा समारोह होना चाहिए जो एक बूलियन कहता है कि मौसम आयतों से टकराता है, हम बस तार्किक ओआरएस द्वारा शर्तों को जोड़ते हैं और परिणाम को नकारते हैं:

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

केवल छूने पर पहले से ही एक सकारात्मक परिणाम प्राप्त करने के लिए, हम "<" और ">" को "<=" और "> =" द्वारा बदल सकते हैं।


3
और उस पर डी मॉर्गन का नियम लागू करें।
बोरझ

6

अपने आप से विपरीत सवाल पूछें: अगर दो आयतें बिल्कुल नहीं काटती हैं तो मैं कैसे निर्धारित कर सकता हूं? जाहिर है, आयत B के बाईं ओर एक आयत A पूरी तरह से प्रतिच्छेद नहीं करता है। इसके अलावा अगर A पूरी तरह से दाईं ओर है। और इसी तरह यदि A पूरी तरह से B से ऊपर है या B से पूरी तरह से नीचे है। किसी अन्य मामले में A और B प्रतिच्छेद है।

इस प्रकार के कीड़े हो सकते हैं, लेकिन मैं एल्गोरिथ्म के बारे में बहुत आश्वस्त हूं:

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

मान लीजिए कि आपने आयतों के पदों और आकारों को इस तरह परिभाषित किया है:

यहां छवि विवरण दर्ज करें

मेरा C ++ कार्यान्वयन इस प्रकार है:

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

ऊपर दिए गए आंकड़े के अनुसार एक उदाहरण फ़ंक्शन कॉल:

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

ifब्लॉक के अंदर की तुलना नीचे की तरह दिखाई देगी:

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

यहाँ जावा एपीआई में यह कैसे किया गया है:

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

ध्यान दें कि C ++ में अतिप्रवाह के लिए वे परीक्षण काम नहीं करेंगे, क्योंकि हस्ताक्षरित पूर्णांक अतिप्रवाह अपरिभाषित है।
बेन वोयगेट

2

प्रश्न में, आप गणित के लिए लिंक करते हैं जब आयताकार रोटेशन के मनमाने कोण पर होते हैं। यदि मैं प्रश्न में कोणों के बारे में थोड़ा समझता हूं, तो मैं व्याख्या करता हूं कि सभी आयतें एक-दूसरे के लंबवत हैं।

ओवरलैप फॉर्मूले के क्षेत्र को जानने वाला एक सामान्य शब्द है:

उदाहरण का उपयोग करना:

   1 2 3 4 5 6

1 + --- + --- +
   | |   
2 + ए + --- + --- +
   | | B |
3 + + + --- + --- +
   | | | | |
4 + --- + --- + --- + --- + +
               | |
5 + सी +
               | |
6 + --- + --- +

1) एक सूची में सभी एक्स निर्देशांक (बाएं और दाएं दोनों) इकट्ठा करें, फिर इसे सॉर्ट करें और डुप्लिकेट हटा दें

१ ३ ४ ५ ६

2) सभी y निर्देशांक (ऊपर और नीचे दोनों) को एक सूची में इकट्ठा करें, फिर इसे सॉर्ट करें और डुप्लिकेट को हटा दें

1 2 3 4 6

3) अद्वितीय x निर्देशांक के बीच अद्वितीय x निर्देशांक * अंतराल के बीच अंतराल की संख्या से एक 2 डी सरणी बनाएं।

४ * ४

4) इस ग्रिड में सभी आयतों को पेंट करें, प्रत्येक कोशिका की गिनती को बढ़ाते हुए।

   १ ३ ४ ५ ६

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

5) जैसा कि आप आयतों को रंगते हैं, इसके ओवरलैप को रोकना आसान है।


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

निर्देशांक के बारे में मत सोचो कि पिक्सल कहाँ हैं। पिक्सल के बीच होने के नाते उन्हें सोचें। इस तरह, एक 2x2 आयत का क्षेत्रफल 4 होना चाहिए, 9 नहीं।

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

1

सबसे आसान तरीका है

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

सबसे पहले इसे अपने दिमाग में रखें कि कंप्यूटर में निर्देशांक प्रणाली उल्टा है। x- अक्ष गणित में समान है लेकिन y- अक्ष नीचे की ओर बढ़ता है और ऊपर की ओर घटता है .. यदि आयत केंद्र से खींची जाती है। अगर X1 निर्देशांक x2 से अधिक है, तो इसके आधे विधुत के बराबर है। तो इसका मतलब है कि आधे जाने पर वे एक-दूसरे को छू लेंगे। और उसी तरह से नीचे की ओर + उसकी ऊँचाई का आधा भाग। टकराएगा ।।


1

आइए बताते हैं कि दो आयतें आयत A और आयत B हैं। उनके केंद्रों को A1 और B1 होने दें (A1 और B1 के निर्देशांक आसानी से पाए जा सकते हैं), ऊंचाइयों को हा और Hb, चौड़ाई को Wa और Wb होने दें, dx को दें। A1 और B1 के बीच की चौड़ाई (x) की दूरी और A1 और B1 के बीच की ऊँचाई (y) की दूरी होनी चाहिए।

अब हम कह सकते हैं कि हम ए और बी ओवरलैप कह सकते हैं: कब

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

0

मैंने C # संस्करण लागू किया है, यह आसानी से 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
प्रशिक्षित आंख के लिए यह स्पष्ट है कि आप इसका मतलब आयत के लिए एक विस्तार वर्ग होना चाहते हैं, लेकिन आपने वास्तव में ऐसा करने के लिए कोई बाउंडिंग या कोड प्रदान नहीं किया है। यह अच्छा होगा यदि आपने ऐसा किया है या समझाया है कि आपकी पद्धति का उपयोग कैसे किया जाता है, और बोनस अंक यदि आपके चर वास्तव में किसी के लिए वर्णनात्मक पर्याप्त नाम थे, तो उनके उद्देश्य / इरादे को समझने के लिए।
22

0

मेरे पास बहुत आसान उपाय है

X1, y1 x2, y2, l1, b1, l2, कॉर्डिनेट और लंबाई और चौड़ाई के क्रमशः होने दें

स्थिति पर विचार करें (x2)

अब ये आयत ओवरलैप होने का एकमात्र तरीका यह है कि बिंदु विकर्ण X1 के लिए, y1 अन्य आयत के अंदर स्थित होगा या इसी तरह बिंदु विकर्ण x2 में होगा, y2 अन्य आयत के अंदर स्थित होगा। जो वास्तव में उपरोक्त स्थिति का तात्पर्य है।


0

A और B दो आयत हो। C उनकी कवरिंग आयत हो।

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) 

यह सभी संभावित मामलों का ध्यान रखता है।


0

यह पुस्तक परिचय से जावा एक्सरसाइजिंग- कॉम्प्रिहेंसिव एडिशन के 3.28 अभ्यास से है। कोड परीक्षण करता है कि क्या दो आयताकार इंडेंटिकल हैं, क्या एक दूसरे के अंदर है और क्या एक दूसरे के बाहर है। यदि इनमें से कोई भी शर्त पूरी नहीं होती है, तो दो ओवरलैप होते हैं।

· .28 (ज्यामिति: दो आयतें) एक प्रोग्राम लिखें जो उपयोगकर्ता को केंद्र में प्रवेश करने के लिए प्रेरित करता है-, y- निर्देशांक, चौड़ाई और दो आयतों की ऊँचाई और निर्धारित करता है कि दूसरा आयत पहले के अंदर है या पहले के साथ ओवरलैप है, जैसा कि चित्र 3.9 में दिखाया गया है। सभी मामलों को कवर करने के लिए अपने कार्यक्रम का परीक्षण करें। यहाँ नमूने रन हैं:

R1 का केंद्र x-, y- निर्देशांक, चौड़ाई और ऊंचाई दर्ज करें: 2.5 4 2.5 43 43 r2 का केंद्र x-, y- निर्देशांक, चौड़ाई और ऊंचाई दर्ज करें: 1.5 5 0.5 3 r2, r1 के अंदर है

R1 का केंद्र x-, y- निर्देशांक, चौड़ाई और ऊंचाई दर्ज करें: 1 2 3 5.5 r2 का केंद्र x-, y-निर्देशांक, चौड़ाई और ऊंचाई दर्ज करें: 3 4 4.5 5 5 ओवरलैप्स r1

R1 का केंद्र x-, y-निर्देशांक, चौड़ाई और ऊंचाई दर्ज करें: 1 2 3 3 r2 का केंद्र x-, y- निर्देशांक, चौड़ाई और ऊंचाई दर्ज करें: 40 45 3 2 r2 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

आप में से जो विशिष्ट x, y, w, h, या x0, y0, X1, X1, के बजाय अपने आयत डेटा के लिए केंद्र बिंदुओं और आधे आकारों का उपयोग कर रहे हैं, यहां बताया गया है कि आप यह कैसे कर सकते हैं:

#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

यदि आयताकार ओवरलैप करते हैं तो ओवरलैप क्षेत्र शून्य से अधिक होगा। अब हम ओवरलैप क्षेत्र पाते हैं:

यदि वे ओवरलैप करते हैं तो ओवरलैप-लेफ्ट का बायां किनारा होगा max(r1.x1, r2.x1)और राइट एज होगा min(r1.x2, r2.x2)। तो ओवरलैप की लंबाई होगीmin(r1.x2, r2.x2) - max(r1.x1, r2.x1)

तो क्षेत्र होगा:

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

यदि area = 0फिर वे ओवरलैप नहीं करते हैं।

सरल है ना?


3
यह ओवरलैप के लिए काम करता है (जो कि सवाल है) लेकिन चौराहे के लिए काम नहीं करेगा, क्योंकि यह काम नहीं करेगा यदि वे एक कोने में बिल्कुल काटते हैं।
लांस रॉबर्ट्स

मैंने इस कोड की कोशिश की और यह बिल्कुल काम नहीं करता है। जब वे ओवरलैप नहीं करते हैं तब भी मुझे केवल पॉजिटिव नंबर मिलते हैं।
ब्रेट

@ ब्रेट: हां, क्योंकि दो नकारात्मक संख्याओं का उत्पाद सकारात्मक है।
बेन Voigt

@BenVoigt, समस्या यह थी कि जब ओवरलैप नहीं था, तो फ़ंक्शन 0 नहीं लौटा था। मैं अपनी टिप्पणी के साथ बहुत अस्पष्ट था, लेकिन हां, मुझे केवल इस समारोह से क्षेत्र> 0 प्राप्त हुआ।
ब्रेट

यदि आप फ्लोटिंग पॉइंट नंबरों के साथ काम कर रहे हैं, तो आमतौर पर किसी भी संख्या की तुलना से पहले घटाव और अन्य अंकगणितीय सामान का उपयोग करना बहुत बुरा विचार है। खासकर यदि आपको एक सटीक मूल्य के साथ तुलना करने की आवश्यकता है - इस मामले में शून्य। यह सिद्धांत में काम करता है, लेकिन व्यवहार में नहीं।
मजा

-1

"यदि आप घटाव x या y करते हैं, तो प्रत्येक आयत का सामना करने वाले दो के कोने के अनुरूप होता है, यदि परिणाम एक ही संकेत हैं, तो दो आयत कुल्हाड़ियों को ओवरलैप नहीं करते हैं" (मुझे खेद है, मुझे यकीन नहीं है कि मेरा अनुवाद सही है )

यहां छवि विवरण दर्ज करें

स्रोत: http://www.ieev.org/2009/05/kiem-tra-hai-hinh-chu-nhat-chong-nhau.html


-1

जावा कोड यह पता लगाने के लिए कि क्या आयत एक दूसरे से संपर्क कर रहे हैं या ओवरलैप कर रहे हैं

...

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

...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.