Я пытаюсь сделать функцию пиксель-координата для шестнадцатеричной карты, но я не правильно понимаю математику, все, что я пытаюсь сделать, кажется немного неправильным, и примеры, которые я нашел, основаны на картах по центру.
Под «массивом» я подразумеваю порядок упорядочения гексов, см. Рис.
Самый точный результат, который я получил, был со следующим кодом, но он все еще выключен и ухудшается с ростом значения:
public HexCell<T> coordsToHexCell(float x, float y){
final float size = this.size; // cell size
float q = (float) ((1f/3f* Math.sqrt(3) * x - 1f/3f * y) / size);
float r = 2f/3f * y / size;
return getHexCell((int) r, (int) q);
}
Экран начинается с 0,0 слева вверху, каждая ячейка знает свой центр.
Все, что мне нужно, это способ перевода экранных координат в шестнадцатеричные координаты. Как я мог это сделать?
источник
Есть два способа справиться с этой проблемой, на мой взгляд.
Используйте лучшую систему координат. Вы можете сделать математику намного проще для себя, если вы хорошо разбираетесь в том, как вы нумеруете гекс. Амит Патель имеет окончательную ссылку на шестиугольные сетки. Вы хотите искать осевые координаты на этой странице.
Заимствовать код у кого-то, кто уже решил это. У меня есть работающий код , который я взял из исходного кода Battle for Wesnoth . Имейте в виду, что моя версия имеет плоскую часть гекса сверху, поэтому вам придется поменять местами x и y.
источник
Я думаю, что ответ Майкла Кристофика верный, особенно в том, что касается упоминания сайта Амит Патель, но я хотел бы поделиться своим подходом новичка к сеткам Hex.
Этот код был взят из проекта, к которому я потерял интерес, и забросил написанный на JavaScript, но положение мыши для шестигранной плитки работало отлично. Я использовал * эту статью GameDev * для моих ссылок. С этого сайта у автора было это изображение, которое показывало, как математически представить все шестнадцатеричные стороны и позиции.
В моем классе визуализации это было определено в методе, который позволял мне устанавливать любую длину стороны Hex, которую я хотел. Здесь показано, потому что некоторые из этих значений были указаны в шестнадцатеричном коде координат пикселя.
В классе ввода мыши я создал метод, который принял координаты x и y экрана, и возвратил объект с шестнадцатеричной координатой, в которой находится пиксель. * Обратите внимание, что у меня была поддельная «камера», поэтому смещения для положения рендера также включены.
Наконец, вот скриншот моего проекта с включенной отладкой рендера. Он показывает красные линии, где код проверяет ячейки TypeA и TypeB вместе с шестнадцатеричными координатами и контурами ячеек.
Надеюсь, это поможет некоторым.
источник
Я на самом деле нашел решение без шестнадцатеричной математики.
Как я уже упоминал в вопросе, каждая ячейка сохраняет свои собственные координаты центра, вычисляя ближайший шестнадцатеричный центр к координатам пикселей, я могу определить соответствующую шестнадцатеричную ячейку с точностью до пикселя (или очень близко к ней).
Я не думаю, что это лучший способ сделать это, так как я должен перебирать каждую ячейку, и я вижу, как это может облагаться налогом, но оставлю код в качестве альтернативного решения:
источник
0…cols-1
и всех строк0…rows-1
вы можете сканироватьcol_guess - 1 … col_guess+1
иrow_guess - 1 … row_guess + 1
. Это всего 9 гексов, так что это быстро и не зависит от размера карты.Вот пример реализации C # одного из методов, размещенных на веб-сайте Амит Патель (я уверен, что перевод на Java не будет проблемой):
Остальная часть проекта доступна здесь как Open Source, включая классы MatrixInt2D и VectorInt2D, на которые есть ссылки выше:
http://hexgridutilities.codeplex.com/
Хотя приведенная выше реализация предназначена для гексов с плоским верхом, библиотека HexgridUtilities включает в себя возможность транспонирования сетки.
источник
Я нашел простой альтернативный подход, который использует ту же логику, что и обычная шахматная доска. Он создает эффект привязки к сетке с точками в центре каждой плитки и в каждой вершине (путем создания более узкой сетки и игнорирования чередующихся точек).
Этот подход хорошо работает для игр, таких как Catan, где игроки взаимодействуют с плитками и вершинами, но не подходит для игр, в которых игроки взаимодействуют только с плитками, поскольку он возвращает точку центра или вершину, координаты которой ближе всего, а не какую шестиугольную плитку координаты в пределах.
Геометрия
Если вы поместите точки в сетку со столбцами, которые составляют четверть ширины плитки, и строками, которые в два раза меньше высоты плитки, вы получите следующий шаблон:
Если затем вы измените код, чтобы пропустить каждую вторую точку в шаблоне шахматной доски (пропустить
if column % 2 + row % 2 == 1
), вы получите следующий шаблон:Реализация
Имея в виду эту геометрию, вы можете создать двумерный массив (как с квадратной сеткой), сохраняя
x, y
координаты для каждой точки сетки (из первой диаграммы) - что-то вроде этого:Примечание. Как обычно, когда вы создаете сетку вокруг точек (вместо размещения точек в самих точках), вам необходимо сместить начало координат (вычесть половину ширины столбца
x
и половину высоты строки из негоy
).Теперь, когда у вас
points
инициализирован 2D-массив ( ), вы можете найти ближайшую точку мыши, как на квадратной сетке, только для того, чтобы создать рисунок на второй диаграмме, нужно только игнорировать все остальные точки:Это будет работать, но координаты округляются до ближайшей точки (или без точки) в зависимости от того, в каком невидимом прямоугольнике находится указатель. Вы действительно хотите круглую зону вокруг точки (поэтому диапазон привязки одинаков во всех направлениях). Теперь, когда вы знаете, какую точку проверять, вы можете легко найти расстояние (используя теорему Пифагора). Подразумеваемый круг все равно должен помещаться внутри исходного ограничивающего прямоугольника, ограничивая его максимальный диаметр шириной столбца (четверть ширины плитки), но он все еще достаточно велик, чтобы хорошо работать на практике.
источник