सबसे पहले, अक्ष-संरेखित आयतों के मामले में, केविन रीड का जवाब सबसे अच्छा है और एल्गोरिथ्म सबसे तेज़ है।
दूसरा, सरल आकृतियों के लिए, टकराव का पता लगाने के लिए सापेक्ष वेग (जैसा कि नीचे देखा गया है) और अलग-अलग अक्ष प्रमेय का उपयोग करें। यह आपको बताएगा कि क्या रैखिक गति (कोई रोटेशन नहीं) के मामले में टकराव होता है। और अगर रोटेशन होता है, तो आपको सटीक होने के लिए एक छोटे टाइमस्टेप की आवश्यकता होती है। अब, सवाल का जवाब देने के लिए:
सामान्य मामले में कैसे बताएं कि क्या दो उत्तल आकृतियाँ प्रतिच्छेद करती हैं?
मैं आपको एक एल्गोरिथ्म दूंगा जो सभी उत्तल आकृतियों के लिए काम करता है और न केवल हेक्सागोन्स के लिए।
मान लीजिए कि 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;
}