Sunday, June 24, 2012

A Brief Geometric Indulgence

Gaming maps have always fascinated, and yet, bothered me. I was raised on a solid diet of SPI hex maps wrought at the unequaled hands of Redmond Simonsen. I especially loved the maps for War of the Ring and the DragonQuest supplement, The Frontiers of Alusia. So moved was I, in fact, that the last 4e campaign map I created was an attempt to capture the feel of those maps (with somewhat mixed results).



For smaller areas, the hex grid is a nice, if old school, way of measuring distance without worrying much about the inherent distortion caused by projecting the face of a 3D world onto a 2D surface. But the larger the map, the more the distortion matters, and the more it bothers me.

I came across an OpenGL demo called HexPlanet while browsing an article on Board Game Geek, about spherical hex maps. That led me to this article as well, which has a nice tutorial on geodesic grids.

The following screen shots are from my ongoing XNA 4.0 attempt at achieving something similar. For the record, this was actually written using Silverlight and it's somewhat hobbled version of XNA.

The cartesian coordinates of the icosahedron are actually fairly simple. An icosahedron with an edge length of 2 has 12 vertices: (0, ±1, ±φ)  (±1, ±φ, 0)  (±φ, 0, ±1).  Since this is going into a 3D framework, I want to start with a base icosahedron where the vertices are actually a unit length from 0,0,0. You can get those values easily enough by normalizing a single vertex and extracting its values:



// Golden ration constants
private const float Phi = 1.618034f;



Vector3.Normalize(new Vector3(0, 1, Phi))

// These values are chosen as if one had normalized a vector with the coordinates
// (0, ±1, ±φ)
// (±1, ±φ, 0)
// (±φ, 0, ±1)
private const float PhiNormalAlpha = 0.5257311f;
private const float PhiNormalBeta = 0.8506508f;

Those values are used in place of 1 and φ to generate the initial twelve vertices.

The end result, is something like this:



But wait, I can hear you say. That's a dodecahedron! Where is the icosahedron we were promised? Rather than use the icosahedron directly, we use its dual polyhedron. That means placing a face at every original vertex. This is because the faces of the icosahedron are triangular, and as we subdivide them, they remain so. The dual polyhedron of the tessellated icosahedron forms a hexagonal grid, however, except at the location of the original vertices, where pentagons remain.



The remnants of the icosahedral heritage is preserved in the fact that no matter how far we subdivide, there will always be twelve pentagons.

Initial terrain is merely split between water and land without further refinement. That is, a hex is either land or water. As we subdivide, we introduce different terrain types (forest, desert, mountains, etc), at a level at which the hex cell size is appropriate.


Further tessellations refine things by adding icecaps and water depth.


So where do things go from here? Honestly, I don't know. I would like to work toward the original "feel" in the map first shown above for my own reasons.

No comments:

Post a Comment