आकृतियाँ (आयतें) चतुर्थ वृक्षों में कैसे काम करती हैं?


10

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

मैं यह जावास्क्रिप्ट में कर रहा हूं, लेकिन मुझे लगता है कि ये प्रश्न किसी भी भाषा में चौकोर पेड़ों पर लागू हो सकते हैं।

मुझे लगता है कि मैं ज्यादातर यह समझता हूं कि क्वाड ट्री में बेसिक (x, y) पॉइंट्स और पॉइंट इंसर्शन कैसे काम करता है, और यह कि मैं इसे पेपर पर कर सकता था।

यहाँ अंक के साथ मेरे प्रयोग की एक JSfiddle है।

क्वाड ट्री पॉइंट

एक मामले के अलावा, अंकों के साथ मेरे परीक्षण अपेक्षित रूप से काम कर रहे हैं।

लेकिन मेरा भ्रम तब शुरू होता है जब आयत जैसी आकृतियाँ शामिल होती हैं। जब आप आकार के साथ एक चौकोर पेड़ से प्राप्त कर रहे हैं, तो क्या यह आकार के प्रत्येक बिंदु की जांच करता है, और वे किस नोड में आते हैं? और कैसे आकार सम्मिलन भी काम करते हैं, जब यह प्रत्येक आकार के लिए (x, y, चौड़ाई, ऊंचाई) मान को स्वीकार करता है? क्या यह अन्य कोने बिंदुओं की गणना करने के लिए शुरुआती बिंदु से चौड़ाई / ऊंचाई का उपयोग करता है, जो तब उपयुक्त नोड में तिरस्कृत होते हैं? यदि एक सम्मिलित आकार चार नोड्स में फैला है, तो क्या उस आकृति का डेटा सभी चार नोडों में सहेजा गया है?

और जब एक पुनर्प्राप्ति विधि एक आकार को पैरामीटर (x, y, चौड़ाई, ऊंचाई) के रूप में स्वीकार करती है, तो वास्तव में क्या चल रहा है? क्या यह पहली बार देखा जा रहा है कि अगर यह डाला जाना है, तो आकार किस नोड में होगा, और फिर उन नोड्स की सभी वस्तुओं को पुनः प्राप्त करेगा?

मेरे पास एक JSfield है जो आकृतियों के साथ काम कर रहा है, लेकिन मैं अपने परीक्षण के परिणामों पर पूरी तरह से भ्रमित हूं। मुझे डुप्लिकेट ऑब्जेक्ट वापस मिल रहे हैं!

क्वाड ट्री आकार

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

बकौल, अगर मैं एक क्वाड ट्री के सभी बिंदुओं को वापस करना चाहता हूं, तो मैं यह कैसे करूंगा? सीमा के पूरे आकार के आकार का उपयोग करके एक पुनर्प्राप्त विधि? उदाहरण के लिए, (0, 0, कैनवस.उपभार, कैनवस.हाईट) को पुनः प्राप्त करें?

जावास्क्रिप्ट QuadTree पुस्तकालय मैं उपयोग कर रहा हूँ, कई अन्य स्रोतों द्वारा निर्दिष्ट किया गया है तो मुझे लगता है वास्तविक क्रियान्वयन सही और सम्मानित है।

मुझे लगता है कि क्वाड ट्री शब्दावली की गलतफहमी से मेरा बहुत भ्रम दूर हो सकता है। जैसे, वे आयामों के बजाय सीमा क्यों कहते हैं, जब एक "बिंदु" की चौड़ाई / ऊंचाई पैरामीटर भी होती है? क्या यह सम्मेलन / शॉर्ट-हैंड की बात है, या वे पूरी तरह से अलग अवधारणाएं हैं?

आपके समय के लिए धन्यवाद!


वे क्वाड ट्री में सामान्य स्थिति के अनुसार जमा होते हैं। आमतौर पर वे केंद्र में होते हैं, लेकिन कोने में हो सकते हैं जैसा आपने परिभाषित किया है। आपका प्रश्न इस एक का एक डुप्लिकेट हो सकता है: QuadTree: केवल अंक, या क्षेत्र स्टोर करें?
MichaelHouse

