00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "cell.hh"
00012
00013
00014 template<class n_option>
00015 voronoicell_base<n_option>::voronoicell_base() :
00016 current_vertices(init_vertices), current_vertex_order(init_vertex_order),
00017 current_delete_size(init_delete_size), current_delete2_size(init_delete2_size),
00018 neighbor(this) {
00019 int i;
00020 ds=new int[current_delete_size];
00021 ds2=new int[current_delete2_size];
00022 mem=new int[current_vertex_order];
00023 mec=new int[current_vertex_order];
00024 mep=new int*[current_vertex_order];
00025 ed=new int*[current_vertices];
00026 nu=new int[current_vertices];
00027 pts=new fpoint[3*current_vertices];
00028 sure.p=pts;
00029 for(i=0;i<3;i++) {
00030 mem[i]=init_n_vertices;
00031 mep[i]=new int[init_n_vertices*(2*i+1)];
00032 mec[i]=0;
00033 }
00034 mem[3]=init_3_vertices;
00035 mep[3]=new int[init_3_vertices*7];
00036 mec[3]=0;
00037 for(i=4;i<current_vertex_order;i++) {
00038 mem[i]=init_n_vertices;
00039 mep[i]=new int[init_n_vertices*(2*i+1)];
00040 mec[i]=0;
00041 }
00042 }
00043
00044
00045 template<class n_option>
00046 voronoicell_base<n_option>::~voronoicell_base() {
00047 delete [] ds;
00048 delete [] ds2;
00049 for(int i=0;i<current_vertex_order;i++) if (mem[i]>0) delete [] mep[i];
00050 delete [] mem;
00051 delete [] mec;
00052 delete [] mep;
00053 delete [] ed;
00054 delete [] nu;
00055 delete [] pts;
00056 }
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 template<class n_option>
00068 void voronoicell_base<n_option>::add_memory(int i) {
00069 int s=2*i+1;
00070 if(mem[i]==0) {
00071 neighbor.allocate(i,init_n_vertices);
00072 mep[i]=new int[init_n_vertices*s];
00073 mem[i]=init_n_vertices;
00074 #if VOROPP_VERBOSE >=2
00075 cerr << "Order " << i << " vertex memory created " << endl;
00076 #endif
00077 } else {
00078 int j=0,k,*l;
00079 mem[i]*=2;
00080 if (mem[i]>max_n_vertices) voropp_fatal_error("Point memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR);
00081 #if VOROPP_VERBOSE >=2
00082 cerr << "Order " << i << " vertex memory scaled up to " << mem[i] << endl;
00083 #endif
00084 l=new int[s*mem[i]];
00085 int m=0;
00086 neighbor.allocate_aux1(i);
00087 while(j<s*mec[i]) {
00088 k=mep[i][j+2*i];
00089 if(k>=0) {
00090 ed[k]=l+j;
00091 neighbor.set_to_aux1_offset(k,m);
00092 } else {
00093 int o;
00094 for(o=0;o<stack2;o++) {
00095 if(ed[ds2[o]]==mep[i]+j) {
00096 ed[ds2[o]]=l+j;
00097 neighbor.set_to_aux1_offset(ds2[o],m);
00098 break;
00099 }
00100 }
00101 if(o==stack2) voropp_fatal_error("Couldn't relocate dangling pointer",VOROPP_INTERNAL_ERROR);
00102 #if VOROPP_VERBOSE >=3
00103 cerr << "Relocated dangling pointer" << endl;
00104 #endif
00105 }
00106 for(k=0;k<s;k++,j++) l[j]=mep[i][j];
00107 for(k=0;k<i;k++,m++) neighbor.copy_to_aux1(i,m);
00108 }
00109 delete [] mep[i];
00110 mep[i]=l;
00111 neighbor.switch_to_aux1(i);
00112 }
00113 }
00114
00115
00116
00117
00118
00119 template<class n_option>
00120 void voronoicell_base<n_option>::add_memory_vertices() {
00121 int i=2*current_vertices,j,**pp,*pnu;
00122 if (i>max_vertices) voropp_fatal_error("Vertex memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR);
00123 #if VOROPP_VERBOSE >=2
00124 cerr << "Vertex memory scaled up to " << i << endl;
00125 #endif
00126 fpoint *ppts;
00127 pp=new int*[i];
00128 for(j=0;j<current_vertices;j++) pp[j]=ed[j];
00129 delete [] ed;ed=pp;
00130 neighbor.add_memory_vertices(i);
00131 pnu=new int[i];
00132 for(j=0;j<current_vertices;j++) pnu[j]=nu[j];
00133 delete [] nu;nu=pnu;
00134 ppts=new fpoint[3*i];
00135 for(j=0;j<3*current_vertices;j++) ppts[j]=pts[j];
00136 delete [] pts;sure.p=pts=ppts;
00137 current_vertices=i;
00138 }
00139
00140
00141
00142
00143
00144 template<class n_option>
00145 void voronoicell_base<n_option>::add_memory_vorder() {
00146 int i=2*current_vertex_order,j,*p1,**p2;
00147 if (i>max_vertex_order) voropp_fatal_error("Vertex order memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR);
00148 #if VOROPP_VERBOSE >=2
00149 cerr << "Vertex order memory scaled up to " << i << endl;
00150 #endif
00151 p1=new int[i];
00152 for(j=0;j<current_vertex_order;j++) p1[j]=mem[j];while(j<i) p1[j++]=0;
00153 delete [] mem;mem=p1;
00154 p2=new int*[i];
00155 for(j=0;j<current_vertex_order;j++) p2[j]=mep[j];
00156 delete [] mep;mep=p2;
00157 p1=new int[i];
00158 for(j=0;j<current_vertex_order;j++) p1[j]=mec[j];while(j<i) p1[j++]=0;
00159 delete [] mec;mec=p1;
00160 neighbor.add_memory_vorder(i);
00161 current_vertex_order=i;
00162 }
00163
00164
00165
00166
00167 template<class n_option>
00168 void voronoicell_base<n_option>::add_memory_ds() {
00169 int i=2*current_delete_size,j,*pds;
00170 if (i>max_delete_size) voropp_fatal_error("Delete stack 1 memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR);
00171 #if VOROPP_VERBOSE >=2
00172 cerr << "Delete stack 1 memory scaled up to " << i << endl;
00173 #endif
00174 pds=new int[i];
00175 for(j=0;j<current_delete_size;j++) pds[j]=ds[j];
00176 delete [] ds;ds=pds;
00177 current_delete_size=i;
00178 }
00179
00180
00181
00182
00183 template<class n_option>
00184 void voronoicell_base<n_option>::add_memory_ds2() {
00185 int i=2*current_delete2_size,j,*pds2;
00186 if (i>max_delete2_size) voropp_fatal_error("Delete stack 2 memory allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR);
00187 #if VOROPP_VERBOSE >=2
00188 cerr << "Delete stack 2 memory scaled up to " << i << endl;
00189 #endif
00190 pds2=new int[i];
00191 for(j=0;j<current_delete2_size;j++) pds2[j]=ds2[j];
00192 delete [] ds2;ds2=pds2;
00193 current_delete2_size=i;
00194 }
00195
00196
00197 template<class n_option>
00198 void voronoicell_base<n_option>::init(fpoint xmin,fpoint xmax,fpoint ymin,fpoint ymax,fpoint zmin,fpoint zmax) {
00199 for(int i=0;i<current_vertex_order;i++) mec[i]=0;up=0;
00200 mec[3]=p=8;xmin*=2;xmax*=2;ymin*=2;ymax*=2;zmin*=2;zmax*=2;
00201 pts[0]=xmin;pts[1]=ymin;pts[2]=zmin;
00202 pts[3]=xmax;pts[4]=ymin;pts[5]=zmin;
00203 pts[6]=xmin;pts[7]=ymax;pts[8]=zmin;
00204 pts[9]=xmax;pts[10]=ymax;pts[11]=zmin;
00205 pts[12]=xmin;pts[13]=ymin;pts[14]=zmax;
00206 pts[15]=xmax;pts[16]=ymin;pts[17]=zmax;
00207 pts[18]=xmin;pts[19]=ymax;pts[20]=zmax;
00208 pts[21]=xmax;pts[22]=ymax;pts[23]=zmax;
00209 int *q=mep[3];
00210 q[0]=1;q[1]=4;q[2]=2;q[3]=2;q[4]=1;q[5]=0;q[6]=0;
00211 q[7]=3;q[8]=5;q[9]=0;q[10]=2;q[11]=1;q[12]=0;q[13]=1;
00212 q[14]=0;q[15]=6;q[16]=3;q[17]=2;q[18]=1;q[19]=0;q[20]=2;
00213 q[21]=2;q[22]=7;q[23]=1;q[24]=2;q[25]=1;q[26]=0;q[27]=3;
00214 q[28]=6;q[29]=0;q[30]=5;q[31]=2;q[32]=1;q[33]=0;q[34]=4;
00215 q[35]=4;q[36]=1;q[37]=7;q[38]=2;q[39]=1;q[40]=0;q[41]=5;
00216 q[42]=7;q[43]=2;q[44]=4;q[45]=2;q[46]=1;q[47]=0;q[48]=6;
00217 q[49]=5;q[50]=3;q[51]=6;q[52]=2;q[53]=1;q[54]=0;q[55]=7;
00218 ed[0]=q;ed[1]=q+7;ed[2]=q+14;ed[3]=q+21;
00219 ed[4]=q+28;ed[5]=q+35;ed[6]=q+42;ed[7]=q+49;
00220 neighbor.init();
00221 nu[0]=nu[1]=nu[2]=nu[3]=nu[4]=nu[5]=nu[6]=nu[7]=3;
00222 }
00223
00224
00225
00226
00227 template<class n_option>
00228 inline void voronoicell_base<n_option>::init_octahedron(fpoint l) {
00229 for(int i=0;i<current_vertex_order;i++) mec[i]=0;up=0;
00230 mec[4]=p=6;l*=2;
00231 pts[0]=-l;pts[1]=0;pts[2]=0;
00232 pts[3]=l;pts[4]=0;pts[5]=0;
00233 pts[6]=0;pts[7]=-l;pts[8]=0;
00234 pts[9]=0;pts[10]=l;pts[11]=0;
00235 pts[12]=0;pts[13]=0;pts[14]=-l;
00236 pts[15]=0;pts[16]=0;pts[17]=l;
00237 int *q=mep[4];
00238 q[0]=2;q[1]=5;q[2]=3;q[3]=4;q[4]=0;q[5]=0;q[6]=0;q[7]=0;q[8]=0;
00239 q[9]=2;q[10]=4;q[11]=3;q[12]=5;q[13]=2;q[14]=2;q[15]=2;q[16]=2;q[17]=1;
00240 q[18]=0;q[19]=4;q[20]=1;q[21]=5;q[22]=0;q[23]=3;q[24]=0;q[25]=1;q[26]=2;
00241 q[27]=0;q[28]=5;q[29]=1;q[30]=4;q[31]=2;q[32]=3;q[33]=2;q[34]=1;q[35]=3;
00242 q[36]=0;q[37]=3;q[38]=1;q[39]=2;q[40]=3;q[41]=3;q[42]=1;q[43]=1;q[44]=4;
00243 q[45]=0;q[46]=2;q[47]=1;q[48]=3;q[49]=1;q[50]=3;q[51]=3;q[52]=1;q[53]=5;
00244 ed[0]=q;ed[1]=q+9;ed[2]=q+18;ed[3]=q+27;ed[4]=q+36;ed[5]=q+45;
00245 neighbor.init_octahedron();
00246 nu[0]=nu[1]=nu[2]=nu[3]=nu[4]=nu[5]=4;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255 template<class n_option>
00256 inline void voronoicell_base<n_option>::init_tetrahedron(fpoint x0,fpoint y0,fpoint z0,fpoint x1,fpoint y1,fpoint z1,fpoint x2,fpoint y2,fpoint z2,fpoint x3,fpoint y3,fpoint z3) {
00257 for(int i=0;i<current_vertex_order;i++) mec[i]=0;up=0;
00258 mec[3]=p=4;
00259 pts[0]=x0*2;pts[1]=y0*2;pts[2]=z0*2;
00260 pts[3]=x1*2;pts[4]=y1*2;pts[5]=z1*2;
00261 pts[6]=x2*2;pts[7]=y2*2;pts[8]=z2*2;
00262 pts[9]=x3*2;pts[10]=y3*2;pts[11]=z3*2;
00263 int *q=mep[3];
00264 q[0]=1;q[1]=3;q[2]=2;q[3]=0;q[4]=0;q[5]=0;q[6]=0;
00265 q[7]=0;q[8]=2;q[9]=3;q[10]=0;q[11]=2;q[12]=1;q[13]=1;
00266 q[14]=0;q[15]=3;q[16]=1;q[17]=2;q[18]=2;q[19]=1;q[20]=2;
00267 q[21]=0;q[22]=1;q[23]=2;q[24]=1;q[25]=2;q[26]=1;q[27]=3;
00268 ed[0]=q;ed[1]=q+7;ed[2]=q+14;ed[3]=q+21;
00269 neighbor.init_tetrahedron();
00270 nu[0]=nu[1]=nu[2]=nu[3]=3;
00271 }
00272
00273
00274
00275
00276
00277
00278 template<class n_option>
00279 inline void voronoicell_base<n_option>::init_test(int n) {
00280 for(int i=0;i<current_vertex_order;i++) mec[i]=0;up=p=0;
00281 switch(n) {
00282 case 0:
00283
00284
00285
00286 add_vertex(1,-2,-1,3,1,5);
00287 add_vertex(0,-1,1,5,0,2);
00288 add_vertex(0,1,0,1,3,6,4);
00289 add_vertex(1,4,-1,4,6,2,0);
00290 add_vertex(-1,4,-1,3,5,2,6);
00291 add_vertex(-1,-2,-1,4,0,1);
00292 add_vertex(0,3,0,4,2,3);
00293 break;
00294 case 1:
00295
00296
00297
00298 add_vertex(-2,2,-1,3,4,1);
00299 add_vertex(2,2,-1,0,5,2);
00300 add_vertex(2,-2,-1,1,6,3);
00301 add_vertex(-2,-2,-1,2,7,0);
00302 add_vertex(-1,1,0,0,7,5);
00303 add_vertex(1,1,1,1,4,6);
00304 add_vertex(1,-1,1,7,2,5);
00305 add_vertex(-1,-1,1,4,3,6);
00306 break;
00307 case 2:
00308
00309
00310
00311
00312 add_vertex(1,-2,-1,1,3,4);
00313 add_vertex(-1,-2,-1,2,0,4,5);
00314 add_vertex(-1,2,-1,1,6,3);
00315 add_vertex(1,2,-1,2,6,5,0);
00316 add_vertex(0,-1,1,5,1,0);
00317 add_vertex(0,0,0,1,4,3,6);
00318 add_vertex(0,1,1,2,5,3);
00319 break;
00320 case 3:
00321
00322
00323
00324 add_vertex(-1,-1,-1,4,3,1);
00325 add_vertex(1,-1,-1,0,2,5);
00326 add_vertex(1,1,-1,6,1,3);
00327 add_vertex(-1,1,-1,2,0,7);
00328 add_vertex(-1,-1,1,7,0,5,8);
00329 add_vertex(1,-1,1,4,1,6,8);
00330 add_vertex(1,1,1,5,2,7,8);
00331 add_vertex(-1,1,1,6,3,4,8);
00332 add_vertex(0,0,2,7,4,5,6);
00333 break;
00334 case 4:
00335
00336
00337
00338
00339
00340
00341 add_vertex(1,-3,-1,5,6,1);
00342 add_vertex(-1,-3,-1,0,6,2);
00343 add_vertex(-3,0,-1,1,7,8,3);
00344 add_vertex(-1,3,-1,2,9,4);
00345 add_vertex(1,3,-1,3,9,5);
00346 add_vertex(3,0,-1,4,8,7,0);
00347 add_vertex(0,-2,1,7,1,0);
00348 add_vertex(0,-1,0,8,2,6,5);
00349 add_vertex(0,1,0,9,2,7,5);
00350 add_vertex(0,2,1,3,8,4);
00351 break;
00352 case 5:
00353
00354
00355
00356
00357 add_vertex(-1,-3,-1,7,1,8,12);
00358 add_vertex(1,-3,-1,2,12,8,0);
00359 add_vertex(3,-1,-1,3,9,13,1);
00360 add_vertex(3,1,-1,4,13,9,2);
00361 add_vertex(1,3,-1,5,10,14,3);
00362 add_vertex(-1,3,-1,6,14,10,4);
00363 add_vertex(-3,1,-1,7,11,15,5);
00364 add_vertex(-3,-1,-1,0,15,11,6);
00365 add_vertex(0,-2,1,0,1,12);
00366 add_vertex(2,0,1,2,3,13);
00367 add_vertex(0,2,1,14,4,5);
00368 add_vertex(-2,0,1,7,15,6);
00369 add_vertex(0,-1,0.5,0,8,1,16);
00370 add_vertex(1,0,0.5,2,9,3,16);
00371 add_vertex(0,1,0.5,4,10,5,16);
00372 add_vertex(-1,0,0.5,6,11,7,16);
00373 add_vertex(0,0,0,15,12,13,14);
00374 break;
00375 case 6:
00376
00377
00378
00379
00380 add_vertex(-1,-3,-1,7,1,8,12);
00381 add_vertex(1,-3,-1,2,12,8,0);
00382 add_vertex(3,-1,-1,3,9,13,1);
00383 add_vertex(3,1,-1,4,13,9,2);
00384 add_vertex(1,3,-1,5,10,14,3);
00385 add_vertex(-1,3,-1,6,14,10,4);
00386 add_vertex(-3,1,-1,7,11,15,5);
00387 add_vertex(-3,-1,-1,0,15,11,6);
00388 add_vertex(0,-2,1,0,1,12);
00389 add_vertex(2,0,1,2,3,13);
00390 add_vertex(0,2,1,14,4,5);
00391 add_vertex(-2,0,1,7,15,6);
00392 add_vertex(0,-1,0,0,8,1,16);
00393 add_vertex(1,0,0,2,9,3,16);
00394 add_vertex(0,1,0,4,10,5,16);
00395 add_vertex(-1,0,0,6,11,7,16);
00396 add_vertex(0,0,0,15,12,13,14);
00397 break;
00398 case 7:
00399
00400
00401
00402 add_vertex(2,-3,-1,3,4,1);
00403 add_vertex(-2,-3,-1,0,4,2);
00404 add_vertex(-2,3,-1,1,7,3);
00405 add_vertex(2,3,-1,2,6,0);
00406 add_vertex(0,-2,0,0,5,1);
00407 add_vertex(0,1,0,4,6,7);
00408 add_vertex(1,2,1,7,5,3);
00409 add_vertex(-1,2,1,5,6,2);
00410 break;
00411 case 8:
00412
00413
00414 add_vertex(3,-2,-1,2,3,1);
00415 add_vertex(-3,-2,-1,0,4,2);
00416 add_vertex(0,4,-1,1,5,0);
00417 add_vertex(1.5,-1,0,7,0,6);
00418 add_vertex(-1.5,-1,0,1,7,8);
00419 add_vertex(0,2,0,8,6,2);
00420 add_vertex(0.75,0.5,0,9,3,5);
00421 add_vertex(0,-1,0,4,3,9);
00422 add_vertex(-0.75,0.5,0,4,9,5);
00423 add_vertex(0,0,1,8,7,6);
00424 break;
00425 case 9:
00426
00427
00428 add_vertex(0,0,0,3,1,2);
00429 add_vertex(1,0,1,3,2,0);
00430 add_vertex(1,1,0,3,0,1);
00431 add_vertex(2,0,0,6,4,2,1,0);
00432 add_vertex(3,1,0,3,6,8,5);
00433 add_vertex(3,2,0,4);
00434 add_vertex(4,0,0,4,3,7,8);
00435 add_vertex(5,0,0,6);
00436 add_vertex(4,1,0,6,4);
00437 }
00438
00439 construct_relations();
00440 neighbor.label_facets();
00441 }
00442
00443
00444
00445
00446
00447 template<class n_option>
00448 void voronoicell_base<n_option>::add_vertex(fpoint x,fpoint y,fpoint z,int a) {
00449 pts[3*p]=x;pts[3*p+1]=y;pts[3*p+2]=z;nu[p]=1;
00450 if (mem[1]==mec[1]) add_memory(1);
00451 neighbor.set_pointer(p,1);
00452 int *q=mep[1]+3*mec[1]++;ed[p]=q;
00453 q[0]=a;q[2]=p++;
00454 }
00455
00456
00457 template<class n_option>
00458 void voronoicell_base<n_option>::add_vertex(fpoint x,fpoint y,fpoint z,int a,int b) {
00459 pts[3*p]=x;pts[3*p+1]=y;pts[3*p+2]=z;nu[p]=2;
00460 if (mem[2]==mec[2]) add_memory(2);
00461 neighbor.set_pointer(p,2);
00462 int *q=mep[2]+5*mec[2]++;ed[p]=q;
00463 q[0]=a;q[1]=b;q[4]=p++;
00464 }
00465
00466
00467 template<class n_option>
00468 void voronoicell_base<n_option>::add_vertex(fpoint x,fpoint y,fpoint z,int a,int b,int c) {
00469 pts[3*p]=x;pts[3*p+1]=y;pts[3*p+2]=z;nu[p]=3;
00470 if (mem[3]==mec[3]) add_memory(3);
00471 neighbor.set_pointer(p,3);
00472 int *q=mep[3]+7*mec[3]++;ed[p]=q;
00473 q[0]=a;q[1]=b;q[2]=c;q[6]=p++;
00474 }
00475
00476
00477 template<class n_option>
00478 void voronoicell_base<n_option>::add_vertex(fpoint x,fpoint y,fpoint z,int a,int b,int c,int d) {
00479 pts[3*p]=x;pts[3*p+1]=y;pts[3*p+2]=z;nu[p]=4;
00480 if (mem[4]==mec[4]) add_memory(4);
00481 neighbor.set_pointer(p,4);
00482 int *q=mep[4]+9*mec[4]++;ed[p]=q;
00483 q[0]=a;q[1]=b;q[2]=c;q[3]=d;q[8]=p++;
00484 }
00485
00486
00487 template<class n_option>
00488 void voronoicell_base<n_option>::add_vertex(fpoint x,fpoint y,fpoint z,int a,int b,int c,int d,int e) {
00489 pts[3*p]=x;pts[3*p+1]=y;pts[3*p+2]=z;nu[p]=5;
00490 if (mem[5]==mec[5]) add_memory(5);
00491 neighbor.set_pointer(p,5);
00492 int *q=mep[5]+11*mec[5]++;ed[p]=q;
00493 q[0]=a;q[1]=b;q[2]=c;q[3]=d;q[4]=e;q[10]=p++;
00494 }
00495
00496
00497
00498
00499 template<class n_option>
00500 inline void voronoicell_base<n_option>::check_relations() {
00501 int i,j;
00502 for(i=0;i<p;i++) {
00503 for(j=0;j<nu[i];j++) {
00504 if (ed[ed[i][j]][ed[i][nu[i]+j]]!=i) cout << "Relational error at point " << i << ", edge " << j << "." << endl;
00505 }
00506 }
00507 }
00508
00509
00510
00511
00512
00513
00514 template<class n_option>
00515 inline void voronoicell_base<n_option>::check_duplicates() {
00516 int i,j,k;
00517 for(i=0;i<p;i++) {
00518 for(j=1;j<nu[i];j++) {
00519 for(k=0;k<j;k++) {
00520 if (ed[i][j]==ed[i][k]) cout << "Duplicate edges: (" << i << "," << j << ") and (" << i << "," << k << ") [" << ed[i][j] << "]" << endl;
00521 }
00522 }
00523 }
00524 }
00525
00526
00527 template<class n_option>
00528 inline void voronoicell_base<n_option>::construct_relations() {
00529 int i,j,k,l;
00530 for(i=0;i<p;i++) for(j=0;j<nu[i];j++) {
00531 k=ed[i][j];
00532 l=0;
00533 while(ed[k][l]!=i) {
00534 l++;
00535 if (l==nu[k]) voropp_fatal_error("Relation table construction failed",VOROPP_INTERNAL_ERROR);
00536 }
00537 ed[i][nu[i]+j]=l;
00538 }
00539 }
00540
00541
00542
00543
00544 template<class n_option>
00545 bool voronoicell_base<n_option>::nplane(fpoint x,fpoint y,fpoint z,fpoint rsq,int p_id) {
00546 int count=0,i,j,k,lp=up,cp,qp,rp,stack=0;stack2=0;
00547 int us=0,ls=0,qs,iqs,cs,uw,qw,lw;
00548 int *edp,*edd;
00549 fpoint u,l,r,q;bool complicated_setup=false,new_double_edge=false,double_edge=false;
00550
00551 sure.init(x,y,z,rsq);
00552
00553
00554
00555 uw=sure.test(up,u);
00556
00557
00558
00559
00560 try {
00561 if(uw==1) {
00562
00563 us=0;
00564 do {
00565 lp=ed[up][us];
00566 lw=sure.test(lp,l);
00567 if(l<u) break;
00568 us++;
00569 } while (us<nu[up]);
00570
00571 if(us==nu[up]) {
00572 return false;
00573 }
00574
00575 ls=ed[up][nu[up]+us];
00576 while(lw==1) {
00577 if(++count>=p) throw true;
00578 u=l;up=lp;
00579 for(us=0;us<ls;us++) {
00580 lp=ed[up][us];
00581 lw=sure.test(lp,l);
00582 if(l<u) break;
00583 }
00584 if(us==ls) {
00585 us++;
00586 while(us<nu[up]) {
00587 lp=ed[up][us];
00588 lw=sure.test(lp,l);
00589 if(l<u) break;
00590 us++;
00591 }
00592 if(us==nu[up]) {
00593 return false;
00594 }
00595 }
00596 ls=ed[up][nu[up]+us];
00597 }
00598
00599
00600
00601
00602 if (lw==0) {
00603 up=lp;
00604 complicated_setup=true;
00605 } else complicated_setup=false;
00606 } else if (uw==-1) {
00607 us=0;
00608 do {
00609 qp=ed[up][us];
00610 qw=sure.test(qp,q);
00611 if(u<q) break;
00612 us++;
00613 } while (us<nu[up]);
00614 if(us==nu[up]) return true;
00615
00616 while(qw==-1) {
00617 qs=ed[up][nu[up]+us];
00618 if(++count>=p) throw true;
00619 u=q;up=qp;
00620 for(us=0;us<qs;us++) {
00621 qp=ed[up][us];
00622 qw=sure.test(qp,q);
00623 if(u<q) break;
00624 }
00625 if(us==qs) {
00626 us++;
00627 while(us<nu[up]) {
00628 qp=ed[up][us];
00629 qw=sure.test(qp,q);
00630 if(u<q) break;
00631 us++;
00632 }
00633 if(us==nu[up]) return true;
00634 }
00635 }
00636 if (qw==1) {
00637 lp=up;ls=us;l=u;
00638 up=qp;us=ed[lp][nu[lp]+ls];u=q;
00639 complicated_setup=false;
00640 } else {
00641 up=qp;
00642 complicated_setup=true;
00643 }
00644 } else {
00645
00646
00647
00648
00649 complicated_setup=true;
00650 }
00651 }
00652 catch(bool except) {
00653
00654
00655
00656
00657 #if VOROPP_VERBOSE >=1
00658 cerr << "Bailed out of convex calculation\n";
00659 #endif
00660 qw=1;lw=0;
00661 for(qp=0;qp<p;qp++) {
00662 qw=sure.test(qp,q);
00663 if (qw==1) {
00664
00665
00666
00667 for(us=0;us<nu[qp];us++) {
00668 lp=ed[qp][us];
00669 if(lp<qp) {
00670 lw=sure.test(lp,l);
00671 if (lw!=1) break;
00672 }
00673 }
00674 if(us<nu[qp]) {
00675 up=qp;
00676 if(lw==0) {
00677 complicated_setup=true;
00678 } else {
00679 complicated_setup=false;
00680 u=q;
00681 ls=ed[up][nu[up]+us];
00682 }
00683 break;
00684 }
00685 } else if (qw==-1) {
00686
00687
00688
00689 for(ls=0;ls<nu[qp];ls++) {
00690 up=ed[qp][ls];
00691 if(up<qp) {
00692 uw=sure.test(up,u);
00693 if (uw!=-1) break;
00694 }
00695 }
00696 if(ls<nu[qp]) {
00697 if(uw==0) {
00698 up=qp;
00699 complicated_setup=true;
00700 } else {
00701 complicated_setup=false;
00702 lp=qp;l=q;
00703 us=ed[lp][nu[lp]+ls];
00704 }
00705 break;
00706 }
00707 } else {
00708
00709
00710
00711 up=qp;
00712 complicated_setup=true;
00713 break;
00714 }
00715 }
00716 if(qp==p) return qw==-1?true:false;
00717 }
00718
00719
00720
00721
00722 if(p==current_vertices) add_memory_vertices();
00723
00724 if (complicated_setup) {
00725
00726
00727
00728 pts[3*p]=pts[3*up];
00729 pts[3*p+1]=pts[3*up+1];
00730 pts[3*p+2]=pts[3*up+2];
00731
00732
00733
00734
00735 i=0;
00736 lp=ed[up][0];
00737 lw=sure.test(lp,l);
00738 if(lw!=-1) {
00739
00740
00741
00742
00743 rp=lw;
00744 do {
00745 i++;
00746
00747
00748
00749
00750
00751 if (i==nu[up]) return false;
00752 lp=ed[up][i];
00753 lw=sure.test(lp,l);
00754 } while (lw!=-1);
00755 j=i+1;
00756
00757
00758
00759
00760 while(j<nu[up]) {
00761 lp=ed[up][j];
00762 lw=sure.test(lp,l);
00763 if (lw!=-1) break;
00764 j++;
00765 }
00766
00767
00768
00769
00770
00771
00772
00773
00774 if(j==nu[up]&&i==1&&rp==0) {
00775 nu[p]=nu[up];
00776 double_edge=true;
00777 } else nu[p]=j-i+2;
00778 k=1;
00779
00780
00781
00782 while (nu[p]>=current_vertex_order) add_memory_vorder();
00783 if (mec[nu[p]]==mem[nu[p]]) add_memory(nu[p]);
00784 neighbor.set_pointer(p,nu[p]);
00785 ed[p]=mep[nu[p]]+(2*nu[p]+1)*mec[nu[p]]++;
00786 ed[p][2*nu[p]]=p;
00787
00788
00789
00790
00791 us=cycle_down(i,up);
00792 while(i<j) {
00793 qp=ed[up][i];
00794 qs=ed[up][nu[up]+i];
00795 neighbor.copy(p,k,up,i);
00796 ed[p][k]=qp;
00797 ed[p][nu[p]+k]=qs;
00798 ed[qp][qs]=p;
00799 ed[qp][nu[qp]+qs]=k;
00800 ed[up][i]=-1;
00801 i++;k++;
00802 }
00803 qs=i==nu[up]?0:i;
00804 } else {
00805
00806
00807
00808
00809 i=nu[up]-1;
00810 lp=ed[up][i];
00811 lw=sure.test(lp,l);
00812 while(lw==-1) {
00813 i--;
00814
00815
00816
00817
00818 if (i==0) return true;
00819 lp=ed[up][i];
00820 lw=sure.test(lp,l);
00821 }
00822
00823
00824 j=1;
00825 qp=ed[up][j];
00826 qw=sure.test(qp,q);
00827 while(qw==-1) {
00828 j++;
00829 qp=ed[up][j];
00830 qw=sure.test(qp,l);
00831 }
00832
00833
00834
00835
00836
00837
00838
00839
00840 if (i==j&&qw==0) {
00841 double_edge=true;
00842 nu[p]=nu[up];
00843 } else {
00844 nu[p]=nu[up]-i+j+1;
00845 }
00846
00847
00848
00849 k=1;
00850 while(nu[p]>=current_vertex_order) add_memory_vorder();
00851 if (mec[nu[p]]==mem[nu[p]]) add_memory(nu[p]);
00852
00853
00854
00855
00856 neighbor.set_pointer(p,nu[p]);
00857 ed[p]=mep[nu[p]]+(2*nu[p]+1)*mec[nu[p]]++;
00858 ed[p][2*nu[p]]=p;
00859 us=i++;
00860 while(i<nu[up]) {
00861 qp=ed[up][i];
00862 qs=ed[up][nu[up]+i];
00863 neighbor.copy(p,k,up,i);
00864 ed[p][k]=qp;
00865 ed[p][nu[p]+k]=qs;
00866 ed[qp][qs]=p;
00867 ed[qp][nu[qp]+qs]=k;
00868 ed[up][i]=-1;
00869 i++;k++;
00870 }
00871 i=0;
00872 while(i<j) {
00873 qp=ed[up][i];
00874 qs=ed[up][nu[up]+i];
00875 neighbor.copy(p,k,up,i);
00876 ed[p][k]=qp;
00877 ed[p][nu[p]+k]=qs;
00878 ed[qp][qs]=p;
00879 ed[qp][nu[qp]+qs]=k;
00880 ed[up][i]=-1;
00881 i++;k++;
00882 }
00883 qs=j;
00884 }
00885 if (!double_edge) {
00886 neighbor.copy(p,k,up,qs);
00887 neighbor.set(p,0,p_id);
00888 } else neighbor.copy(p,0,up,qs);
00889
00890
00891 if (stack2==current_delete2_size) add_memory_ds2();
00892 ds2[stack2++]=up;
00893
00894
00895
00896
00897
00898 cs=k;
00899 qp=up;q=u;
00900 i=ed[up][us];
00901 us=ed[up][nu[up]+us];
00902 up=i;
00903 ed[qp][2*nu[qp]]=-p;
00904
00905 } else {
00906
00907
00908
00909
00910
00911 if (stack==current_delete_size) add_memory_ds();
00912 ds[stack++]=up;
00913 r=1/(u-l);
00914 pts[3*p]=(pts[3*lp]*u-pts[3*up]*l)*r;
00915 pts[3*p+1]=(pts[3*lp+1]*u-pts[3*up+1]*l)*r;
00916 pts[3*p+2]=(pts[3*lp+2]*u-pts[3*up+2]*l)*r;
00917
00918
00919
00920 nu[p]=3;
00921 if (mec[3]==mem[3]) add_memory(3);
00922 neighbor.set_pointer(p,3);
00923 neighbor.set(p,0,p_id);
00924 neighbor.copy(p,1,up,us);
00925 neighbor.copy(p,2,lp,ls);
00926 ed[p]=mep[3]+7*mec[3]++;
00927 ed[p][6]=p;
00928 ed[up][us]=-1;
00929 ed[lp][ls]=p;
00930 ed[lp][nu[lp]+ls]=1;
00931 ed[p][1]=lp;
00932 ed[p][nu[p]+1]=ls;
00933 cs=2;
00934
00935
00936 qs=cycle_up(us,up);
00937 qp=up;q=u;
00938 }
00939
00940
00941
00942 cp=p;rp=p;p++;
00943 while(qp!=up||qs!=us) {
00944
00945
00946
00947
00948 lp=ed[qp][qs];
00949 lw=sure.test(lp,l);
00950
00951 if (lw==1) {
00952
00953
00954
00955 if (stack==current_delete_size) add_memory_ds();
00956 qs=cycle_up(ed[qp][nu[qp]+qs],lp);
00957 qp=lp;
00958 q=l;
00959 ds[stack++]=qp;
00960
00961 } else if (lw==-1) {
00962
00963
00964
00965
00966
00967
00968 if(p==current_vertices) add_memory_vertices();
00969 r=1/(q-l);
00970 pts[3*p]=(pts[3*lp]*q-pts[3*qp]*l)*r;
00971 pts[3*p+1]=(pts[3*lp+1]*q-pts[3*qp+1]*l)*r;
00972 pts[3*p+2]=(pts[3*lp+2]*q-pts[3*qp+2]*l)*r;
00973 nu[p]=3;
00974 if (mec[3]==mem[3]) add_memory(3);
00975 ls=ed[qp][qs+nu[qp]];
00976 neighbor.set_pointer(p,3);
00977 neighbor.set(p,0,p_id);
00978 neighbor.copy(p,1,qp,qs);
00979 neighbor.copy(p,2,lp,ls);
00980 ed[p]=mep[3]+7*mec[3]++;
00981 ed[p][6]=p;
00982 ed[lp][ls]=p;
00983 ed[lp][nu[lp]+ls]=1;
00984 ed[p][1]=lp;
00985 ed[p][0]=cp;
00986 ed[p][nu[p]+1]=ls;
00987 ed[p][nu[p]]=cs;
00988 ed[cp][cs]=p;
00989 ed[cp][nu[cp]+cs]=0;
00990 ed[qp][qs]=-1;
00991 qs=cycle_up(qs,qp);
00992 cp=p++;
00993 cs=2;
00994 } else {
00995
00996
00997
00998
00999
01000 if(p==current_vertices) add_memory_vertices();
01001
01002
01003
01004 k=double_edge?0:1;
01005 qs=ed[qp][nu[qp]+qs];
01006 qp=lp;
01007 iqs=qs;
01008
01009
01010
01011 do {
01012 k++;
01013 qs=cycle_up(qs,qp);
01014 lp=ed[qp][qs];
01015 lw=sure.test(lp,l);
01016 } while (lw==-1);
01017
01018
01019
01020
01021
01022
01023
01024 j=-ed[qp][2*nu[qp]];
01025 if(qp==up&&qs==us) {
01026
01027
01028
01029
01030 new_double_edge=false;
01031 if(j>0) k+=nu[j];
01032 } else {
01033 if (j>0) {
01034
01035
01036
01037
01038 k+=nu[j];
01039
01040
01041
01042
01043
01044
01045 if(lw==0) {
01046
01047
01048
01049 i=-ed[lp][2*nu[lp]];
01050 if(i>0) {
01051
01052
01053
01054 if(ed[i][nu[i]-1]==j) {
01055 new_double_edge=true;
01056 k-=1;
01057 } else new_double_edge=false;
01058 } else {
01059
01060
01061
01062
01063
01064
01065
01066 if (j==rp&&lp==up&&ed[qp][nu[qp]+qs]==us) {
01067 new_double_edge=true;
01068 k-=1;
01069 } else new_double_edge=false;
01070 }
01071 } else new_double_edge=false;
01072 } else {
01073
01074
01075
01076
01077 if(lw==0) {
01078
01079
01080
01081
01082
01083
01084 i=-ed[lp][2*nu[lp]];
01085 if(i==cp) {
01086 new_double_edge=true;
01087 k-=1;
01088 } else new_double_edge=false;
01089 } else new_double_edge=false;
01090 }
01091 }
01092
01093
01094
01095
01096 while(k>=current_vertex_order) add_memory_vorder();
01097 if (mec[k]==mem[k]) add_memory(k);
01098
01099
01100
01101 if(j>0) {
01102
01103
01104
01105
01106 if(nu[j]!=k) {
01107
01108
01109 neighbor.set_aux1(k);
01110 edp=mep[k]+(2*k+1)*mec[k]++;
01111 i=0;
01112 while(i<nu[j]) {
01113 neighbor.copy_aux1(j,i);
01114 edp[i]=ed[j][i];
01115 edp[k+i]=ed[j][nu[j]+i];
01116 i++;
01117 }
01118 edp[2*k]=j;
01119
01120
01121
01122
01123 edd=mep[nu[j]]+(2*nu[j]+1)*--mec[nu[j]];
01124 if(edd!=ed[j]) {
01125 for(lw=0;lw<=2*nu[j];lw++) ed[j][lw]=edd[lw];
01126 neighbor.set_aux2_copy(j,nu[j]);
01127 neighbor.copy_pointer(edd[2*nu[j]],j);
01128 ed[edd[2*nu[j]]]=ed[j];
01129 }
01130 neighbor.set_to_aux1(j);
01131 ed[j]=edp;
01132 } else i=nu[j];
01133 } else {
01134
01135
01136 neighbor.set_pointer(p,k);
01137 ed[p]=mep[k]+(2*k+1)*mec[k]++;
01138 ed[p][2*k]=p;
01139 if (stack2==current_delete2_size) add_memory_ds2();
01140 ds2[stack2++]=qp;
01141 pts[3*p]=pts[3*qp];
01142 pts[3*p+1]=pts[3*qp+1];
01143 pts[3*p+2]=pts[3*qp+2];
01144 ed[qp][2*nu[qp]]=-p;
01145 j=p++;
01146 i=0;
01147 }
01148 nu[j]=k;
01149
01150
01151
01152
01153 if (!double_edge) {
01154 ed[j][i]=cp;
01155 ed[j][nu[j]+i]=cs;
01156 neighbor.set(j,i,p_id);
01157 ed[cp][cs]=j;
01158 ed[cp][nu[cp]+cs]=i;
01159 i++;
01160 }
01161
01162
01163
01164 qs=iqs;
01165 while(i<(new_double_edge?k:k-1)) {
01166 qs=cycle_up(qs,qp);
01167 lp=ed[qp][qs];ls=ed[qp][nu[qp]+qs];
01168 neighbor.copy(j,i,qp,qs);
01169 ed[j][i]=lp;
01170 ed[j][nu[j]+i]=ls;
01171 ed[lp][ls]=j;
01172 ed[lp][nu[lp]+ls]=i;
01173 ed[qp][qs]=-1;
01174 i++;
01175 }
01176 qs=cycle_up(qs,qp);
01177 cs=i;
01178 cp=j;
01179 neighbor.copy(j,new_double_edge?0:cs,qp,qs);
01180
01181
01182
01183 double_edge=new_double_edge;
01184 }
01185 }
01186
01187
01188 ed[cp][cs]=rp;
01189 ed[rp][0]=cp;
01190 ed[cp][nu[cp]+cs]=0;
01191 ed[rp][nu[rp]+0]=cs;
01192
01193
01194 i=0;
01195 while(i<stack) {
01196 j=ds[i];
01197 if(ed[j][nu[j]]!=-1) {
01198 ed[j][nu[j]]=-1;
01199 i++;
01200 } else ds[i]=ds[--stack];
01201 }
01202
01203
01204
01205 for(i=0;i<stack2;i++) {
01206 j=ds2[i];
01207 ed[j][2*nu[j]]=j;
01208 if(ed[j][nu[j]]!=-1) {
01209 ed[j][nu[j]]=-1;
01210 if (stack==current_delete_size) add_memory_ds();
01211 ds[stack++]=j;
01212 }
01213 }
01214
01215
01216 for(i=0;i<stack;i++) {
01217 cp=ds[i];
01218 for(j=0;j<nu[cp];j++) {
01219 qp=ed[cp][j];
01220 if(qp!=-1) {
01221 if (ed[qp][nu[qp]]!=-1) {
01222 if (stack==current_delete_size) add_memory_ds();
01223 ds[stack++]=qp;
01224 ed[qp][nu[qp]]=-1;
01225 }
01226 }
01227 }
01228 }
01229 up=0;
01230
01231
01232 while(stack>0) {
01233 while(ed[--p][nu[p]]==-1) {
01234 j=nu[p];
01235 mec[j]--;
01236 for(i=0;i<=2*j;i++) ed[p][i]=(mep[j]+(2*j+1)*mec[j])[i];
01237 neighbor.set_aux2_copy(p,j);
01238 neighbor.copy_pointer(ed[p][2*j],p);
01239 ed[ed[p][2*j]]=ed[p];
01240 }
01241 up=ds[--stack];
01242 if (up<p) {
01243
01244
01245 pts[3*up]=pts[3*p];
01246 pts[3*up+1]=pts[3*p+1];
01247 pts[3*up+2]=pts[3*p+2];
01248
01249
01250 j=nu[up];
01251 mec[j]--;
01252 for(i=0;i<=2*j;i++) ed[up][i]=(mep[j]+(2*j+1)*mec[j])[i];
01253 neighbor.set_aux2_copy(up,j);
01254 neighbor.copy_pointer(ed[up][2*j],up);
01255 neighbor.copy_pointer(up,p);
01256 ed[ed[up][2*j]]=ed[up];
01257
01258
01259 ed[up]=ed[p];
01260 nu[up]=nu[p];
01261 for(i=0;i<nu[up];i++) {
01262 if (ed[up][i]==-1)
01263 voropp_fatal_error("Dangling edge found",VOROPP_INTERNAL_ERROR);
01264 ed[ed[up][i]][ed[up][nu[up]+i]]=up;
01265 }
01266 ed[up][2*nu[up]]=up;
01267 } else up=p++;
01268 }
01269
01270
01271 if (mec[0]>0) voropp_fatal_error("Zero order vertex formed",VOROPP_INTERNAL_ERROR);
01272
01273
01274 return collapse_order2();
01275 }
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287 template<class n_option>
01288 inline bool voronoicell_base<n_option>::collapse_order2() {
01289 if(!collapse_order1()) return false;
01290 int a,b,i,j,k,l;
01291 while(mec[2]>0) {
01292
01293
01294 i=--mec[2];
01295 j=mep[2][5*i];k=mep[2][5*i+1];
01296 if (j==k) {
01297 #if VOROPP_VERBOSE >=1
01298 cerr << "Order two vertex joins itself" << endl;
01299 #endif
01300 return false;
01301 }
01302
01303
01304 for(l=0;l<nu[j];l++) {
01305 if(ed[j][l]==k) break;
01306 }
01307
01308
01309
01310
01311 a=mep[2][5*i+2];b=mep[2][5*i+3];i=mep[2][5*i+4];
01312 if(l==nu[j]) {
01313 ed[j][a]=k;
01314 ed[k][b]=j;
01315 ed[j][nu[j]+a]=b;
01316 ed[k][nu[k]+b]=a;
01317 } else {
01318 if (!delete_connection(j,a,false)) return false;
01319 if (!delete_connection(k,b,true)) return false;
01320 }
01321
01322
01323 --p;
01324 if(up==i) up=0;
01325 if(p!=i) {
01326 if (up==p) up=i;
01327 pts[3*i]=pts[3*p];
01328 pts[3*i+1]=pts[3*p+1];
01329 pts[3*i+2]=pts[3*p+2];
01330 for(k=0;k<nu[p];k++) ed[ed[p][k]][ed[p][nu[p]+k]]=i;
01331 neighbor.copy_pointer(i,p);
01332 ed[i]=ed[p];
01333 nu[i]=nu[p];
01334 ed[i][2*nu[i]]=i;
01335 }
01336
01337
01338 if(!collapse_order1()) return false;
01339 }
01340 return true;
01341 }
01342
01343
01344
01345
01346
01347
01348 template<class n_option>
01349 inline bool voronoicell_base<n_option>::collapse_order1() {
01350 int i,j,k;
01351 while(mec[1]>0) {
01352 up=0;
01353 #if VOROPP_VERBOSE >=1
01354 cerr << "Order one collapse" << endl;
01355 #endif
01356 i=--mec[1];
01357 j=mep[1][3*i];k=mep[1][3*i+1];
01358 i=mep[1][3*i+2];
01359 if(!delete_connection(j,k,false)) return false;
01360 --p;
01361 if(up==i) up=0;
01362 if(p!=i) {
01363 if (up==p) up=i;
01364 pts[3*i]=pts[3*p];
01365 pts[3*i+1]=pts[3*p+1];
01366 pts[3*i+2]=pts[3*p+2];
01367 for(k=0;k<nu[p];k++) ed[ed[p][k]][ed[p][nu[p]+k]]=i;
01368 neighbor.copy_pointer(i,p);
01369 ed[i]=ed[p];
01370 nu[i]=nu[p];
01371 ed[i][2*nu[i]]=i;
01372 }
01373 }
01374 return true;
01375 }
01376
01377
01378
01379
01380
01381
01382
01383 template<class n_option>
01384 inline bool voronoicell_base<n_option>::delete_connection(int j,int k,bool hand) {
01385 int q=hand?k:cycle_up(k,j);
01386 int i=nu[j]-1,l,*edp,*edd,m;
01387 if(i<1) {
01388 cout << "Zero order vertex formed" << endl;
01389 return false;
01390 }
01391 if(mec[i]==mem[i]) add_memory(i);
01392 neighbor.set_aux1(i);
01393 for(l=0;l<q;l++) neighbor.copy_aux1(j,l);
01394 while(l<i) {
01395 neighbor.copy_aux1_shift(j,l);
01396 l++;
01397 }
01398 edp=mep[i]+(2*i+1)*mec[i]++;
01399 edp[2*i]=j;
01400 for(l=0;l<k;l++) {
01401 edp[l]=ed[j][l];
01402 edp[l+i]=ed[j][l+nu[j]];
01403 }
01404 while(l<i) {
01405 m=ed[j][l+1];
01406 edp[l]=m;
01407 k=ed[j][l+nu[j]+1];
01408 edp[l+i]=k;
01409 ed[m][nu[m]+k]--;
01410 l++;
01411 }
01412
01413 edd=mep[nu[j]]+(2*nu[j]+1)*--mec[nu[j]];
01414 for(l=0;l<=2*nu[j];l++) ed[j][l]=edd[l];
01415 neighbor.set_aux2_copy(j,nu[j]);
01416 neighbor.set_to_aux2(edd[2*nu[j]]);
01417 neighbor.set_to_aux1(j);
01418 ed[edd[2*nu[j]]]=edd;
01419 ed[j]=edp;
01420 nu[j]=i;
01421 return true;
01422 }
01423
01424
01425
01426
01427
01428
01429 template<class n_option>
01430 inline bool voronoicell_base<n_option>::plane(fpoint x,fpoint y,fpoint z) {
01431 fpoint rsq=x*x+y*y+z*z;
01432 return nplane(x,y,z,rsq,0);
01433 }
01434
01435
01436
01437
01438
01439 template<class n_option>
01440 inline bool voronoicell_base<n_option>::plane(fpoint x,fpoint y,fpoint z,fpoint rsq) {
01441 return nplane(x,y,z,rsq,0);
01442 }
01443
01444
01445
01446
01447
01448 template<class n_option>
01449 inline bool voronoicell_base<n_option>::nplane(fpoint x,fpoint y,fpoint z,int p_id) {
01450 fpoint rsq=x*x+y*y+z*z;
01451 return nplane(x,y,z,rsq,p_id);
01452 }
01453
01454
01455
01456
01457
01458
01459 template<class n_option>
01460 inline int voronoicell_base<n_option>::cycle_up(int a,int p) {
01461 return a==nu[p]-1?0:a+1;
01462 }
01463
01464
01465
01466
01467
01468
01469 template<class n_option>
01470 inline int voronoicell_base<n_option>::cycle_down(int a,int p) {
01471 return a==0?nu[p]-1:a-1;
01472 }
01473
01474
01475
01476
01477
01478 template<class n_option>
01479 fpoint voronoicell_base<n_option>::volume() {
01480 const fpoint fe=1/48.0;
01481 fpoint vol=0;
01482 int i,j,k,l,m,n;
01483 fpoint ux,uy,uz,vx,vy,vz,wx,wy,wz;
01484 for(i=1;i<p;i++) {
01485 ux=pts[0]-pts[3*i];
01486 uy=pts[1]-pts[3*i+1];
01487 uz=pts[2]-pts[3*i+2];
01488 for(j=0;j<nu[i];j++) {
01489 k=ed[i][j];
01490 if (k>=0) {
01491 ed[i][j]=-1-k;
01492 l=cycle_up(ed[i][nu[i]+j],k);
01493 vx=pts[3*k]-pts[0];
01494 vy=pts[3*k+1]-pts[1];
01495 vz=pts[3*k+2]-pts[2];
01496 m=ed[k][l];ed[k][l]=-1-m;
01497 while(m!=i) {
01498 n=cycle_up(ed[k][nu[k]+l],m);
01499 wx=pts[3*m]-pts[0];
01500 wy=pts[3*m+1]-pts[1];
01501 wz=pts[3*m+2]-pts[2];
01502 vol+=ux*vy*wz+uy*vz*wx+uz*vx*wy-uz*vy*wx-uy*vx*wz-ux*vz*wy;
01503 k=m;l=n;vx=wx;vy=wy;vz=wz;
01504 m=ed[k][l];ed[k][l]=-1-m;
01505 }
01506 }
01507 }
01508 }
01509 reset_edges();
01510 return vol*fe;
01511 }
01512
01513
01514
01515
01516
01517 template<class n_option>
01518 fpoint voronoicell_base<n_option>::maxradsq() {
01519 int i;fpoint r,s;
01520 r=pts[0]*pts[0]+pts[1]*pts[1]+pts[2]*pts[2];
01521 for(i=3;i<3*p;i+=3) {
01522 s=pts[i]*pts[i]+pts[i+1]*pts[i+1]+pts[i+2]*pts[i+2];
01523 if(s>r) r=s;
01524 }
01525 return r;
01526 }
01527
01528
01529
01530
01531
01532 template<class n_option>
01533 void voronoicell_base<n_option>::draw_pov(ostream &os,fpoint x,fpoint y,fpoint z) {
01534 int i,j,k;fpoint ux,uy,uz;
01535 for(i=0;i<p;i++) {
01536 ux=x+0.5*pts[3*i];uy=y+0.5*pts[3*i+1];uz=z+0.5*pts[3*i+2];
01537 os << "sphere{<" << ux << "," << uy << "," << uz << ">,r}\n";
01538 for(j=0;j<nu[i];j++) {
01539 k=ed[i][j];
01540 if (k<i) os << "cylinder{<" << ux << "," << uy << "," << uz << ">,<" << x+0.5*pts[3*k] << "," << y+0.5*pts[3*k+1] << "," << z+0.5*pts[3*k+2] << ">,r}\n";
01541 }
01542 }
01543 }
01544
01545
01546
01547
01548
01549
01550 template<class n_option>
01551 inline void voronoicell_base<n_option>::draw_pov(const char *filename,fpoint x,fpoint y,fpoint z) {
01552 ofstream os;
01553 os.open(filename,ofstream::out|ofstream::trunc);
01554 draw_pov(os,x,y,z);
01555 os.close();
01556 }
01557
01558
01559
01560
01561
01562 template<class n_option>
01563 inline void voronoicell_base<n_option>::draw_pov(fpoint x,fpoint y,fpoint z) {
01564 draw_pov(cout,x,y,z);
01565 }
01566
01567
01568
01569
01570
01571 template<class n_option>
01572 void voronoicell_base<n_option>::draw_gnuplot(ostream &os,fpoint x,fpoint y,fpoint z) {
01573 int i,j,k;fpoint ux,uy,uz;
01574 for(i=0;i<p;i++) {
01575 ux=x+0.5*pts[3*i];uy=y+0.5*pts[3*i+1];uz=z+0.5*pts[3*i+2];
01576 for(j=0;j<nu[i];j++) {
01577 k=ed[i][j];
01578 if (ed[i][j]<i) os << ux << " " << uy << " " << uz << "\n" << x+0.5*pts[3*k] << " " << y+0.5*pts[3*k+1] << " " << z+0.5*pts[3*k+2] << "\n\n\n";
01579 }
01580 }
01581 }
01582
01583
01584
01585
01586
01587
01588 template<class n_option>
01589 inline void voronoicell_base<n_option>::draw_gnuplot(const char *filename,fpoint x,fpoint y,fpoint z) {
01590 ofstream os;
01591 os.open(filename,ofstream::out|ofstream::trunc);
01592 draw_gnuplot(os,x,y,z);
01593 os.close();
01594 }
01595
01596
01597
01598
01599
01600 template<class n_option>
01601 inline void voronoicell_base<n_option>::draw_gnuplot(fpoint x,fpoint y,fpoint z) {
01602 draw_gnuplot(cout,x,y,z);
01603 }
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614 template<class n_option>
01615 inline void voronoicell_base<n_option>::draw_pov_mesh(ostream &os,fpoint x,fpoint y,fpoint z) {
01616 int i,j,k,l,m,n;
01617 os << "mesh2 {\nvertex_vectors {\n" << p << ",\n";
01618 for(i=0;i<p;i++) {
01619 os << "<" << x+0.5*pts[3*i] << "," << y+0.5*pts[3*i+1] << "," << z+0.5*pts[3*i+2] << ">,\n";
01620 }
01621 os << "}\nface_indices {\n" << 2*(p-2) << ",\n";
01622 for(i=1;i<p;i++) {
01623 for(j=0;j<nu[i];j++) {
01624 k=ed[i][j];
01625 if (k>=0) {
01626 ed[i][j]=-1-k;
01627 l=cycle_up(ed[i][nu[i]+j],k);
01628 m=ed[k][l];ed[k][l]=-1-m;
01629 while(m!=i) {
01630 n=cycle_up(ed[k][nu[k]+l],m);
01631 os << "<" << i << "," << k << "," << m << ">\n";
01632 k=m;l=n;
01633 m=ed[k][l];ed[k][l]=-1-m;
01634 }
01635 }
01636 }
01637 }
01638 reset_edges();
01639 os << "}\ninside_vector <0,0,1>\n}\n";
01640 }
01641
01642
01643
01644
01645
01646
01647
01648 template<class n_option>
01649 inline void voronoicell_base<n_option>::reset_edges() {
01650 int i,j;
01651 for(i=0;i<p;i++) {
01652 for(j=0;j<nu[i];j++) {
01653 if(ed[i][j]>=0) voropp_fatal_error("Edge reset routine found a previously untested edge",VOROPP_INTERNAL_ERROR);
01654 ed[i][j]=-1-ed[i][j];
01655 }
01656 }
01657 }
01658
01659
01660
01661
01662
01663
01664 template<class n_option>
01665 inline void voronoicell_base<n_option>::draw_pov_mesh(const char *filename,fpoint x,fpoint y,fpoint z) {
01666 ofstream os;
01667 os.open(filename,ofstream::out|ofstream::trunc);
01668 draw_pov_mesh(os,x,y,z);
01669 os.close();
01670 }
01671
01672
01673
01674
01675
01676 template<class n_option>
01677 inline void voronoicell_base<n_option>::draw_pov_mesh(fpoint x,fpoint y,fpoint z) {
01678 draw_pov_mesh(cout,x,y,z);
01679 }
01680
01681
01682 template<class n_option>
01683 inline void voronoicell_base<n_option>::perturb(fpoint r) {
01684 for(int i=0;i<3*p;i++) {
01685 pts[i]+=(2*fpoint(rand())/RAND_MAX-1)*r;
01686 }
01687 }
01688
01689
01690 suretest::suretest() : current_marginal(init_marginal) {
01691 sn=new int[2*current_marginal];
01692 }
01693
01694
01695 suretest::~suretest() {
01696 delete [] sn;
01697 }
01698
01699
01700
01701 inline void suretest::init(fpoint x,fpoint y,fpoint z,fpoint rsq) {
01702 sc=0;px=x;py=y;pz=z;prsq=rsq;
01703 }
01704
01705
01706 inline int suretest::test(int n,fpoint &ans) {
01707 ans=px*p[3*n]+py*p[3*n+1]+pz*p[3*n+2]-prsq;
01708 if(ans<-tolerance2) {
01709 return -1;
01710 } else if(ans>tolerance2) {
01711 return 1;
01712 }
01713 return check_marginal(n,ans);
01714 }
01715
01716 int suretest::check_marginal(int n,fpoint &ans) {
01717 int i;
01718 for(i=0;i<sc;i+=2) if(sn[i]==n) return sn[i+1];
01719 if (sc==2*current_marginal) {
01720 i=2*current_marginal;
01721 if (i>max_marginal) voropp_fatal_error("Marginal case buffer allocation exceeded absolute maximum",VOROPP_MEMORY_ERROR);
01722 #if VOROPP_VERBOSE >=2
01723 cerr << "Marginal cases buffer scaled up to " << i << endl;
01724 #endif
01725 int *psn=new int[2*i];
01726 for(int j=0;j<2*current_marginal;j++) psn[j]=sn[j];
01727 delete [] sn;sn=psn;
01728 }
01729 sn[sc++]=n;
01730 sn[sc++]=ans>tolerance?1:(ans<-tolerance?-1:0);
01731 return sn[sc-1];
01732 }
01733
01734
01735
01736 template<class n_option>
01737 void voronoicell_base<n_option>::print_edges() {
01738 int j;
01739 for(int i=0;i<p;i++) {
01740 cout << i << " " << nu[i] << " ";
01741 for(j=0;j<nu[i];j++) cout << " " << ed[i][j];
01742 cout << " ";
01743 while(j<2*nu[i]) cout << " " << ed[i][j++];
01744 cout << " " << ed[i][j];
01745 neighbor.print_edges(i);
01746 cout << " " << pts[3*i] << " " << pts[3*i+1] << " " << pts[3*i+2];
01747 cout << " " << ed[i];
01748 if (ed[i]>=mep[nu[i]]+mec[nu[i]]*(2*nu[i]+1)) cout << " Memory error";
01749 cout << endl;
01750 }
01751 }
01752
01753
01754
01755 template<class n_option>
01756 void voronoicell_base<n_option>::facets(ostream &os) {
01757 int i,j,k,l,m;
01758 for(i=0;i<p;i++) {
01759 for(j=0;j<nu[i];j++) {
01760 k=ed[i][j];
01761 if (k>=0) {
01762 neighbor.print(os,i,j);
01763 ed[i][j]=-1-k;
01764 l=cycle_up(ed[i][nu[i]+j],k);
01765 do {
01766 os << " ";
01767 neighbor.print(os,k,l);
01768 m=ed[k][l];
01769 ed[k][l]=-1-m;
01770 l=cycle_up(ed[k][nu[k]+l],m);
01771 k=m;
01772 } while (k!=i);
01773 os << endl;
01774 }
01775 }
01776 }
01777 reset_edges();
01778 }
01779
01780
01781
01782 template<class n_option>
01783 int voronoicell_base<n_option>::number_of_faces() {
01784 int i,j,k,l,m,s=0;
01785 for(i=0;i<p;i++) {
01786 for(j=0;j<nu[i];j++) {
01787 k=ed[i][j];
01788 if (k>=0) {
01789 s++;
01790 ed[i][j]=-1-k;
01791 l=cycle_up(ed[i][nu[i]+j],k);
01792 do {
01793 m=ed[k][l];
01794 ed[k][l]=-1-m;
01795 l=cycle_up(ed[k][nu[k]+l],m);
01796 k=m;
01797 } while (k!=i);
01798 }
01799 }
01800 }
01801 reset_edges();
01802 return s;
01803 }
01804
01805
01806
01807
01808
01809
01810 void neighbor_none::print(ostream &os,int i,int j) {
01811 os << i;
01812 }
01813
01814
01815
01816 template<class n_option>
01817 inline void voronoicell_base<n_option>::facets() {
01818 facets(cout);
01819 }
01820
01821
01822
01823 template<class n_option>
01824 inline void voronoicell_base<n_option>::facets(const char *filename) {
01825 ofstream os;
01826 os.open(filename,ofstream::out|ofstream::trunc);
01827 facets(os);
01828 os.close();
01829 }
01830
01831
01832
01833
01834 template<class n_option>
01835 void voronoicell_base<n_option>::facet_statistics(ostream &os) {
01836 int *stat,*pstat,current_facet_size=init_facet_size,newc,maxf=0;
01837 stat=new int[current_facet_size];
01838 int i,j,k,l,m,q;
01839 for(i=0;i<current_facet_size;i++) stat[i]=0;
01840 for(i=0;i<p;i++) {
01841 for(j=0;j<nu[i];j++) {
01842 k=ed[i][j];
01843 if (k>=0) {
01844 q=1;
01845 ed[i][j]=-1-k;
01846 l=cycle_up(ed[i][nu[i]+j],k);
01847 do {
01848 q++;
01849 m=ed[k][l];
01850 ed[k][l]=-1-m;
01851 l=cycle_up(ed[k][nu[k]+l],m);
01852 k=m;
01853 } while (k!=i);
01854 if (q>=current_facet_size) {
01855 newc=current_facet_size*2;
01856 pstat=new int[newc];
01857 for(k=0;k<current_facet_size;k++) pstat[k]=stat[k];
01858 while(k<newc) pstat[k]=0;
01859 delete [] stat;
01860 current_facet_size=newc;
01861 stat=pstat;
01862 }
01863 stat[q]++;
01864 if (q>maxf) maxf=q;
01865 }
01866 }
01867 }
01868 reset_edges();
01869 for(i=0;i<=maxf;i++) os << i << " " << stat[i] << endl;
01870 delete [] stat;
01871 }
01872
01873
01874
01875 template<class n_option>
01876 inline void voronoicell_base<n_option>::facet_statistics() {
01877 facet_statistics(cout);
01878 }
01879
01880
01881
01882
01883 template<class n_option>
01884 inline void voronoicell_base<n_option>::facet_statistics(const char *filename) {
01885 ofstream os;
01886 os.open(filename,ofstream::out|ofstream::trunc);
01887 facet_statistics(os);
01888 os.close();
01889 }
01890
01891
01892
01893
01894 template<class n_option>
01895 void voronoicell_base<n_option>::label_facets() {
01896 neighbor.label_facets();
01897 }
01898
01899
01900
01901
01902
01903 template<class n_option>
01904 void voronoicell_base<n_option>::neighbors(ostream &os) {
01905 neighbor.neighbors(os);
01906 }
01907
01908
01909
01910
01911
01912
01913 template<class n_option>
01914 void voronoicell_base<n_option>::check_facets() {
01915 neighbor.check_facets();
01916 }
01917
01918
01919
01920
01921
01922
01923
01924 template<class n_option>
01925 bool voronoicell_base<n_option>::plane_intersects(fpoint x,fpoint y,fpoint z,fpoint rsq) {
01926 fpoint g=x*pts[3*up]+y*pts[3*up+1]+z*pts[3*up+2];
01927 if (g<rsq) return plane_intersects_track(x,y,z,rsq,g);
01928 return true;
01929 }
01930
01931
01932
01933
01934
01935
01936
01937
01938 template<class n_option>
01939 bool voronoicell_base<n_option>::plane_intersects_guess(fpoint x,fpoint y,fpoint z,fpoint rsq) {
01940 up=0;
01941 fpoint g=x*pts[3*up]+y*pts[3*up+1]+z*pts[3*up+2];
01942 if (g<rsq) {
01943 int ca=1,cc=p>>3,mp=1;
01944 fpoint m;
01945 while(ca<cc) {
01946 m=x*pts[3*mp]+y*pts[3*mp+1]+z*pts[3*mp+2];
01947 if (m>g) {
01948 if (m>rsq) return true;
01949 g=m;up=mp;
01950 }
01951 ca+=mp++;
01952 }
01953 return plane_intersects_track(x,y,z,rsq,g);
01954 }
01955 return true;
01956 }
01957
01958
01959
01960
01961
01962
01963
01964
01965 template<class n_option>
01966 inline bool voronoicell_base<n_option>::plane_intersects_track(fpoint x,fpoint y,fpoint z,fpoint rsq,fpoint g) {
01967 int count=0,ls,us,tp;
01968 fpoint t;
01969
01970 for(us=0;us<nu[up];us++) {
01971 tp=ed[up][us];
01972 t=x*pts[3*tp]+y*pts[3*tp+1]+z*pts[3*tp+2];
01973 if(t>g) {
01974 ls=ed[up][nu[up]+us];
01975 up=tp;
01976 while (t<rsq) {
01977 if (++count>=p) {
01978 #if VOROPP_VERBOSE >=1
01979 cerr << "Bailed out of convex calculation" << endl;
01980 #endif
01981 for(tp=0;tp<p;tp++) if (x*pts[3*tp]+y*pts[3*tp+1]+z*pts[3*tp+2]>rsq) return true;
01982 return false;
01983 }
01984
01985
01986
01987
01988 for(us=0;us<ls;us++) {
01989 tp=ed[up][us];
01990 g=x*pts[3*tp]+y*pts[3*tp+1]+z*pts[3*tp+2];
01991 if(g>t) break;
01992 }
01993 if (us==ls) {
01994 us++;
01995 while(us<nu[up]) {
01996 tp=ed[up][us];
01997 g=x*pts[3*tp]+y*pts[3*tp+1]+z*pts[3*tp+2];
01998 if(g>t) break;
01999 us++;
02000 }
02001 if (us==nu[up]) return false;
02002 }
02003 ls=ed[up][nu[up]+us];up=tp;t=g;
02004 }
02005 return true;
02006 }
02007 }
02008 return false;
02009 }
02010
02011
02012
02013
02014 neighbor_track::neighbor_track(voronoicell_base<neighbor_track> *ivc) : vc(ivc) {
02015 int i;
02016 mne=new int*[vc->current_vertex_order];
02017 ne=new int*[vc->current_vertices];
02018 for(i=0;i<3;i++) mne[i]=new int[init_n_vertices*i];
02019 mne[3]=new int[init_3_vertices*3];
02020 for(i=4;i<vc->current_vertex_order;i++) mne[i]=new int[init_n_vertices*i];
02021 }
02022
02023
02024
02025 neighbor_track::~neighbor_track() {
02026 for(int i=0;i<vc->current_vertex_order;i++) if (vc->mem[i]>0) delete [] mne[i];
02027 delete [] mne;
02028 delete [] ne;
02029 }
02030
02031
02032
02033
02034 inline void neighbor_track::allocate(int i,int m) {
02035 mne[i]=new int[m*i];
02036 }
02037
02038
02039
02040 inline void neighbor_track::add_memory_vertices(int i) {
02041 int **pp;
02042 pp=new int*[i];
02043 for(int j=0;j<vc->current_vertices;j++) pp[j]=ne[j];
02044 delete [] ne;ne=pp;
02045 }
02046
02047
02048
02049 inline void neighbor_track::add_memory_vorder(int i) {
02050 int **p2;
02051 p2=new int*[i];
02052 for(int j=0;j<vc->current_vertex_order;j++) p2[j]=mne[j];
02053 delete [] mne;mne=p2;
02054 }
02055
02056
02057
02058
02059 inline void neighbor_track::init() {
02060 int *q;
02061 q=mne[3];
02062 q[0]=-5;q[1]=-3;q[2]=-1;
02063 q[3]=-5;q[4]=-2;q[5]=-3;
02064 q[6]=-5;q[7]=-1;q[8]=-4;
02065 q[9]=-5;q[10]=-4;q[11]=-2;
02066 q[12]=-6;q[13]=-1;q[14]=-3;
02067 q[15]=-6;q[16]=-3;q[17]=-2;
02068 q[18]=-6;q[19]=-4;q[20]=-1;
02069 q[21]=-6;q[22]=-2;q[23]=-4;
02070 ne[0]=q;ne[1]=q+3;ne[2]=q+6;ne[3]=q+9;
02071 ne[4]=q+12;ne[5]=q+15;ne[6]=q+18;ne[7]=q+21;
02072 }
02073
02074
02075
02076 inline void neighbor_track::init_octahedron() {
02077 int *q;
02078 q=mne[4];
02079 q[0]=-5;q[1]=-6;q[2]=-7;q[3]=-8;
02080 q[4]=-1;q[5]=-2;q[6]=-3;q[7]=-4;
02081 q[8]=-6;q[9]=-5;q[10]=-2;q[11]=-1;
02082 q[12]=-8;q[13]=-7;q[14]=-4;q[15]=-3;
02083 q[16]=-5;q[17]=-8;q[18]=-3;q[19]=-2;
02084 q[20]=-7;q[21]=-6;q[22]=-1;q[23]=-4;
02085 ne[0]=q;ne[1]=q+4;ne[2]=q+8;ne[3]=q+12;ne[4]=q+16;ne[5]=q+20;
02086 }
02087
02088
02089
02090 inline void neighbor_track::init_tetrahedron() {
02091 int *q;
02092 q=mne[3];
02093 q[0]=-4;q[1]=-3;q[2]=-2;
02094 q[3]=-3;q[4]=-4;q[5]=-1;
02095 q[6]=-4;q[7]=-2;q[8]=-1;
02096 q[9]=-2;q[10]=-3;q[11]=-1;
02097 ne[0]=q;ne[1]=q+3;ne[2]=q+6;ne[3]=q+9;
02098 }
02099
02100
02101
02102
02103 inline void neighbor_track::set_pointer(int p,int n) {
02104 ne[p]=mne[n]+n*vc->mec[n];
02105 }
02106
02107
02108 inline void neighbor_track::copy(int a,int b,int c,int d) {
02109 ne[a][b]=ne[c][d];
02110 }
02111
02112
02113 inline void neighbor_track::set(int a,int b,int c) {
02114 ne[a][b]=c;
02115 }
02116
02117
02118
02119
02120 inline void neighbor_track::set_aux1(int k) {
02121 paux1=mne[k]+k*vc->mec[k];
02122 }
02123
02124
02125 inline void neighbor_track::copy_aux1(int a,int b) {
02126 paux1[b]=ne[a][b];
02127 }
02128
02129
02130
02131 inline void neighbor_track::copy_aux1_shift(int a,int b) {
02132 paux1[b]=ne[a][b+1];
02133 }
02134
02135
02136
02137 inline void neighbor_track::set_aux2_copy(int a,int b) {
02138 paux2=mne[b]+b*vc->mec[b];
02139 for(int i=0;i<b;i++) ne[a][i]=paux2[i];
02140 }
02141
02142
02143 inline void neighbor_track::copy_pointer(int a,int b) {
02144 ne[a]=ne[b];
02145 }
02146
02147
02148 inline void neighbor_track::set_to_aux1(int j) {
02149 ne[j]=paux1;
02150 }
02151
02152
02153 inline void neighbor_track::set_to_aux2(int j) {
02154 ne[j]=paux2;
02155 }
02156
02157
02158 inline void neighbor_track::print_edges(int i) {
02159 cout << " (";
02160 for(int j=0;j<vc->nu[i];j++) {
02161 cout << ne[i][j] << (j==vc->nu[i]-1?")":",");
02162 }
02163 }
02164
02165
02166
02167 inline void neighbor_track::allocate_aux1(int i) {
02168 paux1=new int[i*vc->mem[i]];
02169 }
02170
02171
02172
02173 inline void neighbor_track::switch_to_aux1(int i) {
02174 delete [] mne[i];
02175 mne[i]=paux1;
02176 }
02177
02178
02179
02180 inline void neighbor_track::copy_to_aux1(int i,int m) {
02181 paux1[m]=mne[i][m];
02182 }
02183
02184
02185 inline void neighbor_track::set_to_aux1_offset(int k,int m) {
02186 ne[k]=paux1+m;
02187 }
02188
02189
02190
02191 void neighbor_track::check_facets() {
02192 int **edp,*nup;edp=vc->ed;nup=vc->nu;
02193 int i,j,k,l,m,q;
02194 for(i=0;i<vc->p;i++) {
02195 for(j=0;j<nup[i];j++) {
02196 k=edp[i][j];
02197 if (k>=0) {
02198 edp[i][j]=-1-k;
02199 q=ne[i][j];
02200 l=vc->cycle_up(edp[i][nup[i]+j],k);
02201 do {
02202 m=edp[k][l];
02203 edp[k][l]=-1-m;
02204 if (ne[k][l]!=q) cerr << "Facet error at (" << k << "," << l << ")=" << ne[k][l] << ", started from (" << i << "," << j << ")=" << q << endl;
02205 l=vc->cycle_up(edp[k][nup[k]+l],m);
02206 k=m;
02207 } while (k!=i);
02208 }
02209 }
02210 }
02211 vc->reset_edges();
02212 }
02213
02214
02215
02216 void neighbor_track::neighbors(ostream &os) {
02217 int **edp,*nup;edp=vc->ed;nup=vc->nu;
02218 int i,j,k,l,m;
02219 for(i=0;i<vc->p;i++) {
02220 for(j=0;j<nup[i];j++) {
02221 k=edp[i][j];
02222 if (k>=0) {
02223 os << " " << ne[i][j];
02224 edp[i][j]=-1-k;
02225 l=vc->cycle_up(edp[i][nup[i]+j],k);
02226 do {
02227 m=edp[k][l];
02228 edp[k][l]=-1-m;
02229 l=vc->cycle_up(edp[k][nup[k]+l],m);
02230 k=m;
02231 } while (k!=i);
02232 }
02233 }
02234 }
02235 vc->reset_edges();
02236 }
02237
02238
02239 void neighbor_track::label_facets() {
02240 int **edp,*nup;edp=vc->ed;nup=vc->nu;
02241 int i,j,k,l,m,q=1;
02242 for(i=0;i<vc->p;i++) {
02243 for(j=0;j<nup[i];j++) {
02244 k=edp[i][j];
02245 if (k>=0) {
02246 edp[i][j]=-1-k;
02247 ne[i][j]=q;
02248 l=vc->cycle_up(edp[i][nup[i]+j],k);
02249 do {
02250 m=edp[k][l];
02251 edp[k][l]=-1-m;
02252 ne[k][l]=q;
02253 l=vc->cycle_up(edp[k][nup[k]+l],m);
02254 k=m;
02255 } while (k!=i);
02256 q++;
02257 }
02258 }
02259 }
02260 vc->reset_edges();
02261 }
02262
02263
02264
02265
02266
02267
02268 void neighbor_track::print(ostream &os,int i,int j) {
02269 os << "(" << i << "," << ne[i][j] << ")";
02270 }