ساخت شش ضلعی منظم - نحوه رسم شش ضلعی. چگونه یک شش ضلعی منظم بسازیم چگونه با مداد یک شش ضلعی بکشیم

آیا مداد نزدیک شما هست؟ به بخش آن نگاهی بیندازید - این یک شش ضلعی منظم یا همانطور که به آن نیز می گویند یک شش ضلعی است. سطح مقطع یک مهره، یک میدان شطرنج شش ضلعی، برخی مولکول های پیچیده کربن (مثلا گرافیت)، یک دانه برف، یک لانه زنبوری و سایر اشیاء نیز این شکل را دارند. اخیراً یک شش ضلعی منظم غول پیکر در آن کشف شده است. آیا عجیب به نظر نمی رسد که طبیعت اغلب از ساختارهایی با این شکل خاص برای خلاقیت خود استفاده می کند؟ بیایید نگاه دقیق تری بیندازیم.

شش ضلعی منتظم چند ضلعی با شش ضلع مساوی و زاویه مساوی است. از دوره مدرسه می دانیم که دارای ویژگی های زیر است:

  • طول اضلاع آن مطابق با شعاع دایره محدود است. از همه، فقط یک شش ضلعی منظم این خاصیت را دارد.
  • زوایا با هم برابرند و قدر هر کدام 120 درجه است.
  • محیط یک شش ضلعی را می توان با استفاده از فرمول Р=6*R در صورتی که شعاع دایره محصور در اطراف آن مشخص باشد، یا Р=4*√(3)*r اگر دایره در آن محاط شده باشد، یافت. R و r شعاع دایره های محصور و محاطی هستند.
  • مساحت اشغال شده توسط یک شش ضلعی منظم به صورت زیر تعیین می شود: S=(3*√(3)*R 2)/2. اگر شعاع ناشناخته است، طول یکی از اضلاع را به جای آن جایگزین می کنیم - همانطور که می دانید، مطابق با طول شعاع دایره محدود است.

شش ضلعی منظم یک ویژگی جالب دارد که به دلیل آن در طبیعت بسیار گسترده شده است - می تواند هر سطحی از هواپیما را بدون همپوشانی و شکاف پر کند. حتی به اصطلاح پال لم وجود دارد که طبق آن یک شش ضلعی منظم که ضلع آن برابر با 1/√(3) است یک تایر جهانی است، یعنی می تواند هر مجموعه ای را با قطر یک واحد پوشش دهد.

اکنون ساخت یک شش ضلعی منظم را در نظر بگیرید. راه های مختلفی وجود دارد که ساده ترین آنها استفاده از قطب نما، مداد و خط کش است. ابتدا یک دایره دلخواه با قطب نما رسم می کنیم سپس در جای دلخواه روی این دایره نقطه می زنیم. بدون تغییر محلول قطب نما، نوک را در این نقطه قرار می دهیم، بریدگی بعدی را روی دایره علامت می زنیم، به همین ترتیب ادامه می دهیم تا هر 6 امتیاز را بدست آوریم. اکنون فقط کافی است آنها را با قطعات مستقیم به یکدیگر متصل کنید و شکل مورد نظر ظاهر می شود.

در عمل، مواقعی وجود دارد که باید یک شش ضلعی بزرگ بکشید. به عنوان مثال، در یک سقف دو طبقه از گچ تخته، در اطراف محل اتصال لوستر مرکزی، باید شش لامپ کوچک در سطح پایین نصب کنید. پیدا کردن قطب نما با این اندازه بسیار بسیار دشوار خواهد بود. در این مورد چگونه باید اقدام کرد؟ چگونه یک دایره بزرگ رسم می کنید؟ بسیار ساده. باید یک نخ محکم به طول دلخواه بردارید و یکی از انتهای آن را در مقابل مداد ببندید. اکنون تنها یافتن دستیار باقی مانده است که انتهای دوم نخ را به سقف در نقطه مناسب فشار دهد. البته در این مورد، خطاهای جزئی ممکن است، اما بعید است که اصلاً برای یک خارجی قابل توجه باشد.

محتوا:

شش ضلعی منتظم که شش ضلعی کامل نیز نامیده می شود دارای شش ضلع مساوی و شش زاویه مساوی است. شما می توانید یک شش ضلعی را با یک متر و یک نقاله، یک شش ضلعی خشن با یک جسم گرد و یک خط کش، یا یک شش ضلعی حتی خشن تر را فقط با یک مداد و کمی شهود بکشید. اگر می خواهید بدانید که چگونه یک شش ضلعی را به روش های مختلف بکشید، کافی است ادامه مطلب را بخوانید.

مراحل

1 با قطب نما یک شش ضلعی کامل بکشید

  1. 1 با استفاده از قطب نما یک دایره بکشید.مداد را داخل قطب نما قرار دهید. قطب نما را به عرض دلخواه شعاع دایره خود باز کنید. شعاع می تواند از چند تا ده ها سانتی متر باشد. در مرحله بعد یک قطب نما را با مداد روی کاغذ بگذارید و یک دایره بکشید.
    • گاهی اوقات ساده تر است که ابتدا نصف دایره و سپس نیمه دیگر را بکشید.
  2. 2 سوزن قطب نما را به لبه دایره حرکت دهید.آن را بالای دایره قرار دهید. زاویه و موقعیت قطب نما را تغییر ندهید.
  3. 3 یک علامت مداد کوچک روی لبه دایره ایجاد کنید.آن را متمایز کنید، اما نه خیلی تیره، زیرا بعداً آن را پاک خواهید کرد. به یاد داشته باشید که زاویه ای را که برای قطب نما تعیین کرده اید ذخیره کنید.
  4. 4 سوزن قطب نما را روی علامتی که به تازگی ایجاد کرده اید حرکت دهید.سوزن را مستقیماً روی علامت قرار دهید.
  5. 5 یک علامت دیگر با مداد روی لبه دایره ایجاد کنید.بنابراین، علامت دوم را در فاصله مشخصی از علامت اول ایجاد می کنید. به حرکت در یک جهت ادامه دهید.
  6. 6 به همین ترتیب چهار علامت دیگر بزنید.شما باید به علامت اصلی برگردید. اگر نه، به احتمال زیاد زاویه ای که قطب نما را در دست گرفته اید و علامت ها را ایجاد کرده اید تغییر کرده است. شاید این اتفاق به دلیل این واقعیت است که شما آن را خیلی محکم فشار داده اید یا برعکس، کمی آن را شل کرده اید.
  7. 7 علامت ها را با خط کش وصل کنید.شش نقطه ای که علامت های شما با لبه دایره تلاقی می کنند، شش رأس شش ضلعی هستند. با استفاده از یک خط کش و مداد، خطوط مستقیمی را بکشید که علائم مجاور را به هم متصل می کند.
  8. 8 هم دایره و هم علامت های روی لبه های دایره و هر علامت دیگری را که ایجاد کرده اید پاک کنید. بعد از اینکه تمام خطوط راهنمای خود را پاک کردید، شش ضلعی کامل شما باید آماده باشد.

