पायथन में बिल्कुल सही, अनंत-परिशुद्धता, खेल भौतिकी (भाग 1)

Nov 26 2022
पूर्ण सटीकता के साथ, कार्यक्रम "न्यूटन का पालना", "टेनिस बॉल और बास्केटबॉल ड्रॉप", और अधिक यह चार लेखों में से पहला है जो आपको दिखाता है कि पायथन में एक संपूर्ण भौतिकी इंजन कैसे प्रोग्राम किया जाए। भौतिकी, गणित और यहां तक ​​कि दर्शनशास्त्र को प्रोग्रामिंग में बदलने की मेरी भव्य महत्वाकांक्षा में यह एक छोटा कदम है।

पूर्ण सटीकता के साथ, प्रोग्राम "न्यूटन का पालना", "टेनिस बॉल और बास्केटबॉल ड्रॉप", और बहुत कुछ

पायथन के साथ न्यूटन का पालना - स्रोत: संपादित https://openai.com/dall-e-2/

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

हम इंजन को कई तरह से सीमित करेंगे- उदाहरण के लिए, हलकों और रेखाओं के बीच न्यूटोनियन टक्करों के लिए। हालाँकि, हम इंजन की सटीकता को सीमित नहीं करेंगे। यह सभी समयों, स्थितियों और वेगों को सटीक भावों जैसे 8*sqrt(3)/3. दूसरे शब्दों में, यह सभी संख्यात्मक अनुमानों से बचा जाता है।

परिणाम सही अनुकरण होंगे, उदाहरण के लिए, न्यूटन का पालना खिलौना। (वीडियो को फिर से चलाने/रोकने के लिए, निचले बाएं कोने में बटन के लिए दबाएं। ध्वनि मददगार है।)

पूर्ण सटीकता वाला भौतिकी इंजन कितना अच्छा है? अन्य बातों के अलावा, यह भौतिक दुनिया की हमारी समझ में सुधार कर सकता है। इस लेख (भाग 1) में, हम इन नई-नई खोजों को देखेंगे:

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

इंजन का निर्माण

मान लीजिए कि हमारे पास पहले से ही पायथन कार्य हैं:

  • दुनिया में किसी भी दो (संभावित रूप से चलती) वस्तुओं को देखते हुए, सटीक समय अवधि लौटाएं जब तक कि वे स्पर्श न करें। उत्तर "कभी नहीं" हो सकता है।
  • किन्हीं दो टकराने वाली वस्तुओं को देखते हुए, कैसे, वास्तव में, टक्कर उनकी गति और दिशा को बदल देगी?

न्यूटन के पालने से शुरू करते हुए, तीन भौतिक जगत को देखते हुए एक दृष्टिकोण के माध्यम से काम करते हैं।

न्यूटन के उद्गम स्थल

हमारे इंजन के लिए सामान्य विचार दुनिया में अगली टक्कर तक सटीक समय का पता लगाना है। ठीक उसी समय आगे बढ़ें। टकराने वाली वस्तुओं की गति को समायोजित करें। दोहराना।

न्यूटन के पालने के लिए, हम पहले हलकों और दीवारों को स्थापित करते हैं।

from perfect_physics import World, Circle, Wall

circle_list = [Circle(x=1, y=0, r=1, vx=1, vy=0, m=1)]
for i in range(1, 6):
    circle_list.append(Circle(x=i * 2 + 4, y=0, r=1, vx=0, vy=0, m=1))
