एक साधारण 2 डी आयत टकराव एल्गोरिथ्म जो यह भी निर्धारित करता है कि आयताकार किन पक्षों से टकराते हैं?


16

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

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

दूसरी ओर, मैं कई आयतों के बारे में सोच रहा था, प्रत्येक पक्ष के लिए प्रत्येक आयत। हालाँकि, फिर से सोचने के बाद, यह दूरी रेंज की जाँच के साथ समानांतर पक्ष होने के समान ही होगा, बस यह दूरी प्रत्येक मिनी-आयत की चौड़ाई है।

इसलिए, इस समस्या का कोई सुझाव?


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

जवाबों:


24

मेरे जवाब से "कौन सा पक्ष मारा गया था?" :

मेरा सुझाव है कि बी और ए के मिन्कोवस्की योग की गणना करें , जो एक नई आयत है, और जाँच कर रहा है कि आयत का केंद्र उस नई आयत (यह जानने के लिए है कि क्या कोई टक्कर हो रही है) और उसके विकर्णों (यह जानने के लिए कि टक्कर कहाँ है ) से अपेक्षाकृत झूठ है घटित हो रहा है):

float w = 0.5 * (A.width() + B.width());
float h = 0.5 * (A.height() + B.height());
float dx = A.centerX() - B.centerX();
float dy = A.centerY() - B.centerY();

if (abs(dx) <= w && abs(dy) <= h)
{
    /* collision! */
    float wy = w * dy;
    float hx = h * dx;

    if (wy > hx)
        if (wy > -hx)
            /* collision at the top */
        else
            /* on the left */
    else
        if (wy > -hx)
            /* on the right */
        else
            /* at the bottom */
}

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

महान समाधान, मेरी जरूरतों के लिए बहुत अच्छा काम किया।
ओपियेटफुच्स

1
क्या dx बनने के साथ कुछ गड़बड़ है या 0 या डाई बन रहा है या दोनों? मुझे इसका कारण बताना चाहिए ... अगर dx = 0 && dy == 0, इसका मतलब है कि दोनों आयत एक ही मूल पर हैं, तो एल्गोरिथ्म डिफ़ॉल्ट रूप से नीचे लौटता है? यदि उनमें से कोई भी 0 है, तो सही परिणाम की उम्मीद है। इसलिए, मुझे लगता है, यह एल्गोरिथ्म उस मामले को छोड़कर सही है जहां dx == 0 && डाई == 0 है, जो अनिश्चित होना चाहिए और नीचे नहीं होना चाहिए। तो, सावधान रहें और धन्यवाद।
प्रशांत

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