1 // Voro++, a 3D cell-based Voronoi library
3 // Author : Chris H. Rycroft (LBL / UC Berkeley)
4 // Email : chr@alum.mit.edu
5 // Date : August 30th 2011
8 * \brief Header file for the voronoicell and related classes. */
10 #ifndef VOROPP_CELL_HH
11 #define VOROPP_CELL_HH
20 /** \brief A class representing a single Voronoi cell.
22 * This class represents a single Voronoi cell, as a collection of vertices
23 * that are connected by edges. The class contains routines for initializing
24 * the Voronoi cell to be simple shapes such as a box, tetrahedron, or octahedron.
25 * It the contains routines for recomputing the cell based on cutting it
26 * by a plane, which forms the key routine for the Voronoi cell computation.
27 * It contains numerous routine for computing statistics about the Voronoi cell,
28 * and it can output the cell in several formats.
30 * This class is not intended for direct use, but forms the base of the
31 * voronoicell and voronoicell_neighbor classes, which extend it based on
32 * whether neighboring particle ID information needs to be tracked. */
33 class voronoicell_base
{
35 /** This holds the current size of the arrays ed and nu, which
36 * hold the vertex information. If more vertices are created
37 * than can fit in this array, then it is dynamically extended
38 * using the add_memory_vertices routine. */
40 /** This holds the current maximum allowed order of a vertex,
41 * which sets the size of the mem, mep, and mec arrays. If a
42 * vertex is created with more vertices than this, the arrays
43 * are dynamically extended using the add_memory_vorder routine.
45 int current_vertex_order
;
46 /** This sets the size of the main delete stack. */
47 int current_delete_size
;
48 /** This sets the size of the auxiliary delete stack. */
49 int current_delete2_size
;
50 /** This sets the size of the extra search stack. */
51 int current_xsearch_size
;
52 /** This sets the total number of vertices in the current cell.
55 /** This is the index of particular point in the cell, which is
56 * used to start the tracing routines for plane intersection
57 * and cutting. These routines will work starting from any
58 * point, but it's often most efficient to start from the last
59 * point considered, since in many cases, the cell construction
60 * algorithm may consider many planes with similar vectors
63 /** This is a two dimensional array that holds information
64 * about the edge connections of the vertices that make up the
65 * cell. The two dimensional array is not allocated in the
66 * usual method. To account for the fact the different vertices
67 * have different orders, and thus require different amounts of
68 * storage, the elements of ed[i] point to one-dimensional
69 * arrays in the mep[] array of different sizes.
71 * More specifically, if vertex i has order m, then ed[i]
72 * points to a one-dimensional array in mep[m] that has 2*m+1
73 * entries. The first m elements hold the neighboring edges, so
74 * that the jth edge of vertex i is held in ed[i][j]. The next
75 * m elements hold a table of relations which is redundant but
76 * helps speed up the computation. It satisfies the relation
77 * ed[ed[i][j]][ed[i][m+j]]=i. The final entry holds a back
78 * pointer, so that ed[i+2*m]=i. The back pointers are used
79 * when rearranging the memory. */
81 /** This array holds the order of the vertices in the Voronoi
82 * cell. This array is dynamically allocated, with its current
83 * size held by current_vertices. */
86 /** This in an array with size 3*current_vertices for holding
87 * the positions of the vertices. */
92 voronoicell_base(double max_len_sq
);
94 void init_base(double xmin
,double xmax
,double ymin
,double ymax
,double zmin
,double zmax
);
95 void init_octahedron_base(double l
);
96 void init_tetrahedron_base(double x0
,double y0
,double z0
,double x1
,double y1
,double z1
,double x2
,double y2
,double z2
,double x3
,double y3
,double z3
);
97 void translate(double x
,double y
,double z
);
98 void draw_pov(double x
,double y
,double z
,FILE *fp
=stdout
);
99 /** Outputs the cell in POV-Ray format, using cylinders for edges
100 * and spheres for vertices, to a given file.
101 * \param[in] (x,y,z) a displacement to add to the cell's
103 * \param[in] filename the name of the file to write to. */
104 inline void draw_pov(double x
,double y
,double z
,const char *filename
) {
105 FILE *fp
=safe_fopen(filename
,"w");
109 void draw_pov_mesh(double x
,double y
,double z
,FILE *fp
=stdout
);
110 /** Outputs the cell in POV-Ray format as a mesh2 object to a
112 * \param[in] (x,y,z) a displacement to add to the cell's
114 * \param[in] filename the name of the file to write to. */
115 inline void draw_pov_mesh(double x
,double y
,double z
,const char *filename
) {
116 FILE *fp
=safe_fopen(filename
,"w");
117 draw_pov_mesh(x
,y
,z
,fp
);
120 void draw_gnuplot(double x
,double y
,double z
,FILE *fp
=stdout
);
121 /** Outputs the cell in Gnuplot format a given file.
122 * \param[in] (x,y,z) a displacement to add to the cell's
124 * \param[in] filename the name of the file to write to. */
125 inline void draw_gnuplot(double x
,double y
,double z
,const char *filename
) {
126 FILE *fp
=safe_fopen(filename
,"w");
127 draw_gnuplot(x
,y
,z
,fp
);
131 double max_radius_squared();
132 double total_edge_distance();
133 double surface_area();
134 void centroid(double &cx
,double &cy
,double &cz
);
135 int number_of_faces();
136 int number_of_edges();
137 void vertex_orders(std::vector
<int> &v
);
138 void output_vertex_orders(FILE *fp
=stdout
);
139 void vertices(std::vector
<double> &v
);
140 void output_vertices(FILE *fp
=stdout
);
141 void vertices(double x
,double y
,double z
,std::vector
<double> &v
);
142 void output_vertices(double x
,double y
,double z
,FILE *fp
=stdout
);
143 void face_areas(std::vector
<double> &v
);
144 /** Outputs the areas of the faces.
145 * \param[in] fp the file handle to write to. */
146 inline void output_face_areas(FILE *fp
=stdout
) {
147 std::vector
<double> v
;face_areas(v
);
148 voro_print_vector(v
,fp
);
150 void face_orders(std::vector
<int> &v
);
151 /** Outputs a list of the number of sides of each face.
152 * \param[in] fp the file handle to write to. */
153 inline void output_face_orders(FILE *fp
=stdout
) {
154 std::vector
<int> v
;face_orders(v
);
155 voro_print_vector(v
,fp
);
157 void face_freq_table(std::vector
<int> &v
);
159 inline void output_face_freq_table(FILE *fp
=stdout
) {
160 std::vector
<int> v
;face_freq_table(v
);
161 voro_print_vector(v
,fp
);
163 void face_vertices(std::vector
<int> &v
);
165 inline void output_face_vertices(FILE *fp
=stdout
) {
166 std::vector
<int> v
;face_vertices(v
);
167 voro_print_face_vertices(v
,fp
);
169 void face_perimeters(std::vector
<double> &v
);
170 /** Outputs a list of the perimeters of each face.
171 * \param[in] fp the file handle to write to. */
172 inline void output_face_perimeters(FILE *fp
=stdout
) {
173 std::vector
<double> v
;face_perimeters(v
);
174 voro_print_vector(v
,fp
);
176 void normals(std::vector
<double> &v
);
177 /** Outputs a list of the perimeters of each face.
178 * \param[in] fp the file handle to write to. */
179 inline void output_normals(FILE *fp
=stdout
) {
180 std::vector
<double> v
;normals(v
);
181 voro_print_positions(v
,fp
);
183 /** Outputs a custom string of information about the Voronoi
184 * cell to a file. It assumes the cell is at (0,0,0) and has a
185 * the default_radius associated with it.
186 * \param[in] format the custom format string to use.
187 * \param[in] fp the file handle to write to. */
188 inline void output_custom(const char *format
,FILE *fp
=stdout
) {output_custom(format
,0,0,0,0,default_radius
,fp
);}
189 void output_custom(const char *format
,int i
,double x
,double y
,double z
,double r
,FILE *fp
=stdout
);
190 template<class vc_class
>
191 bool nplane(vc_class
&vc
,double x
,double y
,double z
,double rsq
,int p_id
);
192 bool plane_intersects(double x
,double y
,double z
,double rsq
);
193 bool plane_intersects_guess(double x
,double y
,double z
,double rsq
);
194 void construct_relations();
195 void check_relations();
196 void check_duplicates();
198 /** Returns a list of IDs of neighboring particles
199 * corresponding to each face.
200 * \param[out] v a reference to a vector in which to return the
201 * results. If no neighbor information is
202 * available, a blank vector is returned. */
203 virtual void neighbors(std::vector
<int> &v
) {v
.clear();}
204 /** This is a virtual function that is overridden by a routine
205 * to print a list of IDs of neighboring particles
206 * corresponding to each face. By default, when no neighbor
207 * information is available, the routine does nothing.
208 * \param[in] fp the file handle to write to. */
209 virtual void output_neighbors(FILE *fp
=stdout
) {}
210 /** This a virtual function that is overridden by a routine to
211 * print the neighboring particle IDs for a given vertex. By
212 * default, when no neighbor information is available, the
213 * routine does nothing.
214 * \param[in] i the vertex to consider. */
215 virtual void print_edges_neighbors(int i
) {};
216 /** This is a simple inline function for picking out the index
217 * of the next edge counterclockwise at the current vertex.
218 * \param[in] a the index of an edge of the current vertex.
219 * \param[in] p the number of the vertex.
220 * \return 0 if a=nu[p]-1, or a+1 otherwise. */
221 inline int cycle_up(int a
,int p
) {return a
==nu
[p
]-1?0:a
+1;}
222 /** This is a simple inline function for picking out the index
223 * of the next edge clockwise from the current vertex.
224 * \param[in] a the index of an edge of the current vertex.
225 * \param[in] p the number of the vertex.
226 * \return nu[p]-1 if a=0, or a-1 otherwise. */
227 inline int cycle_down(int a
,int p
) {return a
==0?nu
[p
]-1:a
-1;}
229 /** This a one dimensional array that holds the current sizes
230 * of the memory allocations for them mep array.*/
232 /** This is a one dimensional array that holds the current
233 * number of vertices of order p that are stored in the mep[p]
236 /** This is a two dimensional array for holding the information
237 * about the edges of the Voronoi cell. mep[p] is a
238 * one-dimensional array for holding the edge information about
239 * all vertices of order p, with each vertex holding 2*p+1
240 * integers of information. The total number of vertices held
241 * on mep[p] is stored in mem[p]. If the space runs out, the
242 * code allocates more using the add_memory() routine. */
244 inline void reset_edges();
245 template<class vc_class
>
246 void check_memory_for_copy(vc_class
&vc
,voronoicell_base
* vb
);
247 void copy(voronoicell_base
* vb
);
249 /** This is the delete stack, used to store the vertices which
250 * are going to be deleted during the plane cutting procedure.
252 int *ds
,*stackp
,*stacke
;
253 /** This is the auxiliary delete stack, which has size set by
254 * current_delete2_size. */
255 int *ds2
,*stackp2
,*stacke2
;
256 /** This is the extra search stack. */
257 int *xse
,*stackp3
,*stacke3
;
259 /** The x coordinate of the normal vector to the test plane. */
261 /** The y coordinate of the normal vector to the test plane. */
263 /** The z coordinate of the normal vector to the test plane. */
265 /** The magnitude of the normal vector to the test plane. */
267 template<class vc_class
>
268 void add_memory(vc_class
&vc
,int i
);
269 template<class vc_class
>
270 void add_memory_vertices(vc_class
&vc
);
271 template<class vc_class
>
272 void add_memory_vorder(vc_class
&vc
);
273 void add_memory_ds();
274 void add_memory_ds2();
275 void add_memory_xse();
276 bool failsafe_find(int &lp
,int &ls
,int &us
,double &l
,double &u
);
277 template<class vc_class
>
278 bool create_facet(vc_class
&vc
,int lp
,int ls
,double l
,int us
,double u
,int p_id
);
279 template<class vc_class
>
280 bool collapse_order1(vc_class
&vc
);
281 template<class vc_class
>
282 inline bool collapse_order2(vc_class
&vc
);
283 template<class vc_class
>
284 bool delete_connection(vc_class
&vc
,int j
,int k
,bool hand
);
285 inline bool search_for_outside_edge(int &up
);
286 inline void add_to_stack(int sc2
,int lp
);
287 inline void reset_mask() {
288 for(int i
=0;i
<current_vertices
;i
++) mask
[i
]=0;
291 inline bool search_downward(unsigned int &uw
,int &lp
,int &ls
,int &us
,double &l
,double &u
);
292 bool definite_max(int &lp
,int &ls
,double &l
,double &u
,unsigned int &uw
);
293 inline bool search_upward(unsigned int &lw
,int &lp
,int &ls
,int &us
,double &l
,double &u
);
294 bool definite_min(int &lp
,int &us
,double &l
,double &u
,unsigned int &lw
);
295 inline bool plane_intersects_track(double x
,double y
,double z
,double rs
,double g
);
296 inline void normals_search(std::vector
<double> &v
,int i
,int j
,int k
);
297 inline bool search_edge(int l
,int &m
,int &k
);
298 inline unsigned int m_test(int n
,double &ans
);
299 inline unsigned int m_testx(int n
,double &ans
);
300 unsigned int m_calc(int n
,double &ans
);
301 inline void flip(int tp
) {ed
[tp
][nu
[tp
]<<1]=-1-ed
[tp
][nu
[tp
]<<1];}
302 int check_marginal(int n
,double &ans
);
303 friend class voronoicell
;
304 friend class voronoicell_neighbor
;
307 /** \brief Extension of the voronoicell_base class to represent a Voronoi
308 * cell without neighbor information.
310 * This class is an extension of the voronoicell_base class, in cases when
311 * is not necessary to track the IDs of neighboring particles associated
312 * with each face of the Voronoi cell. */
313 class voronoicell
: public voronoicell_base
{
315 using voronoicell_base::nplane
;
316 voronoicell() : voronoicell_base(default_length
*default_length
) {}
317 voronoicell(double max_len_sq_
) : voronoicell_base(max_len_sq_
) {}
318 template<class c_class
>
319 voronoicell(c_class
&con
) : voronoicell_base(con
.max_len_sq
) {}
320 /** Copies the information from another voronoicell class into
321 * this class, extending memory allocation if necessary.
322 * \param[in] c the class to copy. */
323 inline void operator=(voronoicell
&c
) {
324 voronoicell_base
* vb((voronoicell_base
*) &c
);
325 check_memory_for_copy(*this,vb
);copy(vb
);
327 /** Cuts a Voronoi cell using by the plane corresponding to the
328 * perpendicular bisector of a particle.
329 * \param[in] (x,y,z) the position of the particle.
330 * \param[in] rsq the modulus squared of the vector.
331 * \param[in] p_id the plane ID, ignored for this case where no
332 * neighbor tracking is enabled.
333 * \return False if the plane cut deleted the cell entirely,
335 inline bool nplane(double x
,double y
,double z
,double rsq
,int p_id
) {
336 return nplane(*this,x
,y
,z
,rsq
,0);
338 /** Cuts a Voronoi cell using by the plane corresponding to the
339 * perpendicular bisector of a particle.
340 * \param[in] (x,y,z) the position of the particle.
341 * \param[in] p_id the plane ID, ignored for this case where no
342 * neighbor tracking is enabled.
343 * \return False if the plane cut deleted the cell entirely,
345 inline bool nplane(double x
,double y
,double z
,int p_id
) {
346 double rsq
=x
*x
+y
*y
+z
*z
;
347 return nplane(*this,x
,y
,z
,rsq
,0);
349 /** Cuts a Voronoi cell using by the plane corresponding to the
350 * perpendicular bisector of a particle.
351 * \param[in] (x,y,z) the position of the particle.
352 * \param[in] rsq the modulus squared of the vector.
353 * \return False if the plane cut deleted the cell entirely,
355 inline bool plane(double x
,double y
,double z
,double rsq
) {
356 return nplane(*this,x
,y
,z
,rsq
,0);
358 /** Cuts a Voronoi cell using by the plane corresponding to the
359 * perpendicular bisector of a particle.
360 * \param[in] (x,y,z) the position of the particle.
361 * \return False if the plane cut deleted the cell entirely,
363 inline bool plane(double x
,double y
,double z
) {
364 double rsq
=x
*x
+y
*y
+z
*z
;
365 return nplane(*this,x
,y
,z
,rsq
,0);
367 /** Initializes the Voronoi cell to be rectangular box with the
369 * \param[in] (xmin,xmax) the minimum and maximum x coordinates.
370 * \param[in] (ymin,ymax) the minimum and maximum y coordinates.
371 * \param[in] (zmin,zmax) the minimum and maximum z coordinates. */
372 inline void init(double xmin
,double xmax
,double ymin
,double ymax
,double zmin
,double zmax
) {
373 init_base(xmin
,xmax
,ymin
,ymax
,zmin
,zmax
);
375 /** Initializes the cell to be an octahedron with vertices at
376 * (l,0,0), (-l,0,0), (0,l,0), (0,-l,0), (0,0,l), and (0,0,-l).
377 * \param[in] l a parameter setting the size of the octahedron.
379 inline void init_octahedron(double l
) {
380 init_octahedron_base(l
);
382 /** Initializes the cell to be a tetrahedron.
383 * \param[in] (x0,y0,z0) the coordinates of the first vertex.
384 * \param[in] (x1,y1,z1) the coordinates of the second vertex.
385 * \param[in] (x2,y2,z2) the coordinates of the third vertex.
386 * \param[in] (x3,y3,z3) the coordinates of the fourth vertex.
388 inline void init_tetrahedron(double x0
,double y0
,double z0
,double x1
,double y1
,double z1
,double x2
,double y2
,double z2
,double x3
,double y3
,double z3
) {
389 init_tetrahedron_base(x0
,y0
,z0
,x1
,y1
,z1
,x2
,y2
,z2
,x3
,y3
,z3
);
393 inline void n_allocate(int i
,int m
) {};
394 inline void n_add_memory_vertices(int i
) {};
395 inline void n_add_memory_vorder(int i
) {};
396 inline void n_set_pointer(int p
,int n
) {};
397 inline void n_copy(int a
,int b
,int c
,int d
) {};
398 inline void n_set(int a
,int b
,int c
) {};
399 inline void n_set_aux1(int k
) {};
400 inline void n_copy_aux1(int a
,int b
) {};
401 inline void n_copy_aux1_shift(int a
,int b
) {};
402 inline void n_set_aux2_copy(int a
,int b
) {};
403 inline void n_copy_pointer(int a
,int b
) {};
404 inline void n_set_to_aux1(int j
) {};
405 inline void n_set_to_aux2(int j
) {};
406 inline void n_allocate_aux1(int i
) {};
407 inline void n_switch_to_aux1(int i
) {};
408 inline void n_copy_to_aux1(int i
,int m
) {};
409 inline void n_set_to_aux1_offset(int k
,int m
) {};
410 inline void n_neighbors(std::vector
<int> &v
) {v
.clear();};
411 friend class voronoicell_base
;
414 /** \brief Extension of the voronoicell_base class to represent a Voronoi cell
415 * with neighbor information.
417 * This class is an extension of the voronoicell_base class, in cases when the
418 * IDs of neighboring particles associated with each face of the Voronoi cell.
419 * It contains additional data structures mne and ne for storing this
421 class voronoicell_neighbor
: public voronoicell_base
{
423 using voronoicell_base::nplane
;
424 /** This two dimensional array holds the neighbor information
425 * associated with each vertex. mne[p] is a one dimensional
426 * array which holds all of the neighbor information for
427 * vertices of order p. */
429 /** This is a two dimensional array that holds the neighbor
430 * information associated with each vertex. ne[i] points to a
431 * one-dimensional array in mne[nu[i]]. ne[i][j] holds the
432 * neighbor information associated with the jth edge of vertex
433 * i. It is set to the ID number of the plane that made the
434 * face that is clockwise from the jth edge. */
436 voronoicell_neighbor() : voronoicell_base(default_length
*default_length
) {
439 voronoicell_neighbor(double max_len_sq_
) : voronoicell_base(max_len_sq_
) {
442 template<class c_class
>
443 voronoicell_neighbor(c_class
&con
) : voronoicell_base(con
.max_len_sq
) {
446 ~voronoicell_neighbor();
447 void operator=(voronoicell
&c
);
448 void operator=(voronoicell_neighbor
&c
);
449 /** Cuts the Voronoi cell by a particle whose center is at a
450 * separation of (x,y,z) from the cell center. The value of rsq
451 * should be initially set to \f$x^2+y^2+z^2\f$.
452 * \param[in] (x,y,z) the normal vector to the plane.
453 * \param[in] rsq the distance along this vector of the plane.
454 * \param[in] p_id the plane ID (for neighbor tracking only).
455 * \return False if the plane cut deleted the cell entirely,
457 inline bool nplane(double x
,double y
,double z
,double rsq
,int p_id
) {
458 return nplane(*this,x
,y
,z
,rsq
,p_id
);
460 /** This routine calculates the modulus squared of the vector
461 * before passing it to the main nplane() routine with full
463 * \param[in] (x,y,z) the vector to cut the cell by.
464 * \param[in] p_id the plane ID (for neighbor tracking only).
465 * \return False if the plane cut deleted the cell entirely,
467 inline bool nplane(double x
,double y
,double z
,int p_id
) {
468 double rsq
=x
*x
+y
*y
+z
*z
;
469 return nplane(*this,x
,y
,z
,rsq
,p_id
);
471 /** This version of the plane routine just makes up the plane
472 * ID to be zero. It will only be referenced if neighbor
473 * tracking is enabled.
474 * \param[in] (x,y,z) the vector to cut the cell by.
475 * \param[in] rsq the modulus squared of the vector.
476 * \return False if the plane cut deleted the cell entirely,
478 inline bool plane(double x
,double y
,double z
,double rsq
) {
479 return nplane(*this,x
,y
,z
,rsq
,0);
481 /** Cuts a Voronoi cell using the influence of a particle at
482 * (x,y,z), first calculating the modulus squared of this
483 * vector before passing it to the main nplane() routine. Zero
484 * is supplied as the plane ID, which will be ignored unless
485 * neighbor tracking is enabled.
486 * \param[in] (x,y,z) the vector to cut the cell by.
487 * \return False if the plane cut deleted the cell entirely,
489 inline bool plane(double x
,double y
,double z
) {
490 double rsq
=x
*x
+y
*y
+z
*z
;
491 return nplane(*this,x
,y
,z
,rsq
,0);
493 void init(double xmin
,double xmax
,double ymin
,double ymax
,double zmin
,double zmax
);
494 void init_octahedron(double l
);
495 void init_tetrahedron(double x0
,double y0
,double z0
,double x1
,double y1
,double z1
,double x2
,double y2
,double z2
,double x3
,double y3
,double z3
);
497 virtual void neighbors(std::vector
<int> &v
);
498 virtual void print_edges_neighbors(int i
);
499 virtual void output_neighbors(FILE *fp
=stdout
) {
500 std::vector
<int> v
;neighbors(v
);
501 voro_print_vector(v
,fp
);
507 inline void n_allocate(int i
,int m
) {mne
[i
]=new int[m
*i
];}
508 inline void n_add_memory_vertices(int i
) {
509 int **pp
=new int*[i
];
510 for(int j
=0;j
<current_vertices
;j
++) pp
[j
]=ne
[j
];
513 inline void n_add_memory_vorder(int i
) {
514 int **p2
=new int*[i
];
515 for(int j
=0;j
<current_vertex_order
;j
++) p2
[j
]=mne
[j
];
516 delete [] mne
;mne
=p2
;
518 inline void n_set_pointer(int p
,int n
) {
519 ne
[p
]=mne
[n
]+n
*mec
[n
];
521 inline void n_copy(int a
,int b
,int c
,int d
) {ne
[a
][b
]=ne
[c
][d
];}
522 inline void n_set(int a
,int b
,int c
) {ne
[a
][b
]=c
;}
523 inline void n_set_aux1(int k
) {paux1
=mne
[k
]+k
*mec
[k
];}
524 inline void n_copy_aux1(int a
,int b
) {paux1
[b
]=ne
[a
][b
];}
525 inline void n_copy_aux1_shift(int a
,int b
) {paux1
[b
]=ne
[a
][b
+1];}
526 inline void n_set_aux2_copy(int a
,int b
) {
527 paux2
=mne
[b
]+b
*mec
[b
];
528 for(int i
=0;i
<b
;i
++) ne
[a
][i
]=paux2
[i
];
530 inline void n_copy_pointer(int a
,int b
) {ne
[a
]=ne
[b
];}
531 inline void n_set_to_aux1(int j
) {ne
[j
]=paux1
;}
532 inline void n_set_to_aux2(int j
) {ne
[j
]=paux2
;}
533 inline void n_allocate_aux1(int i
) {paux1
=new int[i
*mem
[i
]];}
534 inline void n_switch_to_aux1(int i
) {delete [] mne
[i
];mne
[i
]=paux1
;}
535 inline void n_copy_to_aux1(int i
,int m
) {paux1
[m
]=mne
[i
][m
];}
536 inline void n_set_to_aux1_offset(int k
,int m
) {ne
[k
]=paux1
+m
;}
537 friend class voronoicell_base
;