कुशलतापूर्वक त्रिज्या के भीतर सभी संस्थाओं को लगातार कैसे खोजें?


14

मेरे पास बहुत बड़ी संख्या में इकाइयाँ (इकाइयाँ) हैं। प्रत्येक चरण पर, प्रत्येक इकाई को इसके पास की सभी इकाइयों की स्थिति जानने की जरूरत है (दूरी कम है तो निरंतर आर दिया जाता है )। सभी इकाइयाँ निरंतर चलती हैं। यह 3 डी में है।

दिए गए अवरोधों के साथ किसी भी अन्य दी गई इकाई के पास कुल यूनिट की संख्या का औसतन 1% होगा।

मैं यह कैसे कुशलता से कर सकते हैं, बिना क्रूरता के।


7
आप कुछ प्रकार के स्थानिक विभाजन प्रणाली चाहते हैं: en.wikipedia.org/wiki/Space_partitioning
टेट्राद

जवाबों:


15

एक सामान्य अंतरिक्ष विभाजन एल्गोरिदम का उपयोग करें, जैसे कि क्वाडट्री, ऑक्ट्री, बीएसपी ट्री, या यहां तक ​​कि एक साधारण ग्रिड सिस्टम। प्रत्येक के पास प्रत्येक विशिष्ट परिदृश्य के लिए अपने स्वयं के पेशेवरों और विपक्ष हैं। आप इन पुस्तकों में उनके बारे में अधिक पढ़ सकते हैं ।

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

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

ग्रिड के उपयोग से दुनिया को समान रूप से विभाजित क्षेत्रों में विभाजित किया जा सकता है और दुनिया के उपयुक्त क्षेत्र में संस्थाओं को संग्रहीत किया जा सकता है। फिर, एक स्थिति दी गई है, पड़ोसी संस्थाओं को ढूंढना उन क्षेत्रों पर पुनरावृत्ति करने का विषय होगा जो आपकी खोज की त्रिज्या को बाधित करते हैं।

मान लीजिए कि आपकी दुनिया XZ विमान में (-1000, -1000) से (1000, 1000) तक है। उदाहरण के लिए आप इसे 10x10 ग्रिड में विभाजित कर सकते हैं, जैसे:

var grid = new List<Entity>[10, 10];

फिर आप संस्थाओं को ग्रिड में उनकी उपयुक्त कोशिकाओं में जगह देंगे। उदाहरण के लिए XZ (-1000, -1000) के साथ एक इकाई सेल (0,0) पर गिरेगी जबकि XZ (1000, 1000) के साथ एक इकाई सेल (9, 9) पर गिरेगी। फिर दुनिया में एक स्थिति और एक त्रिज्या को देखते हुए, आप यह निर्धारित कर सकते हैं कि कौन से सेल इस "सर्कल" द्वारा प्रतिच्छेद किए जाते हैं और केवल उन पर पुनरावृति करते हैं, जिनके लिए एक सरल डबल है।

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

संपादित करें पर यह मिला एक और मंच है और यह निर्णय के साथ आप मदद कर सकता है:

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

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


विस्तार से उत्तर के लिए धन्यवाद। हाँ, यह सरल ग्रिड समाधान मेरे लिए काफी अच्छा लगता है।
ओसीरिल

0

मैंने कुछ समय पहले यह लिखा था । यह अब एक वाणिज्यिक साइट पर है, लेकिन आप मुफ्त में व्यक्तिगत उपयोग के लिए स्रोत प्राप्त कर सकते हैं। यह ओवरकिल हो सकता है और यह जावा में लिखा गया है, लेकिन यह अच्छी तरह से प्रलेखित है, इसलिए इसे किसी अन्य भाषा में ट्रिम और फिर से लिखना कठिन नहीं होना चाहिए। यह मूल रूप से एक ऑक्ट्री का उपयोग करता है, जिसमें वास्तव में बड़ी वस्तुओं और मल्टी-थ्रेडिंग को संभालने के लिए ट्वीक्स होता है।

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


0

अपनी दक्षता को बढ़ावा देने के लिए, 99% "इकाइयों" को अस्वीकार करने का प्रयास करें जो बहुत सस्ती बाउंडिंग बॉक्स चेक का उपयोग करके लक्ष्य इकाई के पास नहीं हैं। और मुझे आशा है कि आप अपने डेटा को स्थानिक रूप से संरचित किए बिना ऐसा कर सकते हैं। इसलिए यदि आपकी सभी इकाइयाँ एक सपाट डेटा संरचना में संग्रहीत हैं, तो आप इसके माध्यम से शुरू से अंत तक दौड़ लगाने की कोशिश कर सकते हैं और सबसे पहले ब्याज की इकाई के बाउंडिंग बॉक्स के बाहर वर्तमान इकाई है।

ब्याज की इकाई के लिए एक ओवरसाइज़्ड बाउंडिंग बॉक्स को परिभाषित करें, ताकि यह उन वस्तुओं को सुरक्षित रूप से अस्वीकार कर सके, जिनके पास "पास" होने का कोई मौका नहीं है। एक बाउंडिंग बॉक्स से बहिष्करण के लिए चेक एक त्रिज्या जांच की तुलना में सस्ता बनाया जा सकता है। हालाँकि कुछ प्रणालियों पर जहाँ इसका परीक्षण किया गया था, ऐसा नहीं पाया गया था। दोनों लगभग बराबर प्रदर्शन करते हैं। यह नीचे बहुत बहस के बाद संपादित हुआ।

पहला: 2 डी बाउंडिंग बॉक्स क्लिप।

