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 "gul_error.h"
00026 #include "guar_exact.h"
00027 #include "guma_sorting.h"
00028 #include "gugr_basics.h"
00029 #include "gugr_planesweep.h"
00030 #include "gul_io.h"
00031 #include "gul_std.h"
00032 #include "gugr_io.h"
00033
00034 namespace gugr {
00035
00036 using gul::ndebug;
00037
00038 using guar::rational;
00039 using gul::ListNodeInfo;
00040 using std::cout;
00041
00042
00043 #ifdef __BORLANDC__
00044 template float DumpPS<float>::orgx;
00045 template float DumpPS<float>::orgy;
00046 template float DumpPS<float>::scalex;
00047 template float DumpPS<float>::scaley;
00048 template double DumpPS<double>::orgx;
00049 template double DumpPS<double>::orgy;
00050 template double DumpPS<double>::scalex;
00051 template double DumpPS<double>::scaley;
00052 #else
00053 GULAPI float DumpPS<float>::orgx;
00054 GULAPI float DumpPS<float>::orgy;
00055 GULAPI float DumpPS<float>::scalex;
00056 GULAPI float DumpPS<float>::scaley;
00057 GULAPI double DumpPS<double>::orgx;
00058 GULAPI double DumpPS<double>::orgy;
00059 GULAPI double DumpPS<double>::scalex;
00060 GULAPI double DumpPS<double>::scaley;
00061 #endif
00062
00063
00064 int compare_point_to_linerec( point2<rational> *P, linerec *L )
00065 {
00066 return DetermineOrientation( L->B, L->E, *P );
00067 }
00068 int compare_linerec_to_linerec( linerec *L1, linerec *L2 )
00069 {
00070 int sign = DetermineOrientation(L2->B, L2->E, L1->B );
00071 if( sign == 0 )
00072 sign = DetermineOrientation(L2->B, L2->E, L1->E );
00073 return sign;
00074 }
00075 int compare_point_to_eventrec( point2<rational> *C, eventrec *E )
00076 {
00077 int sign = compare( C->x, E->key.x );
00078 if( sign == 0 ) sign = compare( C->y, E->key.y );
00079 return sign;
00080 }
00081 int compare_segment_to_linerec( segment *S, linerec *L )
00082 {
00083 int sign = DetermineOrientation( L->B, L->E, S->B );
00084 if( sign == 0 ) sign = DetermineOrientation( L->B, L->E, S->E );
00085 return sign;
00086 }
00087 int hcompare_point_to_intersection( point2<rational> *C, intersection *R )
00088 {
00089 return compare( C->x, R->I.x );
00090 }
00091 int vcompare_point_to_intersection( point2<rational> *C, intersection *R )
00092 {
00093 return compare( C->y, R->I.y );
00094 }
00095 int compare_pointer_to_pointer( void *p1, void *p2 )
00096 {
00097 if( p1 < p2 ) return -1;
00098 else if( p1 == p2 ) return 0;
00099 return 1;
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 intersection *intersect( Map<linerec>::Node L1, Map<linerec>::Node L2,
00113 const rational& xleft, Map<eventrec> *EvQ,
00114 List<intersection> *Ipts )
00115 {
00116 const rational& x0 = L1.key()->l.v().x;
00117 const rational& y0 = L1.key()->l.v().y;
00118 const rational& dy = L1.key()->l.dy();
00119 const rational& e = L1.key()->E.x;
00120 const rational& X0 = L2.key()->l.v().x;
00121 const rational& Y0 = L2.key()->l.v().y;
00122 const rational& DY = L2.key()->l.dy();
00123 const rational& E = L2.key()->E.x;
00124 rational d;
00125 point2<rational> I;
00126 int sign,bsign,side1,side2;
00127 RefMap<intersection>::Node irnode1, irnode2, irnode;
00128 intersection *i;
00129 int side;
00130 Map<eventrec>::Node enode,enode1;
00131
00132 d = DY - dy;
00133 sign = d.test();
00134 if( sign == 0 ) return 0;
00135
00136 I.x = (y0 - Y0 + X0*DY - x0*dy) / d;
00137
00138 bsign = compare( I.x, xleft );
00139 if( bsign < 0 ) return 0;
00140 sign = compare( I.x, e );
00141 if( sign > 0 ) return 0;
00142 sign = compare( I.x, E );
00143 if( sign > 0 ) return 0;
00144
00145 I.y = y0 + (I.x-x0)*dy;
00146
00147 side1 = L1.key()->I.SearchNode(
00148 &I, hcompare_point_to_intersection, &irnode1 );
00149 side2 = L2.key()->I.SearchNode(
00150 &I, hcompare_point_to_intersection, &irnode2 );
00151 if( side1 == 0 )
00152 i = irnode1.key();
00153 else if( side2 == 0 )
00154 i = irnode2.key();
00155 else
00156 {
00157 i = new intersection( I );
00158 Ipts->Append(i);
00159 }
00160
00161 if( side1 != 0 )
00162 {
00163 irnode = L1.key()->I.NewNode(i);
00164 L1.key()->I.InsertNode( irnode, irnode1, side1 );
00165 }
00166 if( side2 != 0 )
00167 {
00168 irnode = L2.key()->I.NewNode(i);
00169 L2.key()->I.InsertNode( irnode, irnode2, side2 );
00170 }
00171
00172 if( bsign == 0 ) return i;
00173
00174 side = EvQ->SearchNode( &I, compare_point_to_eventrec, &enode );
00175 if( side != 0 )
00176 {
00177 enode1 = EvQ->NewNode( I );
00178 EvQ->InsertNode( enode1, enode, side );
00179 enode = enode1;
00180 }
00181 enode.key()->I.Append( new ListNode<linepair>( linepair(L1,L2) ) );
00182
00183 return i;
00184 }
00185
00186
00187 intersection *intersect_vert( linerec *vL, Map<linerec>::Node L,
00188 List<intersection> *Ipts )
00189 {
00190 const rational& X0 = L.key()->l.v().x;
00191 const rational& Y0 = L.key()->l.v().y;
00192 const rational& DY = L.key()->l.dy();
00193 const rational& yleft = vL->B.y;
00194 const rational& yright = vL->E.y;
00195 const rational& x0 = vL->l.v().x;
00196
00197 point2<rational> I;
00198 int sign,side1,side2;
00199 RefMap<intersection>::Node irnode1, irnode2, irnode;
00200 intersection *i;
00201
00202 I.y = Y0 + (x0 - X0)*DY;
00203
00204 sign = compare( I.y, yleft );
00205 if( sign < 0 ) return 0;
00206 sign = compare( I.y, yright );
00207 if( sign > 0 ) return 0;
00208
00209 I.x = x0;
00210
00211 side1 = vL->I.SearchNode(
00212 &I, vcompare_point_to_intersection, &irnode1 );
00213 side2 = L.key()->I.SearchNode(
00214 &I, hcompare_point_to_intersection, &irnode2 );
00215 if( side1 == 0 )
00216 i = irnode1.key();
00217 else if( side2 == 0 )
00218 i = irnode2.key();
00219 else
00220 {
00221 i = new intersection( I );
00222 Ipts->Append(i);
00223 }
00224
00225 if( side1 != 0 )
00226 {
00227 irnode = vL->I.NewNode(i);
00228 vL->I.InsertNode( irnode, irnode1, side1 );
00229 }
00230 if( side2 != 0 )
00231 {
00232 irnode = L.key()->I.NewNode(i);
00233 L.key()->I.InsertNode( irnode, irnode2, side2 );
00234 }
00235
00236 return i;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246 void finish_line( linerec *L, graph_edge_list *E, graph_vertex_list *V,
00247 int maxE, List<intersection> *Ipts,
00248 List<intersectionseg> *Isegs )
00249 {
00250 ListNode<segment *> *segref = L->S.First();
00251 segment *seg;
00252 int side;
00253 intersection *i,*i1,*i2;
00254 intersectionseg *is;
00255 RefMap<intersection>::Node irnode,irnode1;
00256 Ptr<intersection *> I;
00257 int nI,j;
00258 segtree SegTr;
00259 int left,right,mid,iB,iE,sign,nLf;
00260 Ptr<segnode *> Lf;
00261 segnode *snode;
00262 RefMap<segment>::Node segnod;
00263 graph_edge *e;
00264 RefMap<void>::Node leftowner,rightowner,leftowner1,rightowner1;
00265 RefMap<void> *leftowners,*rightowners;
00266 List< ListNode< ListNodeInfo< ListNode<graph_edge *> > > > *ownerrecs;
00267 ListNode< ListNodeInfo< ListNode<graph_edge *> > > *orec;
00268 ListNode<graph_edge *> *erec;
00269
00270 while( segref != 0 )
00271 {
00272 seg = segref->el;
00273
00274
00275
00276 side = L->I.SearchNode( &seg->B, hcompare_point_to_intersection,
00277 &irnode );
00278 if( side != 0 )
00279 {
00280 i = new intersection( seg->B );
00281 Ipts->Append(i);
00282
00283 irnode1 = L->I.NewNode(i);
00284 L->I.InsertNode( irnode1, irnode, side );
00285 }
00286
00287 side = L->I.SearchNode( &seg->E, hcompare_point_to_intersection,
00288 &irnode );
00289 if( side != 0 )
00290 {
00291 i = new intersection( seg->E );
00292 Ipts->Append(i);
00293
00294 irnode1 = L->I.NewNode(i);
00295 L->I.InsertNode( irnode1, irnode, side );
00296 }
00297
00298 segref = segref->next;
00299 }
00300
00301 nI = L->I.ConvertToArray( &I );
00302
00303 SegTr.init( nI, I );
00304
00305 segref = L->S.First();
00306
00307 while( segref != 0 )
00308 {
00309 seg = segref->el;
00310
00311 left = 0;
00312 right = nI;
00313 mid = (left+right)/2;
00314
00315 for(;;)
00316 {
00317 sign = compare( seg->B.x, I[mid]->I.x );
00318 if( sign == 0 )
00319 break;
00320 else if( sign < 0 )
00321 {
00322 right = mid;
00323 mid = (left+right)/2;
00324 }
00325 else
00326 {
00327 left = mid;
00328 mid = (left+right)/2;
00329 }
00330 }
00331 iB = mid;
00332
00333 left = 0;
00334 right = nI;
00335 mid = (left+right)/2;
00336
00337 for(;;)
00338 {
00339 sign = compare( seg->E.x, I[mid]->I.x );
00340 if( sign == 0 )
00341 break;
00342 else if( sign < 0 )
00343 {
00344 right = mid;
00345 mid = (left+right)/2;
00346 }
00347 else
00348 {
00349 left = mid;
00350 mid = (left+right)/2;
00351 }
00352 }
00353 iE = mid;
00354
00355 SegTr.insert( iB, iE, seg );
00356
00357 segref = segref->next;
00358 }
00359
00360 nLf = SegTr.leaves_to_array( &Lf );
00361
00362 for( j = 0; j < nLf; j++ )
00363 {
00364 e = new graph_edge;
00365 E->Append(e);
00366
00367 i1 = SegTr.m_absz[Lf[j]->m_il];
00368 if( i1->v == 0 )
00369 {
00370 i1->v = new graph_vertex( i1->I, 0 );
00371 V->Append(i1->v);
00372 }
00373 i2 = SegTr.m_absz[Lf[j]->m_ir];
00374 if( i2->v == 0 )
00375 {
00376 i2->v = new graph_vertex( i2->I, 0 );
00377 V->Append(i2->v);
00378 }
00379 e->v[0] = i1->v;
00380 e->v[1] = i2->v;
00381 e->l = L->l;
00382
00383
00384
00385 is = new intersectionseg(e);
00386 Isegs->Append(is);
00387
00388
00389
00390 leftowners = new RefMap<void>;
00391 rightowners = new RefMap<void>;
00392 e->f[0].p = leftowners;
00393 e->f[1].p = rightowners;
00394 e->reserved[0].set_i(0);
00395 ownerrecs = new List< ListNode< ListNodeInfo< ListNode<graph_edge *> > > >;
00396 e->reserved[1].p = ownerrecs;
00397
00398 snode = Lf[j];
00399 while( snode )
00400 {
00401 segnod = snode->m_segs.First();
00402
00403 while( !segnod.IsEmpty() )
00404 {
00405
00406
00407
00408 e->reserved[0].i += segnod.key()->m;
00409
00410
00411
00412 side = leftowners->SearchNode( (void *)segnod.key()->f[0].p,
00413 compare_pointer_to_pointer, &leftowner );
00414 if( side != 0 )
00415 {
00416 leftowner1 = leftowners->NewNode((void *)segnod.key()->f[0].p);
00417 leftowners->InsertNode( leftowner1, leftowner, side );
00418 }
00419
00420
00421
00422 side = rightowners->SearchNode( (void *)segnod.key()->f[1].p,
00423 compare_pointer_to_pointer, &rightowner );
00424 if( side != 0 )
00425 {
00426 rightowner1 = rightowners->NewNode((void *)segnod.key()->f[1].p);
00427 rightowners->InsertNode( rightowner1, rightowner, side );
00428 }
00429
00430
00431
00432 erec = new ListNode<graph_edge *>(e);
00433 segnod.key()->e.Append( erec );
00434
00435
00436
00437
00438
00439 orec = new ListNode< ListNodeInfo< ListNode<graph_edge *> > >(
00440 ListNodeInfo< ListNode<graph_edge *> >(&segnod.key()->e, erec) );
00441 ownerrecs->Append(orec);
00442
00443
00444
00445
00446
00447
00448
00449
00450 segnod = snode->m_segs.Successor(segnod);
00451 }
00452 snode = snode->m_parent;
00453 }
00454
00455 OrientEdge( e );
00456 ConnectEdge( e, maxE );
00457 }
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 }
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 void finish_vertline( linerec *L, graph_edge_list *E, graph_vertex_list *V,
00490 int maxE, List<intersection> *Ipts,
00491 List<intersectionseg> *Isegs )
00492 {
00493 ListNode<segment *> *segref = L->S.First();
00494 segment *seg;
00495 int side;
00496 intersection *i,*i1,*i2;
00497 intersectionseg *is;
00498 RefMap<intersection>::Node irnode,irnode1;
00499 Ptr<intersection *> I;
00500 int nI,j;
00501 segtree SegTr;
00502 int left,right,mid,iB,iE,sign,nLf;
00503 Ptr<segnode *> Lf;
00504 segnode *snode;
00505 RefMap<segment>::Node segnod;
00506 graph_edge *e;
00507 RefMap<void>::Node leftowner,rightowner,leftowner1,rightowner1;
00508 RefMap<void> *leftowners,*rightowners;
00509 List< ListNode< ListNodeInfo< ListNode<graph_edge *> > > > *ownerrecs;
00510 ListNode< ListNodeInfo< ListNode<graph_edge *> > > *orec;
00511 ListNode<graph_edge *> *erec;
00512
00513 while( segref != 0 )
00514 {
00515 seg = segref->el;
00516
00517
00518
00519 side = L->I.SearchNode( &seg->B, vcompare_point_to_intersection,
00520 &irnode );
00521 if( side != 0 )
00522 {
00523 i = new intersection( seg->B );
00524 Ipts->Append(i);
00525
00526 irnode1 = L->I.NewNode(i);
00527 L->I.InsertNode( irnode1, irnode, side );
00528 }
00529
00530 side = L->I.SearchNode( &seg->E, vcompare_point_to_intersection,
00531 &irnode );
00532 if( side != 0 )
00533 {
00534 i = new intersection( seg->E );
00535 Ipts->Append(i);
00536
00537 irnode1 = L->I.NewNode(i);
00538 L->I.InsertNode( irnode1, irnode, side );
00539 }
00540
00541 segref = segref->next;
00542 }
00543
00544 nI = L->I.ConvertToArray( &I );
00545
00546 SegTr.init( nI, I );
00547
00548 segref = L->S.First();
00549
00550 while( segref != 0 )
00551 {
00552 seg = segref->el;
00553
00554 left = 0;
00555 right = nI;
00556 mid = (left+right)/2;
00557
00558 for(;;)
00559 {
00560 sign = compare( seg->B.y, I[mid]->I.y );
00561 if( sign == 0 )
00562 break;
00563 else if( sign < 0 )
00564 {
00565 right = mid;
00566 mid = (left+right)/2;
00567 }
00568 else
00569 {
00570 left = mid;
00571 mid = (left+right)/2;
00572 }
00573 }
00574 iB = mid;
00575
00576 left = 0;
00577 right = nI;
00578 mid = (left+right)/2;
00579
00580 for(;;)
00581 {
00582 sign = compare( seg->E.y, I[mid]->I.y );
00583 if( sign == 0 )
00584 break;
00585 else if( sign < 0 )
00586 {
00587 right = mid;
00588 mid = (left+right)/2;
00589 }
00590 else
00591 {
00592 left = mid;
00593 mid = (left+right)/2;
00594 }
00595 }
00596 iE = mid;
00597
00598 SegTr.insert( iB, iE, seg );
00599
00600 segref = segref->next;
00601 }
00602
00603 nLf = SegTr.leaves_to_array( &Lf );
00604
00605 for( j = 0; j < nLf; j++ )
00606 {
00607 e = new graph_edge;
00608 E->Append(e);
00609
00610 i1 = SegTr.m_absz[Lf[j]->m_il];
00611 if( i1->v == 0 )
00612 {
00613 i1->v = new graph_vertex( i1->I, 0 );
00614 V->Append(i1->v);
00615 }
00616 i2 = SegTr.m_absz[Lf[j]->m_ir];
00617 if( i2->v == 0 )
00618 {
00619 i2->v = new graph_vertex( i2->I, 0 );
00620 V->Append(i2->v);
00621 }
00622 e->v[0] = i1->v;
00623 e->v[1] = i2->v;
00624 e->l = L->l;
00625
00626
00627
00628 is = new intersectionseg(e);
00629 Isegs->Append(is);
00630
00631
00632
00633 leftowners = new RefMap<void>;
00634 rightowners = new RefMap<void>;
00635 e->f[0].p = leftowners;
00636 e->f[1].p = rightowners;
00637 e->reserved[0].set_i(0);
00638 ownerrecs = new List< ListNode< ListNodeInfo< ListNode<graph_edge *> > > >;
00639 e->reserved[1].p = ownerrecs;
00640
00641 snode = Lf[j];
00642 while( snode )
00643 {
00644 segnod = snode->m_segs.First();
00645
00646 while( !segnod.IsEmpty() )
00647 {
00648
00649
00650
00651 e->reserved[0].i += segnod.key()->m;
00652
00653
00654
00655 side = leftowners->SearchNode( (void *)segnod.key()->f[0].p,
00656 compare_pointer_to_pointer, &leftowner );
00657 if( side != 0 )
00658 {
00659 leftowner1 = leftowners->NewNode((void *)segnod.key()->f[0].p );
00660 leftowners->InsertNode( leftowner1, leftowner, side );
00661 }
00662
00663
00664
00665 side = rightowners->SearchNode( (void *)segnod.key()->f[1].p,
00666 compare_pointer_to_pointer, &rightowner );
00667 if( side != 0 )
00668 {
00669 rightowner1 = rightowners->NewNode((void *)segnod.key()->f[1].p);
00670 rightowners->InsertNode( rightowner1, rightowner, side );
00671 }
00672
00673
00674
00675 erec = new ListNode<graph_edge *>(e);
00676 segnod.key()->e.Append( erec );
00677
00678
00679
00680
00681
00682 orec = new ListNode< ListNodeInfo< ListNode<graph_edge *> > >(
00683 ListNodeInfo< ListNode<graph_edge *> >(&segnod.key()->e, erec) );
00684 ownerrecs->Append(orec);
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694 segnod = snode->m_segs.Successor(segnod);
00695 }
00696 snode = snode->m_parent;
00697 }
00698
00699 OrientEdge( e );
00700 ConnectEdge( e, maxE );
00701 }
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 }
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754 void DoIntersectSegments( int nsegs, Map<eventrec>& EvQ,
00755 gugr::graph_edge_list *E, gugr::graph_vertex_list *V )
00756 {
00757
00758 Map<eventrec>::Node enode,evnode,evnode1;
00759 int side,sign;
00760 ListNode<segment *> *begseg;
00761 Map<linerec> SwS;
00762 segment *seg;
00763 ListNode<Map<linerec>::Node> *lrefnode,*lstnode;
00764 Map<linerec>::Node lnode,lnodelo,lnodehi,lnode1,lnode2;
00765 linerec *vlin = 0, *lin;
00766 bool addvend,iflag,iexflag,checkneighbors;
00767 RefMap<intersection>::Node irnode, irnode1;
00768 intersection *irec;
00769 ListNode<linepair> *lpnode;
00770 linepair lpair;
00771 List<intersection> Ipts;
00772 List<intersectionseg> Isegs;
00773 int maxE;
00774
00775 maxE = nsegs*4;
00776
00777
00778
00779 for(;;)
00780 {
00781 enode = EvQ.First();
00782 if( enode.IsEmpty() ) break;
00783
00784
00785
00786 while( enode.key()->BV.nElems > 0 )
00787 {
00788 begseg = enode.key()->BV.First();
00789 enode.key()->BV.Remove( begseg );
00790
00791
00792
00793
00794
00795
00796 addvend = false;
00797 if( vlin == 0 )
00798 {
00799 vlin = new linerec( begseg->el );
00800 delete begseg;
00801 addvend = true;
00802 }
00803 else
00804 {
00805 vlin->S.Append( begseg );
00806
00807 sign = compare( begseg->el->E.y, vlin->E.y );
00808 if( sign > 0 )
00809 {
00810 vlin->E = begseg->el->E;
00811
00812
00813
00814 vlin->endev.key()->EV = 0;
00815
00816 if( (vlin->endev.key()->IsEmpty()) &&
00817 (vlin->endev.key() != enode.key()) )
00818 {
00819 EvQ.RemoveNode( vlin->endev );
00820 EvQ.FreeNode( vlin->endev );
00821 }
00822
00823 addvend = true;
00824 }
00825 }
00826 if( addvend )
00827 {
00828
00829
00830 side = EvQ.SearchNode( &vlin->E, compare_point_to_eventrec, &evnode );
00831 if( side != 0 )
00832 {
00833 evnode1 = EvQ.NewNode( vlin->E );
00834 EvQ.InsertNode( evnode1, evnode, side );
00835 evnode = evnode1;
00836 }
00837 evnode.key()->EV = vlin;
00838 vlin->endev = evnode;
00839 }
00840 }
00841
00842
00843
00844 if( enode.key()->I.nElems > 0 )
00845 iexflag = true;
00846 else
00847 iexflag = false;
00848
00849 if( iexflag ||
00850 ((vlin != 0) && (enode.key()->B.nElems > 0)) ||
00851 ((vlin != 0) && (!enode.key()->E.IsEmpty())) ||
00852 ((enode.key()->B.nElems > 0) && (!enode.key()->E.IsEmpty())) )
00853 {
00854 iflag = true;
00855 if( iexflag )
00856 {
00857
00858
00859 lin = enode.key()->I.First()->el.L1.key();
00860 side = lin->I.SearchNode( &enode.key()->key,
00861 hcompare_point_to_intersection, &irnode );
00862 gul::Assert<InternalError>( ndebug || (side == 0) );
00863
00864 irec = irnode.key();
00865 }
00866 else
00867 {
00868
00869
00870 irec = new intersection( enode.key()->key );
00871 Ipts.Append(irec);
00872 }
00873 }
00874 else
00875 iflag = false;
00876
00877
00878
00879 if( vlin && iflag )
00880 {
00881 side = vlin->I.SearchNode(
00882 &irec->I, vcompare_point_to_intersection, &irnode1 );
00883 if( side != 0 )
00884 {
00885 irnode = vlin->I.NewNode(irec);
00886 vlin->I.InsertNode( irnode, irnode1, side );
00887 }
00888 }
00889
00890
00891
00892 lrefnode = enode.key()->E.First();
00893 while( lrefnode != 0 )
00894 {
00895
00896
00897 lnode = lrefnode->el;
00898 lrefnode = lrefnode->next;
00899
00900 if( iflag )
00901 {
00902
00903
00904 side = lnode.key()->I.SearchNode( &irec->I,
00905 hcompare_point_to_intersection, &irnode );
00906 if( side != 0 )
00907 {
00908 irnode1 = lnode.key()->I.NewNode(irec);
00909 lnode.key()->I.InsertNode( irnode1, irnode, side );
00910 }
00911 }
00912
00913 lnodelo = SwS.Predecessor( lnode );
00914 lnodehi = SwS.Successor( lnode );
00915
00916 SwS.RemoveNode( lnode );
00917
00918
00919
00920 if( !lnodelo.IsEmpty() && !lnodehi.IsEmpty() )
00921 intersect( lnodelo, lnodehi, enode.key()->key.x, &EvQ, &Ipts );
00922 }
00923
00924
00925
00926 while( enode.key()->I.nElems > 0 )
00927 {
00928 lpnode = enode.key()->I.First();
00929 enode.key()->I.Remove( lpnode );
00930 lpair = lpnode->el;
00931 delete lpnode;
00932
00933 lnode1 = lpair.L1;
00934 lnode2 = lpair.L2;
00935
00936 if( !SwS.IsRemoved(lnode1) && !SwS.IsRemoved(lnode2) )
00937 {
00938 SwS.RemoveNode( lnode1 );
00939 SwS.RemoveNode( lnode2 );
00940
00941 lnode1.key()->B = enode.key()->key;
00942 lnode2.key()->B = enode.key()->key;
00943
00944 side = SwS.SearchNode( lnode1.key(), compare_linerec_to_linerec,
00945 &lnode );
00946 gul::Assert<InternalError>(ndebug | (side!=0) );
00947
00948 SwS.InsertNode(lnode1,lnode,side);
00949
00950 lnodelo = SwS.Predecessor( lnode1 );
00951 lnodehi = SwS.Successor( lnode1 );
00952
00953 if( !lnodelo.IsEmpty() )
00954 intersect( lnodelo, lnode1, enode.key()->key.x, &EvQ, &Ipts );
00955 if( !lnodehi.IsEmpty() )
00956 intersect( lnodehi, lnode1, enode.key()->key.x, &EvQ, &Ipts );
00957
00958 side = SwS.SearchNode( lnode2.key(), compare_linerec_to_linerec,
00959 &lnode );
00960 gul::Assert<InternalError>(ndebug | (side!=0) );
00961
00962 SwS.InsertNode(lnode2,lnode,side);
00963
00964 lnodelo = SwS.Predecessor( lnode2 );
00965 lnodehi = SwS.Successor( lnode2 );
00966
00967 if( !lnodelo.IsEmpty() )
00968 intersect( lnodelo, lnode2, enode.key()->key.x, &EvQ, &Ipts );
00969 if( !lnodehi.IsEmpty() )
00970 intersect( lnodehi, lnode2, enode.key()->key.x, &EvQ, &Ipts );
00971 }
00972 }
00973
00974
00975
00976 while( enode.key()->B.nElems > 0 )
00977 {
00978 begseg = enode.key()->B.First();
00979 enode.key()->B.Remove( begseg );
00980 seg = begseg->el;
00981
00982 side = SwS.SearchNode( seg, compare_segment_to_linerec, &lnode );
00983 if( side == 0 )
00984 {
00985 lnode.key()->S.Append( begseg );
00986
00987 sign = compare( begseg->el->E.x, lnode.key()->E.x );
00988 if( sign > 0 )
00989 {
00990 lnode.key()->E = begseg->el->E;
00991
00992
00993
00994 lnode.key()->endev.key()->E.Remove( lnode.key()->endev_node );
00995 delete lnode.key()->endev_node;
00996
00997 if( lnode.key()->endev.key()->IsEmpty() )
00998 {
00999 EvQ.RemoveNode( lnode.key()->endev );
01000 EvQ.FreeNode( lnode.key()->endev );
01001 }
01002
01003 checkneighbors = true;
01004 }
01005 else
01006 {
01007 checkneighbors = false;
01008 }
01009 }
01010 else
01011 {
01012 delete begseg;
01013
01014 lnode1 = SwS.NewNode( seg );
01015 SwS.InsertNode( lnode1, lnode, side );
01016 lnode = lnode1;
01017
01018 checkneighbors = true;
01019 }
01020
01021 if( checkneighbors )
01022 {
01023 lnodelo = SwS.Predecessor( lnode );
01024 lnodehi = SwS.Successor( lnode );
01025
01026 lstnode = new ListNode< Map<linerec>::Node >(lnode);
01027
01028 side = EvQ.SearchNode( &seg->E, compare_point_to_eventrec, &evnode );
01029 if( side != 0 )
01030 {
01031 evnode1 = EvQ.NewNode( seg->E );
01032 EvQ.InsertNode( evnode1, evnode, side );
01033 evnode = evnode1;
01034 }
01035
01036 evnode.key()->E.Append( lstnode );
01037
01038 lnode.key()->endev = evnode;
01039 lnode.key()->endev_node = lstnode;
01040
01041 if( !lnodelo.IsEmpty() )
01042 intersect( lnodelo, lnode, enode.key()->key.x, &EvQ, &Ipts );
01043 if( !lnodehi.IsEmpty() )
01044 intersect( lnodehi, lnode, enode.key()->key.x, &EvQ, &Ipts );
01045 }
01046
01047 if( iflag )
01048 {
01049
01050
01051 side = lnode.key()->I.SearchNode( &irec->I,
01052 hcompare_point_to_intersection, &irnode );
01053 if( side != 0 )
01054 {
01055 irnode1 = lnode.key()->I.NewNode(irec);
01056 lnode.key()->I.InsertNode( irnode1, irnode, side );
01057 }
01058 }
01059 }
01060
01061
01062
01063 if( enode.key()->EV != 0 )
01064 {
01065
01066
01067 if( !SwS.IsEmpty() )
01068 {
01069 side = SwS.SearchNode( &enode.key()->EV->B, compare_point_to_linerec,
01070 &lnode );
01071 if( side > 0 )
01072 lnode = SwS.Successor( lnode );
01073
01074 do
01075 {
01076 if( !lnode.IsEmpty() )
01077 {
01078 irec = intersect_vert( vlin, lnode, &Ipts );
01079 lnode = SwS.Successor( lnode );
01080 }
01081 }
01082 while( !lnode.IsEmpty() && (irec != 0) );
01083 }
01084
01085
01086
01087
01088 finish_vertline( vlin, E, V, maxE, &Ipts, &Isegs );
01089
01090 delete vlin;
01091 vlin = 0;
01092 }
01093
01094
01095
01096 while( (lrefnode = enode.key()->E.First()) != 0 )
01097 {
01098 enode.key()->E.Remove( lrefnode );
01099 lnode = lrefnode->el;
01100 delete lrefnode;
01101
01102
01103
01104
01105
01106
01107 finish_line( lnode.key(), E, V, maxE, &Ipts, &Isegs );
01108 SwS.FreeNode(lnode);
01109 }
01110
01111 EvQ.RemoveNode( enode );
01112 EvQ.FreeNode(enode);
01113 }
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128 Ipts.DeleteElems();
01129 Isegs.DeleteElems();
01130 }
01131
01132 }