तेजी से चलती वस्तुओं के लिए हेक्सागोन टकराव का पता लगाने?


39

ऑब्जेक्ट में एक स्थिति और एक गति वेक्टर होता है। आमतौर पर केवल पोजिशन का उपयोग यह जांचने के लिए किया जाता है कि दो वस्तुएं टकराती हैं, यह बहुत तेज गति वाली वस्तुओं के लिए समस्याग्रस्त है क्योंकि ऐसा हो सकता है कि वस्तु इतनी तेजी से आगे बढ़े कि वह पहली टकराव की जांच में पहली वस्तु के सामने हो, और उसके पीछे दूसरी टक्कर की जाँच।

बाउंडिंगबॉक्स टकराव की विफलता

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

षट्कोण टक्कर जीत

तो मेरा विचार एक बिंदु का विस्तार करने के बजाय, एक आयत का विस्तार क्यों नहीं है? यह एक षट्कोण में परिणाम है।

अब तक, इतना अच्छा है। लेकिन मैं वास्तव में कैसे जांच करूं कि क्या इस तरह के दो हेक्सागोन्स हैं? ध्यान दें कि ये बहुत विशिष्ट षट्कोण हैं।

हेक्सागोन विनिर्देशों

बोनस प्रश्न : क्या यह गणना करना संभव है कि कहां (या उसके बाद कितने समय बाद) टक्कर हुई? यह पता लगाने के लिए बहुत उपयोगी हो सकता है कि वास्तव में क्या हुआ, जैसे कि कहां और कितनी शक्ति के साथ और कैसे वे टकराव और फ्रेम के अंत के बीच के समय में चले गए।


के लिए (ए में लाइनों के लिए) (बी में लाइनें) (लाइनों के पार) टक्कर - सिवाय इसके कि ए मामलों में बी या बी में ए को कवर नहीं करता है। हम्म। =)
जरी कोमप्पा

4
क्या आप बक्से के लिए प्रतिबद्ध हैं? आपके द्वारा खींचे गए बॉक्सों को सटीकता के न्यूनतम नुकसान के साथ हलकों द्वारा दर्शाया जा सकता है लेकिन तुलनात्मक रूप से आसान टक्कर एल्गो। स्वेप्ट सर्कल टकराव का पता लगाने के लिए खोजें। यदि आपकी लंबाई / चौड़ाई का अनुपात 1 से दूर जाता है, तो यह कम आकर्षक होगा।
स्टीव एच।

@SteveH मैं सबसे अधिक लचीले समाधान की तलाश में हूं, इसलिए लंबाई / चौड़ाई अनुपात एक बड़ा सौदा है।
एपीआई-जानवर

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

2
मैंने पहले यह कोशिश नहीं की है, लेकिन ऐसा लगता है कि 2 डी अंतरिक्ष में हेक्सागोन्स के बजाय, आप 2 डी में आंदोलन के बारे में 3 डी अंतरिक्ष में वॉल्यूम के रूप में सोच सकते हैं जहां एक अक्ष समय है। फिर आप (x, y, t) निर्देशांक के साथ दो 3D पॉलीहेड्रा को इंटरसेक्ट कर रहे हैं। यदि दो ठोस ऑब्जेक्ट प्रतिच्छेद करते हैं तो आप न्यूनतम टी मान प्राप्त करना चाहते हैं। आप B के सभी निर्देशांक को A के संदर्भ फ़्रेम में परिवर्तित करके थोड़ा सरल कर सकते हैं। मैंने इसे लागू नहीं किया है, लेकिन यह वह जगह है जहाँ मैं शुरू करूँगा।
amitp

जवाबों:


34

समाधान वास्तव में अपेक्षा से अधिक सरल है। चाल अपने षट्भुज तकनीक से पहले Minkowski घटाव का उपयोग करने के लिए है ।

यहाँ आपकी आयतें A और B हैं, उनके वेगों के साथ vAऔर vB। ध्यान दें कि vAऔर vBवास्तव में वेग नहीं हैं, वे एक फ्रेम के दौरान तय की गई दूरी हैं ।

