00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef GUGR_PLANESWEEP_H
00021 #define GUGR_PLANESWEEP_H
00022
00023 namespace gugr {
00024
00025 using gul::InternalError;
00026 using gul::PoolAllocError;
00027 using gust::PoolAlloc;
00028 using gust::PoolFree;
00029 using gul::Ptr;
00030 using gul::ListNode;
00031 using gul::List;
00032 using gul::Map;
00033 using gul::RefMap;
00034 using guar::rational;
00035 using gul::point2;
00036
00037
00038
00039
00040
00041
00042 struct segment
00043 {
00044 point2<rational> B;
00045 point2<rational> E;
00046 gugr::line l;
00047 gul::ptr_int_union f[2];
00048 int m;
00049 void *reserved[2];
00050
00051 List< ListNode<gugr::graph_edge *> > e;
00052
00053 segment() { m = 0; }
00054 ~segment() { e.DeleteElems(); }
00055
00056 void *operator new( size_t s )
00057 {
00058 size_t dummy;
00059 void *p = PoolAlloc( s, &dummy );
00060 if( p == NULL ) throw PoolAllocError();
00061 return(p);
00062 }
00063 void operator delete( void *p, size_t s )
00064 {
00065 if( p != 0 ) PoolFree( p, s );
00066 }
00067
00068
00069 private:
00070 segment( const segment& other );
00071 segment& operator=( const segment& other );
00072 };
00073
00074 typedef gul::List<gul::ListNode<segment> > segment_list;
00075
00076
00077
00078
00079
00080
00081 struct intersection
00082 {
00083 point2<rational> I;
00084 List< ListNode<segment *> > S;
00085 gugr::graph_vertex *v;
00086
00087 intersection( const point2<rational>& a ) : I(a), v(0) { }
00088 ~intersection() { S.DeleteElems(); }
00089
00090 intersection *next;
00091 intersection *prev;
00092
00093 void *operator new( size_t s )
00094 {
00095 size_t dummy;
00096 void *p = PoolAlloc( s, &dummy );
00097 if( p == NULL ) throw PoolAllocError();
00098 return(p);
00099 }
00100 void operator delete( void *p, size_t s )
00101 {
00102 if( p != 0 ) PoolFree( p, s );
00103 }
00104
00105
00106 private:
00107 intersection( const intersection& other );
00108 intersection& operator=( const intersection& other );
00109
00110 };
00111
00112 struct intersectionseg
00113 {
00114 List< ListNode<segment *> > S;
00115 gugr::graph_edge *e;
00116
00117 intersectionseg( gugr::graph_edge *ae ) : e(ae) { }
00118 ~intersectionseg() { S.DeleteElems(); }
00119
00120 intersectionseg *next;
00121 intersectionseg *prev;
00122
00123 void *operator new( size_t s )
00124 {
00125 size_t dummy;
00126 void *p = PoolAlloc( s, &dummy );
00127 if( p == NULL ) throw PoolAllocError();
00128 return(p);
00129 }
00130 void operator delete( void *p, size_t s )
00131 {
00132 if( p != 0 ) PoolFree( p, s );
00133 }
00134
00135
00136 private:
00137 intersectionseg( const intersectionseg& other );
00138 intersectionseg& operator=( const intersectionseg& other );
00139 };
00140
00141
00142
00143
00144
00145 struct eventrec;
00146
00147 struct linerec
00148 {
00149 point2<rational> B;
00150 point2<rational> E;
00151 point2<rational> Borg;
00152 gugr::line l;
00153 Map<eventrec>::Node endev;
00154 ListNode< Map<linerec>::Node > *endev_node;
00155
00156 List< ListNode<segment *> > S;
00157 RefMap<intersection> I;
00158
00159 linerec( segment *s )
00160 {
00161 B = Borg = s->B; E = s->E; l = s->l;
00162 S.Append(new ListNode<segment *>(s));
00163 }
00164 ~linerec()
00165 {
00166 S.DeleteElems();
00167 I.DeleteElems();
00168 }
00169
00170 void *operator new( size_t s )
00171 {
00172 size_t dummy;
00173 void *p = PoolAlloc( s, &dummy );
00174 if( p == NULL ) throw PoolAllocError();
00175 return(p);
00176 }
00177 void operator delete( void *p, size_t s )
00178 {
00179 if( p != 0 ) PoolFree( p, s );
00180 }
00181
00182
00183 private:
00184 linerec( const linerec& other );
00185 linerec& operator=( const linerec& other );
00186 };
00187
00188 struct linepair
00189 {
00190 Map<linerec>::Node L1;
00191 Map<linerec>::Node L2;
00192
00193 linepair() { }
00194 linepair(Map<linerec>::Node aL1, Map<linerec>::Node aL2)
00195 { L1 = aL1; L2 = aL2; }
00196
00197 void *operator new( size_t s )
00198 {
00199 size_t dummy;
00200 void *p = PoolAlloc( s, &dummy );
00201 if( p == NULL ) throw PoolAllocError();
00202 return(p);
00203 }
00204 void operator delete( void *p, size_t s )
00205 {
00206 if( p != 0 ) PoolFree( p, s );
00207 }
00208 };
00209
00210
00211
00212
00213 struct eventrec
00214 {
00215 point2<rational> key;
00216 List< ListNode<segment *> > BV;
00217 List< ListNode<segment *> > B;
00218 List< ListNode< Map<linerec>::Node > > E;
00219 List<ListNode<linepair> > I;
00220 linerec * EV;
00221
00222 eventrec( const point2<rational>& akey ) { key = akey; EV = 0; }
00223 ~eventrec()
00224 {
00225 BV.DeleteElems();
00226 B.DeleteElems();
00227 E.DeleteElems();
00228 I.DeleteElems();
00229 }
00230 bool IsEmpty()
00231 {
00232 return( (BV.nElems == 0) && (B.nElems == 0) && E.IsEmpty() &&
00233 (I.nElems == 0) && (EV == 0) );
00234 }
00235 void *operator new( size_t s )
00236 {
00237 size_t dummy;
00238 void *p = PoolAlloc( s, &dummy );
00239 if( p == NULL ) throw PoolAllocError();
00240 return(p);
00241 }
00242 void operator delete( void *p, size_t s )
00243 {
00244 if( p != 0 ) PoolFree( p, s );
00245 }
00246
00247
00248 private:
00249 eventrec( const eventrec& other );
00250 eventrec& operator=( const eventrec& other );
00251 };
00252
00253
00254
00255
00256
00257
00258 int compare_pointer_to_pointer( void *p1, void *p2 );
00259
00260 struct segnode
00261 {
00262 public:
00263 int m_il;
00264 int m_ir;
00265
00266 segnode *m_left;
00267 segnode *m_right;
00268 segnode *m_parent;
00269
00270 RefMap<segment> m_segs;
00271
00272 segnode( int left, int right, segnode *parent )
00273 {
00274 m_il = left;
00275 m_ir = right;
00276
00277 m_parent = parent;
00278
00279 if( right - left > 1 )
00280 {
00281 m_left = new segnode( left, (left + right)/2, this );
00282 m_right = new segnode( (left + right)/2, right, this );
00283 }
00284 else
00285 m_left = m_right = 0;
00286 }
00287 ~segnode()
00288 {
00289 delete m_left;
00290 delete m_right;
00291
00292 m_segs.DeleteElems();
00293 }
00294 void *operator new( size_t s )
00295 {
00296 size_t dummy;
00297 void *p = PoolAlloc( s, &dummy );
00298 if( p == NULL ) throw PoolAllocError();
00299 return(p);
00300 }
00301 void operator delete( void *p, size_t s )
00302 {
00303 if( p != 0 ) PoolFree( p, s );
00304 }
00305 void insert( int beg, int end, segment *seg )
00306 {
00307 gul::Assert<gul::InternalError>( ndebug || (beg != end) );
00308
00309 if( (beg <= m_il) && (m_ir <= end) )
00310 {
00311 int side;
00312 RefMap<segment>::Node node,node1;
00313
00314 side = m_segs.SearchNode( seg,
00315 (int (*)(segment *, segment *))compare_pointer_to_pointer, &node );
00316 if( side == 0 ) throw InternalError();
00317
00318 node1 = m_segs.NewNode(seg);
00319
00320 m_segs.InsertNode( node1, node, side );
00321 }
00322 else
00323 {
00324 if( beg < (m_il + m_ir)/2 )
00325 m_left->insert( beg, end, seg );
00326 if( end > (m_il + m_ir)/2 )
00327 m_right->insert( beg, end, seg );
00328 }
00329 }
00330 void remove( int beg, int end, segment *seg )
00331 {
00332 if( (beg <= m_il) && (m_ir <= end) )
00333 {
00334 int side;
00335 RefMap<segment>::Node node;
00336
00337 side = m_segs.SearchNode( seg,
00338 (int (*)(segment *, segment *))compare_pointer_to_pointer, &node );
00339 if( side != 0 ) throw InternalError();
00340
00341 m_segs.RemoveNode( node );
00342 m_segs.FreeNode( node );
00343 }
00344 else
00345 {
00346 if( beg < (m_il + m_ir)/2 )
00347 m_left->remove( beg, end, seg );
00348 if( end > (m_il + m_ir)/2 )
00349 m_right->remove( beg, end, seg );
00350 }
00351 }
00352 void leaves_to_array( int *nL, Ptr<segnode *> *L )
00353 {
00354 if( m_left == 0 )
00355 {
00356 (*L)[*nL] = this;
00357 (*nL)++;
00358 }
00359 else
00360 {
00361 m_left->leaves_to_array( nL, L );
00362 m_right->leaves_to_array( nL, L );
00363 }
00364 return;
00365 }
00366 };
00367
00368 struct segtree
00369 {
00370 public:
00371 int m_nabsz;
00372 Ptr<intersection *> m_absz;
00373 segnode *m_root;
00374
00375 segtree( )
00376 {
00377 m_nabsz = 0;
00378 m_root = 0;
00379 }
00380 segtree( int nabsz, Ptr<intersection *> abszissa )
00381 {
00382 m_nabsz = nabsz;
00383 m_absz = abszissa;
00384
00385 m_root = new segnode(0, m_nabsz-1, 0 );
00386 }
00387 ~segtree()
00388 {
00389 delete m_root;
00390 }
00391 void init( int nabsz, Ptr<intersection *> abszissa )
00392 {
00393 delete m_root;
00394
00395 m_nabsz = nabsz;
00396 m_absz = abszissa;
00397
00398 m_root = new segnode(0, m_nabsz-1, 0 );
00399 }
00400 void insert( int beg, int end, segment *seg )
00401 {
00402 m_root->insert( beg, end, seg );
00403 }
00404 int leaves_to_array( Ptr<segnode *> *L )
00405 {
00406 int nL = 0;
00407
00408 if( m_nabsz > 0 )
00409 {
00410 int maxn = (int)(ceil(log((double)m_nabsz)/log(2.0))*2.0) + 2;
00411 (*L).reserve_pool( maxn );
00412 if( m_root )
00413 m_root->leaves_to_array( &nL, L );
00414 }
00415 return nL;
00416 }
00417 };
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 void DoIntersectSegments( int nsegs, Map<eventrec>& EvQ,
00433 gugr::graph_edge_list *E, gugr::graph_vertex_list *V );
00434
00435
00436
00437
00438 int compare_point_to_eventrec( point2<rational> *C, eventrec *E );
00439
00440
00441 inline void IntersectSegments( int nsegs, Ptr<segment> segs,
00442 gugr::graph_edge_list *E, gugr::graph_vertex_list *V )
00443 {
00444 gul::Map<eventrec> EvQ;
00445 int i,side;
00446 gul::Map<eventrec>::Node enode,enode1;
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 for( i = 0; i < nsegs; i++ )
00459 {
00460 side = EvQ.SearchNode( &segs[i].B, compare_point_to_eventrec, &enode );
00461 if( side != 0 )
00462 {
00463 enode1 = EvQ.NewNode( segs[i].B );
00464 EvQ.InsertNode( enode1, enode, side );
00465 enode = enode1;
00466 }
00467 if( segs[i].l.IsVertical() )
00468 enode.key()->BV.Append( new ListNode<segment *>(&segs[i]) );
00469 else
00470 enode.key()->B.Append( new ListNode<segment *>(&segs[i]) );
00471 }
00472
00473 DoIntersectSegments( nsegs, EvQ, E, V );
00474 }
00475
00476 inline void ISDeleteOwnerMaps( gugr::graph_edge_list &E )
00477 {
00478 graph_edge *e = E.First();
00479
00480 while( e )
00481 {
00482 delete (gul::RefMap<void> *)e->f[0].p;
00483 e->f[0].p = 0;
00484 delete (gul::RefMap<void> *)e->f[1].p;
00485 e->f[1].p = 0;
00486
00487 e = e->next;
00488 }
00489 }
00490
00491 inline void ISDeleteBackpointers( gugr::graph_edge_list& E )
00492 {
00493 graph_edge *e;
00494 gul::List< gul::ListNode< gul::ListNodeInfo< gul::ListNode<graph_edge *>
00495 > > > *L;
00496
00497 e = E.First();
00498 while( e )
00499 {
00500 L = (gul::List< gul::ListNode< gul::ListNodeInfo<
00501 gul::ListNode<graph_edge *> > > > *)e->reserved[1].p;
00502 L->DeleteElems();
00503 delete L;
00504 e->reserved[1].p = 0;
00505
00506 e = e->next;
00507 }
00508 }
00509
00510
00511
00512
00513
00514
00515 template< class T >
00516 class DumpPS
00517 {
00518 public:
00519 GULAPI static T orgx,orgy,scalex,scaley;
00520 public:
00521 static void set_transformation( T aorgx, T aorgy, T ascalex, T ascaley )
00522 {
00523 orgx = aorgx;
00524 orgy = aorgy;
00525 scalex = ascalex;
00526 scaley = ascaley;
00527 }
00528 static void dump_intersection( intersection *i )
00529 {
00530 double dx1,dy1;
00531 T x1,y1;
00532 ListNode<segment *> *snode;
00533
00534 if( i != NULL )
00535 {
00536 i->I.x.dump(dx1);
00537 i->I.y.dump(dy1);
00538 x1 = (T)dx1;
00539 y1 = (T)dy1;
00540
00541 x1 = cnv2coord<T>(x1)*scalex + orgx;
00542 y1 = cnv2coord<T>(y1)*scaley + orgy;
00543 cout << "INTERSECTION POINT\n";
00544 cout << (void *)i << ": (" <<
00545 std::setprecision(8) << x1 << ", " << y1 << ")\n";
00546
00547 cout << "owner segments = {";
00548 snode = i->S.First();
00549 if( snode != 0 )
00550 {
00551 cout << (void *)snode->el;
00552 snode = snode->next;
00553 while( snode != 0 )
00554 {
00555 cout << ", " << (void *)snode->el;
00556 snode = snode->next;
00557 }
00558 }
00559 cout << "}\n";
00560 }
00561 std::cout.flush();
00562 }
00563 static void dump_intersections( List<intersection>& Ipts )
00564 {
00565 intersection *i = Ipts.First();
00566 while( i != 0 )
00567 {
00568
00569 dump_intersection(i);
00570 i = i->next;
00571 }
00572 }
00573 static void dump_linerec( linerec *L )
00574 {
00575 double dx1,dx2,dy1,dy2;
00576 T x1,x2,y1,y2;
00577 RefMap<intersection>::Node ir;
00578 ListNode<segment *> *snode;
00579
00580 cout << "LINEREC\n";
00581 L->Borg.x.dump(dx1);
00582 L->Borg.y.dump(dy1);
00583 L->E.x.dump(dx2);
00584 L->E.y.dump(dy2);
00585
00586 x1 = (T)dx1; x2 = (T)dx2; y1 = (T)dy1; y2 = (T)dy2;
00587
00588 x1 = cnv2coord<T>(x1)*scalex + orgx;
00589 x2 = cnv2coord<T>(x2)*scalex + orgx;
00590 y1 = cnv2coord<T>(y1)*scaley + orgy;
00591 y2 = cnv2coord<T>(y2)*scaley + orgy;
00592
00593 cout << std::setprecision(8) << "(" << x1 << ", " << y1 << "), " <<
00594 "(" << x2 << ", " << y2 << ")\n";
00595 cout.flush();
00596
00597 cout << "segments = {";
00598 snode = L->S.First();
00599 if( snode )
00600 {
00601 cout << (void *)snode->el;
00602 snode = snode->next;
00603 while( snode )
00604 {
00605 cout << ", " << (void *)snode->el;
00606 snode = snode->next;
00607 }
00608 }
00609 cout << "}\n";
00610
00611 ir = L->I.First();
00612 while( !ir.IsEmpty() )
00613 {
00614 dump_intersection( ir.key() );
00615 ir = L->I.Successor( ir );
00616 }
00617 }
00618 static void dump_segment( segment *S )
00619 {
00620 double dx1,dx2,dy1,dy2;
00621 T x1,x2,y1,y2;
00622
00623 std::cout << "SEGMENT ";
00624 S->B.x.dump(dx1);
00625 S->B.y.dump(dy1);
00626 S->E.x.dump(dx2);
00627 S->E.y.dump(dy2);
00628
00629 x1 = (T)dx1; x2 = (T)dx2; y1 = (T)dy1; y2 = (T)dy2;
00630
00631 x1 = cnv2coord<T>(x1)*scalex + orgx;
00632 x2 = cnv2coord<T>(x2)*scalex + orgx;
00633 y1 = cnv2coord<T>(y1)*scaley + orgy;
00634 y2 = cnv2coord<T>(y2)*scaley + orgy;
00635
00636 std::cout << std::setprecision(8) << (void *)S <<
00637 ":(" << x1 << ", " << y1 << "), " <<
00638 "(" << x2 << ", " << y2 << "), L=" << S->f[0].p <<
00639 ", R=" << S->f[1].p << "\n";
00640 std::cout.flush();
00641 }
00642 static void dump_segments( List<ListNode<segment > >& L )
00643 {
00644 ListNode<segment> *sn;
00645 for( sn = L.First(); sn; sn = sn->next )
00646 dump_segment(&sn->el);
00647 }
00648
00649 static void dump_intersectionseg( intersectionseg *i )
00650 {
00651 double dx1,dx2,dy1,dy2;
00652 T x1,x2,y1,y2;
00653 ListNode<segment *> *snode;
00654
00655 cout << "INTERSECTION SEGMENT\n";
00656 i->e->v[0]->v.v().m_x.Dump(dx1);
00657 i->e->v[0]->v.v().m_y.Dump(dy1);
00658 i->e->v[1]->v.v().m_x.Dump(dx2);
00659 i->e->v[1]->v.v().m_y.Dump(dy2);
00660
00661 x1 = (T)dx1; x2 = (T)dx2; y1 = (T)dy1; y2 = (T)dy2;
00662
00663 x1 = cnv2coord<T>(x1)*scalex + orgx;
00664 x2 = cnv2coord<T>(x2)*scalex + orgx;
00665 y1 = cnv2coord<T>(y1)*scaley + orgy;
00666 y2 = cnv2coord<T>(y2)*scaley + orgy;
00667
00668 cout << std::setprecision(8) << (void *)i <<
00669 ": ((" << x1 << ", " << y1 << "), " <<
00670 "(" << x2 << ", " << y2 << "))\n";
00671
00672 cout << "owner segments = {";
00673 snode = i->S.First();
00674 if( snode != 0 )
00675 {
00676 cout << (void *)snode->el;
00677 snode = snode->next;
00678 while( snode != 0 )
00679 {
00680 cout << ", " << (void *)snode->el;
00681 snode = snode->next;
00682 }
00683 }
00684 cout << "}\n";
00685
00686 cout.flush();
00687 }
00688 static void dump_intersectionsegs( List<intersectionseg>& Isegs )
00689 {
00690 intersectionseg *i = Isegs.First();
00691 while( i != 0 )
00692 {
00693 if( i->S.nElems > 1 )
00694 dump_intersectionseg(i);
00695 i = i->next;
00696 }
00697 }
00698
00699 static void dump_edge( graph_edge *e )
00700 {
00701 double dx1,dx2,dy1,dy2;
00702 T x1,x2,y1,y2;
00703 RefMap<void> *owners;
00704 RefMap<void>::Node owner;
00705
00706 e->v[0]->v.v().m_x.Dump(dx1);
00707 e->v[0]->v.v().m_y.Dump(dy1);
00708 e->v[1]->v.v().m_x.Dump(dx2);
00709 e->v[1]->v.v().m_y.Dump(dy2);
00710
00711 x1 = (T)dx1; x2 = (T)dx2; y1 = (T)dy1; y2 = (T)dy2;
00712
00713 x1 = cnv2coord<T>(x1)*scalex + orgx;
00714 x2 = cnv2coord<T>(x2)*scalex + orgx;
00715 y1 = cnv2coord<T>(y1)*scaley + orgy;
00716 y2 = cnv2coord<T>(y2)*scaley + orgy;
00717
00718 cout << (void *)e << "((" << x1 << "," << y1 << "),(" << x2 << "," << y2 <<
00719 ")) ";
00720
00721 cout << "L={";
00722 owners = (RefMap<void> *)e->f[0];
00723 owner = owners->First();
00724 if( !owner.IsEmpty() )
00725 {
00726 cout << (void *)owner.key();
00727 owner = owners->Successor(owner);
00728 while( !owner.IsEmpty() )
00729 {
00730 cout << "," << (void *)owner.key();
00731 owner = owners->Successor(owner);
00732 }
00733 }
00734 cout << "}, R={";
00735 owners = (RefMap<void> *)e->f[1];
00736 owner = owners->First();
00737 if( !owner.IsEmpty() )
00738 {
00739 cout << (void *)owner.key();
00740 owner = owners->Successor(owner);
00741 while( !owner.IsEmpty() )
00742 {
00743 cout << "," << (void *)owner.key();
00744 owner = owners->Successor(owner);
00745 }
00746 }
00747 cout << "}\n";
00748 }
00749 static void dump_edges( graph_edge_list& E )
00750 {
00751 graph_edge *e = E.First();
00752 while( e != 0 )
00753 {
00754 dump_edge(e);
00755 e = e->next;
00756 }
00757 }
00758
00759 static void dump_point( const gul::point2<guar::rational>& P )
00760 {
00761 double dx,dy;
00762 T tx,ty;
00763
00764 P.x.dump(dx);
00765 P.y.dump(dy);
00766
00767 tx = (T)dx;
00768 ty = (T)dy;
00769
00770 tx = cnv2coord<T>(tx)*scalex + orgx;
00771 ty = cnv2coord<T>(ty)*scaley + orgy;
00772
00773 std::cout << "(" << tx << ", " << ty << ")\n";
00774 }
00775
00776 };
00777
00778
00779
00780 inline void IntersectSegments( gul::List< gul::ListNode<segment> >& segs,
00781 gugr::graph_edge_list *E, gugr::graph_vertex_list *V,
00782 bool need_backpointers )
00783 {
00784 gul::Map<eventrec> EvQ;
00785 int side;
00786 gul::Map<eventrec>::Node enode,enode1;
00787 segment *s;
00788 ListNode<segment> *sn;
00789
00790
00791
00792
00793
00794 sn = segs.First();
00795
00796 while( sn )
00797 {
00798 s = &sn->el;
00799
00800 side = EvQ.SearchNode( &s->B, compare_point_to_eventrec, &enode );
00801 if( side != 0 )
00802 {
00803 enode1 = EvQ.NewNode( s->B );
00804 EvQ.InsertNode( enode1, enode, side );
00805 enode = enode1;
00806 }
00807 if( s->l.IsVertical() )
00808 enode.key()->BV.Append( new ListNode<segment *>(s) );
00809 else
00810 enode.key()->B.Append( new ListNode<segment *>(s) );
00811
00812 sn = sn->next;
00813 }
00814
00815 DoIntersectSegments( segs.nElems, EvQ, E, V );
00816
00817 if( !need_backpointers )
00818 {
00819 ISDeleteBackpointers( *E );
00820 }
00821 }
00822
00823
00824 }
00825
00826 #endif
00827