गुरुत्वाकर्षण गणना का अनुकूलन


23

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

ऐसा लगता है कि मुझे प्रदर्शन में सुधार करने में सक्षम होना चाहिए। किसी भी समय, सिस्टम में 99% ऑब्जेक्ट्स का केवल एक वस्तु पर एक नगण्य प्रभाव होगा। मैं निश्चित रूप से वस्तुओं को द्रव्यमान द्वारा नहीं छांट सकता और केवल शीर्ष 10 सबसे बड़ी वस्तुओं या कुछ पर विचार कर सकता हूं, क्योंकि बल द्रव्यमान के साथ दूरी से अधिक भिन्न होता है (समीकरण लाइनों के साथ होता है force = mass1 * mass2 / distance^2)। मुझे लगता है कि दुनिया की दूसरी ओर चट्टान के सैकड़ों छोटे टुकड़ों को अनदेखा करने वाली सबसे बड़ी वस्तुओं और निकटतम वस्तुओं पर विचार करने के लिए एक अच्छा अनुमान होगा , जो संभवतः कुछ भी प्रभावित नहीं कर सकता है - लेकिन यह पता लगाने के लिए कि कौन सी वस्तुएं हैं निकटतम मुझे सभी वस्तुओं पर पुनरावृत्त करना है, और उनकी स्थिति लगातार बदल रही है, इसलिए ऐसा नहीं है कि मैं सिर्फ एक बार कर सकता हूं।

वर्तमान में मैं कुछ ऐसा कर रहा हूं:

private void UpdateBodies(List<GravitatingObject> bodies, GameTime gameTime)
{
    for (int i = 0; i < bodies.Count; i++)
    {
        bodies[i].Update(i);
    }
}

//...

public virtual void Update(int systemIndex)
{
    for (int i = systemIndex + 1; i < system.MassiveBodies.Count; i++)
    {
        GravitatingObject body = system.MassiveBodies[i];

        Vector2 force = Gravity.ForceUnderGravity(body, this);
        ForceOfGravity += force;
        body.ForceOfGravity += -force;
    }

    Vector2 acceleration = Motion.Acceleration(ForceOfGravity, Mass);
    ForceOfGravity = Vector2.Zero;

    Velocity += Motion.Velocity(acceleration, elapsedTime);
    Position += Motion.Position(Velocity, elapsedTime);
}

(ध्यान दें कि मैंने बहुत सारे कोड हटा दिए हैं - उदाहरण के लिए टकराव परीक्षण, मैं टकराव का पता लगाने के लिए दूसरी बार वस्तुओं पर पुनरावृति नहीं करता)।

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

Gravity.ForceUnderGravity(...)और Motion.Velocity(...), आदि कार्यों सिर्फ XNA के सदिश गणित में बनाया का एक सा इस्तेमाल करते हैं।

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

यह अविश्वसनीय सीमाओं के पैमाने पर नहीं है। दुनिया असीमित नहीं है, इसमें एक सीमा शामिल है जो इसे पार करने वाली वस्तुओं को नष्ट कर देती है - मैं एक हजार या तो वस्तुओं को संभालने में सक्षम होना चाहता हूं, वर्तमान में खेल 200 के आसपास चोक करना शुरू कर देता है।

मैं इसे कैसे सुधार सकता हूं इस पर कोई विचार? कुछ हेयुरिस्टिक I का उपयोग लूप की लंबाई को सैकड़ों से घटाकर केवल कुछ करने के लिए किया जा सकता है? कुछ कोड जिन्हें मैं हर अपडेट से कम बार निष्पादित कर सकता हूं? जब तक यह एक सभ्य आकार की दुनिया के लिए अनुमति देने के लिए पर्याप्त तेज नहीं है, तब तक क्या मुझे इसे गुणा करना चाहिए? क्या मुझे GPU की वेग गणनाओं को बंद करने का प्रयास करना चाहिए? यदि हां, तो मैं इसे कैसे आर्किटेक्ट करूंगा? क्या मैं GPU पर स्थिर, साझा डेटा रख सकता हूं? क्या मैं GPU पर HLSL फ़ंक्शन बना सकता हूं और उन्हें मनमाने ढंग से (XNA का उपयोग करके) कॉल कर सकता हूं या क्या उन्हें ड्रा प्रक्रिया का हिस्सा बनना होगा?


