Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

gugr_planesweep.h

Go to the documentation of this file.
00001 /* LIBGUL - Geometry Utility Library
00002  * Copyright (C) 1998-1999 Norbert Irmer
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
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   Structure which describes the input line segments for planesweep algorithm.
00039   It is used for storing the edges of the output graph which make up this
00040   segment too !
00041 -----------------------------------------------------------------------*/
00042 struct segment
00043 {
00044   point2<rational> B;
00045   point2<rational> E;
00046   gugr::line  l;
00047   gul::ptr_int_union  f[2];        // left and right side owners
00048   int                 m;           // multiplicity
00049   void               *reserved[2]; // for internal use
00050 
00051   List< ListNode<gugr::graph_edge *> > e; // output graph edges
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   // shouldn't be copied (because of the destructor)
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   Structures for storing intersection points and segments.
00078   They contain a list of the original line-segments, which
00079   contain this intersections
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; /* for storing all intersections in a list */
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   // musn't be copied (because of the destructor)
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; /* for storing all intersections in a list */
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   // musn't be copied (because of the destructor)
00136 private:
00137   intersectionseg( const intersectionseg& other );  
00138   intersectionseg& operator=( const intersectionseg& other );
00139 };
00140 
00141 /*--------------------------------------------------------------------
00142   Events for Event queue of planesweep algorithm
00143 ---------------------------------------------------------------------*/
00144 
00145 struct eventrec;
00146 
00147 struct linerec  // record for lines formed by one or more overlapping 
00148 {               // line segments
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   // musn't be copied (because of the destructor)
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   Event record for planesweep algorithm
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   // musn't be copied (because of the destructor)
00248 private:
00249   eventrec( const eventrec& other );  
00250   eventrec& operator=( const eventrec& other );
00251 };
00252 
00253 /*----------------------------------------------------------------------
00254   Tree for storing intervalls with a fixed set of abscissa 
00255   (Interval Tree, see Preparata/Shamos)
00256 ----------------------------------------------------------------------*/
00257 
00258 int compare_pointer_to_pointer( void *p1, void *p2 );
00259 
00260 struct segnode
00261 {
00262 public:
00263   int m_il;   // index of left bound of intervall
00264   int m_ir;   // index of right bound of intervall
00265 
00266   segnode *m_left;
00267   segnode *m_right;
00268   segnode *m_parent;
00269 
00270   RefMap<segment> m_segs;     // segments that contain this standard intervall
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   Determine all intersections of a set of line segments
00421 
00422   Remarks: This function currently just creates a graph with intersections
00423   (points and segments) only inserted once.
00424   This isn't very useful alone, but at least, when used in the NURBS
00425   trimming code, it avoids crashes when a graph with intersecting trim
00426   contours is regularized (but the resulting triangulated graph is still
00427   nonsense, since the face flags of the edges of the overlapping trim
00428   contours are inconsistent). 
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 // forward reference, needed for inline definition
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   cout << "PLANESWEEP\n";
00450   cout << "==========\n";
00451   cout << "INPUT SEGMENTS\n";
00452   for( i = 0; i < nsegs; i++ )
00453     DumpPS<float>::dump_segment( &segs[i] );
00454   */  
00455 
00456   /*--- initialize event queue with the lines leftmost endpoints ---*/
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 )         // delete backpointer lists
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   DEBUGGING STUFF
00512   output functions, just for debugging
00513 ------------------------------------------------------------------------*/
00514 // #ifndef NDEBUG
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 //      if( i->S.nElems > 1 )  /* if i is a real intersection */
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 )  /* if i is a real intersection */
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 // #endif
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   /*--- initialize event queue with the lines leftmost endpoints ---*/
00791 
00792   // gugr::DumpPS<float>::dump_segments( segs );
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 

Generated on Mon Jan 21 04:17:30 2002 for GUL 0.6 - Geometry Utility Library by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001