Drawing Hexagons

Note:I have developed a more accurate way of drawing hexagons that draws truly regular hexagons instead of these slightly off ones. I've added this link back to that page here, since this page comes up so high on Google's search. The other, more correct method, is probably what you want.

Drawing hexes for a hex-map was bothering me as a daunting task. With the help of a friend (tangaloor) who gave me a good way to look at them on graph paper, drawing hexes from code became simple.

Hexagons often aren't shown as being on an even grid, while computer displays are usually a grid of pixels. I didn't see a clear way to reconcile this. When I looked up 'how to draw a hexagon', I found lots of things that went in to a lot of trigenometry.

Tangaloor got me to look at it a little differently. Once he did that, the problem resolved it's self neatly, as is so often the case.

Drawing a hexagon is much simpler, if you're drawing it on graph paper, inside a four-by-four grid. A picture being worth a thousand words, here is one:

Labelled hex on grid

The secret here is not to count the squares, but the intersections of the graph paper. Once you do that, the hex draws nicely from even points. I numbered these from zero to four, from left to right, and top to bottom, although any other numbering would work.

At that point, drawing straight lines to even intersections is simple, with a line object or a moveto/lineto mechanism, depending on your graphics system's requirements.

The little blue marks in the middle are where the corners of the enclosing square for the next row of hexes would be, to make the pattern fill in solidly.

To draw a solid grid of hexes, gaps must be left between them on each row, which will be filled in by the hex on the next row. The following image should clarify how hexes need to be drawn to form an evenly filled space.

Layout of hexes

To implement this, I wrote a function that takes as parameters, the x and y co-ordiante of the upper left of the enclosing square, (0,0) as shown here. It also takes, as a parameter the length, in pixels, of the sides of the enclosing square. This should be evenly divisible by four to prevent rounding errors from leaving little glitches in drawing.

The function calculates what I called 'one segment' and 'two segments', which are basically the length of one, or two of the squares on the graph. It divides the total length by four for the 'one segment' length, and doubles that for the 'two segment' length.

It then uses these segment lengths, and the baseline sides to build a line that is the correct shape of a hex. The language I used allows me to construct a single line with many vertices, so it was one call, although, a moveto/lineto/lineto mechanism would work equally well.

The draw routine starts at the leftmost point, and works it's self right, and up, then down and around to the left, making a complete hex.

All the math is integer math, and should be fast.

Further optimization could be done to draw a grid of hexes; only one half of any particular hex needs to be drawn, to draw a complete grid. This code will paint most of the lines twice.

The sample code is written in Python and is small. It's supposed to be relatively self-explanatory. When run, it produces this output: