Part 1: Voronoi Diagrams

This tutorial is a primer on Voronoi diagrams: what they are, what you need them for and how to generate them using a Shader in Unity. You can download the complete Unity page in Part 4.

Technically speaking, Voronoi diagrams are a way to tassellate a space. It means that the end result of Voronoi is a set of “puzzle pieces” which completely fills the space. To start, we need a set of points (often called seeds) in the space. Each seed will generate a piece of this puzzle. The way Voronoi works is by assigning every point of the space to its closest seed. The final result heavily depends on the way distance is measured in the space.

Euclidean distance

Most Voronoi diagrams are are based on the Euclidean distance. The cost between two points is given by the length of the shortest segment which connects them both. It can be calculated easily with the Pythagorean theorem:

In Cg, this function is already implemented and is called distance. The picture on the left shows a Voronoi diagram based on the Euclidean distance, drawn with 100 points. On the right, the same diagram uses a gradient to visualise the actual distance from a pixel to the closest one.

The distance diagram has been calculated using minDist to sample a gradient from black to white.

Manhattan distance

As the name suggests, the Manhattan distance takes his name from the homonym city. The shortest path between two locations is not a straight line, since Manhattan is full of buildings. The shortest distance is the one which goes around building.

half distance_manhattan(float2 a, float2 b) { return abs(a.x - b.x) + abs(a.y - b.y); } 1 2 3 half distance_manhattan ( float2 a , float2 b ) { return abs ( a . x - b . x ) + abs ( a . y - b . y ) ; }

Compared to the Euclidean distance, It is sensibly less expensive to calculate.

Using the Manhattan distance produces very intriguing patterns which resemble circuit boards. This is not a coincidence: many boards are designed to minimise circuit length and avoid curves.

Minkowski distance

Despite looking very different, both the Euclidean and the Manhattan distances are both special cases of a more general metric: the Minkowsi distance. To understand why, you have to remind some algebra. In the same way multiplication and division are the same operator (dividing by is equivalent to multiply by ), even root and exponentiation are deeply connected. Remembering then , we can introduce the Minkowski distance:

When or it equivalent to the Manhattan or Euclidian distance, respectively.

half distance_minkowski(float2 a, float2 b, float p) { return pow(pow(abs(a.x - b.x),p) + pow(abs(a.y - b.y),_P),1/p); } 1 2 3 half distance_minkowski ( float2 a , float2 b , float p ) { return pow ( pow ( abs ( a . x - b . x ) , p ) + pow ( abs ( a . y - b . y ) , _P ) , 1 / p ) ; }

The most fascinating aspect is that is provides a way to smoothly transitioning from the Euclidean to the Manhattan distance, and the other way round.

and : If you are in a higher dimension, the Minkowski distance can be still used, providing that you calculate it on all the components of two pointsand

The next part of this tutorial will focus on the applications of Voronoi diagrams.