1
बस एक नोट, आपने कहा "बड़े पैमाने पर वस्तुएं अपने वेग की गणना के हिस्से के रूप में मलबे पर पुनरावृति नहीं करती हैं, लेकिन मलबे के प्रत्येक टुकड़े को बड़े पैमाने पर कणों पर पुनरावृति करना चाहिए।" मुझे इससे आभास हुआ, कि आप इसे अधिक कुशल मान रहे हैं। हालाँकि, प्रत्येक 100 मलबे की वस्तुओं को 10 बार पुनरावृत्त करना, अभी भी 100 बार 10 बड़े पैमाने पर वस्तुओं की पुनरावृत्ति के समान है। शायद, बड़े पैमाने के ऑब्जेक्ट लूप में प्रत्येक मलबे वस्तु को पुनरावृत्त करना एक अच्छा विचार होगा ताकि आप इसे दूसरी बार न करें।
रिचर्ड मार्स्केल -

आपको कितना सटीक अनुकरण की आवश्यकता है? क्या आपको वास्तव में एक दूसरे की ओर गति करने वाली हर चीज की आवश्यकता है? और क्या आपको वास्तव में एक सच्चे गुरुत्वाकर्षण गणना का उपयोग करने की आवश्यकता है? या क्या आप उन सम्मेलनों से विदा ले सकते हैं जिन्हें आप पूरा करने की कोशिश कर रहे हैं?
अराजकतावादी

@Drackir मुझे लगता है कि आप सही हैं। वे अलग होने के कारण का हिस्सा है क्योंकि गणित व्यापक वस्तुओं के लिए अलग है, और इसका कारण यह है कि वे मूल रूप से गुरुत्वाकर्षण का पालन नहीं करते थे, इसलिए उन्हें शामिल नहीं करना अधिक कुशल था। तो यह वस्तुनिष्ठ है
कार्सन मायर्स

@chaosTechnician के लिए यह बहुत सटीक होना जरूरी नहीं है - वास्तव में अगर यह केवल कुछ सबसे प्रमुख ताकतों के लिए जिम्मेदार है तो एक प्रणाली अधिक स्थिर होगी, जो आदर्श है। लेकिन यह पता लगा रहा है कि किस कुशल तरीके से मैं सबसे अधिक प्रभावी हूं। इसके अलावा गुरुत्वाकर्षण गणना पहले से ही अनुमानित है, यह बस है G * m1 * m2 / r^2, जहां जी को व्यवहार को मोड़ना है। (हालांकि मैं सिर्फ उन्हें एक पथ का अनुसरण नहीं कर सकता, क्योंकि उपयोगकर्ता सिस्टम को परेशान कर सकता है)
कार्सन मायर्स

बड़े पैमाने पर कणों के मलबे का प्रत्येक टुकड़ा क्यों होता है अगर यह बड़े पैमाने पर है? टक्कर?
सैम होसेवर

जवाबों:


26

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

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

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

यदि खेल की दुनिया बहुत बड़ी है, तो आप चतुर्भुज (2 डी) या ऑक्ट्री (3 डी) की तरह एक पदानुक्रमित ग्रिड का उपयोग भी कर सकते हैं , और अनुकरणीय सिद्धांत लागू कर सकते हैं। लंबी दूरी की बातचीत पदानुक्रम के उच्च स्तर के अनुरूप होगी।


1
ग्रिड विचार के लिए +1। मेरा सुझाव है कि ग्रिड के लिए द्रव्यमान के केंद्र को ट्रैक करने के साथ-साथ गणनाओं को थोड़ा और शुद्ध रखने के लिए (यदि आवश्यक हो)।
अराजकतावादी

मुझे यह सुझाव काफी पसंद आया। मैंने कोशिकाओं में वस्तुओं को रखने पर विचार किया था, लेकिन पास की दो वस्तुओं पर विचार करते समय इसे छोड़ दिया, जो तकनीकी रूप से अलग-अलग कोशिकाओं में थीं - लेकिन मैंने कुछ आसन्न कोशिकाओं पर विचार करने के लिए मानसिक छलांग नहीं लगाई, साथ ही साथ अन्य के संयुक्त द्रव्यमान पर भी विचार किया। कोशिकाओं। मुझे लगता है कि अगर मुझे सही करना है तो यह वास्तव में अच्छा काम करना चाहिए।
कार्सन मायर्स

8
यह अनिवार्य रूप से बार्न्स-हट एल्गोरिथ्म है: en.wikipedia.org/wiki/Barnes –Hut_simulation
रसेल बोरोगोव

यह भी इसी तरह लगता है कि गुरुत्वाकर्षण को भौतिकी में कैसे काम करना चाहिए - अंतरिक्ष-समय का झुकना।
लिंक्स पर ज़ैन लिंक्स

