Skip to main content

Procedural roadmap generation & SAE AutoDrive 2018 Competition Shirt

As part of victory spoils, UofT's success in 2017 came with control over the competition shirt. I volunteered and inherited the responsibility, then promptly hot-potato'd it onto my computer to make most of the visually-interesting material. This emphasis on form was spurred by constraints on the color palette when only two tones are possible on top of the shirt's base color. In a similar vein but somewhat more timid on my processor than the goliath that is actual localization and mapping on Zeus, I built a simple tile-based procedural roadmap generator for an ornamental border, which I relate to ornamental vines on medieval texts. And OpenTTD.

Tile design

Tile boundaries are integer multiples of a unit tile length with some number of roads that the builder has to mate at all open boundaries. With relatively modest scales of only a few thousand tiles, I opted for a breadth-first brute force search strategy with some small quick-win optimizations. Growing out from a one-tile seed, an open boundary is popped from a queue of boundaries and a bag of tiles is weighted-shuffled, permuted on all rotations and placements and checked for correctness.

Weighting features

The randomization in the back is just a matter of shuffling the order of iterations of the bag of tiles. While stabilizing the code, it was also interesting to look at the unweighted case, where all tiles are equally likely, and pinning down why it didn't look right.

Man, I wouldn't want to live there. Actually, I don't think anyone could, I have no idea where they would put housing amidst all the intersections. Despite this, reaching some places in the map is not trivial because of the ramps/curves that force traffic to turn only one way. There is also an absurd density of two-lane [highway] roads and cop-out 2-lane roundabouts becuase a two-lane road clearly needed to end right away.

Things very quickly get better by weighting blank spaces and straightaways (which also induce blank space on each side) much higher. Slightly harder to see here is the replacement of intersections over curves, which pushes the plan closer to a neighbourhood.

The above was produced with the below tile weights:

The human touch

In order to accomodate the text and central graphic of the car, I needed to part and deflect some roads. This is actually possible if I occupied the empty space with blank tiles in advance, but to ensure that it didn't leave too many hanging edges on the boundary, this was done manually.