मैंने अपने खेल के लिए महाद्वीपों के नक्शे कैसे बनाए

छवि

भाग 1. एसवीजी और समन्वय प्रणाली


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

दुनिया एक बड़ी जगह है। अधिकांश फंतासी "दुनिया" कार्ड भी सही आकार के समान नहीं होते हैं। उदाहरण के लिए, मध्य-पृथ्वी, जिसमें लॉर्ड ऑफ द रिंग्स कार्रवाई होती है:


यद्यपि ऐसा लगता है कि एक विशाल दुनिया इस पर कब्जा कर ली गई है, वास्तव में, मध्य-पृथ्वी यूरोप के आधार पर बनाई गई थी।


यही है, टॉल्किन दुनिया के लिए "दुनिया" का असली नक्शा मध्य-पृथ्वी (!) के नक्शे से लगभग 50 गुना बड़ा होगा। वास्तव में, मैंने जिन काल्पनिक दुनिया के नक्शे को देखा है उनमें से अधिकांश एक महाद्वीप के आकार के बारे में एक क्षेत्र को दर्शाते हैं:


यह सबसे बड़ा क्षेत्र है जो कल्पना कार्ड शैली में अच्छी तरह से कल्पना करता है।

यही है, वास्तविक "विश्व मानचित्र" बनाने का कार्य शायद बहुत महत्वाकांक्षी है। महाद्वीप का नक्शा (या महाद्वीप का हिस्सा) बनाने के उद्देश्य से बेहतर है। (हालांकि, कार्ड को "दुनिया" के आकार के रूप में मानना ​​अभी भी अधिक सुविधाजनक है) तो कार्ड का आकार क्या होना चाहिए? यदि वर्तमान ड्रेगन एबाउंड कार्ड में "उपमहाद्वीपीय" आकार है, तो हम मान सकते हैं कि आपको 8-10 गुना बड़ा कार्ड बनाने की आवश्यकता है।

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

क्षेत्रीय मानचित्र के "विश्व" के साथ शुरू करने के लिए, वर्तमान में एक इकाई वर्ग के भीतर उत्पन्न किया जा रहा है। प्रत्येक क्षेत्रीय मानचित्र में (-0.5, -0.5) से (0.5, 0.5) तक का समन्वय होता है, और मूल (0,0) क्षेत्र के बीच में होता है।


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

यह समन्वय प्रणाली स्वतंत्र है कि मानचित्र कैसे प्रदर्शित किया जाता है। यह दुनिया बनाने के लिए सिर्फ एक आयामहीन प्रणाली है - शहर (0.12875, -0.223) पर स्थित है, सीमा (0.337, 0.010) से (0.333, 0.017), और इसी तरह से गुजरती है। और यद्यपि मेरे वर्तमान क्षेत्रीय मानचित्र 0.5 से -0.5 की सीमा तक सीमित हैं, यह समन्वय प्रणाली की सीमा नहीं है। मैं इन सीमाओं से परे एक दुनिया बना सकता हूं।

अगला समन्वय प्रणाली वह है जिसे एसवीजी व्यूबॉक्स कहता है। यह सही निर्देशांक सेट करता है जिसका उपयोग ग्राफिक्स बनाने के लिए किया जाएगा। उदाहरण के लिए, ड्रैगन्स एबाउंड शुरुआत में व्यूबॉक्स को निर्देशांक (-500, -500) में सेट करता है और इसकी चौड़ाई 1000 और 1000 की ऊंचाई है:


(चित्र में एक टाइपो है, वाई अक्ष का शीर्ष -500 होना चाहिए, क्षमा करें।)

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

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

