मैं यह कैसे निर्धारित करूं कि एक बहुभुज पूरी तरह से दूसरे में है?


9

मेरे पास 2 बहुभुज हैं। मुझे पता है कि दोनों बहुभुजों के शीर्ष निर्देशांक हैं। यह जांचने का सबसे अच्छा तरीका है कि क्या एक दूसरे के अंदर पूरी तरह से है? उदाहरण के लिए, एल्गोरिथ्म को केवल नीचे दिए गए काले ट्रेपोज़ॉइड को पहचानना चाहिए :

उदाहरण बहुभुज


मैं अभी विस्तृत जवाब नहीं दे सकता (बाद में ऐसा कर सकता हूं), लेकिन आपको टकराव का पता लगाने के लिए अलग-अलग अक्ष प्रमेय के कार्यान्वयन पर एक नज़र डालनी चाहिए। एल्गोरिथ्म को आसानी से संशोधित किया जा सकता है कि आप क्या चाहते हैं। उदा। codezealot.org/archives/55
ट्रैविसग

1
आप बिल्कुल स्पष्ट नहीं हैं कि आप बहुभुज के अंदर एक बहुभुज के बारे में क्या समझते हैं। क्या होगा यदि छोटे बहुभुज के सभी बिंदु बड़े में हैं, लेकिन उनमें से प्रत्येक के पास एक पंक्ति है, क्या वे एक दूसरे में हैं? i47.tinypic.com/4i0sgg.jpg
SpeedyGonzales

@speedyGonzales, यह अंदर बुलाया एलोस है।
उपयोगकर्ता 960567

जवाबों:


5

