घटता के साथ टकराव का पता लगाने


12

मैं एक 2D गेम पर काम कर रहा हूं, जिसमें मैं एक मूविंग सर्कल और कुछ प्रकार के स्टैटिक कर्व्स (शायद बेजियर कर्व्स) के बीच टक्कर का पता लगाना चाहता हूं।

वर्तमान में मेरे खेल में केवल स्टैटिक ज्यामिति के रूप में सीधी रेखाएँ हैं और मैं सर्कल से लाइनों की दूरी की गणना करके टकराव का पता लगा रहा हूँ, और दूरी को वृत्त की त्रिज्या से कम होने की स्थिति में लाइन के बाहर सर्कल का अनुमान लगा रहा हूँ।

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


अद्यतन: महान जवाब के लिए बहुत बहुत धन्यवाद! मुझे आपके द्वारा वर्णित विधि को पूरी तरह से समझने के लिए बेज़ियर कर्व्स पर पढ़ना होगा। फिर मैं आपके पास वापस आऊंगा।

जवाबों:


6

29/09/2012 - 23:20

मैंने यहाँ एक git रेपो बनाया: https://github.com/ArthurWulfWhite/Bezier-Distion/

वहाँ से ज़िप के रूप में स्रोत फ़ाइलों को डाउनलोड करने के लिए आपका स्वागत है। इसमें एक डेमो भी शामिल है जिसे आप FlashDevelop का उपयोग करके संकलित कर सकते हैं। डेमो का उपयोग करने के लिए, फ़्लैश डेवलपमेंट में प्रोजेक्ट खोलें और 'टेस्ट प्रोजेक्ट' पर क्लिक करें। डेमो चलाते समय, एक नए बेज़ियर वक्र और एक नए सर्किल को यादृच्छिक बनाने के लिए LMB पर क्लिक करें।

सौभाग्य!

ज़िप लिंक को देखना मुश्किल है - बस Ctrl + F का उपयोग करें और ज़िप टाइप करें। यह स्रोत कुछ हफ्तों के पुन: खोज और प्रोग्रामिंग का प्रतिनिधित्व करता है, मुझे उम्मीद है कि आप इसका आनंद लेंगे।


यदि आप बीज़ियर को पुन: खंडों में विभाजित करने और उनके साथ टकराव की जाँच करने की योजना बनाते हैं, तो मैं सुझाव देता हूं कि 100,100 सरणी (ग्रिड) बनाएं और प्रत्येक खंड को चार निकटतम वर्गों में रखें, इसलिए आपको केवल 4 या 10,000 के साथ टकराव की जाँच करनी होगी। प्रत्येक फ्रेम खंड।

मुझे लगता है कि आप एक प्रोग्रामर के रूप में और एक गेम निर्माता के रूप में दोनों बॉक्स 2 डी से लाभान्वित होंगे, क्योंकि एक 'सरल' भौतिकी इंजन बनाने में बहुत सी छिपी हुई छोटी बाधाएं हैं जो गति को थोड़ा ऊबड़ और कम द्रव लगता है तो यह हो सकता है।

पुराना उत्तर: शुद्ध तरीका।

आप वास्तव में देख सकते हैं कि क्या वृत्त के केंद्र के बीच की दूरी और वक्र पर निकटतम बिंदु के बीच की दूरी की जांच करके, एक वृत्त बेजियर वक्र से टकरा रहा है।

दूरी के लिए समीकरण (सामान्य रूप में)

व्याख्या की:

बेजियर समीकरण:

q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))

इसे (कुछ बीजगणित के साथ) के लिए संक्षेपित किया जा सकता है - मैं पठनीयता के लिए (x, y) छोड़ दूंगा (वे अभी भी अंक हैं, एक संख्या नहीं)

q(t) = (start -2 * cont + end) t^2 + (-2 * start + 2 * control) + start

बिंदु से दूरी (x, y) है:

sqrt ((q(t).x - point.x)^2 + (q(t).y - point.y)^2)

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

व्युत्पन्न के लिए आपको जड़ों को ढूंढना होगा:

मान लें: a = start b = control c = end d = cirlce केंद्र बिंदु

भेड़ियाग्राम अल्फा का उपयोग कर व्युत्पन्न

मुश्किल हिस्सा इस बिंदु को बढ़ा रहा है, आपको डॉट उत्पाद का उपयोग करना होगा।

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

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

जड़ों को खोजने के लिए आप न्यूटन की तरह किसी भी विश्वसनीय विधि का उपयोग कर सकते हैं, बेज़ियर पर रूट बिंदुओं से दूरी की जांच करें, सर्कल सेंटर के लिए 0 <= t <= 1 और सर्कल के दो सिरों के लिए दूरी की जांच करें (शुरुआत) और अंत) सर्कल सेंटर में, जो भी निकटतम है, आपको बताएगा कि क्या कोई टक्कर है।

यदि त्रिज्या न्यूनतम दूरी से छोटी है, तो टकराव होता है।

कोण लगभग चक्र के केंद्र और बीज़ियर पर निकटतम बिंदु के बीच एक है।

कहा जा रहा है, यदि आप वास्तव में टक्कर भौतिकी के साथ एक खेल बनाने की इच्छा रखते हैं, तो मैं आपको सुझाव देता हूं कि आप बेजियर पर बस पुनरावृति करें

    q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))