मैंने उस प्रश्न को पढ़ा है, लेकिन मुझे अभी भी उत्तर पूरी तरह से समझ में नहीं आया है :(। "आपको इसे सबसे छोटे नोड में संग्रहित करना होगा, जिसमें पूरी तरह से इसे शामिल किया गया हो- भले ही यह क्षमता से अधिक हो (उपयोग करने योग्य कंटेनर)।" - जब वह कहते हैं कि सबसे छोटा नोड जिसमें COMPLETELY होता है, यदि वस्तु बहुत बड़ी है, तो क्या वह नोड अक्सर एक पत्ती का नोड नहीं होगा? एक उच्च-अप नोड में? केवल अन्य नोड्स होते हैं? यह सही नहीं लगता है मुझे, इसका मतलब है कि युक्त नोड में 1 पत्ती और उसके भीतर 4 छोटे नोड्स होंगे।
यूजर 273636286

1
@ user2736286 यदि आप क्वाडट्री लिब के लिए कोड देखते हैं (यह बहुत लंबा नहीं है), तो आप देख सकते हैं कि यह आयत को उच्च स्तर के नोड्स में स्टोर कर सकता है ताकि उन्हें नोड सीमाओं से दूर रखा जा सके। _stuckChildrenकोड में फ़ील्ड के संदर्भ देखें । आप इसे "सीमाओं के साथ आइटम पुनर्प्राप्त करने" में भी देख सकते हैं - यह हमेशा उन नोड्स को लाल करता है जो आपके द्वारा क्लिक किए गए नोड्स की सीमाओं को काटते हैं, रूट नोड तक सभी तरह से।
नाथन रीड

@ user2736286 इसके अलावा, क्वाडट्री लिब की सीमा के साथ आइटम को पुनः प्राप्त करने में एक बग दिखाई देता है - यदि आप इसे एक क्वेरी रेक्ट देते हैं जो कुछ नोड सीमाओं को स्ट्रैडल करता है, तो यह क्वेरी को छूने वाले नोड्स में सभी रेक्टर्स को वापस नहीं करता है। आप इसे "सीमाओं के साथ आइटम पुनर्प्राप्त करने" में आसानी से देख सकते हैं, नोड सीमाओं के पास क्लिक करके।
नाथन रीड

@NathanReed इससे पहले मैंने कोड को समझने की कोशिश की थी, लेकिन मैं इतना कुशल नहीं हूं कि इसे एक वैचारिक आधार के बिना समझ सकूं। जॉन मैकडॉनल्ड्स के छद्म कोड के कारण अब मैं समझता हूं कि आयतों को नोड्स में कैसे डाला जाता है, लेकिन मुझे लगता है कि मैं अभी भी स्पष्ट नहीं हूं कि पुनर्प्राप्ति कैसे काम करती है। के रूप में "सीमा के साथ वस्तुओं को पुनः प्राप्त करने के लिए" - मैं उदाहरण के द्वारा भ्रमित बाहर फ्लैट हूँ। जैसे, जब मैं एक ऐसी परत पर क्लिक करता हूं जो सफाई से सबसे छोटे नोड्स में से एक में फिट होती है, तो उस नोड के बाहर इन सभी अन्य आयतों को उजागर क्यों किया जाता है?
user2736286

जवाबों:


10

Quadtrees आम तौर पर आयतों को संग्रहीत और पुनः प्राप्त करती है। एक बिंदु एक विशिष्ट मामला है जहां चौड़ाई और ऊंचाई शून्य है। रूट नोड के साथ शुरू होने वाले पेड़ में नई आयतों के लिए घर खोजने के लिए निम्नलिखित तर्क का उपयोग किया जाता है:

void Store(Rectangle rect)
{
    if(I have children nodes)
    {
        bool storedInChild = false;
        foreach(Node childNode in nodes)
        {
            if(this rectangle fits entirely inside the childNode bounds)
            {
                childNode.Store(rect);   // Go deeper into the tree
                storedInChild = true;
                break;
            }
        }
        if(not storedInChild)
        {
            Add this rectangle to the current node
        }
    }
    else
    {
        Add this rectangle to the current node
    }
}

ध्यान दें कि आयताकार किसी भी गहराई पर संग्रहीत किया जा सकता है, इसमें पत्ती का क्वाड होना जरूरी नहीं है। यदि आयत जड़ स्तर पर सीमा को सही तरीके से फैलाती है, तो रूट क्वाड आयत को संग्रहीत करेगा।

उदाहरण के लिए, लाल वर्ग उन मापदंडों के बराबर है जो मैं अपनी पुनर्प्राप्ति विधि में दर्ज कर रहा हूं। मुझे लगता है कि चूंकि यह लाल वर्ग सभी चार नोडों में फैला है, इसलिए इसे क्वाड ट्री में प्रत्येक वस्तु को वापस करना चाहिए! लेकिन यह नहीं है, और मुझे यह समझने में परेशानी हो रही है कि यह क्या करता है।

क्वाडट्री को क्वेरी करते समय, यह केवल आयतों को लौटाएगा जो क्वेरी द्वारा निहित हैं। अपने उदाहरण में, आप प्रत्येक 4 चाइल्ड क्वाइड को आगे विस्तार से देखने के लिए बाध्य करते हैं क्योंकि लाल क्वेरी आयत प्रत्येक चाइल्ड क्वैड को प्रतिच्छेद करती है। चूंकि बच्चों के आगे कोई बच्चा नहीं है, इसलिए इन बच्चे quads में से प्रत्येक आयत की तुलना लाल आयत के साथ की जाएगी। चूंकि पेड़ में कोई भी आयत लाल क्वेरी आयत से नहीं टकराती है, इसलिए कुछ भी वापस नहीं किया जाना चाहिए।

जब आप बहुत सारी वस्तुओं, और क्वेरी क्षेत्र (ओं) की तुलना में मौजूद वस्तुओं के लिए बहुत सारे स्थान रखते हैं, तो आपको वास्तव में क्वाडट्रैड्स के लाभ दिखाई देने लगते हैं। इन मामलों में, एक छोटा क्वेरी क्षेत्र क्वैड ट्री के विशाल भाग को विचार से जल्दी से समाप्त कर सकता है। केवल क्वेरी आयत के साथ प्रतिच्छेद करने वाले क्वैड को कभी भी अधिक विस्तार से देखा जाएगा।

संपादित करें

पुनर्प्राप्ति आमतौर पर निम्नलिखित की तरह की जाती है:

List<Rectangle> Query(Rectangle queryRect)
{
    List<Rectangle> results;
    foreach(Node childNode in children)
    {
        if(queryRect intersects with childNode bounds)
        {
            results += childNode.Query(queryRect);   // Dig deeper into the tree
        }
    }

    foreach(Rectangle I have stored in this quad)
    {
        if(queryRect intersects with rect)  // Your library doesn't do this
        {
            results += rect;
        }
    }

    return results;
}

हालाँकि, आपकी लाइब्रेरी में यह नहीं लगता है कि यदि आयतें क्वेरी के साथ वापस आ रही हैं, तो आपको खुद को जोड़ना होगा।


अपने पुस्तकालय को और अधिक विस्तार से देखने के बाद, आपका पुस्तकालय आपके द्वारा निर्दिष्ट क्वेरी आयत के सभी संभावित टक्कर उम्मीदवारों की सूची लौटा रहा है । ऐसा प्रतीत होता है कि यह आपकी नौकरी है कि प्रत्येक उम्मीदवार को अपनी क्वेरी आयत की तुलना करके देखें कि क्या वास्तविक टक्कर है। अधिकांश लाइब्रेरी आपके लिए अंतिम चरण का काम करते हैं और क्वेरी क्षेत्र के साथ वास्तविक टकरावों को वापस करते हैं। इसलिए, आपको retrieveकेवल सूची को चुभाने के लिए अपने तरीके में कुछ तर्क जोड़ना होगा । आप देख सकते हैं कि यह यहाँ और अधिक स्पष्ट रूप से क्या कर रहा है: mikechambers.com/html5/javascript/QuadTree/examples/…
John McDonald

1
@ user2736286 यदि आपने उस पर नहीं उठाया है, तो यह ध्यान में रखना जरूरी है कि जॉनरीडोनल्ड ने क्वेरी और स्टोर फ़ंक्शंस में पुनरावृत्ति पर ध्यान दिया। अगर आपको वह हिस्सा नहीं मिला तो यह बहुत मायने नहीं रखेगा। दोनों के लिए, प्रत्येक पुनरावृत्ति पेड़ में गहरी हो जाती है, अर्थात शाखाओं पर और अंत में पत्तियों पर।
TASagent

धन्यवाद जॉन, आपका छद्म कोड बहुत मददगार है। जब आप कहते हैं "अगर (क्वेरीट्रैक चाइल्डनॉड्स सीमा के साथ प्रतिच्छेद करता है"), तो क्या मूल रूप से इसका मतलब है अगर क्वेरी को सीमा के भीतर समाहित किया गया है - आंशिक रूप से या पूरी तरह से? बस 100% स्पष्ट होना चाहते हैं। इसके अलावा, "सीमा द्वारा आइटम को पुनः प्राप्त करें" उदाहरण में चर्चा की जा रही है, मेरे पास मेरे क्लिक के परिणाम की एक छवि है। Pic ब्लू डॉट जहाँ मैंने क्लिक किया है। तो उस नोड के अंदर केवल दो आयतें ही क्यों नहीं हैं? आयतों को दूर से ही क्यों उजागर किया जाता है? मुझे लगता है कि जो वास्तव में मुझे भ्रमित कर रहा है।
user2736286