2 با یک جسم گرد و یک خط کش یک شش ضلعی خشن بکشید

  1. 1 لبه لیوان را با مداد دایره کنید.به این ترتیب یک دایره ترسیم خواهید کرد. کشیدن با مداد بسیار مهم است، زیرا بعداً باید تمام خطوط کمکی را پاک کنید. همچنین می‌توانید دور یک لیوان، شیشه یا هر چیز دیگری که پایه‌ای گرد دارد، حلقه بزنید.
  2. 2 خطوط افقی در وسط دایره خود بکشید.می توانید از خط کش، کتاب، هر چیزی که لبه مستقیم دارد استفاده کنید. اگر خط کش دارید، می توانید وسط را با محاسبه طول عمودی دایره و تقسیم آن به دو نیم علامت بزنید.
  3. 3 روی نیم دایره یک "X" بکشید و آن را به شش قسمت مساوی تقسیم کنید.از آنجایی که قبلاً یک خط از وسط دایره کشیده‌اید، X باید از عرض آن بیشتر باشد تا قسمت‌ها با هم برابر باشند. تصور کنید که یک پیتزا را به شش تکه تقسیم می کنید.
  4. 4 از هر بخش مثلث بسازید.برای انجام این کار، از خط کش خود برای کشیدن یک خط مستقیم زیر قسمت منحنی هر بخش استفاده کنید و آن را با دو خط دیگر وصل کنید تا یک مثلث تشکیل شود. این کار را با پنج بخش باقی مانده انجام دهید. مانند درست کردن پوسته اطراف برش های پیتزا به آن فکر کنید.
  5. 5 تمام خطوط کمکی را پاک کنید.خطوط راهنما شامل دایره شما، سه خطی که دایره شما را به بخش‌هایی تقسیم می‌کنند و هر علامت دیگری که در طول مسیر ایجاد کرده‌اید است.

3 با یک مداد یک شش ضلعی خشن بکشید

  1. 1 یک خط افقی بکشید.برای کشیدن یک خط مستقیم بدون خط کش، کافی است نقطه شروع و پایان خط افقی خود را بکشید. سپس مداد را در نقطه شروع قرار دهید و خط را تا انتها ادامه دهید. طول این خط می تواند تنها چند سانتی متر باشد.
  2. 2 دو خط مورب از انتهای خط افقی بکشید.خط مورب سمت چپ باید به همان شکلی که خط مورب سمت راست به سمت بیرون باشد. می توانید تصور کنید که این خطوط نسبت به خط افقی یک زاویه 120 درجه تشکیل می دهند.
  3. 3 دو خط افقی دیگر از اولین خطوط افقی که به سمت داخل کشیده شده اند بکشید.این یک تصویر آینه ای از دو خط مورب اول ایجاد می کند. خط پایین سمت چپ باید بازتابی از خط بالا سمت چپ باشد و خط پایین سمت راست باید بازتابی از خط بالا سمت راست باشد. در حالی که خطوط افقی بالایی باید به سمت بیرون باشند، خطوط پایین باید به سمت داخل در پایه نگاه کنند.
  4. 4 یک خط افقی دیگر بکشید و دو خط مورب پایین را به هم وصل کنید.به این ترتیب پایه شش ضلعی خود را ترسیم می کنید. در حالت ایده آل، این خط باید موازی با خط افقی بالایی باشد. در اینجا شما شش ضلعی خود را تکمیل کرده اید.
  • مداد و قطب نما باید تیز باشند تا خطاهای ناشی از علائم بیش از حد گسترده به حداقل برسد.
  • هنگام استفاده از روش قطب نما، اگر به جای هر شش علامت، هر علامت را به هم وصل کنید، یک مثلث متساوی الاضلاع خواهید داشت.

هشدارها

  • قطب نما یک جسم نسبتاً تیز است، بسیار مراقب آن باشید.

اصل عملیات

  • هر روش به رسم شش ضلعی که توسط شش مثلث متساوی الاضلاع با شعاع برابر با طول همه ضلع تشکیل شده است کمک می کند. شش شعاع ترسیم شده یکسان هستند و تمام خطوط ایجاد شش ضلعی نیز طول یکسانی دارند، زیرا عرض قطب نما تغییر نکرده است. با توجه به متساوی الاضلاع بودن شش مثلث، زوایای رئوس آنها 60 درجه است.

چه چیزی نیاز خواهید داشت

  • کاغذ
  • مداد
  • خط كش
  • جفت قطب نما
  • چیزی که می توان آن را زیر کاغذ قرار داد تا سوزن قطب نما سر نخورد.
  • پاک کن

یک مثلث محدود منتظم به صورت زیر ساخته می شود(شکل 38). از مرکز یک دایره معین با شعاع R1 دایره ای با شعاع رسم کنید R2 = 2R1 و آن را به سه قسمت مساوی تقسیم کنید. نقاط تقسیم الف، ب، ج رئوس مثلثی منتظم هستند که دور دایره ای به شعاع محصور شده اند R1 .

شکل 38

چهارضلعی منتظم (مربع)می توان با استفاده از قطب نما و خط کش ساخت (شکل 39). دو قطر متقابل عمود بر یک دایره مشخص رسم می شود. در نظر گرفتن نقاط تقاطع قطرها با دایره به عنوان مرکز، شعاع دایره آر کمان ها را تا زمان تقاطع متقابل آنها در نقاط توصیف کنید آ ب پ ت . نکته ها آ , ب , سی , D و رئوس مربع دور دایره داده شده هستند.

شکل 39

برای ساختن یک شش ضلعی منتظمابتدا باید رئوس مربع توصیف شده را به روشی که در بالا نشان داده شده است بسازید (شکل 40، a). همزمان با تعریف رئوس مربع، یک دایره معین از شعاع آر در نقاط به شش قسمت مساوی تقسیم می شود 1, 2, 3, 4, 5, 6 و اضلاع عمودی مربع را رسم کنید. عبور از نقاط تقسیم دایره 2–5 و 3–6 خطوط مستقیم تا زمانی که با اضلاع عمودی مربع تلاقی کنند (شکل 40، ب)، رئوس به دست آورند. الف، ب، د، ای شش ضلعی منظم محدود شده

شکل 40

قله های دیگر سیو افبا یک قوس دایره ای به شعاع تعریف می شود OA، که آنقدر ترسیم می شود که با ادامه قطر عمودی دایره داده شده قطع شود.
3 جفت

بیایید یاد بگیریم که چگونه یک منشور شش ضلعی را در موقعیت های مختلف رسم کنیم.

روش های مختلف ساخت یک شش ضلعی منظم را بیاموزید، نقاشی های شش ضلعی را بسازید، صحت ساخت آنها را بررسی کنید. بر اساس شش ضلعی ها، منشورهای شش ضلعی بسازید.

منشور شش ضلعی را در شکل در نظر بگیرید. 3.52 و برآمدگی های متعامد آن در شکل. 3.53. در پایه یک منشور شش ضلعی (هگزا وجهی) شش ضلعی های منظم قرار دارند، وجه های جانبی مستطیل های یکسان هستند. برای اینکه بتوانید یک شش ضلعی را در پرسپکتیو به درستی به تصویر بکشید، ابتدا باید یاد بگیرید که چگونه پایه آن را در پرسپکتیو به درستی به تصویر بکشید (شکل 3.54). در شش ضلعی در شکل. 3.55 قله ها از یک تا شش شماره گذاری شده اند. اگر نقاط 1 و 3، 4 و 6 را با خطوط عمودی به هم وصل کنید، متوجه می شوید که این خطوط به همراه نقطه مرکز دایره، قطر 5 - 2 را به چهار قسمت مساوی تقسیم می کنند (این قسمت ها با کمان مشخص می شوند. ). اضلاع مخالف یک شش ضلعی با یکدیگر موازی هستند و یک خط مستقیم از مرکز آن می گذرد و دو راس را به هم متصل می کند (به عنوان مثال ضلع های 6 - 1 و 4 - 3 موازی با خط 5 - 2 هستند). این مشاهدات به شما کمک می کند تا یک شش ضلعی در پرسپکتیو بسازید و همچنین صحت این ساختار را بررسی کنید. دو راه برای ساختن یک شش ضلعی منتظم از یک نمایش وجود دارد: بر اساس دایره محدود و بر اساس مربع.