wall_list = [Wall(x0=0, y0=0, x1=0, y1=1), Wall(x0=20, y0=0, x1=20, y1=1)]
world = World(circle_list, wall_list, xlim=(-1, 21), ylim=(-2, 2))
world.show()

      
                

  • वस्तुओं की प्रत्येक जोड़ी के बीच, सटीक समय अवधि ज्ञात करें जिसमें वे टकराते हैं (यदि कोई हो)। अन्य जोड़ियों और टक्करों पर ध्यान न दें। — इस मामले में, पहला (चलता हुआ) सर्कल दूसरे सर्कल के साथ समय अवधि 3 पर टकराएगा। उस टक्कर को अनदेखा करते हुए, यह तीसरे सर्कल के साथ समय अंतराल 5 पर भी टकराएगा, आदि। यह उस समय दूर की दीवार से टकराएगा अवधि 18.
  • पहली टक्कर (ओं) की समय अवधि ज्ञात करें और विश्व घड़ी को ठीक उतना ही आगे बढ़ाएं। इस मामले में, 3.
  • इन टक्करों में शामिल सभी वस्तुओं के वेगों को समायोजित करें। जैसा कि न्यूटन के पालने से अपेक्षित था, पहला वृत्त स्थिर हो जाता है, और दूसरा वृत्त गति करना शुरू कर देता है।
  • जब तक चाहें दोहराएं। उदाहरण में, दूसरी और तीसरी गेंद अगली बार टाइम स्पैन 0 में टकराएगी। यह वीडियो एक्शन, इवेंट दर इवेंट दिखाता है। (एक "घटना" या तो टक्कर के लिए समय आगे बढ़ रही है या टक्कर के आधार पर गति समायोजित कर रही है)

सामान्य तौर पर, प्रत्येक फ्रेम के लिए, हम:

  • उस फ्रेम के लिए सिमुलेशन क्लॉक मान ज्ञात करें।
  • उस घड़ी के मान से पहले की टक्कर की घटना का पता लगाएं।
  • पिछली टक्कर में दुनिया से शुरू करते हुए, मंडलियों को फ्रेम के घड़ी मूल्य पर ले जाएं। (डिजाइन के अनुसार, इस चाल के दौरान मंडलियां किसी भी चीज से नहीं टकराएंगी।)

वृत्त और त्रिकोण

मेरा दावा है कि समय और स्थान सभी सटीक हैं, लेकिन क्या आप मुझ पर विश्वास करते हैं? यहाँ एक त्रिभुज द्वारा खुदे हुए एक वृत्त के माध्यम से कुछ प्रमाण दिए गए हैं। सबसे पहले, यहां सिर्फ घटनाओं को दिखाने वाला वीडियो है। आप घड़ी को अभिव्यक्तियों पर सेट देख सकते हैं जैसे कि 8*sqrt(3)/3

और यहाँ एक त्रिभुज में वृत्त के लिए नियमित वीडियो है:

इस मामले में, अनुकरण एक पैटर्न में आता है। अनंत परिशुद्धता के बिना, पैटर्न छूट सकता था।

टेनिस बॉल और बास्केटबॉल ड्रॉप

अनंत परिशुद्धता का एक और लाभ देखने के लिए आइए भौतिकी की एक और दुनिया देखें। इस दुनिया में एक टेनिस बॉल और बास्केटबॉल एक गति से दीवार की ओर बढ़ रहा है। बास्केटबॉल का द्रव्यमान टेनिस बॉल का 1000 गुना है। (हमारी दुनिया में कोई गुरुत्वाकर्षण नहीं है।)

from perfect_physics import World, Circle, Wall

big_radius = 10
world_width = 40
folder = root / f"part1/two_size{big_radius}"

