69

To summarize and elaborate upon what has been said in other answers and in comments, triangles, squares and hexagons are the only mathematically possible regular tilings aka regular tessellations of the Euclidean plane. So yeah, this sucks. Triangles are completely useless here, squares suck because you can't move diagonally without having a somewhat ...


29

The author of HyperRogue here. HyperRogue actually uses a tesselation made of hexagons and heptagons, here is the reason why this particular tesselation has been chosen, instead of only octagons or heptagons, for example: Hyperbolic geometry in Hyperbolic Rogue Basically, the octagons are too big. Also some consequences of using hyperbolic geometry in a ...


16

No. √3 is an irrational number, and by definition an irrational number can not be used as a ratio between two natural numbers (integers) such as pixel counts. However, there is no rule that says you have to use ideal hexagons in your game tiles. If you approximate it closely and avoid any miscalculations that may result, which you should be able to do ...


11

Finding an algorithm is usually best done with a data structure that makes the algorithm easy. In this case, your territory. The territory should be an unordered (O(1) hash) set of borders and elements. Whenever you add an element to the territory, you iterate over adjacent tiles and see if they should be a border tile; in this case, they are a border ...


10

I don't recommend using the "increase the dimensions and orbit in a cylinder" trick here. It has several disadvantages: More expensive to compute: Perlin noise needs to select and interpolate \$d^2\$ gradient vectors per evaluation, so going from 2 dimensions to 5 means doing 8x more work. More distortion: by evaluating it on a membrane in higher-...


9

While I don't know of any truly official convention for classifying these, in the mathematical sense, I'll take Anko's advice and write up what I do know... Amit Patel (Red Blob Games) wrote what I'd consider the definitive guide to using hexagonal grids in games. This guide uses the nomenclature: flat topped pointy topped So while it's not super ...


9

If you need to find edges of holes in the middle of your territory too, then your linear in the area of the territory bound is the best we can do. Any tile on the interior could potentially be a hole that we need to count, so we need to look at every tile in the area bounded by the territory's outline at least once to be sure we've found all the holes. But ...


7

As Vector57 noted, the problem is you are using the wrong coordinate system. The algorithm described is meant to be used with cube coordinates, which have x, y and z components: This may not be obvious from the algorithm's pseudocode, but that's because it's a simplification of this: var results = [] for each -N ≤ dx ≤ N: for each -N ≤ dy ≤ N: ...


7

I'd consider a Square-based grid as a "base" type of tiles in any game. Such grid is simple to imagine and moves over this grid are simple to understand. It's also very simple to implement "under the hood". Those are few reasons why even the Chess game uses it :). Additionally, this grid helps you make "regular" levels, because Vertical and Horizontal are ...


7

As long as your movement space isn't Euclidean and things can block an entire grid space, you'll have this problem. If you want people to not "play the grid" you're probably going to have to not use a grid.


7

Notice: Whether or not a tile is on the boundary only depends on it and its neighbors. Because of that: It is easy to run this query lazily. For instance: You do not need to search for the boundary on the whole map, only on what is visible. It is easy to run this query in parallel. In fact, I could image some shader code that does this. And if you need it ...


7

This is most intuitive way that I can think of.


6

