degenerate.cc – Degenerate vertices
This example demonstrates the ability of the code to handle degenerate vertices, that are connected to more than three neighbors, that occur when the cutting planes precisely intersect with existing vertices. To make the routines tolerant to numerical errors, Voro++ takes the approach that a cutting plane intersects an existing vertex if it is within a small tolerance of that vertex – this amount can be set in the source file “config.hh”.
In this example, a Voronoi cell is constructed using plane cuts at specific angles that lead to high order vertices in each of the six coordinate directions (x, y, z, -x, -y, -z). In lines 28 to 36, a number of planes cuts are applied, by rotating around each coordinate direction.
The creation of the degenerate vertices requires significant internal
reordering of memory. Once the cell is created, two diagnostic routines are
carried out to ensure that the calculation is correct. The routine
check_relations()
ensures that the relation table describing how
edges are linked to each other is current. The routine
check_duplicates()
makes sure that there are no duplicate edges
between two vertices. The resulting cell is output in Gnuplot and POV-Ray
formats, to the files “degenerate.gnu” and
“degenerate_v.pov” respectively.
The left image above shows the POV-Ray output, using the header file
“degenerate.pov”. We see vertices of order 32 in the coordinate
directions, and there are also many vertices of order 4 that arise due to
symmetry. The middle image shows the cell if the value of theta
is
changed to pi/4
. The resulting cell has a very similar structure,
although some edges are missing due to the planes from one direction perfectly
matching with the planes from the neighboring direction. The right image shows
the cell if theta=pi/4+0.25
. For this value, the planes from one
direction begin to interfere with the others, creating a pattern with many
order 4 vertices.
Code listing
1: // Degenerate Voronoi cell 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: const double pi=3.1415926535897932384626433832795; 11: 12: // The number of planes to be cut around each coordinate axis 13: const int n=32; 14: const double step=2*pi/n; 15: 16: // The angle (in radians) of the cutting planes from horizontal 17: const double theta=pi/4-0.25; 18: 19: int main() { 20: double x,y,z,phi; 21: voronoicell v; 22: 23: // Initialize the Voronoi cell to be a cube of side length 2, centered 24: // on the origin 25: v.init(-1,1,-1,1,-1,1); 26: 27: // Plane cutting 28: for(phi=0;phi<2*pi-0.5*step;phi+=step) { 29: x=cos(theta);y=cos(phi)*sin(theta);z=sin(phi)*sin(theta); 30: v.plane(x,y,z,1); 31: v.plane(-x,y,z,1); 32: v.plane(y,x,z,1); 33: v.plane(y,-x,z,1); 34: v.plane(y,z,x,1); 35: v.plane(y,z,-x,1); 36: } 37: 38: // Check that the relation table is correct, and that there are no 39: // duplicate edges 40: v.check_relations(); 41: v.check_duplicates(); 42: 43: // Output the Voronoi cell to a file in Gnuplot format 44: v.draw_gnuplot(0,0,0,"degenerate.gnu"); 45: 46: // Output the Voronoi cell to a file in POV-Ray format 47: v.draw_pov(0,0,0,"degenerate_v.pov"); 48: }