Everything you ever wanted to know about hexagonal grids
redblobgames.com
redblobgames.com
http://en.wikipedia.org/wiki/Forest-fire_model
The grid is usually rectangular, and I've always found this a bit odd: hexagons represent 2-d sphere packing, so they always seemed more natural to me. I once asked researchers in the field about this, around 2006, and they responded that rectangular grids serve just as well. I just found this paper from 2007 where apparently hexagonal grids fare better:
http://www.sciencedirect.com/science/article/pii/S0307904X06...
This makes me wonder, for realistic models that are meant to model a notion of neighbour cells, why aren't we always using hexagonal grids in 2d or higher-dimensional analogues? With rectangular grids, you're always faced with the choice of defining whether touching on edges and corners count as neighbours or not, which seems like an unnatural choice. Why, then, does this not seem to matter in the end?
Of course, with a small-enough grid rotational symmetry should be restored (or you've chosen a poor discretization!). One might rephrase your statement as: the lattice artifacts / discretization errors vanish faster on a hex grid. Could be.
When I worked on fire-spreading models [0] the grids we used were square. I would wager that this is because it makes thinking significantly easier. In my current field[1], square lattices are chosen because of the underlying supercomputing architecture. The communication mesh in tera- and petascale computers tend to be rectangular [2]. At these scales, having a nice rectangular layout of the local subvolumes simplifies communication algorithms and can provide a dramatic speedup---in this case having fewer neighbors is better.
[0]: In high school I implemented the fact that fires burn faster uphill while working for David Keyes on http://www.cs.cmu.edu/~caliente/
[1]: Lattice QCD codes use a (4D spacetime) rectangular lattice https://usqcd-software.github.io/
[2]: The BlueGene/Q, for example, is a 5-dimensional rectangular torus.
In higher dimensions there are applications to broadband coding (you want the densest possible constellation).
Disclosure: I heard some advanced lectures about FEM intended for students who intended to write a diploma thesis about this topic.
If you were talking about EE DSP stuff, you'd call it quantization noise. Theoretically a floating point A/D converter would be nice / interesting if such a thing existed, but in practice you minimizing that noise source by using more fixed bits per sample.
[1]: http://vincentwoo.com/2013/03/08/above-and-beyond-the-affirm...
Tangentially, I'd love to know the best way to create the visuals for this kind of content. I assume no one's writing all those SVGs by hand, right?
I used d3.js for this page (and most of the pages on my site).
For a given shape of map (rectangular, triangular, hexagonal, parallelogram, etc.) I generate a set of cube hex coordinates. I then use d3 to instantiate an SVG shape for each coordinate. D3 will maintain the mapping from the cube coordinate to the SVG shape, so I can set element classes on mouse events, and then I style those with CSS.
For example, in the line drawing example, I have a generic function that creates a hexagonal shaped grid (of hexagons)[1]. On mouseover, I figure out which hex it is, then run the line drawing algorithm to create a set of coordinates from the start point to the hex you're pointing to. I then tell d3 to iterate over all the SVG dom nodes and set the "selected" class if it's in the set returned by the line drawing routine[2]. The color changes with the CSS rule #diagram-line .selected polygon {fill: hsl(200, 50%, 80%); }
I've used canvas for some of the pages but I find svg much easier to work with. I can attach mouse events to the elements, and I can set properties (such as color) easily without redrawing everything. D3 is great for maintaining a mapping from data (such as a set of hex coordinates) to dom nodes (such as a set of svg <polygon>s). D3 also has transitions, but I think most of my needs could be handled with CSS transitions instead of D3's JS transitions.
[1] See http://www.redblobgames.com/grids/hexagons/Grid.hx : hexagonalShape() [2] See http://www.redblobgames.com/grids/hexagons/ui.js : makeLineDrawer()
a regular 2d array, but with every-other row logically offset by 50% of the cells width, thus you end up with:
[ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ]
super simple data structure (normal 2d array), and pathfinding isn't difficult (use hex algos). I wonder why nobody ever writes about this....Edit: ahh, the article kind-of describes this in the "Offset coordinates" section, just no explicit mention of able to use an array for storage.
How about storing the map directly in cubic coordinates? The storage structure would be a dictionary with a three-value tuple as the key. Iterating along any of the three axes is perfectly simple, and all directions work the same way. Algorithms like A* work directly on a list of neighboring hexes with no coordinate conversion required. Serialization to a savegame format or network communication would look like JSON with key-value pairs of the 3-tuple (key) to the tile data (value).
The advantage of the 2D array structure is only a bit of performance, that the coordinates of each tile are implicitly defined by the array indices. I'd venture to say that our modern languages and platforms don't need that optimization any more. We insert another layer of abstraction in decoupling the tile's coordinates away from its storage location in memory.
Put another way, the only conversion occurring is between the 3-tuple key and the physical location in memory, and that's abstracted away from us in whatever mechanism (hashtable or whatever) that the dictionary uses internally. Everything at the application level works directly with cubic coordinates. By getting rid of the 2D array storage, we get rid of the last remnants of anything rectangularly-related, with never any need at all to convert to the rectangular vestiges of axial or offset coordinates.
Given how simple it is to write a solid abstraction that implements the coordinate-based lookup with an array storage, and given how much better such an implementation behaves in terms of instruction counts and memory layout (think cache locality), you'd be silly not to use an array.
Not everything using A* runs millions of pathfinding queries in tight loops. Maybe it's an offline turn-based game that runs A* once per move and saving 10 μs just won't ever matter as compared to the complexity cost of implementing and maintaining the extra abstraction.
Perhaps we need a countering meme about gratuitous de-optimization...
To wit: http://mathworld.wolfram.com/Space-FillingPolyhedron.html
http://www.redblobgames.com/pathfinding/a-star/introduction....