(I don't have enough reputation to comment) The answer here is that the distances are wrong. A is closer than B. To convince yourself, compare A and the reflection of B w.r.t. the player, so I don't think there is an issue here. Hex grids are tricky in a lot of ways.


6

The logic is simple: your contour is the set of all the edges that separate border tiles from non-border tiles. You can code the following: for each boundary tile for each edge if edge is shared with a hex tile that is NOT in the boundary tile list mark as contour edge render all contour edges Note that if you want the contour to ...


5

All three uniform 2D grids can be stored in a rectangular grid, you just have to scale and shear it to fit the one you're aiming for. To know what regions you need to load just transform the viewport extents to the data's coordinate system.


5

Can't comment yet, so I'll give answer short answer. From my experience, square tiles are a little simpler to implement. If you are using e.g. a two-dimensional array, tile position is array index multiplied with tile size (at least that's what it boils down to). Finding neighboring tiles is as simple as adding one to the index (and maybe wrapping the value ...


5

Thanks for a fascinating puzzle! Yes, it looks like we can do better than a conversion through cartesian coordinates of hexagon centers. It can be done entirely with integer math, though I've included a rational in a matrix below to keep the notation concise. You're right that both the encoding and decoding processes require loops. Fortunately, because SHM ...


5

I prefer to do hex-cell coordinate math in what Amit calls cubical coordinates on your linked page. For the rest of this answer, (X, Y, Z) will refer to cubical coordinates. Basically, for any of the 6 sectors you're interested in, one of the positive or negative X, Y, or Z axes will correspond to the radial distance. For example, in Figure 1, as X ...


5

Assuming you have Hex objects stored in a 2d array, just make each Hex own some of its edges and vertices. For example, have each hex own the edges with arrows pointing to them as well as the two vertices between those edges: __ / \ <3 \__/ <2 ^ 1 We only store three edges and two vertices, so where do the others come from? Well, continuing ...


4

Amit Patel has provided an excellent resource for getting ranges on his site. In the article, he uses the following algorithm for collecting hex tiles within a range: for each -N ≤ Δx ≤ N: for each max(-N, -Δx-N) ≤ Δy ≤ min(N, -Δx+N): Δz = -Δx-Δy results.append(H.add(Cube(Δx, Δy, Δz))) This creates bounds aligned with the hex grid: ...


4

Just in case anyone is interested: Lets assume sqrt(3) is rational: Therefore, there must be two integral numbers a and b such that a/b = sqrt(3) We assume these numbers are coprime, if they have a common factor, we divide by it producing a coprime pair, a and b We know that (a/b)^2 = 3 and therefore a^2 = 3 * b^2. 3 * b^2 is devisible by 3 as b^2 is ...


4

I think it'll be easier to solve this if you move one step at a time instead of one-or-two. For each location on the map there's a single direction to move in. Let's calculate that direction. First observation: if you're using the 3-valued “cube” coordinates, the largest coordinate tells you which of the six “wedges” you're in. Here's a diagram showing the ...


4

So upon further inspection your problem actually has nothing to do with coordinate system conversions. This could have been made more clear by not naming your axial coordinates X and Y but rather Q and R. The problem you're actually having is bad loop conditions. The original code sample produces delta q's and r's which you try to convert, in your for loops, ...


4

The usual approach here is to pretend like you're solving a maze blindfolded: keep your left hand in contact with the wall, and follow its contours until you reach the exit (or in this case, until you return to your starting point) Assuming we start with some tile in the region we want to outline, but not necessarily on the edge of that region, we can keep ...


3

Try turning on the grid in Tiled (Ctrl+G) and adjusting your "Tile Side Length" in the Map Properties so that the grid matches correctly with your tiles. It may fix the libgdx rendering issue, and would improve the mouse picking in Tiled a little. I know setting up a hexagonal map (and even an isometric map) is somewhat confusing at the moment. It's ...


3

For me, I do not see much difference hex-maps and plain 2D arrays. If you look at following picture - it is nothing more then array with some render offset for rows: As you can see, it technically really is an array. Array with "overriden" getUpper and getLower - some playing with indexes. Though I dont really know how they did it in Civ5, it really appears ...


3

As I mentioned above, there won't be a perfect solution here, because the hexagons that make up a Goldberg polyhedron tend to be irregular and non-congruent with each other. From one part of the sphere to another they distort in different ways. In general there's no rotation that will align a regular source hexagon with a given tile perfectly. But, there ...


3

The condition part of the for-loop tells the loop when to stop looping. This is different from the continue statement that just skips the rest of the current step and moves on to the next. Consider the following loop; for(i = 0; i < 10; i += 1) { if (i % 2 == 0) continue; // Skip even indices // Do stuff } If you were to extract the ...


3

First, let's define a standard ordering of basis vectors to use. These are the offsets to each of the six hexes in the closest ring around our center, in clockwise order from top-left. int3[] spokes = { new int3( 0, 1, -1), new int3( 1, 0, -1), new int3( 1, -1, 0), new int3( 0, -1, 1), new int3(-1, 0, 1), new int3(-1, 1, 0) }; ...


3

Here's a simple method which does not become more complex as the map grows in radius: Keep a list of the center coordinates of your main map (0, 0, 0), and its 6 shifted copies. After a move that might take you off the edge of the map, calculate the distance to your destination tile from each of these center points. Stop when you find a center point whose ...


Only top voted, non community-wiki answers of a minimum length are eligible