मुझे यह विचार पसंद है - लेकिन मुझे ईमानदारी से लगता है कि इसे थोड़ा और अधिक परिशोधन की आवश्यकता है - अगर दो वस्तुएं एक-दूसरे के बहुत करीब हैं, लेकिन अलग-अलग कोशिकाओं में क्या होता है? मैं देख सकता था कि आपका तीसरा पैराग्राफ कैसे मदद कर सकता है - लेकिन सिर्फ इंटरेक्टिंग ऑब्जेक्ट्स पर एक परिपत्र घेरा क्यों नहीं?
जोनाथन डिकिंसन

16

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

Http://mathandcode.com/programs/javagrav/ पर जाएँ और "स्टार्ट" और "शो क्वाडट्री" दबाएँ।

विकल्प टैब में, आप देख सकते हैं कि कण गणना 200,000 तक सभी तरह से जा सकती है। मेरे कंप्यूटर पर, गणना लगभग 2 सेकंड में समाप्त होती है (200,000 डॉट्स की ड्राइंग में लगभग 1 सेकंड लगता है, लेकिन गणना एक अलग धागे पर चलती है)।

यहां बताया गया है कि मेरा एप्लेट कैसे काम करता है:

  1. यादृच्छिक द्रव्यमान, स्थिति, और शुरुआती वेग के साथ यादृच्छिक कणों की एक सूची बनाएं।
  2. इन कणों से चतुष्कोण का निर्माण करें। प्रत्येक क्वाडट्री नोड में प्रत्येक सबनोड के द्रव्यमान का केंद्र होता है। मूल रूप से, प्रत्येक नोड के लिए आपके पास तीन मूल्य हैं: मास, मास और मास। हर बार जब आप किसी दिए गए नोड में एक कण जोड़ते हैं, तो आप क्रमशः particle.x * particle.mass और particle.y * particle.mass द्वारा द्रव्यमान और द्रव्यमान बढ़ाते हैं। स्थिति (द्रव्यमान / द्रव्यमान, द्रव्यमान / द्रव्यमान) नोड के द्रव्यमान के केंद्र के रूप में समाप्त हो जाएगी।
  3. प्रत्येक कण के लिए, बलों की गणना करें (पूरी तरह से वर्णित यहां )। यह शीर्ष नोड पर शुरू करके और क्वाडट्री के प्रत्येक उप-नोड के माध्यम से पुनरावृत्ति किया जाता है जब तक कि दिए गए सबनोड पर्याप्त छोटा नहीं होता है। एक बार जब आप पीछे हटना बंद कर देते हैं, तो आप कण से नोड के द्रव्यमान के केंद्र तक दूरी की गणना कर सकते हैं, और फिर आप नोड के द्रव्यमान और कण के द्रव्यमान का उपयोग करके बल की गणना कर सकते हैं।

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

इसे भी देखें: http://www.youtube.com/watch?v=XAlzniN6L94 इसके बड़े प्रतिपादन के लिए


पहला लिंक मर चुका है। क्या एप्लेट कहीं और होस्ट किया गया है?
एको

1
फिक्स्ड! क्षमा करें, उस डोमेन पर किराए का भुगतान करना भूल गया, और किसी ने इसे ऑटो-खरीदा: \ इसके अलावा, 3 मिनट एक 1.3 साल पुराने पोस्ट 8D पर एक बहुत अच्छी प्रतिक्रिया समय है

और मुझे जोड़ना चाहिए: मेरे पास स्रोत कोड नहीं है। यदि आप कुछ सोर्स कोड की तलाश कर रहे हैं तो पार्ट-एनडी (सी में लिखा हुआ) देखें। मुझे यकीन है कि वहाँ अन्य लोग भी हैं।

3

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

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

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


प्रक्रिया को पास में अलग करना एक उत्कृष्ट विचार है, क्योंकि अद्यतन अंतराल (जहां तक ​​मुझे पता है) एक दूसरे का बहुत छोटा अंश है। गुरुत्वाकर्षण क्षेत्र की बनावट AWESOME है, लेकिन शायद अभी मेरी पहुंच से थोड़ा परे है।
कार्सन मायर्स

1
पिछले अद्यतन के बाद से कितने समय-स्लाइस को छोड़ दिया गया है, इसके द्वारा लागू बलों को गुणा करना न भूलें।
लिंक्स पर ज़ैन लिंक्स

@ सीनमेडिलेमिच: क्या आप गुरुत्वाकर्षण क्षेत्र की बनावट पर थोड़ा और विस्तार कर सकते हैं? मुझे क्षमा करें, मैं एक ग्राफिक्स प्रोग्रामर नहीं हूं, लेकिन यह वास्तव में दिलचस्प लगता है; मुझे अभी समझ नहीं आया कि इसे कैसे काम करना चाहिए। और / या हो सकता है कि आपके पास तकनीक के वर्णन का लिंक हो?
फेलिक्स डॉमबेक