بر اساس دایره محدود شده. شکل را در نظر بگیرید. 3.56. تمام رئوس یک شش ضلعی منتظم متعلق به دایره ای هستند که شعاع آن برابر با ضلع شش ضلعی است.


شش ضلعی افقی. یک بیضی افقی از باز شدن دلخواه، یعنی یک دایره محدود در پرسپکتیو رسم کنید. حالا باید شش نقطه روی آن پیدا کنید که رئوس شش ضلعی هستند. هر قطر دایره داده شده را از مرکز آن بکشید (شکل 3.57). نقاط انتهایی قطر - 5 و 2 که روی بیضی قرار دارند، رئوس شش ضلعی هستند. برای یافتن رئوس باقی مانده، لازم است این قطر را به چهار بخش یکسان تقسیم کنیم. قطر قبلاً توسط نقطه مرکزی دایره به دو شعاع تقسیم شده است ، باقی می ماند که هر شعاع را به نصف تقسیم کنیم. در طراحی پرسپکتیو، هر چهار بخش به طور مساوی با دور شدن از بیننده منقبض می شوند (شکل 3.58). اکنون از میان نقاط شعاع - نقاط A و B - خطوط مستقیم عمود بر خط مستقیم 5 - 2 بکشید. می توانید جهت آنها را با استفاده از مماس های بیضی در نقاط 5 و 2 پیدا کنید (شکل 3.59). این مماس ها بر قطر 5 - 2 عمود خواهند بود و خطوطی که از طریق نقاط A و B موازی با این مماس ها کشیده شده اند نیز بر خط 5 - 2 عمود خواهند بود. نقاط به دست آمده در تقاطع این خطوط با بیضی را به صورت زیر تعیین کنید. 1، 3، 4، 6 (شکل 3.60). هر شش راس را با خطوط مستقیم وصل کنید (شکل 3.61).

صحت ساخت خود را به روش های مختلف بررسی کنید. اگر ساختار درست باشد، خطوطی که رئوس مخالف شش ضلعی را به هم متصل می کنند در مرکز دایره قطع می شوند (شکل 3.62)، و اضلاع مخالف شش ضلعی با قطرهای مربوطه موازی هستند (شکل 3.63). روش دیگر تأیید در شکل نشان داده شده است. 3.64.

شش ضلعی عمودی. در چنین شش ضلعی، خطوط متصل کننده نقاط 7 و 3، b و 4 و همچنین مماس های دایره محدود شده در نقاط 5 و 2 دارای جهت عمودی هستند و آن را در ترسیم پرسپکتیو حفظ می کنند. بنابراین با رسم دو مماس عمودی به بیضی، نقاط 5 و 2 (نقاط لمسی) را پیدا می کنیم. آنها را با یک خط مستقیم به هم وصل کنید و سپس قطر 5 - 2 حاصل را با در نظر گرفتن برش های چشم انداز آنها به 4 قسمت مساوی تقسیم کنید (شکل 3.65). خطوط عمودی را از طریق نقاط A و B رسم کنید و در تقاطع آنها با بیضی نقاط 1,3,6l4 را پیدا کنید. سپس به ترتیب نقاط 1 - 6 را با خطوط مستقیم وصل کنید (شکل 3.66). درستی ساخت شش ضلعی را مانند مثال قبلی بررسی کنید.

روش توصیف شده برای ساختن یک شش ضلعی به شما امکان می دهد این شکل را بر اساس یک دایره بدست آورید که به تصویر کشیدن در پرسپکتیو آسان تر از مربع با نسبت های داده شده است. بنابراین، این روش ساخت شش ضلعی دقیق ترین و جهانی به نظر می رسد. روش ساخت بر اساس مربع، ترسیم شش ضلعی را زمانی که از قبل یک مکعب در شکل وجود دارد، آسان می کند، به عبارت دیگر، زمانی که نسبت مربع و جهت اضلاع آن مشخص شده است.

بر اساس مربع. شکل را در نظر بگیرید. 3.67. یک شش ضلعی که در یک مربع در جهت افقی 5 - 2 حک شده است برابر با ضلع مربع و به طور عمودی کمتر از طول آن است.

شش ضلعی عمودی. یک مربع عمودی در پرسپکتیو رسم کنید. یک خط مستقیم از طریق تقاطع مورب ها، به موازات اضلاع افقی آن بکشید. قسمت 5 - 2 حاصل را به چهار قسمت مساوی تقسیم کنید و خطوط عمودی را از طریق نقاط A و B بکشید (شکل 3.68). خطوطی که شش ضلعی را از بالا و پایین محدود می کنند با اضلاع مربع منطبق نیستند. آنها را در فاصله ای (1114 الف) از اضلاع افقی مربع و به موازات آنها بکشید. با اتصال نقاط 1 و 3 به این ترتیب با نقطه 2 و نقاط 6 و 4 با نقطه 5 یک شش ضلعی بدست می آوریم (شکل 3.69).

شش ضلعی افقی به همان ترتیب ساخته شده است (شکل 3.70 و 3.71).

این روش ساخت فقط برای شش ضلعی با باز شدن کافی مناسب است. اگر دهانه شش ضلعی ناچیز است، بهتر است از روش بر اساس دایره محدود استفاده کنید. برای بررسی یک شش ضلعی ساخته شده از طریق یک مربع، می توانید از روش هایی استفاده کنید که قبلاً برای شما شناخته شده است.

علاوه بر این، یکی دیگر وجود دارد - برای توصیف یک دایره در اطراف شش ضلعی حاصل (در شکل شما - یک بیضی). تمام رئوس شش ضلعی باید متعلق به این بیضی باشد.

با تسلط بر مهارت های ترسیم شش ضلعی، آزادانه به سمت کشیدن منشور شش ضلعی خواهید رفت. با دقت به نمودار در شکل نگاه کنید. 3.72، و همچنین طرح هایی برای ساخت منشورهای شش ضلعی بر اساس دایره (شکل 3.73؛ 3.74 و 3.75) و بر اساس یک مربع (شکل 3.76؛ 3.77 و 3.78). شش ضلعی های عمودی و افقی را به روش های مختلف رسم کنید. در ترسیم شش ضلعی عمودی، اضلاع بلند وجوه جانبی خطوطی عمودی موازی با یکدیگر خواهند بود و شش ضلعی پایه هر چه از خط افق دورتر باشد بازتر خواهد بود. در ترسیم یک شش ضلعی افقی، اضلاع طولانی وجه های جانبی در نقطه ناپدید شدن در افق همگرا می شوند و دهانه شش ضلعی پایه بزرگتر خواهد بود، هر چه از بیننده دورتر باشد. هنگام ترسیم یک شش ضلعی، همچنین مطمئن شوید که وجوه موازی هر دو پایه در پرسپکتیو همگرا هستند (شکل 3.79؛ 3.80).

