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