In part one, we covered the drawing of smooth, anti-aliased hexagons in a grid-like fashion. In this post, we will extend that beginning into a program to draw hexagon fills that can be used for a tiled background. The key improvements that were identified in the previous post:
- Canvas sizing and shape wrapping
- Color wrapping around the edges
- Configurable, mostly random coloring
Canvas sizing and shape wrapping
To be able to use the generated image as a tiled background, the shapes must wrap from left to right. That is, if a row contains a hexagon that is cut off on the left edge, the portion that was cut off should be the end of that row on the right edge, and vice-versa.
This is a complex way of saying that the width of the image must be an exact multiple of the pattern size. The pattern in this case is the smallest shape from which a repeating pattern can be constructed. For the hexagons generator we have, this pattern is one column wide and two rows tall.
Because the pattern size is very closely coupled to the dimensions of the hexagon, we make this information available as a property of
class HexagonGenerator. We then modify the existing script to draw only outlines so we can see how things are constructed:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
class HexagonGenerator(object): # Rest of class as previously defined @property def pattern_size(self): return self.col_width, self.row_height * 2 def main(): hexagon_generator = HexagonGenerator(40) width, height = hexagon_generator.pattern_size image = Image.new('RGB', (int(width * 2), int(height * 3)), 'white') draw = Draw(image) draw.rectangle((0, 0, width, height), Brush('black', opacity=64)) colors = (('red', 'blue'), ('green', 'purple')) for row in range(5): for column in range(3): hexagon = hexagon_generator(row, column) color = colors[row % 2][column % 2] draw.polygon(list(hexagon), Pen(color, width=3)) draw.flush() image.show()