चरण 1

अब आयत B को बिंदु P से बदलें, और आयत A को आयत C = A + (- B) के साथ बदलें, जिसमें A और B के आयामों का योग है। Minkowski इसके अतिरिक्त गुण अवस्था बताती है कि बिंदु और नए आयत के बीच टकराव होता है। अगर और केवल अगर मूल दो आयतों के बीच टकराव होता है:

चरण 2

लेकिन अगर आयत C वेक्टर के साथ चलती है vA, और बिंदु P वेक्टर के साथ-साथ चलती है vB, तो संदर्भ फ्रेम का एक सरल परिवर्तन हमें बताता है कि यह वैसा ही है जैसा कि आयत C अभी भी था, और बिंदु P वेक्टर के साथ स्थानांतरित हुआ vB-vA:

चरण 3

फिर आप यह बताने के लिए एक साधारण बॉक्स-सेगमेंट चौराहे फॉर्मूला का उपयोग कर सकते हैं कि नए संदर्भ फ्रेम में टक्कर कहाँ होती है।

अंतिम चरण उचित संदर्भ फ्रेम में वापस जाना है। बस दूरी वेक्टर की लंबाई से घिरा चौराहे तक बिंदु से यात्रा को विभाजित vB-vAऔर आप एक मूल्य मिल जाएगा sऐसा है कि 0 < s < 1। टक्कर उस समय होती है s * Tजहां Tआपके फ्रेम की अवधि होती है।

Madshogo द्वारा टिप्पणी :
श्री जानवर के स्वयं के उत्तर में इस तकनीक का एक बड़ा लाभ यह है कि यदि कोई रोटेशन नहीं है, तो "मिन्कोव्स्की घटाव" A + (- B) की गणना सभी बाद के समय के लिए एक बार की जा सकती है !

केवल एल्गोरिथ्म है कि सभी में समय लगता है तो यह (मिंकोवस्की योग, जटिलता ओ (MN) जहां मीटर में कोने की संख्या है एक और n में कोने की संख्या बी ) केवल एक बार इस्तेमाल किया जा सकता, प्रभावी रूप से टक्कर पता लगाने के लिए एक निरंतर बना समय की समस्या!

बाद में, आप यह सुनिश्चित कर सकते हैं कि और बी आपके दृश्य के विभिन्न भागों (आपके चतुर्भुज?) के हैं और अब आप नहीं टकराएंगे।

इसके विपरीत, श्री बीस्ट की विधि को प्रत्येक समय कदम पर काफी गणनाओं की आवश्यकता होती है।

इसके अलावा, अक्ष-संरेखित आयतों के लिए, A + (- B) की तुलना में बहुत अधिक गणना की जा सकती है, वास्तव में सभी योगों को, शीर्ष पर शीर्ष द्वारा। बस A को B की ऊंचाई और उसकी चौड़ाई B की चौड़ाई (प्रत्येक तरफ एक आधा) जोड़कर विस्तार करें ।

लेकिन यह सब केवल तभी काम करता है जब न तो और न ही बी घूम रहा है और अगर दोनों उत्तल हैं। यदि रोटेशन होता है या आप अवतल आकृतियों का उपयोग करते हैं तो आपको स्वेप्ट वॉल्यूम / क्षेत्रों का उपयोग करना चाहिए।
टिप्पणी का अंत


4
एक दिलचस्प दृष्टिकोण की तरह लगता है, हालांकि, मैं इसे अभी तक 100% समझ नहीं पाता, क्या होता है जब वस्तु वास्तव में छोटी होती है और दो लाइनों के बीच चलती है? i.imgur.com/hRolvAF.png
एपीआई-जानवर