شبکه های شش ضلعی (شبکه های شش ضلعی) در برخی از بازی ها استفاده می شود، اما آنها به سادگی و معمولی شبکه های مستطیل نیستند. من تقریباً 20 سال است که منابعی را درباره شبکه های هگزا جمع آوری کرده ام و این راهنما را برای ظریف ترین رویکردهای پیاده سازی شده در ساده ترین کد نوشته ام. این مقاله به طور مکرر از کتابچه های راهنمای چارلز فو و کلارک وربروژ استفاده می کند. من روش های مختلف ایجاد شبکه های شش ضلعی، رابطه آنها و همچنین رایج ترین الگوریتم ها را شرح خواهم داد. بسیاری از بخش‌های این مقاله تعاملی هستند: انتخاب نوع شبکه، نمودارها، کدها و متون مربوطه را تغییر می‌دهد. (توجه به .: این فقط در مورد اصل صدق می کند، به شما توصیه می کنم آن را مطالعه کنید. در ترجمه، تمام اطلاعات نسخه اصلی حفظ می شود، اما بدون تعامل.).

نمونه‌های کد موجود در مقاله با شبه کد نوشته شده‌اند، بنابراین خواندن و درک آن‌ها برای نوشتن پیاده‌سازی خودتان آسان‌تر است.

هندسه

شش ضلعی ها چند ضلعی شش ضلعی هستند. شش ضلعی های منتظم همه ضلع ها (وجه ها) به طول یکسان دارند. ما فقط با شش ضلعی های معمولی کار خواهیم کرد. به طور معمول، شبکه های شش گوش از جهت افقی (بالای تیز) و عمودی (بالای تخت) استفاده می کنند.


شش ضلعی های صاف (چپ) و تیز (راست) بالا

شش ضلعی ها 6 وجه دارند. هر صورت با دو شش ضلعی مشترک است. شش ضلعی ها 6 نقطه گوشه دارند. هر نقطه گوشه با سه شش ضلعی مشترک است. می توانید در مقاله من در مورد قطعات مش (مربع، شش ضلعی و مثلث) در مورد مراکز، لبه ها و نقاط گوشه بیشتر بخوانید.

گوشه ها

در یک شش ضلعی منظم، زوایای داخلی 120 درجه است. شش "گوه" وجود دارد که هر یک مثلث متساوی الاضلاع با زوایای داخلی 60 درجه است. نقطه گوشه من(60° * i) + 30 درجه، واحد اندازه از مرکز است. در کد:

تابع hex_corner (مرکز، اندازه، i): var angle_deg = 60 * i + 30 var angle_rad = PI / 180 * angle_deg return Point(center.x + size * cos(angle_rad)، center.y + size * sin(angle_rad) )
برای پر کردن یک شش ضلعی، باید رئوس چند ضلعی را از hex_corner(…, 0) به hex_corner(…, 5) بدست آورید. برای ترسیم طرح کلی شش ضلعی، باید از این رئوس استفاده کنید و سپس دوباره خط را در hex_corner (…, 0) بکشید.

تفاوت بین این دو جهت این است که x و y با هم عوض می شوند که باعث تغییر زاویه می شود: شش ضلعی های بالای تخت دارای زوایای 0 درجه، 60 درجه، 120 درجه، 180 درجه، 240 درجه، 300 درجه هستند و شش ضلعی های بالای تیز دارای زاویه هستند. 30 درجه، 90 درجه، 150 درجه، 210 درجه، 270 درجه، 330 درجه.


گوشه های شش گوش با بالای صاف و تیز

اندازه و مکان

حالا می خواهیم چندین شش ضلعی را با هم مرتب کنیم. در جهت افقی، ارتفاع شش ضلعی ارتفاع = اندازه * 2 است. فاصله عمودی بین شش ضلعی های مجاور vert = ارتفاع * 3/4 ​​است.

عرض شش ضلعی عرض = sqrt(3)/2 * ارتفاع است. فاصله افقی بین شش ضلعی های مجاور horiz = عرض .

برخی از بازی ها از پیکسل آرت برای شش ضلعی ها استفاده می کنند که دقیقاً با شش ضلعی های صحیح مطابقت ندارد. فرمول های زاویه و موقعیت که در این بخش توضیح داده شده اند با ابعاد این شش ضلعی ها مطابقت ندارند. بقیه مقاله که الگوریتم های شبکه شش ضلعی را توصیف می کند، حتی اگر شش ضلعی ها کمی کشیده یا فشرده شده باشند، کاربرد دارد.



دستگاه های مختصات

بیایید شروع به جمع آوری شش ضلعی ها در یک شبکه کنیم. در مورد شبکه های مربع، تنها یک راه واضح برای جمع آوری وجود دارد. برای شش ضلعی ها، رویکردهای زیادی وجود دارد. من توصیه می کنم از مختصات مکعبی به عنوان نمایش اولیه استفاده کنید. مختصات محوری یا مختصات افست باید برای ذخیره نقشه ها و نمایش مختصات به کاربر استفاده شود.

مختصات افست

متداول ترین روش، جبران هر ستون یا سطر متوالی است. ستون ها با col یا q نشان داده می شوند. ردیف ها با ردیف یا r نشان داده می شوند. شما می توانید ستون ها/ردیف های فرد یا زوج را جبران کنید، بنابراین شش ضلعی های افقی و عمودی هر کدام دو گزینه دارند.


آرایش افقی "فرد-r"


آرایش افقی "جلو-r"


آرایش عمودی "فرد-q"


آرایش عمودی "جلو-q"

مختصات مکعبی

راه دیگر برای نگاه کردن به شبکه های شش ضلعی، دیدن در آنها است سهمحورهای اصلی، نه دو، مانند شبکه های مربع. آنها تقارن ظریف را نشان می دهند.

شبکه ای از مکعب ها را بردارید و قطع کردنصفحه مورب در x + y + z = 0 . این ایده عجیبی است، اما به ما کمک می کند تا الگوریتم های شبکه شش ضلعی را ساده کنیم. به طور خاص، ما قادر خواهیم بود از عملیات استاندارد مختصات دکارتی استفاده کنیم: جمع و تفریق مختصات، ضرب و تقسیم بر یک مقدار اسکالر، و همچنین فواصل.

به سه محور اصلی روی شبکه مکعب ها و رابطه آنها با شش محور توجه کنید موربجهت های شبکه شش ضلعی ها محورهای مورب شبکه با جهت اصلی شبکه شش ضلعی مطابقت دارد.


شش ضلعی


کوبا

از آنجایی که ما قبلاً الگوریتم هایی برای شبکه های مربع و مکعب داریم، استفاده از مختصات مکعبی به ما امکان می دهد این الگوریتم ها را با شبکه های شش ضلعی تطبیق دهیم. من از این سیستم برای اکثر الگوریتم های مقاله استفاده خواهم کرد. برای استفاده از الگوریتم‌هایی با سیستم مختصات متفاوت، مختصات مکعبی را تبدیل می‌کنم، الگوریتم را اجرا می‌کنم و سپس آن‌ها را دوباره تبدیل می‌کنم.

