Tuesday, April 26, 2016

image - Storing a hex grid


I've been creating a small hex grid framework for Unity3D and have come to the following dilemma. This is my coordinate system (taken from here):


enter image description here


It all works pretty nicely except for the fact I have no idea how to store it. I originally intended to store this in a 2D array and use images to generate my maps.


One problem was that it had negative values (this was easily fixed by offsetting the coordinates a bit).


However, due to this coordinate system, such an image or bitmap would have to be diamond shaped - and since these structures are square shaped, this would cause a lot of headaches even if I hack something together. Is there anything I'm missing that could fix this? I recall seeing a forum post regarding this in the unity forums but I can no longer find the link.


Is writing a set of coordinate translators the best solution here?


If you guys think it would be helpful, I can post code and images of my problem.



Answer



The parallelogram coordinates you're using are easier to work with, but they do have the drawback of being weird for rectangular maps. One approach is to store it with the offset coordinates but actually use parallelogram coordinates in your game logic.



Observation: in each row of the map, the grid data is contiguous. All the wasted space is on the left and right.


Solution: within that row, store data starting at the leftmost column instead of the column marked 0. Calculate the first column of the rectangular map in your coordinate system, then subtract that from the column coordinate to determine where in the array it goes. This works for negative column coordinates too.


Perform the conversion in the getter and setter for the map, with something like this:


inline function get(q, r) {
first_column_in_this_row = -floor(q/2);
return array[r][q - first_column_in_this_row];
}

You'll have to modify this to work with your choice of coordinates and map (pay attention to off by one differences). In some layouts you'll want to offset the columns by the row instead of vice versa.


You can use the same trick to make maps of other shapes; it's not limited to rectangles.



If you're using C or C++ you can use pointer arithmetic to make this faster. Instead of storing an array of pointers to arrays, store an array of pointers that have been adjusted by first_column_in_row. (This may not be portable)


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...