platonic.cc – Creating the five Platonic solids

Tetrahedron Cube Octahedron Dodecahedron Icosahedron

This example script uses the Voronoi cell class to compute the five Platonic solids. In each case the Voronoi cell is initialized to be a cube, and then plane cuts are applied create the desired shape.

The tetrahedron can be constructed using four plane cuts, and the cube requires no plane cuts, as it is the default shape. The octahedron can be made by applying eight plane cuts at the corners of a cube. This could alternatively be constructed directly using the routine init_octahedron(), that creates an octahedron as the default shape. The dodecahedron and icosahedron are created by orienting the shapes so that the coordinates can be expressed in terms of the Golden Ratio. On lines 11 and 12, the golden ratio and its inverse are set in the variables Phi and phi respectively, and these are then referenced in the plane function calls.

The program outputs the results in Gnuplot format to files named “tetrahedron.gnu”, “cube.gnu”, “octahedron.gnu”, “dodecahedron.gnu”, and “icosahedron.gnu”. These can be visualized from within gnuplot using the command “splot <filename>”, resulting in images like those shown above.

As noted in the single cell example, a Voronoi cell that is constructed by random plane cuts will have vertices of order three with extremely high probability. In this example, we see that the explicit construction leads to the creation of higher-order vertices in the octahedron and icosahedron cases. The code recognizes these and stores them as higher-order vertices, as opposed to several lower order vertices clustered together.

Code listing

 1: // Platonic solids example code
 2: //
 3: // Author   : Chris H. Rycroft (LBL / UC Berkeley)
 4: // Email    : chr@alum.mit.edu
 5: // Date     : August 30th 2011
 6: 
 7: #include "voro++.hh"
 8: using namespace voro;
 9: 
10: // Golden ratio constants
11: const double Phi=0.5*(1+sqrt(5.0));
12: const double phi=0.5*(1-sqrt(5.0));
13: 
14: int main() {
15:         voronoicell v;
16: 
17:         // Create a tetrahedron
18:         v.init(-2,2,-2,2,-2,2);
19:         v.plane(1,1,1);
20:         v.plane(1,-1,-1);
21:         v.plane(-1,1,-1);
22:         v.plane(-1,-1,1);
23:         vector<int> vi;
24:         v.face_freq_table(vi);
25:         voro_print_vector(vi);
26: 
27:         v.draw_gnuplot(0,0,0,"tetrahedron.gnu");
28: 
29:         // Create a cube. Since this is the default shape
30:         // we don't need to do any plane cutting.
31:         v.init(-1,1,-1,1,-1,1);
32:         v.draw_gnuplot(0,0,0,"cube.gnu");
33: 
34:         // Create an octahedron
35:         v.init(-2,2,-2,2,-2,2);
36:         v.plane(1,1,1);
37:         v.plane(-1,1,1);
38:         v.plane(1,-1,1);
39:         v.plane(-1,-1,1);
40:         v.plane(1,1,-1);
41:         v.plane(-1,1,-1);
42:         v.plane(1,-1,-1);
43:         v.plane(-1,-1,-1);
44: 
45:         v.draw_gnuplot(0,0,0,"octahedron.gnu");
46: 
47:         // Create a dodecahedron
48:         v.init(-2,2,-2,2,-2,2);
49:         v.plane(0,Phi,1);
50:         v.plane(0,-Phi,1);
51:         v.plane(0,Phi,-1);
52:         v.plane(0,-Phi,-1);
53:         v.plane(1,0,Phi);
54:         v.plane(-1,0,Phi);
55:         v.plane(1,0,-Phi);
56:         v.plane(-1,0,-Phi);
57:         v.plane(Phi,1,0);
58:         v.plane(-Phi,1,0);
59:         v.plane(Phi,-1,0);
60:         v.plane(-Phi,-1,0);
61: 
62:         v.draw_gnuplot(0,0,0,"dodecahedron.gnu");
63: 
64:         // Create an icosahedron
65:         v.init(-2,2,-2,2,-2,2);
66:         v.plane(1,1,1);
67:         v.plane(-1,1,1);
68:         v.plane(1,-1,1);
69:         v.plane(-1,-1,1);
70:         v.plane(1,1,-1);
71:         v.plane(-1,1,-1);
72:         v.plane(1,-1,-1);
73:         v.plane(-1,-1,-1);
74:         v.plane(0,phi,Phi);
75:         v.plane(0,phi,-Phi);
76:         v.plane(0,-phi,Phi);
77:         v.plane(0,-phi,-Phi);
78:         v.plane(Phi,0,phi);
79:         v.plane(Phi,0,-phi);
80:         v.plane(-Phi,0,phi);
81:         v.plane(-Phi,0,-phi);
82:         v.plane(phi,Phi,0);
83:         v.plane(phi,-Phi,0);
84:         v.plane(-phi,Phi,0);
85:         v.plane(-phi,-Phi,0);
86: 
87:         v.draw_gnuplot(0,0,0,"icosahedron.gnu");
88: 
89: }