یاد بگیرید که مختصات مکعبی چگونه برای شبکه ای از شش ضلعی کار می کنند. هنگام انتخاب شش ضلعی، مختصات مکعبی مربوط به سه محور برجسته می شوند.

  1. هر جهت از شبکه مکعب مربوط به خطوطروی شبکه ای از شش ضلعی ها سعی کنید یک شش ضلعی با z برابر با 0، 1، 2، 3 انتخاب کنید تا اتصال را ببینید. خط با رنگ آبی مشخص شده است. همین کار را برای x (سبز) و y (بنفش) امتحان کنید.
  2. هر جهت شبکه شش ضلعی ترکیبی از دو جهت شبکه مکعبی است. به عنوان مثال، "شمال" شبکه شش ضلعی بین +y و -z قرار دارد، بنابراین هر گام به سمت "شمال" y را 1 افزایش می دهد و z را 1 کاهش می دهد.
مختصات مکعبی یک انتخاب معقول برای سیستم مختصات شبکه شش ضلعی است. شرط x + y + z = 0 است، بنابراین باید در الگوریتم‌ها حفظ شود. این شرط همچنین تضمین می کند که همیشه یک مختصات متعارف برای هر شش ضلعی وجود خواهد داشت.

سیستم های مختصات مختلفی برای مکعب ها و شش ضلعی ها وجود دارد. در برخی از آنها، شرط با x + y + z = 0 متفاوت است. من فقط یکی از سیستم های متعدد را نشان دادم. شما همچنین می توانید مختصات مکعبی را با x-y، y-z، z-x ایجاد کنید، که مجموعه ای از ویژگی های جالب خود را دارند، اما من در اینجا به آنها نمی پردازم.

اما ممکن است استدلال کنید که نمی‌خواهید 3 عدد را برای مختصات ذخیره کنید زیرا نمی‌دانید چگونه یک نقشه را ذخیره کنید.

مختصات محوری

سیستم مختصات محوری، که گاهی اوقات "ذوزنقه ای" نامیده می شود، بر اساس دو یا سه مختصات از سیستم مختصات مکعبی ساخته می شود. از آنجایی که شرط x + y + z = 0 را داریم، مختصات سوم مورد نیاز نیست. مختصات محوری برای ذخیره نقشه ها و نمایش مختصات به کاربر مفید است. همانند مختصات مکعبی، می توانید از عملیات استاندارد جمع، تفریق، ضرب و تقسیم مختصات دکارتی با آنها استفاده کنید.

سیستم های مختصات مکعبی و محوری زیادی وجود دارد. در این راهنما، من همه ترکیب ها را پوشش نمی دهم. من دو متغیر q (ستون) و r (ردیف) را انتخاب می کنم. در مدارهای این مقاله، q با x و r مطابق با z است، اما این نگاشت دلخواه است زیرا می‌توانید مدارها را بچرخانید و بچرخانید تا نگاشت‌های متفاوتی به دست آورید.

مزیت این سیستم نسبت به شبکه های جابجایی، وضوح بیشتر الگوریتم ها است. نقطه ضعف سیستم این است که ذخیره یک نقشه مستطیل شکل کمی عجیب است. بخش ذخیره نقشه ها را ببینید. برخی از الگوریتم‌ها حتی در مختصات مکعبی واضح‌تر هستند، اما از آنجایی که شرط x + y + z = 0 را داریم، می‌توانیم مختصات ضمنی سوم را محاسبه کرده و در این الگوریتم‌ها استفاده کنیم. در پروژه هایم، محورها را q , r , s می نامم، بنابراین شرط به نظر می رسد q + r + s = 0 است و می توانم در صورت نیاز s = -q - r را محاسبه کنم.

تبرها

مختصات افست اولین چیزی است که بیشتر مردم به آن فکر می کنند زیرا با مختصات دکارتی استاندارد که برای شبکه های مربعی استفاده می شود یکسان هستند. متأسفانه یکی از دو محور باید بر خلاف دانه پیش برود و در نتیجه کار را پیچیده می کند. Cube و Axial کمی کاربردی هستند و الگوریتم های ساده تری دارند، اما ذخیره سازی نقشه کمی پیچیده تر است. سیستم دیگری وجود دارد به نام «مرتبط» یا «دو»، اما در اینجا آن را بررسی نمی کنیم. برخی کار با آن را آسان تر از مکعبی یا محوری می دانند.


مختصات افست، مکعبی و محوری

محورجهتی است که مختصات مربوطه در آن افزایش می یابد. عمود بر محور خطی است که مختصات روی آن ثابت می ماند. نمودارهای شبکه ای بالا خطوط عمودی را نشان می دهند.

تحول هماهنگ کنید

این احتمال وجود دارد که از مختصات محوری یا آفست در پروژه خود استفاده کنید، اما بسیاری از الگوریتم ها به راحتی در مختصات مکعبی بیان می شوند. بنابراین، ما باید بتوانیم مختصات بین سیستم ها را تبدیل کنیم.

مختصات محوری ارتباط نزدیکی با مختصات مکعبی دارند، بنابراین تبدیل ساده است:

# تبدیل مختصات مکعبی به محوری q = x r = z # تبدیل مختصات محوری به مکعب x = q z = r y = -x-z
در کد، این دو تابع را می توان به صورت زیر نوشت:

تابع cube_to_hex(h): # var محوری q = h.x var r = h.z بازگشت Hex(q, r) تابع hex_to_cube(h): # مکعب var x = h.q var z = h.r var y = -x-z بازگشت مکعب(x, y ز)
مختصات آفست کمی پیچیده تر است:

شش ضلعی های همسایه

با توجه به یک شش ضلعی، چه شش شش ضلعی در کنار آن قرار دارد؟ همانطور که ممکن است انتظار داشته باشید، پاسخ در مختصات مکعبی ساده‌ترین پاسخ، در مختصات محوری نسبتاً ساده و در مختصات افست کمی دشوار است. همچنین ممکن است لازم باشد شش شش ضلعی "مورب" را محاسبه کنید.

مختصات مکعبی

حرکت یک فاصله در مختصات هگز یکی از سه مختصات مکعبی را 1+ و دیگری را 1- تغییر می دهد (مجموع باید 0 باقی بماند). سه مختصات ممکن می توانند با 1+ تغییر کنند و دو مختصات باقی مانده می توانند با -1 تغییر کنند. این شش تغییر احتمالی را به ما می دهد. هر کدام مربوط به یکی از جهت های شش ضلعی است. ساده‌ترین و سریع‌ترین راه این است که تغییرات را از پیش محاسبه کنید و آنها را در جدول مکعب (dx, dy, dz) مختصات مکعبی در زمان کامپایل قرار دهید:

جهت های متغیر = [ مکعب(+1، -1، 0)، مکعب(+1، 0، -1)، مکعب(0، +1، -1)، مکعب(-1، +1، 0)، مکعب( -1، 0، +1)، Cube(0، -1، +1) ] تابع cube_direction(جهت): تابع جهت بازگشت cube_neighbor(hex، جهت): return cube_add(hex، cube_direction(جهت))

مختصات محوری

مانند قبل، برای شروع از سیستم مکعبی استفاده می کنیم. بیایید جدول Cube(dx,dy,dz) را بگیریم و آن را به جدول Hex(dq, dr) تبدیل کنیم:

جهت‌های متغیر = [ Hex(+1، 0)، Hex(+1، -1)، Hex(0، -1)، Hex(-1، 0)، Hex(-1، +1)، Hex(0، +1) ] تابع hex_direction(جهت): تابع جهت بازگشت hex_neighbor(hex، جهت): var dir = hex_direction (جهت) return Hex(hex.q + dir.q, hex.r + dir.r)

مختصات افست