-1: यह तरीका किसी भी तरह से आपको सुनिश्चित नहीं होने देता है कि टक्कर हो। यह केवल आपको यह सुनिश्चित करने की अनुमति देता है कि ऐसा नहीं होता है, उस स्थिति में जहां खंड और एक्सट्रूडेड वॉल्यूम प्रतिच्छेद नहीं करते हैं । लेकिन यह पूरी तरह से संभव है कि वे एक दूसरे से टकराएं और फिर भी कोई टकराव न हो। क्या गलत है "अब आप उपयोग कर सकते हैं [...] सरल खंड-खंड चौराहे का फैसला करने के लिए जहां टक्कर हुई" भाग।
जर्सला

2
@ कामशोगो तुम सही हो। मैंने माना कि ऑब्जेक्ट आकार की तुलना में टाइमस्टेप काफी छोटा था कि यह एक समस्या नहीं होगी, लेकिन यह निश्चित रूप से सामान्य मामले में बहुत मजबूत नहीं है। मैं इसे ठीक करने में लगूंगा।
सैम होसेवर

@SamHocevar यदि आप उस उत्तर को संशोधित कर सकते हैं जो बहुत अच्छा होगा।
एपीआई-जानवर

1
@LuisAlves हां और ना ... सब तर्क काम करता है, लेकिन आप प्रतिस्थापित करना होगा vB-vAसाथ g(t)-f(t)जहां fऔर gसमय के साथ ए और बी के पदों पर रहे हैं। चूंकि यह अब एक सीधी रेखा नहीं है, इसलिए आपको एक बॉक्स - पैरामीट्रिक वक्र चौराहे समस्या को हल करना होगा।
सैम होसेवर

17

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

दूसरा, सरल आकृतियों के लिए, टकराव का पता लगाने के लिए सापेक्ष वेग (जैसा कि नीचे देखा गया है) और अलग-अलग अक्ष प्रमेय का उपयोग करें। यह आपको बताएगा कि क्या रैखिक गति (कोई रोटेशन नहीं) के मामले में टकराव होता है। और अगर रोटेशन होता है, तो आपको सटीक होने के लिए एक छोटे टाइमस्टेप की आवश्यकता होती है। अब, सवाल का जवाब देने के लिए:


सामान्य मामले में कैसे बताएं कि क्या दो उत्तल आकृतियाँ प्रतिच्छेद करती हैं?

मैं आपको एक एल्गोरिथ्म दूंगा जो सभी उत्तल आकृतियों के लिए काम करता है और न केवल हेक्सागोन्स के लिए।

मान लीजिए कि X और Y दो उत्तल आकृतियाँ हैं। यदि वे केवल एक बिंदु है, तो वे प्रतिच्छेद करते हैं, अर्थात एक बिंदु x if X और एक बिंदु y = Y ऐसा है कि x = y । यदि आप अंतरिक्ष को सदिश स्थान मानते हैं, तो यह राशि x - y = 0 कहती है । और अब हम इस Minkowski व्यापार के लिए मिलता है:

मिंकोवस्की योग की एक्स और वाई सब का सेट है x + y के लिए एक्स ∈ एक्स और वाई ∈ वाई


एक्स और वाई के लिए एक उदाहरण


एक्स, वाई और उनके मिंकोव्स्की योग, एक्स + वाई

मान लेना (-Y) y then Y के लिए all -y का सेट है , फिर पिछले पैराग्राफ को दिया गया है, X और Y इंटरसेक्ट यदि और केवल X + (-Y) में 0 हो , यानी मूल

साइड कमेंट: मैं X - Y के बजाय X + (-Y) क्यों लिखूं ? ठीक है, क्योंकि गणित में, और बी के मिंकोव्स्की अंतर नामक एक ऑपरेशन होता है, जिसे कभी-कभी एक्स - वाई लिखा जाता है, एक्स एक्स और वाई ( वाई के लिए सभी एक्स - वाई के सेट से कोई लेना-देना नहीं है (असली मिंकस्की) अंतर थोड़ा अधिक जटिल है)।

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

एक्स और वाई के मिंकोवस्की योग में एक शांत संपत्ति है, जो यह है कि अगर एक्स और वाई उत्तल हैं, तो एक्स + वाई भी है। और यह पता लगाना कि एक बिंदु उत्तल सेट से संबंधित है या नहीं , यदि वह सेट उत्तल (ज्ञात नहीं) उत्तल था, तो बहुत आसान है।