big = Circle(x=world_width // 2, y=0, r=big_radius, vx=1, vy=0, m=big_radius**3)
little = Circle(x=big.x - big_radius - 1, y=0, r=1, vx=1, vy=0, m=1)
circle_list = [big, little]
wall_list = [Wall(x0=0, y0=0, x1=0, y1=1), Wall(x0=world_width, y0=0, x1=world_width, y1=1)]
world = World(circle_list, wall_list, xlim=(-1, world_width + 1), ylim=(-big_radius - 1, big_radius + 1))
world.run_in_place(2, show=True)
print([circle.vx for circle in world.circle_list])

जैसा कि अपेक्षित था (यदि आपने पहले ही भौतिक दुनिया में इसे आजमाया है), तो टेनिस बॉल की गति बढ़ जाती है। हालाँकि, इसने मुझे केवल तीन गुना तेजी से आगे बढ़ने से चौंका दिया।

आइए एक पल के लिए आगे बढ़ें और उन उपकरणों का उपयोग करें जिन्हें हम भाग 3 में विकसित करेंगे। यह पायथन कोड असीमित द्रव्यमान वाले बास्केटबॉल की टेनिस गेंदों पर प्रभाव दिखाता है। टेनिस बॉल 1 की गति से अंदर जाती है और ठीक 3 की गति से बाहर जाती है।

from sympy import limit, simplify, oo
from perfect_physics import load
cc_velocity_solution = load("data/cc_velocity_solution.sympy")
a_vx, a_vy, b_vx, b_vy  = cc_velocity_solution.subs([("a_x", 10), ("a_y", 0), ("a_r", 10), ("a_vx", -1), ("a_vy", 0),
                            ("b_x", -1), ("b_y", 0), ("b_r", 1), ("b_vx", 1), ("b_vy", 0), ("b_m", 1)])
print(simplify(b_vx))
limit(b_vx, "a_m", oo)
# prints (1 - 3*a_m)/(a_m + 1)
# returns -3

जब मैंने इसे लंबे समय तक चलने दिया तो इंजन ने मुझे और भी चौंका दिया। देखें कि 20 सेकंड के वीडियो समय पर क्या होता है (सिमुलेशन समय 200):

बास्केटबॉल टेनिस बॉल को स्क्वैश करता है। इसके कारण टेनिस बॉल एक ही वीडियो फ्रेम में 80 से अधिक बार आगे पीछे उछलती है। टेनिस बॉल 31 से अधिक की गति तक पहुँचती है। वीडियो के ऑडियो ट्रैक पर, टेनिस बॉल का कंपन 2000 हर्ट्ज (बीट्स/सेकंड) से अधिक का स्वर उत्पन्न करता है।

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

सारांश भाग 1

यह काम करता है! हमारे पास एक संपूर्ण भौतिकी इंजन है। हमने थोड़ी-सी भौतिकी को प्रोग्रामिंग में बदल दिया है।

हमने मान लिया कि हमने दो पायथन कार्यों के साथ शुरुआत की है जो हमें बताते हैं - वस्तुओं की किसी भी जोड़ी के लिए - दो चीजें 1) उनकी अगली टक्कर तक का समय (यदि कोई हो) और 2) उनके वेगों पर उस टक्कर का प्रभाव। हमने देखा कि इन दो कार्यों को बार-बार एक आदर्श भौतिकी इंजन में कैसे बदलना है: अगली टक्कर तक समय में आगे बढ़ना और टक्कर में शामिल सभी वस्तुओं के वेगों को समायोजित करना।

हमने एक वीडियो फ्रेम से पहले हुई टक्कर को देखकर और फिर उस फ्रेम में समय को आगे बढ़ाते हुए (टक्कर की चिंता किए बिना) वीडियो बनाया।

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

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

यदि आपके पास सिमुलेशन के लिए विचार हैं जो आप चाहते हैं कि मैं चलाऊं, तो कृपया उन्हें मुझे भेजें। वे भाग 5 का आधार बन सकते हैं।

आप इस कोड को CarlKCarlK/perfect-physics (github.com) से डाउनलोड कर सकते हैं । अगर रुचि है तो मुझे बताएं और मैं एक अच्छा इंस्टॉलर बनाउंगा।

कार्ल एम. कैडी को फॉलो करें — अगले भागों की सूचनाओं के लिए माध्यम। सभी भाग पढ़ने के लिए स्वतंत्र होंगे। अंत में, YouTube पर, मेरे पास पुराने (अनुमानित) भौतिकी सिमुलेशन और कुछ कोशिश करने वाले-हास्य प्रकृति के वीडियो हैं ।