एक पथ (निर्देशांक की सूची) पर चलते समय मेरे पात्रों को कैसे चिकना करना है?


15

मेरे पास निर्देशांक के साथ एक सूची है - ए * एल्गोरिदम से आउटपुट - और मैं अपने पात्रों को आसानी से घुमाव के साथ इस पथ का पालन करना चाहूंगा।

इसलिए मेरे पास जैसा कुछ है और मैं सी प्राप्त करना चाहता हूं

यहाँ छवि विवरण दर्ज करें

मैं यह कैसे कर सकता हूँ ?

संपादित करें

खुद को थोड़ा और स्पष्ट करने के लिए:

मुझे चिकनी मोड़ में अधिक दिलचस्पी है क्योंकि मुझे पहले से ही पता है कि एक नोड से दूसरे तक कैसे चलना है।

संपादित करें

जैसा कि कई लोगों को यह उपयोगी लगता है (मुझे भी) मैं डैनियल शिफमैन के "कोड की प्रकृति" के लिए लिंक पोस्ट कर रहा हूं, जहां वह बहुत सारे गेम AI (और भौतिकी) समस्याओं की चर्चा करता है जैसे स्टीयरिंग व्यवहार http://natureofcode.com/book/chapter- 6-स्वायत्त-एजेंटों / # chapter06_section8


एकता में निर्मित नहीं है?
joltmode

@ ठीक है हां, लेकिन मेरे पास मेरा संस्करण वैसे भी लागू है। इस प्रश्न का बिंदु मार्ग पर चलते समय चिकने घुमाव (घुमाव) प्राप्त करना है।
पेट्रीक

3
इस संबंध में Google के लिए एक अच्छा शब्द 'स्टीयरिंग बिहेवियर' है :)
रॉय टी।

3
@RoyT। बेशक ! मैं इस कुछ सप्ताह पहले पढ़ने किया गया है और पहले से ही भूल गया: / इस भयानक गणित + भौतिकी स्पष्टीकरण के साथ निम्न पथ पर एक महान लेख है natureofcode.com
पेट्रिक

1
मैं सिर्फ लिंक के लिए @Patryk को धन्यवाद देना चाहता था - वास्तव में सूचनात्मक लग रहा है, और मैं स्टीयरिंग व्यवहार पर एक अच्छे संसाधन की तलाश कर रहा हूं।
क्रिश्चियन

जवाबों:


7

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

एक बार जब आप इस तरह अनावश्यक किनारों को हटा देते हैं, तो आपका पहला मामला ( ए -> बी ) हल हो जाता है। अपने ग्राफ में किनारों को चिकना करना कई तरीकों से पूरा किया जा सकता है। सबसे अधिक संभावना है, हर्मीट स्प्लिन काम करेगा (आपके बाधा घनत्व और टाइल-आकार पर थोड़ा निर्भर करता है)। एक अन्य विकल्प स्टीयरिंग व्यवहार हो सकता है, जहां आप अगले तरीके की ओर बढ़ना शुरू करते हैं, जैसे ही आप वर्तमान लक्ष्य से आधा टाइल दूर होते हैं (यह वास्तव में इस बात पर निर्भर करता है कि आपका "एजेंट" कितनी तेजी से चलता / बदल जाता है)।


9

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

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

थीटा * बनाम पथ चौरसाई

वहाँ एक अच्छा लेख समझा थीटा * (जिसमें से मैं ऊपर छवि चुरा लिया) है यहाँ


2

एक अधिक मानवीय यथार्थवादी आंदोलन के लिए, स्टीयरिंग बिहेवियर के साथ एकीकरण करने का प्रयास करें। (क्लासिक OpenSteer http://sharpsteer.codeplex.com/ का संस्करण # ) आपको AStar का आउटपुट मिलता है और स्टीयरिंग बिहेवियर को मूवमेंट के बारे में ध्यान रखने देता है (नमूनों में से एक यह दिखाता है कि यह कैसे करना है, एक पथ का अनुसरण करते हुए)


1

बिंदु से बिंदु तक नेविगेशन के मामले में, मैंने कोणों (वर्तमान खिलाड़ी दिशा बनाम वर्तमान बिंदु से अगले बिंदु तक दिशा) में अंतर का उपयोग किया और फिर आंदोलन के रूप में धीरे-धीरे कोण को अंतिम कोण में बदल दिया। इस खेल को यहां देखें जहां हवाई जहाज 1 बिंदु से दूसरे बिंदु पर जाते हैं लेकिन मोड़ अचानक नहीं है लेकिन ध्यान से देखने पर मार्ग के बिंदुओं को पहचान सकते हैं। (खेल केवल मोबाइल पर काम करता है, हालांकि अधिमानतः iPhone / iPad)।


यह वही है जो मैंने किया।
प्रात:

1

मुझे कैटमुल-रोम स्प्लिन्स (क्यूबिक स्लाइन का एक प्रकार @bummzack द्वारा अनुशंसित) के साथ अच्छी किस्मत मिली है। उन लोगों के बारे में अच्छी बात यह है कि तख़्ता हमेशा नियंत्रण बिंदुओं के माध्यम से जाएगा, कई अन्य नहीं करते हैं। कुछ इस तरह से लागू करें:

t    = <time*>
t12  = t + 1.0
t23  = t
t34  = t - 1.0
t123 = (t + 1.0) / 2.0
t234 = t / 2

c1 = controlpoint[0];
c2 = controlpoint[1];
c3 = controlpoint[2];
c4 = controlpoint[3];

l12 = lerp(c1, c2, t12);
l23 = lerp(c2, c3, t23);
l34 = lerp(c3, c4, t34);
position = lerp(lerp(l12, l23, t123), lerp(l23, l34, t234), t);

* समय नियंत्रण अंक 1 और 2 के बीच एक मान [0,1] है।


0

A-> B को ग्रिड की बजाय नेविगेशन मेश का उपयोग करके हल किया जा सकता है। इसका अर्थ है डेटा जनरेशन में पाथफंडिंग में एक बड़ा बदलाव।

C और D जैसे मामले केवल कोने काटने वाले हैं: यदि चरित्र एक पथ में और "कोने" के अंदर चल रहा है (सेल जहां पिछली, वर्तमान, अगली कोशिकाएं एक सीधी रेखा पर नहीं हैं), तो इसे पिछले और अगले सेल दोनों की दिशा में धकेलें । एकमात्र समस्या वास्तविक स्थिति से दूरी (धकेलने की दूरी) निर्धारित करना है। संभवतः इनपुट के रूप में वर्तमान सेल से दूरी की आवश्यकता होगी। कुछ इस तरह:

push_dir = average( prevcell.pos, nextcell.pos ) - curcell.pos;
push_dist = cell_half_width - distance( char.pos, curcell.pos );
char.pos += push_dir * push_dist;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.