در مختصات محوری بسته به جایی که در شبکه قرار داریم تغییراتی ایجاد می کنیم. اگر در یک ستون/ردیف افست باشیم، این قانون با حالت ستون/ردیف بدون افست متفاوت است.

مانند قبل، جدولی از اعداد برای اضافه کردن به col و row ایجاد می کنیم. با این حال، این بار دو آرایه خواهیم داشت، یکی برای ستون ها/ردیف های فرد و دیگری برای زوج ها. به (1،1) در نقشه شبکه بالا نگاه کنید و متوجه شوید که چگونه ستون و ردیف با حرکت در هر یک از شش جهت تغییر می کنند. حالا بیایید روند را برای (2،2) تکرار کنیم. جداول و کد برای هر یک از چهار نوع شبکه جابجایی متفاوت خواهد بود، در اینجا کد مربوطه برای هر نوع شبکه آورده شده است.

odd-r
جهت‌های var = [ [ Hex(+1، 0)، Hex(0، -1)، Hex(-1، -1)، Hex(-1، 0)، Hex(-1، +1)، Hex(0 , +1) ]، [ Hex(+1، 0)، Hex(+1، -1)، Hex(0، -1)، Hex(-1، 0)، Hex(0، +1)، Hex( +1، +1) ] ] تابع offset_neighbor(hex، جهت): var parity = hex.row و 1 var dir = جهت ها بازگشت Hex(hex.col + dir.col، hex.row + dir.row)


حتی-ر
جهت‌های var = [ [ Hex(+1، 0)، Hex(+1، -1)، Hex(0، -1)، Hex(-1، 0)، Hex(0، +1)، Hex(+1 , +1) ]، [ Hex(+1، 0)، Hex(0، -1)، Hex(-1، -1)، Hex(-1، 0)، Hex(-1، +1)، Hex (0، +1) ] ] تابع offset_neighbor (هگز، جهت): var parity = hex.row و 1 var dir = جهت ها بازگشت Hex(hex.col + dir.col، hex.row + dir.row)


برای سطرهای زوج (حتی) و فرد (ODD) شبکه بندی کنید

فرد-ق
جهت‌های var = [ [ Hex(+1، 0)، Hex(+1، -1)، Hex(0، -1)، Hex(-1، -1)، Hex(-1، 0)، Hex(0 , +1) ]، [ Hex(+1، +1)، Hex(+1، 0)، Hex(0، -1)، Hex(-1، 0)، Hex(-1، +1)، Hex (0، +1) ] ] تابع offset_neighbor(hex، جهت): var parity = hex.col و 1 var dir = جهت ها بازگشت Hex(hex.col + dir.col، hex.row + dir.row)


زوج-q
جهت‌های var = [ [ Hex(+1، +1)، Hex(+1، 0)، Hex(0، -1)، Hex(-1، 0)، Hex(-1، +1)، Hex(0 , +1) ]، [ Hex(+1، 0)، Hex(+1، -1)، Hex(0، -1)، Hex(-1، -1)، Hex(-1، 0)، Hex (0، +1) ] ] تابع offset_neighbor(hex، جهت): var parity = hex.col و 1 var dir = جهت ها بازگشت Hex(hex.col + dir.col، hex.row + dir.row)


شبکه برای ستون های زوج (حتی) و فرد (ODD).

مورب ها

حرکت در فضای "مورب" در مختصات شش ضلعی یکی از سه مختصات مکعبی را 2± و دو مختصات دیگر را ∓1 تغییر می دهد (مجموع باید 0 باقی بماند).

قطرهای متغیر = [ مکعب(+2، -1، -1)، مکعب(+1، +1، -2)، مکعب(-1، +2، -1)، مکعب(-2، +1، +1 ), Cube(-1، -1، +2)، Cube(+1، -2، +1) ] تابع cube_diagonal_neighbor(hex، جهت): return cube_add (هگز، مورب)
مانند قبل، می‌توانیم با حذف یکی از سه مختصات، این مختصات را به مختصات محوری تبدیل کنیم، یا با محاسبه پیش‌محاسبه نتایج، آن‌ها را به مختصات افست تبدیل کنیم.


فاصله ها

مختصات مکعبی

در سیستم مختصات مکعبی، هر شش ضلعی یک مکعب در فضای سه بعدی است. شش ضلعی های همسایه در شبکه شش ضلعی 1 و در شبکه مکعبی 2 فاصله دارند. این امر محاسبه فاصله را ساده می کند. در شبکه ای از مربع ها، فواصل منهتن abs(dx) + abs(dy) است. در شبکه ای از مکعب ها، فواصل منهتن abs(dx) + abs(dy) + abs(dz) است. فاصله در شبکه شش ضلعی ها برابر است با نیمی از آنها:

تابع cube_distance(a, b): return (abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z)) / 2
معادل این نماد این است که بگوییم یکی از سه مختصات باید مجموع دو مختصات دیگر باشد و سپس آن را به عنوان فاصله بدست آوریم. شما می توانید فرم دوبخشی یا فرم حداکثر مقدار را در زیر انتخاب کنید، اما آنها نتیجه یکسانی دارند:

تابع cube_distance(a, b): بازگشت حداکثر (abs(a.x - b.x)، abs(a.y - b.y)، abs(a.z - b.z))
در شکل، حداکثر مقادیر با رنگ مشخص شده است. همچنین توجه داشته باشید که هر رنگ یکی از شش جهت "مورب" را نشان می دهد.

gif


مختصات محوری

در سیستم محوری، مختصات سوم به طور ضمنی بیان می شود. برای محاسبه فاصله از محوری به مکعبی تبدیل می کنیم:

تابع hex_distance(a, b): var ac = hex_to_cube(a) var bc = hex_to_cube(b) return cube_distance(ac, bc)
اگر کامپایلر در کیس شما hex_to_cube و cube_distance (داخلی) را جاسازی کند، کدی مانند این تولید می‌کند:

تابع hex_distance(a, b): return (abs(a.q - b.q) + abs(a.q + a.r - b.q - b.r) + abs(a.r - b.r)) / 2
روش های مختلفی برای نوشتن فاصله بین شش ضلعی ها در مختصات محوری وجود دارد، اما صرف نظر از نحوه نوشتن فاصله بین شش ضلعی ها در سیستم محوری از فاصله منهتن در سیستم مکعبی به دست می آید.. به عنوان مثال، "تفاوت تفاوت ها" توصیف شده با نوشتن a.q + a.r - b.q - b.r به صورت a.q - b.q + a.r - b.r و استفاده از فرم مقدار حداکثر به جای شکل دوقسمت cube_distance به دست می آید. اگر ارتباط با مختصات مکعبی را مشاهده کنید، همه آنها مشابه هستند.

مختصات افست

همانند مختصات محوری، مختصات افست را به مختصات مکعبی تبدیل می کنیم و سپس از فاصله مکعبی استفاده می کنیم.

تابع offset_distance(a, b): var ac = offset_to_cube(a) var bc = offset_to_cube(b) return cube_distance(ac, bc)
ما از همین الگو برای بسیاری از الگوریتم ها استفاده خواهیم کرد: تبدیل از شش ضلعی به مکعب، اجرای نسخه مکعبی الگوریتم، و تبدیل نتایج مکعب شده به مختصات شش ضلعی (مختصات محوری یا افست).

خط کشی

چگونه از یک شش ضلعی به دیگری خط بکشیم؟ من از درون یابی خطی برای ترسیم خطوط استفاده می کنم. خط به طور مساوی در نقاط N+1 نمونه برداری می شود و محاسبه می شود که این نمونه ها در کدام شش ضلعی قرار دارند.

