Sometimes hexagons just make better shapes than squares do. With that in mind, I decided to have some fun creating fields of hexagons, and then doing stuff with them. I created a script that fills a rectangular field with hexagons, then moves and colors the hexagons according to some simple algorithms. The results are pretty interesting to me, so I decided to share them.
The script I wrote keeps track of each hex’s set of neighboring hexes, and does a simple walk through all of them, backtracking when it reaches dead ends (a simple maze-building algorithm). Once the walk is finished, it goes back to the start point and moves each hex vertically a tiny bit for each step — so each neighboring step is slightly higher than its predecessor. When I choose to color the hexes, the color is applied the same way — by slightly changing the color parameters from the previous hex. That way, immediate neighbors are hardly distinguishable from each other, but there are sharp contours in height and color where the walk wraps back adjacent to hexes that it hasn’t visited recently.
I’m sure there’s a metaphor about the human condition there somewhere…
The script also sets up the camera, lighting, materials, and rendering parameters. For this script, I’m using the Arnold renderer for Maya 2016 Extension 2. Once I edit the parameters in the script, I launch this script, then hit the render button. Done.
This is what I do to launch the script (I made a quick shelf button):
import hexagonal reload(hexagonal) hexagonal.test()
This script is an intermediate complexity script to make the most use of, but a beginning scripter can edit the basic parameters without a problem.
Some simple parameters to look for in the script:
hexResolution = 75
The higher hexResolution is, the smaller each hex will be in the final rendered image. The number is roughly the width of the rectangle that hexes are fitted into, so ~25 hexes of radius 1.0 will fit into a width of 75. 25 is a good minimum value, 300-400 is a good maximum. There are time estimates in the script for how long my computer was taking to finish the script with various settings
lightIntensity = 7
lightIntensity sets the intensity on the procedurally created lights. The lights are a randomly created hemisphere of point lights. Their intensity value is driven from a dynamic attribute on their parent transform. This script sets it to this value.
The coloring code is very fun to play with, but it is a bit more complex than just changing a single integer. But it’s written to support easy changes if you understand what you want to do.
The coloring code is here inside the colorHexesBySteps function
def colorHexesBySteps(rectGrp, mazeWalkSteps, maxWalkLen):
The coloring code lets you assign a spectrum of color that changes along the walk through the grid of hexes. You can change any parameter of the HSV color space. The walk changes from a value of zero to one. You can map that onto all or part of the H, S, and/or V parameter of the color.
Each color component lets you select three things:
- Do you want this to modulate this component?
- If not, what should the value of this component always be?
- What number should I start at (map to zero)
- How much should be added to this number as I walk through the whole grid of hexes? (range)
For Hue, these parameters are called:
- moduleH – a boolean for whether we want to module the Hue
- h – the base value of the hue before we start to modulate it
- hueRange – the range of value that is added to the base value through the whole walk.
The unchanging component values are set inside baseHSV, and only used if we do not modulate that component
Try mixing and matching modulating various values to see interesting combinations. You don’t need to use a whole color spectrum — just try modulating across blue, or only using the high saturation colors. Values are wrapped into the 0-1 range before being applied, so you can use range values that repeat the spectrum many times across the whole walk. Setting the values to be negative can also produce interesting results.
You can even edit your color scheme without regenerating the whole grid. You can change the color parameters in the script, then run this to rebuild the colors of the grid without changing the walk.
reload(hexagonal) t = hexagonal.rebuildHexMaze('hexGroup1', wantColor=1, wantMove=0)