Проблема рисования сетки шестиугольника
Кажется, у меня возникли проблемы с построением правильной шестнадцатеричной сетки:
Как вы можете видеть, шестиугольники немного смещены, хотя я считаю, что моя математика верна (некоторые из них проверены с помощью http://www.redblobgames.com/grids/hexagons/).
Мой метод рисования состоит в том, чтобы начать с верхнего левого шестиугольника (первая плитка в первом ряду) и нарисовать этот ряд плиток. Затем для следующей строки есть отрицательное смещение X и положительное смещение Y и т. Д., Пока оно не достигнет среднего ряда, при котором смещения X увеличиваются до 0:
private function drawHexGrid(inputGraphics:Graphics, inputPos:Point, inputGrid:HexGrid, inputTileSize:int):void {
var rootThree:Number = Math.sqrt(3); // seems like this will be used a lot
// total number of rows and also size of largest row (in tiles)
var totalRows:int = (2 * inputGrid.size) - 1;
// the other useful dimension of a hex tile
var triSize:Number = rootThree * 0.5 * inputTileSize;
var topLeft:Point = new Point(-(inputGrid.size - 1) * triSize, -(1.5 * (inputGrid.size - 1) * inputTileSize));
topLeft.x += inputPos.x;
topLeft.y += inputPos.y;
var currentPos:Point = topLeft.clone();
// step size between each tile and row
var xStep:Number = rootThree * inputTileSize;
var yStep:Number = triSize * rootThree;
var offsetDirection:int = -1;
var rowLimit:int = inputGrid.size;
var offsetAmount:int = 0; // offsetAmount goes 1 to n, then back to 0 again, used for calculating thw row offsets
var mazeTiles:Vector.<Tile> = inputGrid.getTiles();
var tileCounter:int = 0; // index to cycle through mazeTiles
for(var rowCount:int = 0; rowCount < totalRows; rowCount++){
currentPos.x = topLeft.x + (offsetAmount * rootThree / -2 * inputTileSize);
for(var counter:int = 0; counter < rowLimit; counter++){
drawHexTile(inputGraphics, currentPos.x, currentPos.y, inputTileSize, mazeTiles[tileCounter++]);
currentPos.x += xStep;
}
currentPos.y += yStep;
if(rowCount == (inputGrid.size - 1)){
offsetDirection *= -1;
}
rowLimit += offsetDirection * -1;
offsetAmount -= offsetDirection;
} // end of for loop
} // end of drawHexGrid()
Фактический чертеж каждого шестиугольника находится в этом цикле:
private function drawHexTile(inputGraphics:Graphics, inputX:int, inputY:int, inputSize:int, inputTile:Tile):void {
inputGraphics.lineStyle(0.1, 0, 1);
var convertToRadians:Number = Math.PI / 180;
// easier to draw by wall, since need to look up each wall and can set a starting degree without having to worry about the 'end degree'
// (since the end may not be 360 degrees if the starting degree is in the negatives or a high degree)
var degrees:int = -150; // starting wall is the top left wall of the hexagon tile
for(var counter:int = 0; counter < 6; counter++){
if(inputTile.walls[counter] == true){
inputGraphics.moveTo(inputX + (Math.cos(degrees * convertToRadians) * inputSize),
inputY + (Math.sin(degrees * convertToRadians) * inputSize));
inputGraphics.lineTo(inputX + (Math.cos((degrees + 60) * convertToRadians) * inputSize),
inputY + (Math.sin((degrees + 60) * convertToRadians) * inputSize));
}
degrees += 60;
}
} // end of drawHexTile() method
На первый взгляд, я думаю, что проблема связана с точностью математики с плавающей запятой, хотя я не уверен, как это исправить.
Есть идеи?
Я знаю, что мой метод рисования будет иметь много перекрывающихся линий, что на данный момент хорошо. Если это помогает, общий код предназначен для генератора с шестигранной лабиринтом, который работает нормально и, таким образом, может быть проигнорирован, поскольку это не является частью проблемы.
И если это поможет, то, как я храню шестигранные листы, находится в одном длинном массиве, проиндексированном так:
where n=4
0 1 2 3
4 5 6 7 8
9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27
28 29 30 31 32
33 34 35 36
2 ответа
Хотя это не является предпочтительным для конечного продукта, попробуйте изменить все значения int на Num. Посмотри что получится. Также сосредоточьтесь на своем коде, который имеет дело с позицией X каждой новой плитки.
из ваших комментариев
... эээ... это сработало. Я не знаю почему. =| Я просто сделал глобальную замену целых чисел, и это сработало. Хм, вернусь и вручную заменим, чтобы увидеть, какая именно переменная int сделала это.
Ой! Я понял. В drawHexTile() я установил inputX и inputY как типы int. Но на самом деле, рассчитываемые позиции были плавающими значениями, поэтому они округлялись до целых долей, неявно вызывая смещение. Простая ошибка (рефлекторно), никакой магии, в конце концов, не исправлено.
Выглядит как проблема с плавающей точкой в вашем drawHexTile. Вы пытались округлить координаты рисования, чтобы у вас всегда были круглые пиксельные координаты? Что-то вроде
inputGraphics.moveTo(Math.floor(inputX + (Math.cos(degrees * convertToRadians) * inputSize)), Math.floor(inputY + (Math.sin(degrees * convertToRadians) * inputSize)));
inputGraphics.lineTo(Math.floor(inputX + (Math.cos((degrees + 60) * convertToRadians) * inputSize)), Math.floor(inputY + (Math.sin((degrees + 60) * convertToRadians) * inputSize)));