एक ग्रिड आधारित तरल सिमुलेशन में दबाव का अनुकरण


30

मेरे XNA गेम में 2 डी ग्रिड आधारित पानी की व्यवस्था है, हमारे पास पानी गिरने और फैलने का अनुकरण करने के लिए सेलुलर ऑटोमेटा का उपयोग करने की एक विधि है।

ढलान के नीचे बहने वाले पानी का उदाहरण:

जल भौतिकी

प्रत्येक टाइल में एक बाइट में संग्रहित 0 से 255 मान द्रव्यमान हो सकता है। मैं उपयोग नहीं करता हूं floats, मैंने जो पुरानी पानी की व्यवस्था की थी, हालांकि इसमें जटिलताओं को जोड़ा गया था और एक प्रदर्शन हिट था।

प्रत्येक पानी टाइल नियमों के एक सरल सेट के साथ खुद को अपडेट करता है:

  1. यदि नीचे दी गई टाइल में जगह है, तो वर्तमान टाइल से नीचे की ओर जितना संभव हो उतना नीचे जाएं (फ़्लो डाउन)
  2. यदि 2 भुजाएँ समान नहीं हैं और शून्य नहीं हैं और दोनों निष्क्रिय हैं, तो हमें 3 टाइलों का योग मिलता है (बाएँ + वर्तमान + दाएँ) और इसे 3 से विभाजित करके शेष को बीच (वर्तमान) टाइल पर छोड़ दें
  3. यदि उपरोक्त नियम ने योग के रूप में 2 की संख्या दी है, तो हमें टाइल्स को दो पक्षों में विभाजित करना चाहिए (1, 0, 1)
  4. यदि नियम 2 ने 1 को राशि के रूप में दिया है, तो प्रवाह करने के लिए एक यादृच्छिक पक्ष चुनें
  5. यदि नियम 2 विफल हो गया है, तो हमें यह देखना चाहिए कि क्या एक पक्ष निष्क्रिय है और दूसरा नहीं है। अगर यह सच है, तो हम वर्तमान टाइल को 2 टाइलों के लिए आधे में विभाजित करते हैं

मैं दबाव को शामिल करने के लिए इस तर्क का विस्तार कैसे कर सकता हूं? दबाव तरल पदार्थ "यू-बेंड्स" से अधिक हो जाएगा और हवा की जेब में भर जाएगा।

वर्तमान में यह कैसे विफल रहता है पर उदाहरण:

दबाव विफल

पानी यू-बेंड के प्रत्येक तरफ बहना और बराबर होना चाहिए। इसके अतिरिक्त, मैंने यह पता लगाने के लिए तरीके बनाए हैं कि पानी का ब्लॉक कितना नीचे है, और इसलिए यह कितना दबाव महसूस कर रहा है। अब मुझे इन संख्याओं को लेने और दबाव को बराबर करने के लिए अन्य क्षेत्रों में लागू करने में सक्षम होने की आवश्यकता है।


समस्या यह है कि इसे एक सेलुलर ऑटोमेटा रखना मुश्किल है। चूंकि अब प्रत्येक ब्लॉक को यह जानने की जरूरत है कि इसके आगे क्या है। मैंने एक सिस्टम बनाया है जो आप 3D में चाहते हैं। यह एक बहुत ही जटिल प्रणाली है, लेकिन मुझे लगता है कि यह 2 डी में अधिक उल्लेखनीय होगा।
MichaelHouse

@ Byte56 वैसे तो हमें सेलुलर ऑटोमेटा होने की आवश्यकता नहीं है , जब तक हम इसे उचित गति से चालू रख सकते हैं।
साइराल

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

धन्यवाद, कि सराहना की जाएगी। मैं बौने किले के निर्माता के साथ कुछ साक्षात्कार पढ़ता हूं और उसने यह किया है कि मैं यह विश्वास करता हूं, लेकिन मुझे यकीन नहीं था कि वह कुछ समस्याओं को कैसे पार कर सकता है, इसलिए मैंने कभी कोशिश नहीं की।
साइरेल