हम संभवतः के सभी गणना कर सकता है नहीं एक्स - y के लिए एक्स ∈ एक्स और वाई ∈ वाई क्योंकि वहाँ इस तरह के अंक की एक अनन्तता हैं एक्स और वाई , इसलिए उम्मीद है, के बाद से एक्स , वाई और X + Y उत्तल कर रहे हैं, हम सिर्फ उपयोग कर सकते हैं एक्स और वाई को आकार देने वाले "सबसे बाहरी" अंक , जो उनके कोने हैं, और हम एक्स + वाई के सबसे बाहरी अंक प्राप्त करेंगे , और कुछ और भी।

ये अतिरिक्त बिंदु एक्स + वाई के सबसे बाहरी लोगों द्वारा "घिरे" हैं ताकि वे नए प्राप्त उत्तल आकार को परिभाषित करने में योगदान न करें। हम कहते हैं कि वे बिंदुओं के समूह के " उत्तल पतवार " को परिभाषित नहीं करते हैं । तो हम क्या करते हैं कि हम अंतिम एल्गोरिथ्म की तैयारी में उनसे छुटकारा पा लेते हैं जो हमें बताता है कि मूल उत्तल पतवार के भीतर है या नहीं।


एक्स + वाई के उत्तल पतवार। हमने "अंदर" को हटा दिया है।

हम इसलिए मिलते हैं

एक पहला, भोली एल्गोरिथ्म

boolean intersect(Shape X, Shape Y) {

  SetOfVertices minkowski = new SetOfVertices();
  for (Vertice x in X) {
    for (Vertice y in Y) {
      minkowski.addVertice(x-y);
    }
  }
  return contains(convexHull(minkowski), Vector2D(0,0));

}

लूप में स्पष्ट रूप से जटिलता ओ (एमएन) होती है जहां एम और एन प्रत्येक आकार के कोने की संख्या होती है। minkoswkiसेट होता है एम.एन. अधिक से अधिक तत्वों। convexHullएल्गोरिथ्म एक जटिलता पर निर्भर करता है कि है एल्गोरिथ्म आप का इस्तेमाल किया है, और आप के लिए लक्ष्य कर सकते हैं ओ (कश्मीर लॉग (के)) जहां कश्मीर अंक के सेट के आकार है, इसलिए हमारे मामले में हम पाते हैं ओ (MN लॉग (MN) ) का हैcontainsएल्गोरिथ्म एक जटिलता किनारों (2 डी में) या उत्तल पतवार के चेहरे (3 डी में) की संख्या के साथ रैखिक है कि, तो यह वास्तव में अपने शुरू करने आकार पर निर्भर करता है, लेकिन यह अधिक से अधिक नहीं होगा ओ (MN)

मैं आपको containsउत्तल आकृतियों के लिए एल्गोरिथ्म के लिए गूगल करूँगा , यह एक बहुत ही आम बात है। अगर मेरे पास समय हो तो मैं इसे यहां रख सकता हूं।


लेकिन यह टकराव का पता लगाने का काम हम कर रहे हैं, इसलिए हम इसे बहुत अधिक अनुकूलित कर सकते हैं

हमारे पास मूल रूप से दो शरीर A और B एक टाइमस्टेप dt के दौरान बिना घुमाव के घूम रहे थे (जो मैं आपकी तस्वीरों को देखकर बता सकता हूं)। आइए कॉल वी एक और वी बी के संबंधित गति एक और बी , जो अवधि के बारे में हमारी timestep दौरान लगातार कर रहे हैं डीटी । हम निम्नलिखित प्राप्त करते हैं:

और, जैसा कि आप अपने चित्रों में इंगित करते हैं, ये निकाय क्षेत्रों में (या वॉल्यूम में, 3D में) चलते हुए स्वीप करते हैं:

और वे टाइमस्टेप के बाद ए ' और बी' के रूप में समाप्त होते हैं ।

हमारे भोले एल्गोरिथ्म को यहां लागू करने के लिए, हमें केवल स्वेप्ट वॉल्यूम की गणना करनी होगी। लेकिन हम ऐसा नहीं कर रहे हैं।

के संदर्भ फ्रेम में बी , बी (ओह!) के लिए कदम नहीं करता है। और A में B के संबंध में एक निश्चित वेग है जो आपको v A - v B से मिलता है (आप इसका रूपांतरण कर सकते हैं, A के संदर्भ फ्रेम में B के सापेक्ष वेग की गणना कर सकते हैं )।

सापेक्षिक गति

बाएं से दाएं: आधार संदर्भ फ्रेम में वेग; सापेक्ष वेग; सापेक्ष वेगों की गणना करना।

के बारे में करके बी का अपना संदर्भ फ्रेम में स्थिर के रूप में, आप केवल मात्रा की गणना करने के लिए है कि एक यह के दौरान ले जाता है के रूप में के माध्यम से स्वीप डीटी अपने रिश्तेदार वेग के साथ वी - वी बी

यह Minkowski राशि गणना (कभी-कभी बहुत) में उपयोग किए जाने वाले कोने की संख्या कम हो जाती है।

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

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

मान लीजिए कि आप अपने द्रव्यमान के केंद्रों के संबंध में A और B की त्रिज्या जानते हैं (यह कहना है, द्रव्यमान के बीच की दूरी और इससे दूर का शिखर), इस तरह:

टक्कर हो सकता है केवल यदि यह संभव है कि का सीमा चक्र एक की है कि मिलने बी । हम यहाँ देखते हैं कि यह नहीं होगा, और कंप्यूटर को यह बताने का तरीका है कि C B से I तक की दूरी को निम्न चित्र के रूप में गणना करें और सुनिश्चित करें कि यह A और B के त्रिज्या के योग से बड़ा है । यदि यह बड़ा है, तो कोई टक्कर नहीं। अगर यह छोटा है, तो टक्कर।

यह उन आकृतियों के साथ बहुत अच्छी तरह से काम नहीं करता है जो लंबे होते हैं, लेकिन वर्गों या ऐसी अन्य आकृतियों के मामले में, टकराव को नियंत्रित करने के लिए एक बहुत अच्छा अनुमानी है

B पर लागू अलग अक्ष प्रमेय और A द्वारा प्रवाहित आयतन , हालांकि, आपको बताता है कि क्या टक्कर होती है। संबंधित एल्गोरिथ्म की जटिलता प्रत्येक उत्तल आकृति के कोने की संख्या के योग के साथ रैखिक है, लेकिन जब टकराव को वास्तव में संभालने का समय आता है तो यह कम जादुई होता है।

टकरावों का पता लगाने में मदद करने के लिए चौराहों का उपयोग करने वाला हमारा नया, बेहतर एल्गोरिदम , लेकिन वास्तव में यह बताने के लिए अलग-अलग अक्ष प्रमेय जितना अच्छा नहीं है कि क्या टक्कर होती है

boolean mayCollide(Body A, Body B) {

  Vector2D relativeVelocity = A.velocity - B.velocity;
  if (radiiHeuristic(A, B, relativeVelocity)) {
    return false; // there is a separating axis between them
  }

  Volume sweptA = sweptVolume(A, relativeVelocity);
  return contains(convexHull(minkowskiMinus(sweptA, B)), Vector2D(0,0));

}

boolean radiiHeuristic(A, B, relativeVelocity)) {
  // the code here
}

Volume convexHull(SetOfVertices s) {
  // the code here
}

boolean contains(Volume v, Vector2D p) {
  // the code here
}

SetOfVertices minkowskiMinus(Body X, Body Y) {

  SetOfVertices result = new SetOfVertices();
  for (Vertice x in X) {
    for (Vertice y in Y) {
      result.addVertice(x-y);
    }
  }
  return result;

}

