00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "stdafx.h"
00021
00022 #include <iostream>
00023
00024 #include "gul_types.h"
00025 #include "guar_exact.h"
00026 #include "gugr_basics.h"
00027 #include "gugr_regularize.h"
00028 #include "gugr_triangulate.h"
00029 #include "gul_io.h"
00030 #include "gul_std.h"
00031 #include "gugr_planesweep.h"
00032 #include "gugr_io.h"
00033
00034 namespace gugr {
00035
00036 using gul::AllocError;
00037 using gul::InternalError;
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 void Triangulate( graph_edge_list *E, graph_vertex_list *V,
00049 const rational& far_left, triangle_list *T )
00050 {
00051 vertex farleft;
00052 graph_edge *e, *eb, *ea,*left,*right,**tmpE;
00053 graph_vertex *v;
00054 int ileft,iright,codel,coder,nE,Win,Wout,ie,iea,ieb;
00055 int nP,i;
00056 graph_edge *e1;
00057 monpoly_info *P,*tmpP;
00058 int li,ri;
00059
00060 tmpE = (graph_edge **)alloca( sizeof(graph_edge *)*(E->nElems) );
00061 if( !tmpE ) throw AllocError();
00062
00063 if( V->head != NULL ) v = V->head->next;
00064 else return;
00065 if( v->next == NULL ) return;
00066
00067 e = E->head;
00068 while( e != NULL )
00069 { e->reserved[0].set_i(1); e = e->next; }
00070
00071
00072
00073 while( v->next != NULL )
00074 {
00075 nE = IncidentEdges( v, tmpE );
00076
00077 farleft = vertex( point2<rational>(far_left,v->v.v().y) );
00078 EdgeInsertPosition( v->v, farleft, nE, tmpE, &ileft, &iright,
00079 &codel, &coder );
00080 left = tmpE[ileft]; right = tmpE[iright];
00081
00082 if( right->v[0] == v )
00083 e = eb = right->e[0];
00084 else
00085 e = eb = right;
00086
00087 Win = 0;
00088 while( e->v[1] == v )
00089 {
00090 Win += e->reserved[0].i;
00091 e = e->e[1];
00092 }
00093 Wout = 1;
00094 while( e->e[0] != eb )
00095 {
00096 Wout++;
00097 e = e->e[0];
00098 }
00099 ea = e;
00100
00101 if( Win > Wout )
00102 ea->reserved[0].set_i(Win-Wout+1);
00103
00104 v = v->next;
00105 }
00106
00107
00108
00109
00110
00111 nP = 0;
00112
00113 nE = IncidentEdges( v, tmpE );
00114
00115 farleft = vertex( point2<rational>(far_left,v->v.v().y) );
00116 EdgeInsertPosition( v->v, farleft, nE, tmpE, &ileft, &iright,
00117 &codel, &coder );
00118 e1 = right = tmpE[iright];
00119
00120 do
00121 {
00122 e1->reserved[1].set_i(nP);
00123 nP += e1->reserved[0].i;
00124 e1 = e1->e[1];
00125 }
00126 while( e1 != right );
00127 nP--;
00128
00129 P = tmpP = (monpoly_info *)alloca( sizeof(monpoly_info) * nP );
00130 if( P == NULL ) throw AllocError();
00131
00132 for( i = 0; i < nP; i++ ) new(tmpP++) monpoly_info;
00133
00134
00135
00136
00137
00138
00139
00140 v = v->prev;
00141
00142 while( v->prev != NULL )
00143 {
00144 nE = IncidentEdges( v, tmpE );
00145
00146 farleft = vertex( point2<rational>(far_left,v->v.v().y) );
00147 EdgeInsertPosition( v->v, farleft, nE, tmpE, &ileft, &iright,
00148 &codel, &coder );
00149 if( tmpE[iright]->v[0] == v )
00150 ie = iea = iright;
00151 else
00152 ie = iea = ileft;
00153
00154 Wout = 0;
00155 do
00156 {
00157 Wout += tmpE[ie]->reserved[0].i;
00158
00159
00160
00161 li = tmpE[ie]->reserved[1].i-1;
00162 if( (li >= 0) && (tmpE[ie]->f[0].i > 0) )
00163 {
00164
00165
00166
00167
00168
00169 if( P[li].AppendRight(*v, *tmpE[ie]->v[1]) )
00170 {
00171
00172
00173
00174
00175 TriangulateMonotonePolygon( &P[li].Vl, &P[li].Vr, &P[li].E, T );
00176 }
00177 }
00178 ri = li + tmpE[ie]->reserved[0].i;
00179 if( (ri < nP) && (tmpE[ie]->f[1].i > 0) )
00180 {
00181
00182
00183
00184
00185
00186 if( P[ri].AppendLeft(*v, *tmpE[ie]->v[1]) )
00187 {
00188
00189
00190
00191
00192 TriangulateMonotonePolygon( &P[ri].Vl, &P[ri].Vr, &P[ri].E, T );
00193 }
00194 }
00195
00196
00197
00198 ie--; if(ie < 0) ie = nE-1;
00199 }
00200 while( tmpE[ie]->v[0] == v );
00201
00202 Win = 0;
00203 while( tmpE[ie] != tmpE[iea] )
00204 {
00205 Win += tmpE[ie]->reserved[0].i;
00206 ie--; if(ie < 0) ie = nE-1;
00207 }
00208 ieb = iea+1;
00209 if( ieb == nE ) ieb = 0;
00210
00211 if( Wout > Win )
00212 tmpE[ieb]->reserved[0].i += (Wout-Win);
00213
00214
00215
00216 i = tmpE[iea]->reserved[1].i;
00217 e = tmpE[ieb];
00218 e->reserved[1].set_i(i);
00219 i += e->reserved[0].i;
00220 e = e->e[1];
00221
00222 while( e->v[1] == v )
00223 {
00224 e->reserved[1].set_i(i);
00225 i += e->reserved[0].i;
00226 e = e->e[1];
00227 }
00228
00229
00230 v = v->prev;
00231 }
00232
00233
00234
00235 nE = IncidentEdges( v, tmpE );
00236
00237 farleft = vertex( point2<rational>(far_left,v->v.v().y) );
00238 EdgeInsertPosition( v->v, farleft, nE, tmpE, &ileft, &iright,
00239 &codel, &coder );
00240 if( tmpE[iright]->IsHorizontal() )
00241 ie = iea = iright;
00242 else
00243 ie = iea = ileft;
00244
00245 do
00246 {
00247 li = tmpE[ie]->reserved[1].i-1;
00248 if( (li >= 0) && (tmpE[ie]->f[0].i > 0) )
00249 {
00250
00251
00252
00253
00254
00255 if( P[li].AppendRight(*v, *tmpE[ie]->v[1]) )
00256 {
00257
00258
00259
00260
00261 TriangulateMonotonePolygon( &P[li].Vl, &P[li].Vr, &P[li].E, T );
00262 }
00263 }
00264 ri = li + tmpE[ie]->reserved[0].i;
00265 if( (ri < nP) && (tmpE[ie]->f[1].i > 0) )
00266 {
00267
00268
00269
00270
00271
00272 if( P[ri].AppendLeft(*v, *tmpE[ie]->v[1]) )
00273 {
00274
00275
00276
00277
00278 TriangulateMonotonePolygon( &P[ri].Vl, &P[ri].Vr, &P[ri].E, T );
00279 }
00280 }
00281
00282 ie--; if(ie < 0) ie = nE-1;
00283 }
00284 while( ie != iea );
00285
00286 for( i = 0; i < nP; i++ )
00287 {
00288 P[i].Vl.DeleteElems();
00289 P[i].Vr.DeleteElems();
00290 P[i].E.DeleteElems();
00291 }
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 void TriangulateMonotonePolygon(
00304 graph_vertex_list2 *V1, graph_vertex_list2 *V2,
00305 graph_edge_list *E, triangle_list *T )
00306
00307 {
00308 graph_vertex_list2 Vq, S;
00309 graph_vertex *vh,*v1,*v2,*vi,*vi_1,*vs,*vt,*v,*vh1,*vh2;
00310 graph_edge *e;
00311 triangle *tri;
00312 int sign;
00313 graph_vertex_list V;
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 vh1 = V1->Last();
00332 V1->Remove(vh1);
00333 V.Append(vh1);
00334
00335 vh2 = V2->Last();
00336 V2->Remove(vh2);
00337 V.Append(vh2);
00338
00339 v1 = V1->Last();
00340 V1->Remove(v1);
00341 v1->reserved[0].set_i(-1);
00342
00343 v2 = V2->Last();
00344 V2->Remove(v2);
00345 v2->reserved[0].set_i(+1);
00346
00347 if( (V1->Last() == NULL) && (V2->Last() == NULL) )
00348 {
00349 delete v1; delete v2;
00350 V1->DeleteElems();
00351 V2->DeleteElems();
00352 V.DeleteElems();
00353 E->DeleteElems();
00354 return;
00355 }
00356
00357 vh = new graph_vertex( vh2->v, NULL, vh2->reserved[1].i );
00358 Vq.AppendRight(vh);
00359 vh->reserved[0].set_i(0);
00360
00361 e = new graph_edge();
00362 E->Append(e);
00363 e->l = v1->e->l;
00364 e->v[0] = v1;
00365 e->v[1] = vh;
00366 v1->e = e;
00367
00368 e = new graph_edge();
00369 E->Append(e);
00370 e->l = v2->e->l;
00371 e->v[0] = v2;
00372 e->v[1] = vh;
00373 v2->e = e;
00374
00375 while( (v1 != NULL) || (v2 != NULL) )
00376 {
00377 if( v1 != NULL )
00378 {
00379 if( v2 != NULL )
00380 sign = compare( v1->v.v().y, v2->v.v().y );
00381 else
00382 sign = +1;
00383 }
00384 else sign = -1;
00385
00386 if( sign >= 0 )
00387 {
00388 if( v1->e->IsHorizontal() )
00389 {
00390 vs = v1;
00391 vt = V1->Last();
00392 while( (vt != NULL) && (vt->e->IsHorizontal()) )
00393 {
00394 V1->Remove(vt);
00395 delete v1;
00396 v1 = vt;
00397 vt = V1->Last();
00398 }
00399 if( v1 != vs )
00400 {
00401 e = new graph_edge();
00402 E->Append(e);
00403 e->l = v1->e->l;
00404 e->v[0] = v1;
00405 e->v[1] = vh;
00406 v1->e = e;
00407 }
00408 }
00409 v1->reserved[0].set_i(-1);
00410 Vq.AppendRight(v1);
00411 vh = v1;
00412 v1 = V1->Last();
00413 if( v1 != NULL ) V1->Remove(v1);
00414 }
00415 else
00416 {
00417 if( v2->e->IsHorizontal() )
00418 {
00419 vs = v2;
00420 vt = V2->Last();
00421 while( (vt != NULL) && (vt->e->IsHorizontal()) )
00422 {
00423 V2->Remove(vt);
00424 delete v2;
00425 v2 = vt;
00426 vt = V2->Last();
00427 }
00428 if( v2 != vs )
00429 {
00430 e = new graph_edge();
00431 E->Append(e);
00432 e->l = v2->e->l;
00433 e->v[0] = v2;
00434 e->v[1] = vh;
00435 v2->e = e;
00436 }
00437 }
00438
00439 v2->reserved[0].set_i(+1);
00440 Vq.AppendRight(v2);
00441 vh = v2;
00442 v2 = V2->Last();
00443 if( v2 != NULL ) V2->Remove(v2);
00444 }
00445 }
00446
00447 vh->prev->reserved[0].set_i(0);
00448 Vq.Remove(vh);
00449 delete vh;
00450
00451
00452
00453 v = Vq.First();
00454 Vq.Remove(v);
00455 S.AppendRight(v);
00456
00457 v = Vq.First();
00458 Vq.Remove(v);
00459 S.AppendRight(v);
00460
00461 v = Vq.First();
00462 Vq.Remove(v);
00463
00464 while( v->reserved[0].i != 0 )
00465 {
00466 vi = S.Last();
00467 v1 = S.First();
00468
00469 e = v->e;
00470
00471 if( e->v[1] == vi )
00472 {
00473 vi_1 = vi->prev;
00474
00475 sign = DetermineOrientation(v->v.v(),vi->v.v(),vi_1->v.v());
00476 sign *= v->reserved[0].i;
00477
00478 if( (sign == 0) && (v->e->IsHorizontal()) )
00479 {
00480 S.Remove(vi);
00481 V.Append(vi);
00482 S.AppendRight(v);
00483 }
00484 else
00485 {
00486 while( (sign > 0) && (S.nElems > 1) )
00487 {
00488 tri = new triangle();
00489 if( vi->reserved[0].i == +1 )
00490 {
00491 tri->v[0] = v->v; tri->code0 = v->reserved[1].i;
00492 tri->v[1] = vi->v; tri->code1 = vi->reserved[1].i;
00493 tri->v[2] = vi_1->v; tri->code2 = vi_1->reserved[1].i;
00494
00495
00496
00497
00498
00499
00500 }
00501 else
00502 {
00503 tri->v[0] = v->v; tri->code0 = v->reserved[1].i;
00504 tri->v[1] = vi_1->v; tri->code1 = vi_1->reserved[1].i;
00505 tri->v[2] = vi->v; tri->code2 = vi->reserved[1].i;
00506
00507
00508
00509
00510
00511
00512 }
00513 T->Append(tri);
00514
00515 S.Remove(vi);
00516 V.Append(vi);
00517 if( S.nElems > 1 )
00518 {
00519 vi = vi_1;
00520 vi_1 = vi->prev;
00521 sign = DetermineOrientation(v->v.v(),vi->v.v(),vi_1->v.v());
00522 sign *= v->reserved[0].i;
00523 }
00524 }
00525 S.AppendRight(v);
00526 }
00527 }
00528 else
00529 {
00530 gul::Assert<gul::InternalError>( ndebug || (e->v[1] == v1) );
00531
00532 if( v->e->IsHorizontal() )
00533 {
00534 gul::Assert<gul::InternalError>( ndebug || (S.nElems == 2) );
00535 S.Remove(v1);
00536 V.Append(v1);
00537 S.AppendRight(v);
00538 }
00539 else
00540 {
00541 v2 = v1->next;
00542 do
00543 {
00544 tri = new triangle();
00545 if( v2->reserved[0].i == +1 )
00546 {
00547 tri->v[0] = v->v; tri->code0 = v->reserved[1].i;
00548 tri->v[1] = v2->v; tri->code1 = v2->reserved[1].i;
00549 tri->v[2] = v1->v; tri->code2 = v1->reserved[1].i;
00550
00551
00552
00553
00554
00555
00556 }
00557 else
00558 {
00559 tri->v[0] = v->v; tri->code0 = v->reserved[1].i;
00560 tri->v[1] = v1->v; tri->code1 = v1->reserved[1].i;
00561 tri->v[2] = v2->v; tri->code2 = v2->reserved[1].i;
00562
00563
00564
00565
00566
00567
00568 }
00569 T->Append(tri);
00570
00571 S.Remove(v1);
00572 V.Append(v1);
00573 v1 = v2;
00574 v2 = v1->next;
00575 }
00576 while( v2 != NULL );
00577
00578 S.AppendRight(v);
00579 }
00580 }
00581
00582 v = Vq.First();
00583 Vq.Remove(v);
00584 }
00585
00586
00587
00588 v1 = S.First();
00589 do
00590 {
00591 v2 = v1->next;
00592
00593 tri = new triangle();
00594 if( (int)v2->reserved[0].i == +1 )
00595 {
00596 tri->v[0] = v->v; tri->code0 = v->reserved[1].i;
00597 tri->v[1] = v2->v; tri->code1 = v2->reserved[1].i;
00598 tri->v[2] = v1->v; tri->code2 = v1->reserved[1].i;
00599
00600
00601
00602
00603
00604
00605 }
00606 else
00607 {
00608 tri->v[0] = v->v; tri->code0 = v->reserved[1].i;
00609 tri->v[1] = v1->v; tri->code1 = v1->reserved[1].i;
00610 tri->v[2] = v2->v; tri->code2 = v2->reserved[1].i;
00611
00612
00613
00614
00615
00616
00617 }
00618 T->Append(tri);
00619
00620 S.Remove(v1);
00621 V.Append(v1);
00622 v1 = v2;
00623 v2 = v1->next;
00624 }
00625 while( v2 != NULL );
00626 S.Remove(v1);
00627 V.Append(v1);
00628
00629 delete v;
00630
00631 gul::Assert<gul::InternalError>( ndebug ||
00632 ((S.nElems == 0) && (Vq.nElems == 0) &&
00633 (V1->nElems == 0) && (V2->nElems == 0)) );
00634
00635
00636
00637
00638
00639 V.DeleteElems();
00640 E->DeleteElems();
00641 }
00642
00643 }