gif


  1. ابتدا N را محاسبه می کنیم که فاصله بین نقاط انتهایی به صورت شش ضلعی خواهد بود.
  2. سپس از N+1 نقطه بین نقاط A و B به طور مساوی نمونه برداری می کنیم. با استفاده از درون یابی خطی، تعیین می کنیم که برای مقادیر i از 0 تا N، با احتساب آنها، هر نقطه A + (B - A) * 1.0/N * باشد. من . در شکل، این نقاط کنترل به رنگ آبی نشان داده شده اند. نتیجه مختصات ممیز شناور است.
  3. هر نقطه کنترل (شناور) را به شش ضلعی (int) برگردانید. الگوریتم cube_round نامیده می شود (به زیر مراجعه کنید).
اتصال همه چیز به یکدیگر برای کشیدن یک خط از A به B:

تابع lerp(a, b, t): // برای شناورها a + (b - a) برمی گرداند * تابع t cube_lerp(a, b, t): // برای شش ضلعی ها Cube را برمی گرداند(lerp(a.x, b.x, t) lerp(a.y، b.y، t)، lerp(a.z، b.z، t)) تابع cube_linedraw(a، b): var N = cube_distance(a, b) var results = برای هر 0 ≤ i ≤ N: results.append( cube_round(cube_lerp(a, b, 1.0/N * i))) نتایج را برمی گرداند
یادداشت:

  • مواقعی وجود دارد که cube_lerp نقطه ای را دقیقاً در لبه بین دو شش ضلعی برمی گرداند. سپس cube_round آن را به یک طرف یا آن طرف حرکت می دهد. خطوط اگر در یک جهت جابجا شوند بهتر به نظر می رسند. این کار را می توان با افزودن یک مکعب شش گوش "epsilon" (1e-6، 1e-6، -2e-6) به یک یا هر دو نقطه پایانی قبل از شروع حلقه انجام داد. این خط را در یک جهت "تکان می دهد" تا به مرزهای لبه برخورد نکند.
  • الگوریتم خط DDA در شبکه های مربع، N را با حداکثر فاصله در امتداد هر یک از محورها برابر می کند. ما همین کار را در فضای مکعبی انجام می دهیم، که مشابه فاصله در یک شبکه شش ضلعی است.
  • تابع cube_lerp باید یک مکعب با مختصات شناور برگرداند. اگر به یک زبان تایپ ایستا برنامه نویسی می کنید، نمی توانید از نوع Cube استفاده کنید. به جای آن می‌توانید یک نوع FloatCube تعریف کنید، یا اگر نمی‌خواهید نوع دیگری تعریف کنید، تابع (inline) را در کد ترسیم خط خود به‌صورت درون خطی قرار دهید.
  • می توانید کد را با درون خطی کردن (inline) cube_lerp و سپس محاسبه B.x-A.x، B.x-A.y و 1.0/N در خارج از حلقه بهینه کنید. ضرب را می توان به جمع مکرر تبدیل کرد. نتیجه چیزی شبیه به یک الگوریتم خط DDA است.
  • من از مختصات محوری یا مکعبی برای ترسیم خطوط استفاده می کنم، اما اگر می خواهید با مختصات افست کار کنید، بررسی کنید.
  • گزینه های زیادی برای کشیدن خطوط وجود دارد. گاهی اوقات "پوشش بیش از حد" مورد نیاز است. کد رسم خطوط روکش شده در شش ضلعی برای من ارسال شده است، اما هنوز آن را بررسی نکرده ام.

محدوده سفر

محدوده مختصات

با توجه به مرکز شش ضلعی و محدوده N، کدام شش ضلعی ها در N پله آن قرار دارند؟

ما می توانیم از فرمول فاصله شش ضلعی فاصله = max(abs(dx)، abs(dy)، abs(dz)) رو به عقب کار کنیم. برای یافتن تمام شش ضلعی ها در N، به max(abs(dx)، abs(dy)، abs(dz)) ≤ N نیاز داریم. این بدان معنی است که هر سه مقدار مورد نیاز است: abs(dx) ≤ N و abs(dy) ≤ N و abs(dz) ≤ N. با حذف مقدار مطلق -N ≤ dx ≤ N و -N ≤ dy ≤ N و -N ≤ dz ≤ N به دست می آید. در کد، این یک حلقه تو در تو خواهد بود:

نتایج Var = برای هر -N ≤ dx ≤ N: برای هر -N ≤ dy ≤ N: برای هر -N ≤ dz ≤ N: اگر dx + dy + dz = 0: results.append(cube_add(center, Cube(dx , dy, dz)))
این حلقه کار خواهد کرد، اما نسبتا ناکارآمد خواهد بود. از تمام مقادیر dz که در حلقه تکرار می‌کنیم، فقط یک مورد در واقع شرایط مکعب‌ها dx + dy + dz = 0 را برآورده می‌کند. در عوض، ما مستقیماً مقدار dz را محاسبه خواهیم کرد که شرط را برآورده می کند:

نتایج var = برای هر -N ≤ dx ≤ N: برای هر max(-N, -dx-N) ≤ dy ≤ min(N, -dx+N): var dz = -dx-dy results.append(cube_add( مرکز، مکعب (dx، dy، dz)))
این حلقه فقط از مختصات مورد نیاز عبور می کند. در شکل، هر محدوده یک جفت خط است. هر خط یک نابرابری است. تمام شش ضلعی هایی را می گیریم که شش نابرابری را برآورده می کنند.

gif


محدوده های همپوشانی

اگر نیاز به یافتن شش ضلعی هایی دارید که در چندین محدوده قرار دارند، می توانید قبل از ایجاد لیستی از شش ضلعی ها، محدوده ها را طی کنید.

می توان به این مسئله از منظر جبر یا هندسه برخورد کرد. از نظر جبری، هر ناحیه به صورت شرایط نابرابری به شکل -N ≤ dx ≤ N بیان می شود و باید محل تلاقی این شرایط را پیدا کنیم. از نظر هندسی، هر ناحیه یک مکعب در فضای سه بعدی است و ما دو مکعب را در فضای سه بعدی قطع می کنیم تا یک مکعب در فضای سه بعدی به دست آوریم. سپس آن را به صفحه x + y + z = 0 برمی گردانیم تا شش ضلعی ها را بدست آوریم. من این مشکل را به صورت جبری حل می کنم.

ابتدا شرط -N ≤ dx ≤ N را به شکل کلی تر x min ≤ x ≤ x max بازنویسی می کنیم و x min = center.x - N و x max = center.x + N را می گیریم. بیایید همین کار را برای y و z انجام دهیم و در نتیجه یک نمای کلی از کد قسمت قبل به دست می‌آید:

نتایج Var = برای هر xmin ≤ x ≤ xmax: برای هر max(ymin, -x-zmax) ≤ y ≤ min(ymax, -x-zmin): var z = -x-y results.append(Cube(x, y, ز))
تقاطع دو محدوده a ≤ x ≤ b و c ≤ x ≤ d max(a, c) ≤ x ≤ min(b, d) است. از آنجایی که مساحت شش ضلعی ها به صورت محدوده هایی بر روی x، y، z بیان می شود، می توانیم هر یک از محدوده های x، y، z را به صورت جداگانه قطع کنیم و سپس از یک حلقه تودرتو برای ایجاد لیستی از شش ضلعی ها در محل تقاطع استفاده کنیم. برای یک ناحیه از شش ضلعی ها، x min = H.x - N و x max = H.x + N را می گیریم، به طور مشابه برای y و z. برای تقاطع دو ناحیه شش ضلعی، x min = max (H1.x - N، H2.x - N) و x max = min (H1.x + N، H2.x + N) را به طور مشابه برای y و z . همین الگو برای تقاطع سه یا چند منطقه کار می کند.