@ फेलिक्सडोमबेक: प्रभाव के क्षेत्र का प्रतिनिधित्व करने वाले मंडलियों के रूप में अपनी वस्तुओं को प्रस्तुत करें। टुकड़ा shader वस्तु के केंद्र पर और उचित परिमाण (केंद्र से दूरी और वस्तु के द्रव्यमान पर आधारित) के साथ एक वेक्टर इंगित करता है। हार्डवेयर सम्मिश्रण इन वैक्टर को योगात्मक मोड में संभाल सकता है। परिणाम सटीक गुरुत्वाकर्षण क्षेत्र नहीं होगा, लेकिन लगभग निश्चित रूप से एक खेल की जरूरतों के लिए काफी अच्छा होगा। GPU का उपयोग करते हुए एक और दृष्टिकोण के रूप में, इस CUDA- आधारित एन-बॉडी ग्रेविटी सिमुलेशन तकनीक को देखें: http.developer.nvidia.com/GPUGems3/gpugems3_ch31.html
सीन मिडलडविच

3

मैं एक क्वाड ट्री का उपयोग करने की सलाह दूंगा। वे आपको जल्दी और कुशलता से एक मनमाना आयताकार क्षेत्र में सभी वस्तुओं को देखने की अनुमति देते हैं। यहाँ उन पर विकि लेख है: http://en.wikipedia.org/wiki/Quadtree

और SourceForge पर मेरे अपने XNA क्वाड ट्री प्रोजेक्ट का एक बेशर्म लिंक: http://sourceforge.net/projects/quadtree/

मैं सभी बड़ी वस्तुओं की एक सूची भी रखूंगा ताकि वे दूरी की परवाह किए बिना हर चीज के साथ बातचीत कर सकें।


0

बस (संभवतः भोले) इनपुट का एक छोटा सा। मैं गेम प्रोग्रामिंग नहीं करता, लेकिन जो मैं महसूस कर रहा हूं वह यह है कि आपकी मूलभूत अड़चन गुरुत्वाकर्षण-कारण-से-गुरुत्वाकर्षण गणना है। प्रत्येक ऑब्जेक्ट X पर पुनरावृत्ति करने और फिर प्रत्येक ऑब्जेक्ट Y से गुरुत्वाकर्षण प्रभाव को खोजने और इसे जोड़ने के बजाय, आप प्रत्येक जोड़ी X, Y को ले सकते हैं और उनके बीच बल पा सकते हैं। कि हे (एन ^ 2) से गुरुत्वाकर्षण गणना की संख्या में कटौती करनी चाहिए। तब आप बहुत कुछ जोड़ रहे होंगे (O (n ^ 2)), लेकिन यह सामान्य रूप से कम खर्चीला होता है।

इस बिंदु पर भी आप नियमों को लागू कर सकते हैं जैसे "यदि गुरुत्वाकर्षण बल \ epsilon से कम होगा क्योंकि ये निकाय बहुत छोटे हैं, तो बल को शून्य पर सेट करें"। यह संरचना अन्य उद्देश्यों के लिए भी फायदेमंद हो सकती है (टकराव का पता लगाने सहित)।


यह मौलिक रूप से मैं क्या कर रहा हूं। एक्स को शामिल करने वाली सभी जोड़ियों के बाद, मैं एक्स पर फिर से पुनरावृति नहीं करता। मुझे X और Y, X और Z, आदि के बीच बल लगता है, और उस बल को जोड़ी में दोनों वस्तुओं पर लागू करते हैं। लूप पूरा होने के बाद,ForceOfGravity वेक्टर सभी बलों का योग है, और फिर इसे एक वेग और नई स्थिति में बदल दिया जाता है। मुझे यकीन नहीं है कि गुरुत्वाकर्षण की गणना विशेष रूप से महंगी है, और अगर यह एक सीमा से अधिक है तो जाँच पहले एक ध्यान देने योग्य राशि नहीं बचाएगी, मुझे नहीं लगता
कार्सन मायर्स

0

Seanmiddleditch के उत्तर देने में, मुझे लगा कि मैं गुरुत्वाकर्षण क्षेत्र के विचार पर कुछ प्रकाश (विडंबना?) बहा सकता हूं।

