Перемещение шестиугольников с кубическими координатами в квадратное образование

Он работает для большинства из них:

работает

Проблема начинается, когда высота намного больше ширины (3x9, 3x11, 5x11 и т. д.).

не работает правильно

Как вы можете видеть, первая строка неуместна, дальнейшее увеличение высоты будет повторять этот шаблон.

Вот код (Примечание: мои z и y для координат куба поменялись местами):

void SpawnHexGrid(int Width, int Height)
    {
        int yStart = -Height / 2;
        int yEnd = yStart + Height;

        for (int y = yStart; y < yEnd; y++)
        {
            int xStart = -(Width + y) / 2;
            int xEnd = xStart + Width;

            if (Width % 2 == 0)
            {
                if (y % 2 == 0)
                {
                    xStart++;
                }
            }
            else
            {
                if (y % 2 != 0)
                {
                    xStart++;
                }
            }
            Debug.Log("y: " + y + " , Start: " + xStart + " , End: " + xEnd);

            for (int x = xStart; x < xEnd; x++)
            {
                SetHexagon(new Cube(x, y));
            }
        }
    }

Редактировать:

После перехода на решение @Idle_Mind моя сетка выглядит так:

введите здесь описание изображения

Редактировать снова:

Я нашел решение, после перехода на решение @Idle_Mind я исправил наклон, снова используя y:

int xStart = -Width / 2 - (y / 2);

но это вызвало ту же проблему, что и раньше, но на этот раз я понял, что это как-то связано со способом округления int, когда y отрицательно, xStart будет на 1 ниже, чем ожидалось, поэтому я просто добавляю 1 всякий раз, когда y отрицательно:

int add = 0;

    if (y < 0)
    {
        add = 1;
    }
    int xStart = -Width / 2 - ((y - add) / 2);

Теперь это работает как шарм, спасибо всем.


person Gruhlum    schedule 16.06.2019    source источник


Ответы (2)


Измените свой SpawnHexGrid() на:

void SpawnHexGrid(int Width, int Height)
{
    int xStart = -Width / 2;
    int yStart = -Height / 2;
    int yEnd = yStart + Height;

    for (int y = yStart; y < yEnd; y++)
    {
        int xEnd = xStart + Width + (y%2==0 ? 0 : -1);

        for (int x = xStart; x < xEnd; x++)
        {
            SetHexagon(new Cube(x, y));
        }
    }
}

Моя тестовая установка:

введите здесь описание изображения

---------- РЕДАКТИРОВАТЬ ----------

Я не понимаю, почему вы используете значение y как часть вашего расчета для x. Сделайте x постоянным для всего столбца, как вы ожидаете для обычной сетки. В моем коде более короткие строки по-прежнему начинаются с ТАКОВОЙ координаты x, что и более длинные; меняется только их длина. Затем, когда вы рисуете, я просто вычисляю позицию для нормальной сетки, но добавляю половину ширины шестиугольника для всех нечетных позиций по оси y, в результате чего получается смещение, необходимое для шестиугольников.

Например, вот сетка 5x5, нарисованная «нормально» без смещения нечетных строк Y. Понятно, что начальная координата X для всех строк одинакова: введите здесь описание изображения

Таким образом, сохраненные координаты x,y основаны на обычной сетке, но код рисования сдвигает нечетные строки y. Здесь я изменяю координату X, только для рисования, нечетных строк y:

if (pt.Y % 2 != 0)
{
    center.Offset(Width / 2, 0);
}

Итак, после добавления смещения (опять же, только во время рисования) для нечетных строк Y это теперь выглядит так:

введите здесь описание изображения

А вот показана сетка с внутренней координатой каждого отображаемого шестиугольника:

введите здесь описание изображения

Надеюсь, это проясняет, как я подошел к этому.

person Idle_Mind    schedule 16.06.2019
comment
Теперь это выглядит яснее, но мои шестиугольники теперь наклонены, я обновил вопрос изображением. - person Gruhlum; 16.06.2019
comment
Тогда нам нужно посмотреть, как вы на самом деле рисуете шестиугольники. - person Idle_Mind; 16.06.2019
comment
Что помогло избавиться от тильта? - person Idle_Mind; 16.06.2019
comment
См. нижнюю половину моего отредактированного поста для получения дополнительных комментариев, которые могут оказаться полезными. - person Idle_Mind; 16.06.2019
comment
Да, разница в том, что я использовал систему координат кубов ссылка. В этой системе (1, 0) находится справа вверху от (0, 0), а (2, 0) находится справа вверху от (1, 0) и так далее. Вот почему ваше решение сначала было для меня наклонным. - person Gruhlum; 17.06.2019
comment
Попался. Отличная ссылка! - person Idle_Mind; 17.06.2019

Я считаю, что вы просто чередуете другой размер строки для шестиугольной карты. Если это так, что-то вроде этого должно работать:

class Program
{
    static void Main(string[] args)
    {
        const int Height = 4;
        const int Width = 4;

        for (int y = 0; y < Height; ++y)
        {
            int rowSize = y % 2 > 0 ? Width + 1 : Width;

            for (int x = 0; x < rowSize; ++x)
            {
                Console.WriteLine($"{x}:{y}");
            }
        }

        Console.ReadLine();
    }
}
person MikeJ    schedule 16.06.2019
comment
проблема с этим решением заключается в том, что сетка больше не центрирована. - person Gruhlum; 16.06.2019
comment
Затем вам нужно будет добавить смещение к каждой координате x. Вы должны быть в состоянии вывести это вне цикла. Вы не показали никакой глобальной системы координат, в которой пытались центрировать вывод в своем вопросе. - person MikeJ; 16.06.2019