स्क्रीन पर ग्राफिक्स प्रदर्शित करने के निर्देशांक को नियंत्रित करने के लिए, एसवीजी का एक तीसरा समन्वय प्रणाली है जिसे व्यूपोर्ट कहा जाता है। व्यूपोर्ट पृष्ठ का वह हिस्सा है जिसमें ग्राफिक्स खींचे जाने चाहिए (वेब ​​पेज पर, यह <svg> तत्व है)। इसकी एक चौड़ाई, ऊंचाई और स्थान है। स्थान व्यूपोर्ट के ऊपरी बाएं कोने का निर्देशांक है। यही है, अगर मुझे निर्देशांक (30, 100) के साथ व्यूपोर्ट में नक्शा प्रदर्शित करना था, जिसकी ऊंचाई और चौड़ाई 800 है, तो व्यूपोर्ट समन्वय प्रणाली इस तरह दिखाई देगी:


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

संक्षेप में: दुनिया के निर्देशांक (0.10, 0.33) में स्थित एक शहर निर्देशांक (100, 330) में खींचा गया है और स्क्रीन पर (110, 764) में प्रदर्शित किया गया है।

अब आप समझ सकते हैं कि यह भ्रामक क्यों हो सकता है!

यदि मैं इनमें से प्रत्येक समन्वय प्रणाली को बदल दूं तो क्या होगा? मान लीजिए कि पहले समन्वय प्रणाली में मैं प्रत्येक धुरी पर -0.25 से 0.25 तक की दुनिया पैदा करूंगा। तब परिणामी दुनिया सामान्य दुनिया से चार गुना छोटी होगी और व्यूपोर्ट के केवल मध्य भाग को भर देगी:


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

अगर मैं व्यूबॉक्स का आकार दोगुना कर दूं तो क्या होगा? खैर, अगर मैं पहले SC और व्यूबॉक्स (1000 से 2000) के बीच का अनुपात भी दोगुना कर दूं, तो कुछ भी ज्यादा नहीं बदलेगा। यदि अनुपात 1000 के बराबर रहता है, तो मानचित्र फिर से आधा हो जाएगा।


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

और इसके विपरीत, अगर मैं व्यूबॉक्स के आकार को आधे से कम कर देता हूं, तो यह एक मानचित्र ज़ूम प्रभाव पैदा करेगा:


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

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


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


यह किसी भी अन्य नक्शे की तरह दिखता है, लेकिन वास्तव में यह एक बड़े नक्शे का केंद्रीय हिस्सा है। यही है, अब मैं मानचित्र के अन्य भागों को अवलोकन विंडो में स्थानांतरित करने के लिए व्यूबॉक्स को बदल सकता हूं:


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

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

भाग 2. स्थायी कार्ड बनाना


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

नामों की नियुक्ति के साथ समस्या, जिसका मैंने पिछले भाग में वर्णन किया था, स्पष्ट रूप से इन दो प्रकारों के एक कार्ड पर ध्यान देने योग्य है:


यहाँ एक ही दुनिया है, केवल दृश्य को बाईं ओर स्थानांतरित कर दिया गया है:


आप देख सकते हैं कि भूगोल समान है, लेकिन कई नाम बदल गए हैं। चूंकि दो प्रकार की अलग-अलग वस्तुएं दिखाई देती हैं, और नाम बनाने की प्रक्रिया यादृच्छिक संख्याओं द्वारा नियंत्रित होती है, विभिन्न नाम प्राप्त होते हैं।

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

इस समस्या को समाप्त करने के बाद, दो कार्डों पर नाम स्थिर रहते हैं:


और:


भविष्य के लिए एक और ध्यान दें: अगर मैं मैप ऑब्जेक्ट्स के नामों को बदलने के लिए अन्तरक्रियाशीलता सुविधा का उपयोग करता हूं, तो यह परिवर्तन अपने वर्तमान स्वरूप में फिर से निर्मित नहीं होगा, और शायद यह प्रतिलिपि प्रस्तुत करने योग्य भी नहीं होगा। यह विचार करने लायक है।

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

अब मानचित्र के आकार को चौगुना करें और मानचित्र विंडो में इसका केवल एक चौथाई भाग दिखाएं:


सामान्य तौर पर, सब कुछ अच्छा लगता है (नक्शे पर नदियों की एक दिलचस्प प्रणाली है, एक बड़ी झील है, लेकिन आप देख सकते हैं कि शहर बहुत दुर्लभ हैं। ऐसा इसलिए हुआ क्योंकि ड्रेगन एबाउंड 10-20 शहरों का निर्माण करता है। यह अंतराल सामान्य आकार की दुनिया के लिए अच्छी तरह से अनुकूल है, लेकिन खराब है। जब आकार चार गुना बड़ा होता है। इसलिए, अंतराल को दुनिया के सापेक्ष आकार के अनुसार बदलना चाहिए। संभवतः, इसे कई स्थानों पर किया जाना चाहिए।

समस्या को ठीक करने के बाद यहां एक ही कार्ड दिया गया है:


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


अब तस्वीर अधिक तार्किक है। दाईं ओर, कमडन मैप पर मुश्किल से दिखाई देता है, लेकिन लेबल अभी भी स्थित है जहां यह दिखाई देता है।

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

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


जोड़े गए स्थान पीढ़ी प्रक्रिया को बदलते हैं, इसलिए इलाके ऊपर दिखाए गए नक्शे से भिन्न होते हैं, लेकिन इस पर आप तटों पर जोड़े गए विवरण देख सकते हैं।

सौभाग्य से, जब बड़े कार्ड बनाने के प्रदर्शन को रूपरेखा करते हुए, मैंने देखा कि अधिकांश प्रोसेसर समय स्पष्ट समस्याओं द्वारा लिया जाता है। डिबगिंग के बाद, मैंने सबसे अधिक परेशान करने वालों को खत्म कर दिया, जिससे मुझे नक्शे और भी अधिक बनाने की अनुमति मिली। यहाँ पूरे 4x कार्ड है:


25% ज़ूम प्रदर्शन किया। यह लगभग अधिकतम मानचित्र आकार जैसा दिखता है जिसे Chrome प्रदर्शित कर सकता है। विश्व पीढ़ी की प्रक्रिया बड़े मानचित्रों को संसाधित कर सकती है, लेकिन उन्हें प्रदर्शित करने की कोशिश करने से ब्राउज़र क्रैश हो जाता है। इस अर्थ में, फ़ायरफ़ॉक्स अधिक कार्यात्मक प्रतीत होता है; यह मूल आकार से 9 गुना बड़ा कार्ड प्रदर्शित कर सकता है। इस तरह के नक्शे का एक हिस्सा है - मैंने इसे पूर्ण आकार में छोड़ दिया, इसलिए आप इसे आकार और विस्तार से बेहतर समझने के लिए एक अलग विंडो में खोल सकते हैं।


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

सबसे अच्छा समाधान स्वयं SVG को सहेजना है ताकि इसे Inkscape जैसे प्रोग्राम में खोला जा सके।

मैं SVG मैप्स को Inkscape में कट और पेस्ट करने में सक्षम था, लेकिन दुनिया के नक्शे के लिए SVG इतने बड़े हैं कि जब मैं ब्राउज़र क्रैश को काटने की कोशिश करता हूँ! सौभाग्य से, मुझे FileSaver.js मिला और आप इसे एसवीजी को सीधे एक फ़ाइल में सहेजने के लिए उपयोग कर सकते हैं, और फिर इसे इंकस्केप में खोल सकते हैं, इस प्रकार एक बहुत बड़ी छवि बना सकते हैं।

कम से कम सैद्धांतिक रूप से। जब मैं इन नक्शों को इंकस्केप में खोलने की कोशिश करता हूं, तो मुझे कुछ समस्याओं का सामना करना पड़ता है।

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

दूसरी समस्या यह है कि इंकस्केप में प्रोसेसिंग मास्क में त्रुटियां हैं। Inkscape केवल एक तत्व के साथ मास्क बनाता है, और कई तत्वों के साथ खराब तरीके से मास्क को संभालता है। ड्रेगन एबाउंड कई तत्वों के साथ कई मास्क बनाता है। आप प्रत्येक गेम मास्क के सभी तत्वों को एक (वैकल्पिक) समूह तत्व में समूहीकृत करके इस समस्या को हल कर सकते हैं।

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

चौथी समस्या फोंट की है। ड्रेगन एबाउंड वेब फोंट और स्थानीय रूप से संग्रहीत फोंट दोनों का उपयोग करता है; दोनों WOFF2 प्रारूप में। ब्राउज़र में, उन्हें सीएसएस फ़ॉन्ट-परिवार शैली का उपयोग करके पाठ पर लागू किया जाता है, और मानचित्र तैयार करने से पहले, वेब पेज पर उपयोग के लिए तैयार होने के लिए सभी संभावित फोंट अपलोड किए जाते हैं। जब गेम में एक ही फाइल खोली जाती है, तो यह सिस्टम फॉन्ट डायरेक्टरी में फोंट की खोज करता है, और ऐसा लगता है कि किसी भी तरह से कोई अन्य फॉन्ट डायरेक्टरी निर्दिष्ट नहीं की जा सकती। एक सरल समाधान (कम से कम मशीन पर जहां मैं विकसित कर रहा हूं) गेम फॉन्ट को सिस्टम फॉन्ट डायरेक्टरी में स्थापित करने के लिए है। हालाँकि, यह उतना सरल नहीं है जितना लगता है, क्योंकि फ़ॉन्ट नामों का मिलान होना चाहिए, और विंडोज पर फ़ॉन्ट नाम को बदलने के कोई आसान तरीके नहीं हैं। लेकिन, निश्चित रूप से, ऐसी योजना कंप्यूटर पर काम नहीं करेगी, जिस पर सभी आवश्यक फोंट स्थापित नहीं हैं। एक अधिक पोर्टेबल समाधान SVG फोंट को मानचित्रों में एम्बेड करना है । यह मेरी TODO सूची में होगा।

अंत में, मैं इस मैप जनरेशन इंटरफ़ेस में आया:


विस्तृत इनपुट फ़ील्ड दुनिया के कुल आकार को निर्दिष्ट करते हैं, जहां 1x1 स्रोत के नक्शे का आकार है। Vbx का आकार (व्यूबॉक्स) मानचित्र पर प्रदर्शित दुनिया के टुकड़े के आकार को निर्धारित करता है; स्क्रीनशॉट में, इसका मूल्य भी 1x1 है, अर्थात यह मानचित्र पूरी दुनिया को प्रदर्शित करेगा। Vbx केंद्र फ़ील्ड दुनिया में मानचित्र केंद्र के स्थान को निर्दिष्ट करता है; 0, 0 दुनिया का केंद्र है। अंत में, एसवीजी पैरामीटर प्रति 1 स्क्रीनबॉक्स आकार इकाई में स्क्रीन पिक्सल की संख्या निर्दिष्ट करते हैं; 775 के मूल्य पर, 775x775 पिक्सेल की राशि में स्क्रीन पर 1x1 मानचित्र प्रदर्शित किया जाएगा। यह सुविधाजनक है जब मैं एक बहुत बड़ा मानचित्र बनाता हूं। पैरामीटर को कम मूल्य (उदाहरण के लिए, 150 पिक्सेल) पर सेट करके, मैं स्क्रीन पर एक बड़े मानचित्र को एक पूरे के रूप में फिट कर सकता हूं।

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

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

भाग 3. सुशी रूपों


पिछले भाग में कई बदलाव किए, अब मैं ऐसी दुनियाएँ उत्पन्न कर सकता हूँ जो पिछले वाले से बहुत बड़ी हैं (8 गुना तक अधिक) और उन्हें बड़ी ग्राफ़िक छवियों के रूप में सहेजें:


(फ़्लिकर में पूर्ण संकल्प 4800x2400 में नक्शा देखने के लिए एक अलग विंडो में छवि खोलें।)

मैं इन मानचित्रों को उसी प्रक्रियात्मक पीढ़ी का उपयोग करके उत्पन्न करता हूं जिसने क्षेत्रीय मानचित्र बनाए। ऊपर दिखाए गए नक्शे में काफी नियमित महाद्वीपीय आकार और कुछ दिलचस्प बाहरी द्वीप हैं। हालांकि, यह मुख्य रूप से भाग्य पर निर्भर करता है। यहाँ एक और नक्शा है:


यह कार्ड द्वीपों और स्विस सुशी पनीर से सिर्फ अराजकता है।

यहाँ एक और उदाहरण है, दो पिछले कार्डों के बीच में। यह पूरी तरह से यथार्थवादी नहीं है, लेकिन यह काल्पनिक परिवेश के लिए दिलचस्प हो सकता है:


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

मैंने जिन काल्पनिक दुनिया के नक्शे देखे हैं उनमें से अधिकांश एक बड़े द्वीप महाद्वीप का प्रतिनिधित्व करते हैं (छोटे द्वीपों के साथ), उदाहरण के लिए, जैसे एंडलीन का यह नक्शा:


या महाद्वीप का प्रायद्वीप, अंगोरुन के इस नक्शे पर:


समय-समय पर, एक नक्शा पूरी तरह से भूमि या कई द्वीप महाद्वीपों से बना होता है, लेकिन वे नियम के अपवाद होने की अधिक संभावना रखते हैं।

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


मुझे इस नक्शे पर एक बड़े केंद्रीय समुद्र की उम्मीद नहीं थी, लेकिन यह एक सुखद आश्चर्य है। यहाँ एक और उदाहरण है:


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


मानचित्र के आकार द्वारा लिए गए दीर्घवृत्त (विकृत) के साथ एक चक्र के बजाय सुशी को मास्क करके इसे आसानी से ठीक किया जाता है:


इन केंद्रीय द्वीपों को नक्शा भरने के लिए बढ़ाया जाता है, लेकिन महाद्वीपीय मानचित्रों के लिए कई मामलों में हमें महाद्वीप के चारों ओर "सीमा" छोड़ने की आवश्यकता होती है। दो पैरामीटर एक्स और वाई कुल्हाड़ियों के साथ द्वीप को भरने वाले नक्शे के आकार को नियंत्रित करते हैं।


यहाँ एक ही सीमा प्रबंधन प्रणाली है जिसमें अधिक तार्किक विकृतियाँ हैं:


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

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

तो, अब द्वीप महाद्वीप ठीक काम कर रहे हैं, और हम "प्रायद्वीपीय" महाद्वीपों के कार्यान्वयन पर आगे बढ़ेंगे - नक्शे जिसमें महाद्वीप अपने किनारे से नक्शे पर दिखाई देता है।


इस मामले में, महाद्वीप तीन किनारों पर ढह नहीं सकता। लेकिन ऐसे मानचित्रों की मुख्य विशेषता यह है कि नक्शे में प्रदर्शित महाद्वीप और मानचित्र के बाहर की जमीन के बीच उनका महत्वपूर्ण भूमि संबंध है।

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


बेशक, यह गारंटी नहीं देता है कि भूमि का द्रव्यमान बहुत दिलचस्प होगा, और वास्तव में यह एकीकृत होगा:


एकल महाद्वीप की समानता द्वीप महाद्वीप की एक ही पीढ़ी का उपयोग करके बनाई जा सकती है, लेकिन एक ही समय में द्वीप को नक्शे के किनारे पर स्थानांतरित करना। आपको ऐसा कुछ मिलता है:


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


जाहिर है, राहत की पीढ़ी के लिए कई अन्य दृष्टिकोण हैं, लेकिन ये दो, कम से कम, मुझे महाद्वीपीय पैमाने पर सबसे आम रूपों को उत्पन्न करने का अवसर देते हैं।

एक चौकस पाठक महाद्वीपों के कई नक्शों पर धारियों के रूप में जंगलों के अजीब रूपों को नोटिस कर सकता है। अगली बार मैं पवन मॉडल और बायोम की समस्याओं से निपटना शुरू कर दूंगा जो इन विषमताओं का कारण बनते हैं।

भाग 4. पवन मॉडल


जैसा कि कहा गया है, ड्रेगन अबाउंड मैप्स पर महाद्वीपों का आकार मौसम और बायोम के अवास्तविक पैटर्न दिखाना शुरू कर दिया। यह उदाहरण दिखाता है कि जंगल प्रचलित हवा की दिशा के साथ बना हुआ है:


इसका कारण टूटे हुए कोड में नहीं है; बल्कि, मौसम और बायोम मॉडल बहुत सरल हैं, और बड़े पैमाने पर यह स्पष्ट हो जाता है। इन समस्याओं से निपटने के लिए, मैंने पवन मॉडल को संशोधित करके शुरू किया।

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

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

मुझे किस ग्रिड का उपयोग करना चाहिए? आदर्श रूप से, ग्रिड को अपने पड़ोसियों से समान क्षेत्रों के बराबर होना चाहिए। और यह विवरण हेक्सागोन्स के ग्रिड की तरह है।


वास्तव में, हेक्सागोन्स का एक ग्रिड समतल सतह को समान क्षेत्रों में विभाजित करने का सबसे अच्छा तरीका है

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

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


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

एक विकल्प बनाने के बाद, अब मुझे सीखना होगा कि कैसे सूचकांक को हेक्सागोन्स के ग्रिड से जोड़ा जाए। उदाहरण के लिए, यदि मैं एक हेक्सागोनल सेल (3, 3) की तलाश में हूं, तो उसके पड़ोसी क्या होंगे? यदि प्रत्येक सेल की चौड़ाई 5 पिक्सेल है, तो सेल के केंद्र (3, 3) के निर्देशांक क्या होंगे? और इसी तरह।इससे निपटना मुश्किल हो सकता है, इसलिए मुझे खुशी है कि अमित ने मेरे लिए यह किया।

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


ये हेक्सागोन उन लोगों की तुलना में बहुत बड़े हैं जिन्हें मैं पवन मॉडल के लिए उपयोग करूंगा, लेकिन वे मुझे दिखाते हैं कि सब कुछ सही तरीके से रखा गया है।

यहाँ मैंने मानचित्र के किनारों को खोला और केवल केंद्रीय षट्भुज और सीमाओं पर यह जांचने के लिए कि क्या मैं वास्तव में पूरा नक्शा बंद करता हूँ:


ऊपर और नीचे नक्शे के बाहर हैं, लेकिन अगर मैं मानचित्र के एक हिस्से को याद नहीं करता हूं, तो विदेशों में कई कोशिकाओं की उपस्थिति महत्वपूर्ण नहीं है।

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


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


इस मामले में, खोज विपरीत दिशा में जगह लेती है - हेक्सागोन को भूमि के रूप में चिह्नित किया जाता है यदि इसमें कोई भूमि है। जो बेहतर है वह इस बात पर निर्भर करता है कि आपको क्या चाहिए।

किसी भी स्थिति में, मैं हेक्सागोन्स के आकार को कम करके सटीकता बढ़ा सकता हूं:


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

आप इस समाधान का उपयोग कर सकते हैं - लापता त्रिकोण की ऊंचाई को अपने पड़ोसियों के औसत के रूप में लें, या उनके पड़ोसियों के अधिकतम के रूप में।


सामान्य तौर पर, जब हेक्सागोन और स्थानों के बीच बंधन एक से एक नहीं होता है, तो लापता जानकारी को भरने के लिए सुधार की आवश्यकता होती है।

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

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

दूसरे चरण (यह निर्धारित करना कि कुल हवा कैसे षट्भुज को छोड़ती है) को विचार की आवश्यकता होती है। सबसे आसान मामला सीधे षट्भुज के माध्यम से बहने वाली हवा है:


इस मामले में, हम हवा को बदलाव के बिना अगले सेल में स्थानांतरित करने की उम्मीद करते हैं। (यहाँ, लाल सदिश मूल पवन है, और नीला प्रपंच पवन का सदिश है।)

लेकिन क्या होगा अगर हवा सीधे पड़ोसी कोशिका में नहीं जाती है?


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

फैलती हवा की दिशा पर निर्णय लेना भी आवश्यक है। मूल पवन की दिशा बनाए रखने के लिए एक विकल्प है:


ऐसा लगता है कि यह सबसे यथार्थवादी विकल्प है, लेकिन एक और भी है - हेक्सागोन के किनारे के अनुसार हवा की दिशा को बदलने के लिए कि यह अंतर करता है:


यह दृष्टिकोण कम सटीक है, लेकिन इसका एक फायदा है: आने वाली हवाएं हमेशा छह दिशाओं में से एक में रहेंगी, जिससे गणना सरल हो सकती है।

इलाके पर विचार करते समय एक और कठिनाई उत्पन्न होती है। जब कोई पहाड़ हवा में उठता है तो क्या होना चाहिए?


इस मामले में, हवा का हिस्सा पहाड़ के ऊपर से गुजरता है (संभवतः वर्षा पैदा करता है), लेकिन हवा का हिस्सा पक्ष में बदल जाता है।


इसलिए, जिस तरह से हवा षट्भुज से निकलती है, उसकी दिशा पर निर्भर करती है, साथ ही साथ पड़ोसी कोशिकाओं में स्थलाकृति।

अब चलो बात करते हैं कि वैक्टर का प्रतिनिधित्व कैसे करें। दो मुख्य विकल्प हैं। सबसे पहले, एक वेक्टर को एक्स और वाई मूल्यों के रूप में दर्शाया जा सकता है, उदाहरण के लिए इस तरह:


यदि हम (0, 0) पर शुरू होने वाले वेक्टर को आकर्षित करते हैं, तो (X, Y) अंतिम बिंदुओं के निर्देशांक हैं। इस तरह के रिकॉर्ड से वैक्टर को योग करना बहुत आसान हो जाता है। हम सभी मानों (X, Y) को जोड़ते हैं और एक नया वेक्टर प्राप्त करते हैं:


एक अन्य विकल्प वेक्टर के कोण और लंबाई का उपयोग करना है:


इस रूप में, घूमने वाले वैक्टर जैसे ऑपरेशन करना या उसकी लंबाई बदलना आसान है।
पवन मॉडल में आवश्यक अधिकांश संचालन के लिए, पहला विकल्प बेहतर है, लेकिन कुछ मामलों में दूसरा बेहतर है, इसलिए यदि आवश्यक हो तो उनके बीच स्विच करना सुविधाजनक होगा। पहिया को सुदृढ़ नहीं करने के लिए, मैंने जावास्क्रिप्ट और विक्टर के लिए एक वेक्टर लाइब्रेरी की तलाश की। विक्टर पूरी तरह से सामने आए , इसलिए मैंने इसका लाभ उठाया।

मैं प्रत्येक षट्भुज में एक पवन वेक्टर जोड़कर शुरू करूँगा और देख सकता हूँ कि क्या मैं इसकी कल्पना कर सकता हूँ:


यह अब तक अच्छा लग रहा है।

अगला चरण यह जांचना है कि क्या मैं विंड वेक्टर को सही ढंग से विभाजित कर सकता हूं और इसे अगले सेल में वितरित कर सकता हूं। सबसे पहले, आपको अन्य कोशिकाओं की ओर जाने वाले कोणों की गणना करने की आवश्यकता है। मुझे अमित के पेज पर फिर से जवाब मिला :


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

उदाहरण के लिए, अगर हवा वेक्टर में 22 डिग्री का कोण है:


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

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


यहाँ हम देखते हैं कि हवाएँ विकर्ण के साथ मिलती हैं और नीचे के कोने की ओर उड़ने के लिए जोड़ती हैं।

अगला कदम हवा पर भूमि के प्रभाव को ध्यान में रखना है। बेशक, असली पवन मॉडल बहुत जटिल हैं, लेकिन मैं मुख्य रूप से इस बात में दिलचस्पी रखता हूं कि भूगोल कैसे सतह की हवाओं को प्रभावित करता है। सबसे सरल स्तर पर, यह हवा की दिशा और गति पर भूमि की ऊँचाई और तराई का प्रभाव है। मैंने कई अलग-अलग दृष्टिकोणों के साथ प्रयोग किया, लेकिन परिणामस्वरूप मैं दो सरल नियमों पर बस गया :

  1. हवा बाधाओं से दूर हो जाती है।
  2. जब यह ऊपर उठता है और नीचे गिरता है, तो हवा धीमी हो जाती है।

एक बाधा तब होती है जब हवा एक सेल में एक उच्च ऊंचाई के साथ उड़ती है, उदाहरण के लिए, एक पहाड़ के साथ एक सेल में। जब ऐसा होता है, तो मैं उन दो कोशिकाओं को देखता हूं जिनमें हवा चल रही है, और हवा के कोण को बदलते हैं ताकि यह दो हेक्सागोन्स के निचले हिस्से की ओर इशारा करे। कोण परिवर्तन की भयावहता दो कोशिकाओं के बीच की ऊंचाई के अंतर पर निर्भर करती है, इसलिए जब हवा पहाड़ों के साथ दो पड़ोसी कोशिकाओं में बहती है, तो इसकी दिशा थोड़ी बदल जाती है, लेकिन अगर यह एक पर्वत के साथ एक सेल में और एक मैदान के साथ एक सेल में उड़ती है, तो यह खाली सेल की ओर अधिक मुड़ जाएगी:


हवा की ताकत को समायोजित किया जा सकता है। ऊपर के नक्शे पर, वह बहुत मजबूत है, जिससे कई अवास्तविक बायोम का उदय होगा। यहाँ एक अधिक तार्किक अर्थ है:


राहत के कारण हवा की गति का एक बड़ा हिस्सा अभी भी बना हुआ है, लेकिन तेज हवा के बड़े अंतराल और घाटियां छोटी हो गई हैं।

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


जैसा कि आप देख सकते हैं, अब ब्रीच के ऊपर की हवा थोड़ी कम होने लगी है।

यह ऑपरेशन हवा की दिशाओं के थोक को निर्धारित करता है। दूसरा हिस्सा हवा का मंदी है जब ऊपर उठ रहा है और कम होने पर त्वरण। मैं यह महसूस कर सकता हूं कि जिस सेल से हवा आती है, उस सेल की सापेक्ष ऊंचाई को देखते हुए, और सेल की ऊंचाई जिस में हवा चलती है, और यदि आवश्यक हो तो इसे धीमा / धीमा कर देता है।

यहाँ है कि यह सब कैसा दिखता है:


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

अब मैं मौजूदा वर्षा एल्गोरिदम में एक नई हवा का स्थान ले सकता हूं। यहां एक तुलना (बाईं ओर पुरानी हवाएं, दाईं ओर नई हवाएं) हैं:


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

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

इस सबका बिंदु हवा की पीढ़ी को तेज करना और सरल बनाना है ताकि महाद्वीपीय मानचित्रों में नए पवन व्यवहार को जोड़ा जा सके। क्या मैंने ऐसा किया? मैंने मूल पवन मॉडल और नए षट्भुज-आधारित मॉडल की रूपरेखा तैयार की। यह पता चला कि नया मॉडल मूल (!) की तुलना में 15-20 गुना तेज है। यह एक बहुत ही महत्वपूर्ण त्वरण है जो कार्ड पर बहुत कम प्रभाव डालता है। प्रयोग यह स्पष्ट करते हैं कि मॉडल हेक्सागोन्स के आकार के लिए विशेष रूप से संवेदनशील नहीं है, इसलिए यदि आवश्यक हो, तो मैं कोशिकाओं के आकार में वृद्धि करके एल्गोरिथ्म को और भी तेज कर सकता हूं।

अगली बार हम महाद्वीपीय पैमाने के पवन पैटर्न को लागू करने के लिए एक नए पवन मॉडल का उपयोग करने पर काम करेंगे, और फिर उन्हें वर्षा मॉडल और बायोम से जोड़ेंगे।

Source: https://habr.com/ru/post/hi429620/


All Articles