1
ध्यान दें, एक बार जब आप एयर प्रेशर जोड़ लेते हैं, तो दो एयर-पॉकेट उदाहरण संभावित रूप से पूरी तरह से वैध (बंद दबाव कक्ष) होते हैं। मैं मान रहा हूँ कि आप 255 बाइट का उपयोग नहीं कर रहे हैं , बल्कि मान 0-255; किसी भी मामले में, आप शायद इस तरह से पूरी रेंज का उपयोग नहीं करना चाहते हैं। मैं शायद इसे दबाव के of 1 वायुमंडल ’के लिए hmm, 0-15 तक सीमित कर दूंगा (उच्च दाब, दाएं?) जैसी कोई चीज नहीं है, जिससे उच्च दबाव की अनुमति मिलती है, जिसकी आपको वर्तमान में कमी है। एक बार जब आप सिम में 'वायु' ब्लॉक को शामिल करते हैं, तो पानी के ब्लॉक के स्वाभाविक रूप से उच्च 'वजन' को झुकना चाहिए।
क्लॉकवर्क-म्यूजियम

जवाबों:


6

ध्यान दें कि मैंने कभी ऐसा नहीं किया है; ये केवल विचार हैं जो मदद कर सकते हैं। या पूरी तरह से फर्जी हो सकता है। मैं टेरारिया के बाद से इस समस्या से निपटना चाहता हूं, लेकिन मैं अभी इस तरह के खेल पर काम नहीं कर रहा हूं।

एक ऐसा तरीका जिस पर मैंने विचार किया है वह यह है कि दुनिया के निचले भाग से प्रत्येक सतह जल खंड (इसके ऊपर कोई जल खंड और इसके ऊपर कोई जल खंड नहीं है) को एक प्रारंभिक दबाव मान (या एक समारोह) के बराबर दिया जाए। किसी भी अभेद्य टाइल का निहित दबाव मूल्य MAX_PRESSURE(255 का कहना है) है, और एक खुली हवा के लिए टाइल MIN_PRESSURE(0) है।

प्रेशर तब किसी भी टाइल से टाइल के उच्च दबाव के साथ प्रत्येक टिक, सेलुलर ऑटोमेटा शैली के दौरान कम दबाव के साथ ऊपर / नीचे / बग़ल में फैल जाता है। मैं वास्तव में क्या बराबरी करने के लिए बाहर निकालने के लिए एक वास्तविक सिमुलेशन प्राप्त करना होगा। एक ब्लॉक का दबाव इसके निहित दबाव के बराबर होना चाहिए और साथ ही चारों ओर से "अतिरिक्त" दबाव बराबर होगा (इसलिए आपको केवल इस अतिरिक्त दबाव को संग्रहीत करने की आवश्यकता होगी, न कि अंतर्निहित दबाव)।

यदि सतह की टाइल पर दबाव होता है, तो इसके निहित ऊँचाई-आधारित दबाव से अधिक होगा और यदि ऊपर की टाइल में पानी के लिए खाली स्थान है, तो पानी का एक छोटा हिस्सा ऊपर की ओर बढ़ जाता है। पानी तभी नीचे बहता है, जब दोनों में टाइल की अपेक्षा के मुकाबले कम दबाव होता है।

यह मोटे तौर पर इस विचार का अनुकरण करता है कि जितना गहरा पानी "बिंदु" का उतना अधिक दबाव होता है, यद्यपि दबाव के मान वास्तविक दबाव की तुलना में अधिक ऊंचाई का प्रतिनिधित्व करते हैं (चूंकि उच्च टाइल से उच्च "दबाव" होने की उम्मीद है)। यह hसमीकरण में शब्द की तरह दबाव थोड़े को बनाता है (लेकिन वास्तव में नहीं):

P' = P + qgh

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

मैं अनिश्चित हूं कि कैसे निपटना है या क्या किसी को भी "एयर बबल" से निपटने की जरूरत है जो बनाया जाएगा (जहां एक गैर-सतह टाइल में गैर-पूर्ण पानी की मात्रा होगी क्योंकि पानी ऊपर की ओर धकेल दिया जाता है)। मैं अभी भी अनिश्चित हूं कि आप एक तरफ असमान होने के कारण पानी के दबाव से कैसे बचेंगे और फिर दूसरी तरफ, असमान होने के बाद भी टिक नहीं पाएंगे।


20

मैंने एक सिस्टम बनाया है जो आप 3 डी में हैं। मेरे पास एक छोटा सा वीडियो है जो यहां के सरल यांत्रिकी और यहां एक ब्लॉग पोस्ट को प्रदर्शित करता है

यहाँ मैं एक अदृश्य दीवार के पीछे दबाव यांत्रिकी से बना एक छोटा सा GIF है (उच्च गति पर खेला जाता है):

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

सिस्टम के कुछ फीचर्स का अंदाजा लगाने के लिए मुझे इसमें शामिल डेटा के बारे में बताएं। वर्तमान प्रणाली में, पानी के प्रत्येक ब्लॉक में 2 बाइट्स शामिल हैं:

//Data2                          Data
//______________________________  _____________________________________
//|0    |0      |000   |000    |  |0        |0       |000      |000   |
//|Extra|FlowOut|Active|Largest|  |HasSource|IsSource|Direction|Height|
//------------------------------  -------------------------------------
  • Height आपके दबाव के समान क्यूब में पानी की मात्रा है, लेकिन मेरे सिस्टम में सिर्फ 8 स्तर हैं।
  • Directionदिशा प्रवाह है। यह तय करते समय कि पानी आगे कहां बहेगा, इसकी वर्तमान दिशा में जारी रहने की संभावना अधिक है। इसका उपयोग जरूरत पड़ने पर अपने स्रोत क्यूब तक एक प्रवाह को जल्दी से वापस करने के लिए भी किया जाता है।
  • IsSourceइंगित करता है कि क्या यह घन एक स्रोत घन है, जिसका अर्थ है कि यह कभी भी पानी से बाहर नहीं निकलता है। नदियों, झरनों, आदि के स्रोत के लिए उपयोग किया जाता है। ऊपर के जीआईएफ में बाईं ओर स्थित क्यूब एक स्रोत क्यूब है, उदाहरण के लिए।
  • HasSourceइंगित करता है कि क्या यह घन स्रोत क्यूब से जुड़ा है। जब एक स्रोत से जुड़ा होता है, तो क्यूब्स अन्य "फुलर" गैर-स्रोत क्यूब्स की मांग करने से पहले अधिक पानी के लिए स्रोत को टैप करने का प्रयास करेंगे।
  • Largestइस क्यूब को बताता है कि इसके और इसके स्रोत क्यूब के बीच सबसे बड़ा प्रवाह क्या है। इसका मतलब है कि यदि पानी एक संकीर्ण खाई से बह रहा है, तो यह इस घन के प्रवाह को सीमित करता है।
  • Activeएक काउंटर है। जब इस घन में सक्रिय प्रवाह होता है, तो यह या उससे, सक्रिय हो जाता है। अन्यथा सक्रिय बेतरतीब ढंग से घटाया जाता है। एक बार सक्रिय हिट शून्य (जिसका अर्थ सक्रिय नहीं है), इस घन में पानी की मात्रा कम होने लगेगी। इस तरह के कृत्य वाष्पीकरण या जमीन में भिगोने जैसे कार्य करते हैं। ( यदि आपके पास प्रवाह है, तो आपको ईब होना चाहिए! )
  • FlowOutइंगित करता है कि क्या यह घन एक घन से जुड़ा है जो दुनिया के किनारे पर है। एक बार जब दुनिया के किनारे पर एक रास्ता बनाया जाता है, तो पानी किसी भी अन्य जगह पर उस रास्ते को चुनता है।
  • Extra भविष्य के उपयोग के लिए एक अतिरिक्त बिट है।

अब जब हम डेटा जानते हैं, तो एल्गोरिथ्म के एक उच्च स्तरीय अवलोकन को देखने की सुविधा देता है। सिस्टम का मूल विचार नीचे और बाहर बहने को प्राथमिकता देना है। जैसा कि मैंने वीडियो में बताया है, मैं नीचे से ऊपर तक काम करता हूं। पानी की प्रत्येक परत को y अक्ष में एक समय में एक स्तर पर संसाधित किया जाता है। प्रत्येक स्तर के लिए क्यूब्स को यादृच्छिक रूप से संसाधित किया जाता है, प्रत्येक क्यूब प्रत्येक स्रोत पर अपने स्रोत से पानी खींचने का प्रयास करेगा।

फ्लो क्यूब्स अपने प्रवाह की दिशा का पालन करके अपने स्रोत से पानी खींचते हैं जब तक कि वे स्रोत क्यूब या प्रवाह माता-पिता के साथ क्यूब तक नहीं पहुंचते। प्रत्येक क्यूब में प्रवाह की दिशा को संचय करना स्रोत से पथ का अनुसरण करना आसान बनाता है क्योंकि लिंक की गई सूची को पार करना आसान है।

एल्गोरिथ्म के लिए छद्म कोड निम्नानुसार है:

for i = 0 to topOfWorld //from the bottom to the top
   while flowouts[i].hasitems() //while this layer has flow outs
       flowout = removeRandom(flowouts[i]) //select one randomly
       srcpath = getPathToParent(flowout) //get the path to its parent
       //set cubes as active and update their "largest" value
       //also removes flow from the source for this flow cycle
       srcpath.setActiveAndFlux() 

//now we deal with regular flow
for i = 0 to topOfWorld //from the bottom to the top
    while activeflows[i].hasitems() //while this layer has water
        flowcube = removeRandom(activeflows[i]) //select one randomly
        //if the current cube is already full, try to distribute to immediate neighbors
        flowamt = 0
        if flowcube.isfull 
           flowamt = flowcube.settleToSurrounding
        else
           srcpath = getPathToParent(flowcube) //get the path to its parent
           flowamt = srcpath.setActiveAndFlux()
           flowcube.addflow(flowamt)

        //if we didn't end up moving any flow this iteration, reduce the activity
        //if activity is 0 already, use a small random chance of removing flow
        if flowamt == 0
           flowcube.reduceActive()

 refillSourceCubes()

प्रवाह के विस्तार के लिए बुनियादी नियम जहां (प्राथमिकता के आधार पर):

  1. यदि नीचे के क्यूब में पानी कम है, तो नीचे प्रवाह करें
  2. यदि समान स्तर पर आसन्न क्यूब में पानी कम है, तो बाद में प्रवाह करें।
  3. यदि ऊपर के क्यूब में पानी कम है और स्रोत क्यूब ऊपर के क्यूब से अधिक है, तो प्रवाह करें।

मुझे पता है, यह बहुत उच्च स्तर है। लेकिन विस्तार से रास्ता पकड़े बिना अधिक विस्तार में जाना कठिन है ।

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

  • ताल । जब पानी का एक बड़ा पूल हो जाता है, तो बच्चे से लेकर माता-पिता तक के संकेत किसी भी दिशा में प्रवाहित करने के लिए जो कुछ भी यादृच्छिक घन का चयन किया जाता है, के एक पागल गड़बड़ की तरह हैं। मूर्खतापूर्ण स्ट्रिंग के साथ बाथटब भरने की तरह। जब आप टब को खाली करना चाहते हैं, तो क्या आपको अपने स्रोत के पीछे मूर्खतापूर्ण स्ट्रिंग के मार्ग का पालन करना चाहिए? या आपको बस वही लेना चाहिए जो सबसे करीब है? तो ऐसी स्थितियों में जहां क्यूब्स एक बड़े पूल में हैं, उन्हें संभवतः अपने माता-पिता के प्रवाह की उपेक्षा करना चाहिए और जो कुछ भी उनके ऊपर है, उससे खींचें। मैं इसके लिए कुछ बुनियादी काम कोड के साथ आया था, लेकिन एक सुरुचिपूर्ण समाधान कभी नहीं था जिसके साथ मैं खुश हो सकता हूं।

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


धन्यवाद! बहुत सूचनाप्रद! मैं जल्द ही इस पर काम करना शुरू कर दूंगा और अगर सब ठीक हो जाए तो इसे स्वीकार करूंगा।
साइरेल

ज़रूर। मैं आपके सिस्टम के एक हाइब्रिड की कल्पना करता हूं और यह एक 2D दुनिया के लिए बहुत प्रभावी होगा। यदि आप विवरणों पर चर्चा करना चाहते हैं तो मुझे चैट में (@ बाइट 56 के साथ) पिंग करें।
MichaelHouse

ठीक है, एक दिन या इससे पहले कि मैं इसे बाहर की कोशिश करने का मौका मिल सकता है।
साइरेल

3
जाहिर है। मैंने शायद इसे काम करने में महीनों बिताए (और इसे फिर से काम कर रहा हूं)। मैं थोड़ी देर के लिए चारों ओर हो जाएगा, हालांकि :)
MichaelHouse

2

मैं सीन से सहमत हूं लेकिन मैं इसे थोड़ा अलग तरीके से करूंगा:

एक ब्लॉक अपने स्वयं के वजन के बराबर दबाव उत्पन्न करता है (इसमें कितना पानी है) और इसे नीचे और बगल में ब्लॉक पर लागू होता है। मुझे लगता है कि कोई कारण नहीं है कि यह दुनिया में स्थिति प्रासंगिक है।