भाग या भरा हुआ। यदि दो स्पर्श, या तो पूरी तरह से दूसरे द्वारा निहित है। आप Quadtrees पर विकी पढ़ना चाहते हैं , लेकिन मैंने आपकी तस्वीर ले ली है, और अलग-अलग बच्चे की सीमाओं का प्रतिनिधित्व करने के लिए इसे रंग दिया है। नीले आयतों के सभी पहले बच्चे के quads की सीमाओं के साथ प्रतिच्छेद कर रहे हैं, फिर मैजेंटा एक परत गहरी और हरे रंग की एक परत अभी भी गहरा हो रहा है। रेड आयताकार क्लिक किए गए क्वाड के साथ प्रतिच्छेद करते हैं। आप पुस्तकालय बच्चे की सीमाओं पर सभी आयतों को वापस लाते
जॉन मैकडॉनल्ड

ठीक है, इसलिए मैंने अपनी पूरी कोशिश की है कि मैं लिबास के सोर्स कोड पर जाऊं और मैं आखिरकार स्टिक चाइल्ड्रेन के व्यवहार को समझूं, और यह कि मेरे पिक्स में जो अतिरिक्त एक्स्ट्रा रेक्ट हैं वे सिर्फ स्टैचिल्ड्रेन हैं। मूल रूप से मैंने सोचा था कि कई नोड्स को फैलाने वाली कोई भी परत बस अपने डेटा को दोहराएगी और प्रत्येक छोटे नोड में डाली जाएगी। अब मुझे एहसास हुआ कि अटक गए बच्चे नोड्स में नहीं फैलते हैं, लेकिन यह केवल एक नोड में रहता है, यही वजह है कि मुझे सभी अभिभावकों के नोड्स की भी जांच करनी है, और न केवल मेरी क्वेरी आयत वाले सबसे छोटे नोड को। तस्वीर के लिए धन्यवाद; यह अब बहुत अधिक समझ में आता है :)
user2736286
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.