## odd_even.cc – An odd–even coloring of a Voronoi cell

The `voronoicell`

class contains a number of functions that can
be used to directly interrogate the structure of a Voronoi cell. In the
cell_statistics.cc example code many
features of a Voronoi cell are calculated and printed to the screen. However,
for every aspect of the cell, there are also routines that can directly
pass back the information about the cell.

Several of these routines return information using the C++
vector
template in the STL. For some aspects of the Voronoi cell, it is difficult to
know *a priori* how much data will be returned, and using vectors
provides a standard way to return a variable amount of data.

In the following code, a random Voronoi cell is constructed using 250
planes, using the same procedure as in the
single_cell.cc example code. On line 41,
a vector of face orders is created: each entry of the vector corresponds to the
number of sides making up one face (*eg.* 3=triangle, 4=quadrilateral,
5=pentagon). On line 42, a vector of the normal vectors for each face is computed.
Voro++ guarantees that all routines that return information about faces do so
in the same order, allowing the entries into the two vectors to be matched with
each other.

Lines 46–52 construct the Voronoi cell as a POV-Ray intersection of planes. For each face, a plane is constructed with a normal from the previously computed vector. The texture is chosen depending on whether the face has an odd or even number of sides, using a bitwise AND operation to test whether the first bit is 0 or 1.

On line 55, the standard POV-Ray routine is used to output the Voronoi cell in POV-Ray format using cylinders for edges and spheres for vertices. These can be rendered with the command

`povray +H800 +W800 +A0.1 -J +Oodd_even.png odd_even.pov`

to produce the image above. Faces with an even number of sides are shown in black and those with an odd number of sides are shown in white.

## Code listing

1: // Odd/even face coloring code 2: // 3: // Author : Chris H. Rycroft (LBL / UC Berkeley) 4: // Email : chr@alum.mit.edu 5: // Date : August 30th 2011 6: 7: #include <vector> 8: using namespace std; 9: 10: #include "voro++.hh" 11: using namespace voro; 12: 13: // This function returns a random floating point number between 0 and 1 14: double rnd() {return double(rand())/RAND_MAX;} 15: 16: int main() { 17: unsigned int i; 18: double x,y,z,rsq,r; 19: voronoicell v; 20: 21: // Initialize the Voronoi cell to be a cube of side length 2, centered 22: // on the origin 23: v.init(-1,1,-1,1,-1,1); 24: 25: // Cut the cell by 250 random planes which are all a distance 1 away 26: // from the origin, to make an approximation to a sphere 27: for(i=0;i<250;i++) { 28: x=2*rnd()-1; 29: y=2*rnd()-1; 30: z=2*rnd()-1; 31: rsq=x*x+y*y+z*z; 32: if(rsq>0.01&&rsq<1) { 33: r=1/sqrt(rsq);x*=r;y*=r;z*=r; 34: v.plane(x,y,z,1); 35: } 36: } 37: 38: // Calculate the orders of the faces and the normal vectors 39: vector<int> f_vert; 40: vector<double> nor; 41: v.face_orders(f_vert); 42: v.normals(nor); 43: 44: // Output POV-Ray planes with textures based on whether a face is 45: // composed of an odd or even number of edges 46: const char* parity[2]={"even","odd"}; 47: FILE *fp=safe_fopen("odd_even_pl.pov","w"); 48: for(i=0;i<f_vert.size();i++) 49: fprintf(fp,"plane{<%g,%g,%g>,0.5 texture{t_%s}}\n" 50: ,nor[3*i],nor[3*i+1],nor[3*i+2] 51: ,parity[f_vert[i]&1]); 52: fclose(fp); 53: 54: // Save the Voronoi cell as a spheres and cylinders 55: v.draw_pov(0,0,0,"odd_even_v.pov"); 56: }