2

मुझे नहीं लगता कि 'षट्भुज' का उपयोग करना मददगार है। अक्ष-संरेखित आयतों के लिए सटीक टकराव प्राप्त करने का एक तरीका यहां दिया गया है:

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

उस समय अंतराल की गणना करें जिस पर एक अक्ष अंतर पर दो रेखाएं (जैसे यह समय पर शुरू होती है (वस्तुओं के वर्तमान पृथक्करण / वस्तुओं के वेग के सापेक्ष)), और दूसरी धुरी के लिए भी ऐसा ही करें। यदि वे समय अंतराल ओवरलैप करते हैं, तो ओवरलैप के भीतर का शुरुआती समय टकराव का समय है।


3
आप अपना स्केच भूल गए।
माइकलहाउस

2
@ बाइटे 56 नहीं, मेरा मतलब है कि यह एक एल्गोरिथ्म का स्केच है, यहां तक ​​कि स्यूडोकोड भी नहीं।
केविन रीड

ओह मैं समझा। मेरी गलती।
माइकलहाउस

यह वास्तव में सबसे आसान तरीका है। मैंने इसे लागू करने के लिए संबंधित कोड जोड़ा है।
पाशा

1

मुझे नहीं लगता कि आयत की तुलना में अधिक पक्षों के साथ बहुभुज की टक्कर की गणना करने का एक आसान तरीका है। मैं इसे लाइनों और वर्गों जैसे आदिम आकार में तोड़ दूंगा:

function objectsWillCollide(object1,object2) {
    var lineA, lineB, lineC, lineD;
    //get projected paths of objects and store them in the 'line' variables

    var AC = lineCollision(lineA,lineC);
    var AD = lineCollision(lineA,lineD);
    var BC = lineCollision(lineB,lineC);
    var BD = lineCollision(lineB,lineD);
    var objectToObjectCollision = rectangleCollision(object1.getRectangle(), object2.getRectangle());

    return (AC || AD || BC || BD || objectToObjectCollision);
}

वस्तुओं के मार्ग और अंतिम स्थिति का चित्रण

ध्यान दें कि मैं प्रत्येक ऑब्जेक्ट के स्टार्ट-स्टेट को कैसे अनदेखा करता हूं, जैसा कि पिछली गणना के दौरान जांचना चाहिए था।


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

0

अलग एक्सिस प्रमेय

सेपरेट एक्सिस प्रमेय कहता है, "यदि हम एक ऐसी धुरी पा सकते हैं जिस पर दो उत्तल आकृतियाँ प्रतिच्छेद नहीं करती हैं तो दो आकृतियाँ प्रतिच्छेद नहीं करती हैं" या IT के लिए अधिक व्यावहारिक:

"दो उत्तल आकार केवल तभी प्रतिच्छेद करते हैं यदि वे सभी संभावित अक्षों पर प्रतिच्छेद करते हैं।"

अक्ष संरेखित आयतों के लिए वास्तव में 2 संभावित अक्ष हैं: x और y। लेकिन प्रमेय केवल आयतों तक सीमित नहीं है, यह किसी भी उत्तल आकृति पर केवल अन्य अक्षों को जोड़कर लागू कर सकता है, जिन पर आकृतियाँ प्रतिच्छेद कर सकती हैं। विषय पर अधिक जानकारी के लिए N के डेवलपर द्वारा इस ट्यूटोरियल की जाँच करें: http://www.metanetsoftware.com/technique/tutorialA.html##ection1

कार्यान्वित यह इस तरह दिखता है:

axes = [... possible axes ...];
collision = true;
for every index i of axes
{
  range1[i] = shape1.getRangeOnAxis(axes[i]);
  range2[i] = shape2.getRangeOnAxis(axes[i]);
  rangeIntersection[i] = range1[i].intersectionWith(range2[i]);
  if(rangeIntersection[i].length() <= 0)
  {
    collision = false;
    break;
  }
}

एक्सिस को सामान्यीकृत वैक्टर के रूप में दर्शाया जा सकता है।