प्रत्येक टिक पर पानी को उच्च दबाव से कम दबाव पर ले जाएँ, लेकिन बराबर करने के लिए आवश्यक पानी के एक अंश को स्थानांतरित करें। यदि ब्लॉक में दबाव नीचे वर्ग पर लागू किया जा रहा है, तो पानी को धक्का दिया जा सकता है।

आपको लूप मिलेंगे जहां पानी का दबाव बहुत दूर तक बहता है और फिर उसे सही करना पड़ता है, लेकिन जब से आप पानी की पूरी मात्रा को टिक नहीं करते हैं, तब तक ये गीला हो जाएगा। मुझे लगता है कि यह वास्तव में एक अच्छी बात है क्योंकि आप एक ऐसे क्षेत्र में बाढ़ के प्रभाव को बढ़ाएंगे जैसे आप वास्तविकता में हैं।


यदि पानी ऊपर जाना था जब ऊपर से लगाया जा रहा दबाव बहुत अधिक था, तो यह कम दबाव वाले ब्लॉक में नहीं जाएगा। ऊपर दिए गए दबाव के लिए, यह नीचे दिए गए ब्लॉक से अधिक होना चाहिए। इसके अतिरिक्त, दबाव के साथ-साथ नीचे और बाएं / दाएं ऊपर बढ़ना है।
MichaelHouse

@ बाइट 56 आप मेरे कहे का गलत मतलब निकाल रहे हैं। मैं कह रहा हूँ कि पानी ऊपर चला जाता है जब आप जिस ब्लॉक का विश्लेषण कर रहे हैं वह दबाव ऊपर से लागू होने के लिए बहुत अधिक है, इसलिए नहीं कि ऊपर से दबाव बहुत बढ़िया है!
लोरेन Pechtel

"पानी ऊपर जाता है जब ब्लॉक में दबाव आप कर रहे हैं विश्लेषण है: ठीक है, तो मुझे अलग तरीके से व्यक्त जो आपने कहा है तो मैं समझते हैं की तुलना में अधिक ऊपर से दबाव लागू किया जा रहा"। क्या वो सही है?
MichaelHouse

@ बाइट 56 हां। ब्लॉक में दबाव इसके ऊपर पानी का भार होना चाहिए या जब हम ऊपर कहीं ठोस सतह रखते हैं तो इसे बग़ल में लगाया जाना चाहिए। इस पर बहुत कम दबाव का मतलब है कि ऊपर पर्याप्त पानी नहीं है, पानी ऊपर ले जाएं।
लोरेन Pechtel

मैं बस इतना कहना चाहूंगा कि यदि आप बहते पानी से निपट रहे हैं तो यह पर्याप्त नहीं होगा और आपको जड़ता पर भी विचार करना होगा या पानी बहुत धीमी गति से आगे बढ़ेगा।
घन

1

आप एक नियम जोड़ सकते हैं जो टाइलों के साथ बाईं या दाईं (दीवारों के माध्यम से) जाने की कोशिश करता है जब तक कि आपको एक नि: शुल्क स्पॉट नहीं मिलता है, तल पर परतों के साथ शुरू होता है। यदि आप नहीं ढूंढ सकते हैं, तो टाइल वर्तमान स्थिति पर रहती है। यदि आप पाते हैं, तो एक और नियम स्थानांतरित टाइल के प्रतिस्थापन की गारंटी देगा (यदि आवश्यक हो)।


यह भी एक अच्छा विचार है, निश्चित नहीं है कि यह सभी मामलों में काम करेगा लेकिन मैं इस पर विचार करूंगा।
साइरेल

ठीक है! मुझे पता है कि यह काम किया या नहीं। संबंध
अल्मनेग्रा

मैं, बस हाल ही में थोड़ा व्यस्त हो जाएगा।
साइरेल

-2

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

इससे भी बेहतर है कि उन ब्लॉकों में एक और परिभाषा जोड़ दी जाए जो उपयोगकर्ता को प्रति ब्लॉक दबाव की मात्रा में प्रवेश करने की अनुमति देता है, जिससे पानी के ब्लॉक की मात्रा के अनुसार दबाव बढ़ जाता है।


1
"जब आप सामान्य रूप से पानी के ब्लॉक ले जाने के अपने तरीके का उपयोग करते हैं और जाँच करते हैं कि क्या यह ऊपर जा सकता है, तो यह नहीं हो सकता।" हाँ ... यह पहले से ही नहीं कर सकता। समस्या यही है, मैं इसे वैसा ही बने रहने का रास्ता नहीं ढूँढ रहा हूँ।
साइरेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.