सबसे पहले, इसे बनावट के रूप में न सोचें, लेकिन मूल्यों का एक असतत क्षेत्र जो संशोधित कर सकता है (दो आयामी सरणी, जैसा कि यह था); और सिमुलेशन की बाद की सटीकता उस क्षेत्र का संकल्प हो सकती है।

जब आप किसी ऑब्जेक्ट को फ़ील्ड में पेश करते हैं, तो इसकी गुरुत्वाकर्षण क्षमता की गणना आसपास के सभी मूल्यों के लिए की जा सकती है; जिससे एक गुरुत्वाकर्षण सिंक बनता है क्षेत्र में।

लेकिन इनमें से कितने बिंदुओं की गणना आपको पहले की तरह अधिक या अप्रभावी होने से पहले करनी चाहिए? शायद नहीं कई, यहां तक ​​कि 32x32 प्रत्येक वस्तु के लिए पुनरावृति करने के लिए एक पर्याप्त क्षेत्र है। इसलिए पूरी प्रक्रिया को कई पास में तोड़ दें; अलग-अलग रिज़ॉल्यूशन (या सटीकता) के साथ प्रत्येक।

यानी, पहला पास 4x4 ग्रिड में प्रतिनिधित्व की जाने वाली वस्तुओं की गणना कर सकता है, जिसमें प्रत्येक सेल मान अंतरिक्ष में 2 डी समन्वय का प्रतिनिधित्व करता है। एक ओ (एन * 4 * 4) उप-कुल जटिलता देते हुए।

दूसरा पास अधिक सटीक हो सकता है, 64x64 रिज़ॉल्यूशन के गुरुत्वाकर्षण क्षेत्र के साथ, प्रत्येक सेल मान के साथ अंतरिक्ष में 2 डी का समन्वय होता है। हालांकि, जैसा कि जटिलता बहुत अधिक है, आप प्रभावित आसपास की कोशिकाओं की त्रिज्या को प्रतिबंधित कर सकते हैं (शायद, केवल आसपास के 5x5 कोशिकाओं को अद्यतन किया जाता है)।

एक अतिरिक्त तीसरे पास का उपयोग उच्च सटीकता गणना के लिए किया जा सकता है, शायद 1024x1024 का एक संकल्प। बिना किसी समय को याद किए आप वास्तव में 1024x1024 अलग-अलग गणना कर रहे हैं, लेकिन केवल इस क्षेत्र के भागों (शायद 6x6 उप-खंडों) पर काम कर रहे हैं।

इस तरह, अद्यतन के लिए आपकी समग्र जटिलता हे (n * (4 * 4 + 5 * 5 + 6 * 6))।

फिर प्रत्येक गुरुत्वाकर्षण क्षेत्र (4x4, 64x64, 1024x1024) के लिए अपनी प्रत्येक वस्तु के वेग में परिवर्तन की गणना करने के लिए, आप बस एक ग्रिड सेल पर बिंदु जन स्थिति का नक्शा तैयार करते हैं, उस ग्रिड कोशिकाओं को एक नए वेक्टर में समग्र गुरुत्वाकर्षण संभावित वेक्टर लागू करते हैं; प्रत्येक "परत" या "पास" के लिए दोहराएं; फिर उन्हें एक साथ जोड़ें। यह आपको एक अच्छा परिणामी गुरुत्वाकर्षण बल वेक्टर प्रदान करना चाहिए।

इसलिए, समग्र जटिलता है: O (n *) (4 * 4 + 5 * 5 + 6 * 6) + n)। वास्तव में क्या मायने रखता है (जटिलता के लिए) पास में गुरुत्वाकर्षण क्षमता की गणना करते समय आप कितने आसपास की कोशिकाओं को अपडेट करते हैं, गुरुत्वाकर्षण क्षेत्रों के समग्र संकल्प नहीं।

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

मुझे उम्मीद है कि यह समझ में आया।


0

कैसे एक और दृष्टिकोण के बारे में:

अपने द्रव्यमान के आधार पर वस्तुओं पर प्रभाव का एक क्षेत्र निर्दिष्ट करें - वे उस सीमा से परे एक औसत दर्जे का प्रभाव डालने के लिए बहुत छोटे हैं।

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

अपने गुरुत्वाकर्षण की गणना केवल उस वस्तु से संबंधित सूची में वस्तुओं पर करें जो एक वस्तु में है।

आपको केवल उन सूचियों को अद्यतन करना होगा जब कोई वस्तु नए ग्रिड सेल में जाती है।

ग्रिड सेल जितना छोटा होगा आप प्रति अपडेट उतना ही कम काम करेंगे लेकिन सूची को अपडेट करने के लिए आप जितना अधिक काम करेंगे।

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