एक सीमा 1-आयामी रेखा है। प्रारंभ को सबसे छोटे अनुमानित बिंदु पर सेट किया जाना चाहिए, सबसे बड़े अनुमानित बिंदु का अंत।

इसे "व्यापक" आयत पर लागू करना

प्रश्न में षट्कोण का निर्माण वस्तु के AABB "स्वीपिंग" द्वारा किया जाता है। स्वीपिंग किसी भी आकार में सटीक एक संभव टक्कर अक्ष जोड़ता है: आंदोलन वेक्टर।

shape1 = sweep(originalShape1, movementVectorOfShape1);
shape2 = sweep(originalShape2, movementVectorOfShape2);

axes[0] = vector2f(1.0, 0.0); // X-Axis
axes[1] = vector2f(0.0, 1.0); // Y-Axis
axes[2] = movementVectorOfShape1.normalized();
axes[3] = movementVectorOfShape2.normalized();

अब तक बहुत अच्छा है, अब हम पहले से ही जांच कर सकते हैं कि क्या दो हेक्सागोन्स के प्रतिच्छेदन। लेकिन यह और बेहतर हो जाता है।

यह समाधान किसी भी उत्तल आकृतियों के लिए काम करेगा (उदाहरण के लिए त्रिकोण) और किसी भी उत्तल उत्तल आकृतियों (उदाहरण के लिए सप्तक)। हालांकि जितना अधिक जटिल आकार उतना ही कम प्रभावी होगा।


बोनस: जहां जादू होता है।

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

इसका मतलब है कि हम उस समय को प्राप्त कर सकते हैं जिसमें टक्कर इन दो अक्षों से हो सकती है। इसके लिए हमें आंदोलन अक्षों पर दो चौराहों के बीच चौराहे को खोजने की आवश्यकता है। इससे पहले कि हम ऐसा कर सकें, हमें हालांकि दोनों सीमाओं को सामान्य करने की आवश्यकता है, इसलिए हम वास्तव में उनकी तुलना कर सकते हैं।

shapeRange1 = originalShape1.getRangeOnAxis(axes[2]);
shapeRange2 = originalShape2.getRangeOnAxis(axes[3]);
// Project them on a scale from 0-1 so we can compare the time ranges
timeFrame1 = (rangeIntersection[2] - shapeRange1.center())/movementVectorOfShape1.project(axes[2]);
timeFrame2 = (rangeIntersection[3] - shapeRange2.center())/movementVectorOfShape2.project(axes[3]);
timeIntersection = timeFrame1.intersectionWith(timeFrame2);

जब मैंने यह सवाल पूछा तो मैं थोड़े पहले ही समझौता स्वीकार कर लिया था कि इस पद्धति के साथ कुछ दुर्लभ झूठी सकारात्मकताएं होंगी। लेकिन मैं गलत था, इस समय चौराहे की जाँच करके हम परीक्षण कर सकते हैं कि क्या टक्कर "वास्तव में" हुई थी और हम उन झूठी सकारात्मक चीजों को छाँट सकते हैं:

if(collision)
{
  [... timeIntersection = see above ...]
  if(timeIntersection.length() <= 0)
    collision = false;
  else
    collisionTime = timeIntersection.start; // 0: Start of the frame, 1: End of the frame
}

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


1
आपके समाधान खोजने के लिए बधाई! लेकिन जैसा कि मैंने पहले कहा: सिर्फ इसलिए कि हेक्सागोन्स प्रतिच्छेद का मतलब यह नहीं है कि टक्कर होगी। आप अपनी विधि का उपयोग टकराव के समय की गणना करने के लिए कर सकते हैं जो आप चाहते हैं, यदि कोई टक्कर नहीं है, तो यह बहुत उपयोगी नहीं है। दूसरा, आप सापेक्ष गति का उपयोग कर सकते हैं ताकि केवल 1 स्वेप्ट मात्रा की गणना हो, और सैट का उपयोग करते समय गणनाओं को सरल बनाया जा सके। अंत में, मुझे केवल एक मोटा-मोटा अंदाजा है कि आपकी "चौराहे का समय" चाल कैसे काम करती है, क्योंकि हो सकता है कि आपको अपने सूचकांक मिल गए हों, shapeRange1 == shapeRange2अपने कोड के साथ देखकर , क्या यह नहीं है?
जलसा

