platonic.cc – Creating the five Platonic solids
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: }