एक विधि के लिए कई स्रोत स्निपेट हैं जो " बहुभुज के अंदर बिंदु " के लिए एक परीक्षण करते हैं । यह सिद्धांत जॉर्डन के वक्र प्रमेय से बहुभुज ( http://www-cgrl.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Octavian/compgeom.html ) पर आता है।

भोला तरीका होगा: उस विधि होने, इसे कॉल PointInsidePolygon(Point p, Polygon poly):

  bool isInside = true;
  for each (Point p in innerPoly)
  {
    if (!PointInsidePolygon(p, outerPoly))
    {
      isInside = false; // at least one point of the innerPoly is outside the outerPoly
      break;
    }
  }
  if (!isInside) return false;
  // COMPULSORY EDGE INTERSECTION CHECK
  for each (innerEdge in innerPoly)
    for each (outerEdge in outerPoly)
    {
      if (EdgesIntersect(innerEdge, outerEdge))
      {
        isInside = false;
        break;
      }
    }

  return isInside;

सैद्धांतिक रूप से, यह आपके बहुभुज के लिए किसी भी परिदृश्य को याद नहीं करना चाहिए, लेकिन यह इष्टतम समाधान नहीं है।

"एज" केस टिप्पणी

  • PointInsidePolygon(..) यदि बिंदु बहुभुज की सीमा पर है, तो वापस लौटना चाहिए (या तो एक किनारे पर है या एक शीर्ष पर है)

  • EdgesIntersect(..)यदि innerEdgeएक सबसेट (ज्यामितीय रूप से बुद्धिमान) है, तो उसे वापस लौटना चाहिए outerEdge। इस मामले में, किनारे स्पष्ट रूप से प्रतिच्छेद करते हैं, लेकिन एल्गोरिथ्म के उद्देश्य के लिए, हमें यह इंगित करने की आवश्यकता है कि चौराहा isInsideचर के पीछे शब्दार्थ को नहीं तोड़ रहा है

सामान्य टिप्पणीकार :

  • एज बनाम एज चौराहे की जाँच के बिना, जैसा कि टिप्पणियों में बताया गया है, दृष्टिकोण कुछ अवतल बहुभुजों के लिए झूठी सकारात्मक लौटा सकता है (जैसे वी आकार का क्वाड और आयताकार - आयत का वी आकार के अंदर इसके सभी कोने हो सकते हैं, लेकिन इसे देखें , इस प्रकार कम से कम कुछ क्षेत्रों के बाहर)।

  • आंतरिक बहुभुज के कोने के कम से कम एक के लिए एक के बाद एक बाहरी के अंदर होने की जाँच करता है, और अगर कोई इंटरसेक्टिंग किनारों नहीं हैं, तो इसका मतलब है कि हालत संतुष्ट होने के बाद मांगी गई है।


1
बाहरी पॉलीगॉन अवतल होने पर यह झूठी सकारात्मक लौटाएगा।
सम होसेवार

2
काफी मजेदार है, जबकि टेओड्रॉन और नाइटहाइट 6 व्यक्तिगत रूप से गलत हैं, जब संयुक्त होते हैं, तो उन्हें एक सही उत्तर देना चाहिए। यदि बहुभुज के सभी बिंदु एक दूसरे के अंदर हैं, और यदि उनकी रेखाएं नहीं मिलती हैं, तो पहला पाली पूरी तरह से दूसरे के अंदर है।
हैकवर्ट

सच है, यह झूठी सकारात्मक लौटाता है, इसे किनारे के चौराहों पर भी लेने की जरूरत है।
तेओद्रोन

यह सही उत्तर लगता है। मुझे लगता है कि दूसरे लूप की स्थिति की जांच करने की आवश्यकता नहीं है।
user960567

यह समापन बिंदु चौराहों या यदि किनारों पर ओवरलैप के लिए काम नहीं करता है।
ब्रैंडन कोह

2

प्रत्येक लाल रेखा के साथ एक लाइन चौराहा करने की कोशिश करें। छद्मकोश में:

// loop over polygons
for (int i = 0; i < m_PolygonCount; i++)
{
    bool contained = false;

    for (int j = 0; j < m_Polygon[i].GetLineCount(); j++)
    {
        for (int k = 0; k < m_PolygonContainer.GetLineCount(); k++)
        {
            // if a line of the container polygon intersects with a line of the polygon
            // we know it's not fully contained
            if (m_PolygonContainer.GetLine(k).Intersects(m_Polygon[i].GetLine(j)))
            {
                contained = false;
                break;
            }
        }

        // it only takes one intersection to invalidate the polygon
        if (!contained) { break; }
    }

    // here contained is true if the polygon is fully inside the container
    // and false if it's not
}

हालांकि, जैसा कि आप देख सकते हैं, यह समाधान धीमा हो जाएगा क्योंकि आप जांच करने के लिए अधिक बहुभुज जोड़ते हैं। एक अलग समाधान हो सकता है:

  • एक सफेद रंग के साथ एक पिक्सेल बफर के लिए कंटेनर बहुभुज रेंडर करें।
  • एक सफेद रंग के साथ एक अलग पिक्सेल बफर में एक बच्चे के बहुभुज को रेंडर करें।
  • एक XOR मास्क के साथ बहुभुज बफर पर कंटेनर बफर को मास्क करें।
  • सफेद पिक्सेल की संख्या गिनें; यदि यह 0 से अधिक है, तो बहुभुज कंटेनर द्वारा पूरी तरह से निहित नहीं है।

यह समाधान बहुत तेज़ है, लेकिन यह आपके कार्यान्वयन पर निर्भर करता है (और आप अपने चेक के परिणाम के साथ क्या करना चाहते हैं) क्या समाधान आपके लिए सबसे अच्छा काम करता है।


1
लाइन चौराहों को पूरी तरह से निहित बहुभुज स्पॉट करने के लिए पर्याप्त नहीं होगा।
काइलोटन

1
प्रश्न: यदि बहुभुज पूरी तरह से विच्छिन्न हैं, तो कोई भी किनारा नहीं काटेगा। क्या यह इस मामले में काम करेगा? दूसरा, ग्राफिक्स आधारित दृष्टिकोण वास्तव में काम करना चाहिए!
तेओद्रोन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.