**Introduction**

What makes dice fair? Intuitively, when we roll a fair die with sides, we expect each of its possible outcomes to have the same probability of occurring. What shapes have this property?

I think this is an interesting problem, in part because it *seems* like there should be an elegant mathematical solution, but some unpleasantly complicated physics gets in the way. For example, even a standard six-sided die can be vulnerable to manipulation by a skilled cheat. The difficulty is that the fairness of a particular shape of die may depend on assumptions about *how* the die is rolled– what is the probability distribution from which we randomly draw the die’s initial position, velocity, and angular momentum? What surface does the die land on– can it slide and/or bounce, and if so, with what coefficients of friction and restitution, etc.?

(For this discussion, we will focus on dice that are convex polyhedra, having flat polygonal faces with no holes or indentations. There are other interesting possibilities, though. For example, consider flipping a cylinder as a “three-sided coin,” which may land on heads, tails, or on its curved “edge.”)

**Symmetry**

One way to get around this dependence on physics modeling assumptions is to appeal to *symmetry*: if there is *any* shape of die that could possibly be considered fair, then a sufficient (but perhaps not necessary) condition for fairness is *face-transitivity*— the group of symmetries of the die should act transitively on its faces. That is, given any pair of faces and , there must be a rigid transformation of the die into itself that maps to .

To see why this is the criteria that we want, suppose that Charlie is a skilled-but-myopic cheat with the ability to roll the die biased toward any face that he desires. However, he can only see the resting position and shape of the rolled die, not the labels on its faces. So, after the roll, but *before the outcome is announced*, an objective third party, Oscar, selects a face uniformly at random, and has an opportunity to secretly rotate the rolled die, *preserving its original location*, to show the randomly selected face , instead of the face that Charlie intended to roll.

Intuitively, if the die is fair, then Oscar should be able to prevent Charlie from having undue advantage, without Charlie being aware that the die was moved. No matter what face Charlie tries to roll, and no matter what truly random face Oscar selects, it should be possible to rotate one to the other without changing the “space taken up” by the die.

**Rotations vs. reflections**

A convex polyhedron that is face-transitive is called an isohedron. Wolfram’s *MathWorld* page (as well as a great Numberphile video with Persi Diaconis) describes 30 types of isohedra, noting that they “make fair dice” … but face-transitivity is a property that requires some qualification. These 30 types of dice all have the property that their *full* symmetry group acts transitively on their faces, where by “full” we mean that not just rotations but also reflections– think turning the die “inside out”– are allowed.

Since we can’t expect Oscar to secretly turn a physical die inside out, if we more realistically constrain the allowed transformations to include rotations only, then we can ask whether this *proper* symmetry *sub*group also acts transitively on the faces of a die. It turns out that there are six types of isohedra– including two infinite classes of dipyramids– where this is not the case, i.e., the *proper* symmetry group does *not* act transitively on the faces. Instead, these “less fair” dice each have two distinct orbits of faces, where it is impossible to rotate a face from one orbit into a face from another orbit while preserving the overall space taken up by the die.

The figure below shows all 30 isohedra, with the six less fair dice shown with their two orbits of faces in red and green.

**Implementation notes**

Models of these isohedra and Python code to compute their symmetry groups and face orbits are available on GitHub. I started with the models on the *MathWorld* page, but modified them to provide exact coordinates for all vertices, scaled to have unit minimum edge length. Computing the symmetries mapping one face to another is very similar to the telescope registration problem described here, although there are some interesting additional wrinkles due to working in limited floating-point precision.

**References**:

Regarding your code: The Wavefront .obj format is really convenient. It’s like the Netpbm of 3D models — including irritating minor limitations — and it’s always the first format I go to when I need to handle model data, especially since Blender supports it.

Yeah, I chose it since Mathematica supports it, but mostly because it looked really easy to parse, as in my too-quick-and-dirty Python loader.

Speaking of irritating minor limitations– I didn’t see a similarly “minimal” way to specify per-face colors (e.g., the separate face orbits in red/green) without resorting to a separate materials file.