बीच में प्रत्येक टुकड़े को पुनरावर्ती रूप से विभाजित करें जब तक कि यह काफी छोटा न हो, 10 पिक्सेल या उससे कम का कहना है, तो बक्सों से मोटे तौर पर निर्माण करें और भौतिकी के लिए Box2d का उपयोग करें क्योंकि यह संभव है कि यह सभी टकराव पहचान कोड लिखना एक महान साबित होगा। टाइम सिंक जो कि गेमप्ले को ज्यादा नहीं बढ़ाता है। Box2d का उपयोग अतीत में अनगिनत परियोजनाओं में खुद को साबित किया है।


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

आपके खेल में कितनी वस्तुएँ हैं? एक-दूसरे से कितने टकरा सकते हैं? कभी-कभी भौतिकी इंजन का उपयोग करने से महान लाभ मिल सकता है, जैसे कि यह टकराव के समय की सही गणना करता है। (कारण फ्रेम असतत हैं और टकराव वास्तविक हैं (जब आप किसी फ्रेम को प्रस्तुत करते हैं तो ठीक नहीं होता है)
AturSams

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

मैंने अभी कुछ और विवरण जोड़े, शुभकामनाएँ। :)
AturSams

मैं खेल की तरह एक साधारण इलास्टो उन्माद बना रहा हूं। केवल तीन गतिमान वृत्त और स्थिर ज्यामिति। पूरा इंजन समाप्त हो गया है और शानदार काम कर रहा है। केवल एक ही चीज़ बची है जो घटता है जिसके लिए मैं इस उत्तर में मदद के लिए atm धन्यवाद हल करने वाला हूँ :) आप जिस कोड का उल्लेख करते हैं उसे पोस्ट करने के लिए स्वतंत्र महसूस करें। आपको लगता है कि वास्तविक जीवन में इसका उपयोग करना कितना उचित होगा? बीज़ियर को छोटी लाइनों में परिवर्तित करने से बेहतर है?
पालदीपंड

7

ऐसा करने के लिए, मैं:

  • बीज़ियर वक्र को विच्छेद रेखा खंडों में तोड़ें और उन्हें संग्रहीत करें।

  • इन सभी खंडों को पूरे वक्र के लिए एक अक्ष संरेखित बाउंडिंग बॉक्स में रखें।

टक्कर की पहचान हुई है :

1) जाँच करें कि गोला मुख्य बाउंडिंग बॉक्स के अंदर है या नहीं। यदि नहीं, तो कोई टक्कर नहीं।

2) अन्यथा, जाँच करें कि क्या ऊपर से अलग-अलग खंडों की गणना किसी क्षेत्र से टकराकर हुई है। विकिपीडिया से रेखा-क्षेत्र चौराहा लेख देखें ।

संपादित करें: यदि आपको उच्च परिशुद्धता की आवश्यकता है और अच्छा प्रदर्शन चाहते हैं, तो आप पूरे वक्र के लिए एक मुख्य बाउंडिंग बॉक्स भी बना सकते हैं, फिर वक्र को दो खंडों में विभाजित कर सकते हैं (जैसे: [0.0 - 0.5]और [0.5 - 1.0])। उनमें से प्रत्येक के लिए एक गुलदस्ता बॉक्स बनाएं, फिर इनमें से प्रत्येक खंड को दो खंडों में उप-विभाजित करें (इस प्रकार दे रहे हैं [0 - 0.25], [0.25 - 0.5]और [0.5 - 0.75], [0.75 - 1.0])। इस तरह से जारी रखें जब तक आप पर्याप्त सटीकता तक नहीं पहुंचते। अंत में आपके पास binary treeमुख्य वक्र बाउंडिंग बॉक्स के साथ रूट और लाइन सेगमेंट में पत्तियों पर बाउंडिंग बॉक्स होंगे। पेड़ में खोज O(log n)करने से आपको बदले में O(n)(जहां n= वक्र के लिए लाइन सेगमेंट की संख्या) मिल जाएगी


यह समाधान मेरे लिए समझ में आता है और निश्चित रूप से समझने में सबसे आसान है और मैं इसके साथ समझौता कर सकता हूं। लेकिन मैं उत्सुक हूँ अगर एक और "शुद्ध" विकल्प मौजूद है।
पालदीपंड 20

5

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

यह लेख इसे एक बिंदु तक शामिल करता है: http://students.cs.byu.edu/~tom/557/text/cic.pdf

अच्छा हिस्सा यह है कि एल्गोरिथ्म किसी भी रेखा के साथ काम करता है, आपको बस वक्र में एक कठोर परिवर्तन लागू करना होगा ताकि आप अपनी लक्ष्य रेखा को ऑक्स अक्ष के समानांतर होने पर विचार कर सकें।

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


मैंने अभी तक लेख नहीं पढ़ा है। लेकिन मैं एक लाइन और एक बेजियर वक्र के बीच चौराहे से एक सर्कल और एक बेजियर के बीच चौराहे तक कैसे पहुंच सकता हूं? एक सर्कल और एक बहुभुज के खिलाफ टक्कर की जाँच करना मुझे बहुत जटिल लगता है।
पालदीपंड 20
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.