// returns true if the circle supplied is completely OUTSIDE the bounding box, rectClip
bool canTrivialRejectCircle(Vertex2D& vCentre, WorldUnit radius, Rect& rectClip) {
  if (vCentre.x + radius < rectClip.l ||
    vCentre.x - radius > rectClip.r ||
    vCentre.y + radius < rectClip.b ||
    vCentre.y - radius > rectClip.t)
    return true;
  else
    return false;
}

कुछ इस तरह की तुलना में (3 डी में):

BOOL bSphereTest(CObject3D* obj1, CObject3D* obj2 )
{
  D3DVECTOR relPos = obj1->prPosition - obj2->prPosition;
  float dist = relPos.x * relPos.x + relPos.y * relPos.y + relPos.z * relPos.z;
  float minDist = obj1->fRadius + obj2->fRadius;
  return dist <= minDist * minDist;
}.

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

यह लेख तुच्छ अस्वीकृति के लिए बॉक्स का समर्थन करता है। http://www.h3xed.com/programming/bounding-box-vs-bounding-circle-collision-detection-performance-as3

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

मैं बस नहीं चाहता था कि अगर आप इसे टाल सकते हैं तो आप इस तरह की जटिलता को पेश करने की परेशानी में जा रहे हैं। साथ ही इस जटिल डेटा को अप-टू-डेट रखने की लागत के बारे में क्या कहेंगे क्योंकि ऑब्जेक्ट प्रति सेकंड कई बार चलते हैं?

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


1
ओपी ने विशेष रूप से कहा कि वह एक क्रूर बल दृष्टिकोण से बचना चाहते हैं, जो कि आपके पहले पैराग्राफ में वर्णित है। इसके अलावा, आप एक बाउंडिंग बॉक्स की जांच कैसे करते हैं? यह सिर्फ गलत है।
नॉटलेश

हाँ, मुझे पता है कि वह पाशविक बल से बचना चाहता है जो उसके आवेदन के लिए एक पदानुक्रमित डेटा संरचना शुरू करने के प्रयास में जाने से बचा जाएगा। लेकिन वह बहुत प्रयास हो सकता है। यदि वह ऐसा नहीं करना चाहता है, तो वह रैखिक दृष्टिकोण की कोशिश कर सकता है जो कि क्रूर बल है, लेकिन अगर उसकी सूची बहुत बड़ी नहीं है तो वह इतना बुरा प्रदर्शन नहीं कर सकता है। मैं अपने 2 डी बाउंडिंग बॉक्स ट्रिवियल रिजेक्ट फ़ंक्शन में डालने के लिए ऊपर दिए गए कोड को संपादित करने का प्रयास करूंगा। मुझे नहीं लगता कि मैं गलत था।
सियारान

GDnet का लिंक टूट गया है, लेकिन विहित क्षेत्र का परीक्षण बहुत सरल है, बहुत सस्ता है और शाखा नहीं है:inside = (dot(p-p0, p-p0) <= r*r)
लार्स विकलंड

मैंने इसके बजाय ऊपर कोड चिपकाया है। यह बाउंडिंग बॉक्स की तुलना में कुछ भी सस्ता लगता है।
सियारन

1
@Ciaran काफी ईमानदारी से, यह लेख वास्तव में बुरा लगता है। सबसे पहले यह यथार्थवादी डेटा के साथ परीक्षण नहीं करता है, बल्कि बार-बार समान मूल्यों का उपयोग करता है। नहीं कुछ तुम एक वास्तविक परिदृश्य में सामना करेंगे। और नहीं, लेख के अनुसार बीबी केवल तेज है जब कोई टक्कर नहीं है (उदाहरण के लिए चेक पहले ifबयान में विफल रहता है )। बहुत यथार्थवादी भी नहीं। लेकिन काफी ईमानदारी से, अगर आप इस तरह की चीजों को अनुकूलित करना शुरू कर रहे हैं, तो आप निश्चित रूप से गलत जगह पर शुरू कर रहे हैं।
बंमज़ैक

0

मुझे इसका जवाब देना है क्योंकि मेरे पास टिप्पणी करने या अपवोट करने के लिए अंक नहीं हैं। इस प्रश्न को पूछने वाले 99% लोगों के लिए, एक बाउंडिंग बॉक्स समाधान है, जैसा कि सियारन द्वारा वर्णित है। एक संकलित भाषा में, यह पलक झपकते 100,000 अपरोक्ष इकाइयों को अस्वीकार कर देगा। गैर-ब्रूट-बल समाधानों के साथ बहुत अधिक ओवरहेड शामिल है; छोटी संख्या के साथ (1000 से कम के अनुसार) वे ब्रूट बल जाँच की तुलना में प्रसंस्करण समय के मामले में अधिक महंगे होंगे। और वे बहुत अधिक प्रोग्रामिंग समय लेंगे।

मुझे यकीन नहीं है कि प्रश्न में "बहुत बड़ी संख्या" का अर्थ क्या है, या उत्तर के लिए यहां देख रहे अन्य लोगों को इससे क्या मतलब होगा। मुझे संदेह है कि मेरे ऊपर की संख्या रूढ़िवादी हैं और इसे 10 से गुणा किया जा सकता है; मैं व्यक्तिगत रूप से पाशविक बल तकनीकों के खिलाफ काफी पूर्वाग्रही हूं और वे कितनी अच्छी तरह से काम करते हैं, इस पर गंभीरता से नाराज हैं। लेकिन मैं किसी के साथ नहीं कहना चाहूंगा, 10,000 इकाइयों को एक फैंसी समाधान के साथ समय बर्बाद करने के लिए जब कोड की कुछ त्वरित लाइनें चाल चलेंगी। जरूरत पड़ने पर वे हमेशा बाद में फैंसी ले सकते हैं।

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


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