gif


موانع

در صورت وجود موانع، پر کردن با محدودیت فاصله ساده‌تر است (جستجوی اول عرض). در شکل زیر خود را به چهار حرکت محدود می کنیم. در کد، fringes[k] آرایه‌ای از تمام شش ضلعی‌هایی است که می‌توان در k مرحله به آن‌ها رسید. در هر عبور از حلقه اصلی، سطح k-1 را با سطح k گسترش می دهیم.

تابع cube_reachable(شروع، حرکت): var visited = set() شروع به بازدید شده var fringes = fringes.append() برای هر 1 اضافه کنید< k ≤ movement: fringes.append() for each cube in fringes: for each 0 ≤ dir < 6: var neighbor = cube_neighbor(cube, dir) if neighbor not in visited, not blocked: add neighbor to visited fringes[k].append(neighbor) return visited

چرخش

برای یک بردار شش ضلعی معین (تفاوت بین دو شش ضلعی)، ممکن است لازم باشد آن را بچرخانیم تا به شش ضلعی دیگر اشاره کنیم. اگر به چرخش 1/6 پایبند باشید، این کار با مختصات مکعبی آسان است.

چرخش 60 درجه به راست، هر مختصات را یک موقعیت به راست تغییر می دهد:

[x، y، z] به [-z، -x، -y]
چرخش 60 درجه به چپ، هر مختصات را یک موقعیت به چپ تغییر می دهد:

[x، y، z] به [-y، -z، -x]



"بازی" [در مقاله اصلی] با نمودار، می توانید ببینید که هر چرخش 60 درجه تغییر می کندعلامت می دهد و مختصات را به صورت فیزیکی "چرخش" می کند. پس از چرخش 120 درجه، علائم دوباره یکسان هستند. چرخش 180 درجه علائم را معکوس می کند، اما مختصات به موقعیت اصلی خود می چرخند.

در اینجا دنباله کامل چرخش موقعیت P حول موقعیت مرکزی C است که منجر به یک موقعیت جدید R می شود:

  1. موقعیت های P و C را به مختصات مکعبی تبدیل کنید.
  2. محاسبه یک بردار با تفریق مرکز: P_from_C = P - C = Cube(P.x - C.x، P.y - C.y، P.z - C.z).
  3. چرخش بردار P_from_C همانطور که در بالا توضیح داده شد و به بردار حاصل با نام R_from_C اختصاص می دهیم.
  4. تبدیل یک بردار به موقعیت با اضافه کردن یک مرکز: R = R_from_C + C = مکعب (R_from_C.x + C.x، R_from_C.y + C.y، R_from_C.z + C.z).
  5. تبدیل موقعیت مکعبی R به سیستم مختصات مورد نظر.
چندین مرحله از تبدیل وجود دارد، اما هر یک از آنها بسیار ساده است. می توان برخی از این مراحل را با تعریف چرخش مستقیم در مختصات محوری کوتاه کرد، اما بردارهای شش ضلعی با مختصات افست کار نمی کنند و من نمی دانم چگونه مراحل مختصات افست را کوتاه کنم. همچنین به بحث در مورد روش های دیگر برای محاسبه چرخش در stackexchange مراجعه کنید.

حلقه

حلقه ساده

برای اینکه بفهمید یک شش ضلعی به حلقه ای با شعاع معین تعلق دارد یا خیر، باید فاصله این شش ضلعی تا مرکز را محاسبه کنید و بفهمید که آیا برابر با شعاع است یا خیر. برای به دست آوردن لیستی از تمام این شش ضلعی ها، باید گام های شعاع از مرکز بردارید، و سپس بردارهای چرخانده شده را در طول مسیر در امتداد حلقه دنبال کنید.

تابع cube_ring (مرکز، شعاع): var results = # این کد برای شعاع == 0 کار نمی کند. می فهمی چرا؟ var cube = cube_add(مرکز، مقیاس_مکعب(مکعب_جهت(4)، شعاع)) برای هر 0 ≤ i< 6: for each 0 ≤ j < radius: results.append(cube) cube = cube_neighbor(cube, i) return results
در این کد، مکعب از حلقه شروع می شود که به صورت یک فلش بزرگ از مرکز به گوشه نمودار نشان داده شده است. من زاویه 4 را برای شروع انتخاب کردم زیرا با مسیری که اعداد جهت من طی می کنند مطابقت دارد. ممکن است به زاویه شروع متفاوتی نیاز داشته باشید. در هر مرحله از حلقه داخلی، مکعب یک شش ضلعی در اطراف حلقه حرکت می کند. پس از 6 * قدم شعاع، او به همان جایی می رسد که شروع کرده بود.


حلقه های مارپیچی

با قدم زدن در حلقه ها به صورت مارپیچ، می توانیم داخل حلقه ها را پر کنیم:

تابع cube_spiral (مرکز، شعاع): نتایج var = برای هر 1 ≤ k ≤ شعاع: نتایج = نتایج + حلقه_مکعب (مرکز، k) نتایج برمی‌گرداند



مساحت شش ضلعی بزرگ برابر است با مجموع تمام دایره ها به اضافه 1 برای مرکز. از این فرمول برای محاسبه مساحت استفاده کنید.

پیمایش شش ضلعی ها به این روش می تواند برای محاسبه دامنه حرکت نیز استفاده شود (به بالا مراجعه کنید).

منطقه دید

چه چیزی از یک موقعیت مشخص با فاصله مشخص قابل مشاهده است و توسط موانع مسدود نمی شود؟ ساده ترین راه برای تعیین این، کشیدن یک خط به هر شش ضلعی در محدوده داده شده است. اگر خط به دیوارها نرسد، یک شش ضلعی می بینید. ماوس را روی شش ضلعی ها [در نمودار در مقاله اصلی] حرکت دهید تا خطوطی را که به آن شش ضلعی ها کشیده شده اند و دیوارهایی که خطوط به هم می رسند، ببینید.

این الگوریتم می تواند در مناطق بزرگ کند باشد، اما پیاده سازی آن آسان است، بنابراین توصیه می کنم با آن شروع کنید.

gif



تعاریف مختلفی از رویت وجود دارد. آیا می خواهید مرکز یک شش ضلعی دیگر را از مرکز شش ضلعی اولیه ببینید؟ آیا می خواهید قسمتی از شش ضلعی دیگر را از مرکز اصلی ببینید؟ شاید هر بخشی از شش ضلعی دیگر از هر نقطه شروع؟ آیا موانع کمتر از یک شش ضلعی کامل هستند؟ دامنه مفهومی پیچیده تر و متنوع تر از آنچه به نظر می رسد است. بیایید با ساده ترین الگوریتم شروع کنیم، اما انتظار داشته باشید که پاسخ را در پروژه شما به درستی محاسبه کند. حتی مواردی وجود دارد که یک الگوریتم ساده نتایج غیرمنطقی می دهد.

من می خواهم این راهنما را بیشتر گسترش دهم. من دارم