Проста генерація гексагональної (шестикутної) сітки з центру поворот матриці на будь-який кут

Доброго дня. Нещодавно я зіткнувся з проблемою генерації шестикутної сітки з центру. Є методи генерації рядками. Вони придатні для будь-чого. А такого методу я не знайшов. Може погано шукав, хто знає. На форумі мені запропонували три кривих рішення:
1. Милиці (варіант, який найгірший).
2. Генерація по рядках та викидання непотрібного. В принципі найправильніше рішення, але на жаль, мені потрібно щоб саме з центру. Потім зручно додавати потрібні комірки буде.
3. Косі координати. Це складна мегажесть, на яку можна вбити хмару часу. Я її не зміг осилити.
А тепер, перейдемо до нашого алгоритму.

Суть на пальцях


Нам потрібно отримати комірчастуструктуру аля ця.

Проста генерація гексагональної (шестикутної) сітки з центру поворот матриці на будь-який кут

Першим кроком буде генерація першого, центрального гексагона.

Якщо наш глядач досить прозорливий, то він помітить, що прилягають по сторонам осередки утворюють осі матриці.
Проста генерація гексагональної (шестикутної) сітки з центру поворот матриці на будь-який кут

З першим рядом проблем не виникне, якщо знати радіус і кут, то все шестикутники ляжуть як треба. Проблеми йдуть з другим рядом. Деякі вічка не будуть лежати де треба. А причина в наступному. У нашій структурі, є періодичність. Але вона не кругова, а гексагональна. Просто в першому ряду вони сходяться.
Проста генерація гексагональної (шестикутної) сітки з центру поворот матриці на будь-який кут

На малюнку видно, що центри шестикутників лежати і на окружності, і на матричному шестикутнику. Однак на другому ряду проблема видна чітко.
Проста генерація гексагональної (шестикутної) сітки з центру поворот матриці на будь-який кут

Видно, що на лише осьові шестикутники (зелені) лежать на окружності. Центри інших зміщені до центру і лежать на матричному шестикутнику. Тому, через радіальну симетрію таку сітку не поставити.
Звідси випливає наступне рішення.
Будуємо спочатку лише осьові шестикутники.
Потім обчислюємо вектори. На малюнку вказано напрямок векторів. Воно може бути зворотним.
Проста генерація гексагональної (шестикутної) сітки з центру поворот матриці на будь-який кут

Але нам потрібен не цей вектор. Точніше не він сам, а його частина.
Проста генерація гексагональної (шестикутної) сітки з центру поворот матриці на будь-який кут

Нам потрібен синій вектор. Цей зсув, яке додається до осьового шестикутник для отримання точних координат. Жовтий вектор ділиться на число частин, рівну кількість шестикутників між осьовими шестикутниками + 1 (або номер шару).
Після цього, можна генерувати як завгодно великі матриці з центру.


А тепер наведу код, цього неподобства. Я програмував на Xors3D, але думаю, що кому треба, той зрозуміє як ця штука працює (тим більше, код простий, а суть пояснив вище). Нам потрібна всього одна функція - функція створення осередку.
Ось її код.

; Vector calculating
If Order> 0 Then - обчислюємо вектора, якщо ряд не нульовий (де центральний гексагон)
Vector (i, 0) = ((CellRadius * Sin (Angle + 60) * Order-CellRadius * Sin (Angle) * Order)) / (Order) - 0 = X, перша координата вектора
Vector (i, 1) = ((CellRadius * Cos (Angle + 60) * Order-CellRadius * Cos (Angle) * Order)) / (Order) - 1 = Z, друга координата вектора
End If
Next

Що маємо на виході:

Проста генерація гексагональної (шестикутної) сітки з центру поворот матриці на будь-який кут

Апгрейд 1.0 - Поворот на будь-який кут матриці


Можуть виникнути ситуації, коли нашу гексагональную сітку треба кудись примкнути під потрібним кутом. Я подумав над цим, і модернізованих функцію - тепер можна повертати всю матрицю на довільний кут!
Отже, код:

Важливі відмінності:
Function CreateCell (X #, Z #, Order%, AddAngle%) - з'явився новий аргумент, це і є довільний кут - AddAngle.
Angle # = 360 / Limit * i + AddAngle - додаємо зсув для розрахунку кутів і векторів.
xRotateEntity Cell \ Sprite, 90, -AddAngle, 0 - поворот спрайту навколо вертикальної осі в протилежну сторону.

Що маємо на виході:
17 градусів.

Проста генерація гексагональної (шестикутної) сітки з центру поворот матриці на будь-який кут

30 градусів.
Проста генерація гексагональної (шестикутної) сітки з центру поворот матриці на будь-який кут

10 градусів.
Проста генерація гексагональної (шестикутної) сітки з центру поворот матриці на будь-який кут