@ कामशोगो को अभी और समझदारी चाहिए।
एपीआई-बीस्ट २४'१३

मुझे अभी भी समझ में नहीं आया कि सीमा का सामान्यीकरण कैसे काम करता है, लेकिन मुझे लगता है कि मुझे चित्र की आवश्यकता है। आशा है कि ये आपके काम आएगा।
जर्सला

-2

जब तक बह क्षेत्र दोनों बंद हो जाते हैं (किनारे-रेखाओं द्वारा बनाई गई सीमा में कोई अंतराल नहीं), निम्नलिखित काम करेगा (बस लाइन-लाइन और बिंदु-आयत / बिंदु-त्रि तक आपके टकराव परीक्षणों को कम करें):

  1. क्या उनके किनारे छूते हैं? (लाइन-लाइन टकराव) जाँच करें कि क्या किसी स्वेप्ट क्षेत्र की कोई भी बढ़त दूसरे स्वेप्ट क्षेत्र की किसी भी किनारे-रेखा के साथ प्रतिच्छेदन करती है। प्रत्येक बह क्षेत्र में 6-पक्ष हैं।

  2. क्या बड़े के अंदर एक छोटा है? (अक्ष संरेखित आकृतियों (पॉइंट-रेक्ट और पॉइंट-ट्राई) का उपयोग करें) स्व-क्षेत्रों को फिर से ओरिएंट करें (घुमाएँ) ताकि बड़ा एक अक्ष-संरेखित हो और परीक्षण करें कि क्या छोटा आंतरिक है (परीक्षण द्वारा कि कोई कोने बिंदु सभी या कोई भी नहीं होना चाहिए) धुरी-संरेखित बह क्षेत्र के भीतर हैं)। यह आपके हेक्स को ट्रिस और रेक्ट्स में विघटित करने के लिए किया जाता है।

आप पहले कौन सा परीक्षण करते हैं, यह प्रत्येक की संभावना पर निर्भर करता है (सबसे पहले होने वाली सबसे आम बात करें)।

आपको स्वेप्ट बाउंडिंग सर्कल (हेक्स के बजाय कैप्सूल) का उपयोग करना आसान लग सकता है क्योंकि यह दो अर्ध-मंडलियों और एक आयत में विभाजित होने पर आसान होता है जब यह अक्ष-संरेखित होता है। .. मैं आपको समाधान आकर्षित करने देता हूँ


अगर आयतों में से एक वास्तव में छोटा है और दो धार लाइनों के बीच की जगह के भीतर चलता है तो काम नहीं करता है।
जर्सला

@madshogo मैंने अभी अपनी प्रतिक्रिया में जोड़ा है। अब पूर्ण समाधान होना चाहिए।
अक्षतंतु

1
"अक्ष संरेखित आकृतियों (बिंदु-आयत और बिंदु-त्रि) का उपयोग करें": आप कुल्हाड़ियों के साथ त्रिकोण या "बिंदु-त्रिकोण" (जो भी मतलब है) को कैसे संरेखित करते हैं? "ताकि बड़ा एक अक्ष-संरेखित हो": आप यह कैसे बता सकते हैं कि कौन सा दूसरे से बड़ा है? क्या आप उनके क्षेत्रों की गणना करते हैं? "यह आपके हेक्स को ट्रिस और रेक्ट्स में विघटित करने के लिए किया जाता है।": कौन सा हेक्स? वहाँ दॊ है। "(या इस प्रतिक्रिया को बढ़ाएँ यदि आप चाहते हैं कि मैं आपके लिए इसे स्पष्ट करूँ)": क्या आप गंभीर हैं ??
जलसा

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