shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/src/ssi_dsearch_build.cpp
Go to the documentation of this file.
00001 #include <shape/ssi_dsearch.hpp>
00002 
00003 namespace mmx {
00004 namespace  shape_ssi {
00005 
00006 template<class Container>
00007 void search( Container& c, sdpoint_t * first, sdpoint_t * last, double epsilonn ) 
00008 {
00009   sdknode* root;
00010   root = make(first,last,dim_cmp<sdpoint_t>());
00011   for ( sdpoint_t * p = first; p < last; p++ )
00012     search(c,root,p,0,epsilonn);
00013   delete root;
00014 };
00015 
00016 
00017 template<class Container>
00018  void search( Container& c, pdpoint_t * first, pdpoint_t * last, double epsilonn ) 
00019 {
00020   pdknode* root;
00021   pdpoint_t ** tmp = new pdpoint_t*[last-first];
00022   int i;
00023   for ( i = 0; i < last-first; i++ )
00024     tmp[i] = first + i;
00025   root = make(tmp,tmp + (last-first),dim_cmp<pdpoint_t>());
00026   delete[] tmp;
00027   for ( pdpoint_t * p = first; p < last; p++ )
00028     search(c,root,p,0,epsilonn);
00029   delete root;
00030 };
00031 
00032 template<class Container>
00033 void search( Container& c, sdknode * curr, sdpoint_t * const  query, unsigned dim, double eps  ) 
00034 {
00035   if (! curr ) return;
00036   
00037   bool left  = (*query)[dim]-eps<(*(curr->data))[dim];   
00038   bool right = (*query)[dim]+eps>(*(curr->data))[dim];
00039   
00040   if ( (left && right) && (query<curr->data) && (curve(query) != curve(curr->data)) )
00041     {
00042       double d = distance(curr->data,query);
00043       if ( (d<eps) ) 
00044         container_add(c,assoc_t<sdpoint_t>(query,curr->data,d));
00045     };
00046   if ( left  ){  search( c, curr->l, query, (dim+1)%4, eps ); };
00047   if ( right ){  search( c, curr->r, query, (dim+1)%4, eps ); };
00048 };
00049 
00050 template<class Container>
00051  void search( Container& c, pdknode * curr, pdpoint_t * const  query, unsigned dim, double eps  ) 
00052 {
00053   if (! curr ) return;
00054   
00055   bool left  = (*query)[dim]-eps<(*(curr->data))[dim];   
00056   bool right = (*query)[dim]+eps>(*(curr->data))[dim];
00057   if ( (left && right) && (query<curr->data) && (curve(query) != curve(curr->data)) )
00058     {
00059       double d = distance(curr->data,query);
00060       if ( (d<eps) ) 
00061         container_add(c,assoc_t<pdpoint_t>(query,curr->data,d));
00062     };
00063   if ( left  ){  search( c, curr->l, query, (dim+1)%4, eps ); };
00064   if ( right ){  search( c, curr->r, query, (dim+1)%4, eps ); };
00065 };
00066 
00067 
00068 void build_pheap( pheap_t& h, pdpoint_t * first, pdpoint_t * last, double prec )
00069 {
00070   search(h,first,last,prec);
00071 };
00072 
00073 void build_pset( pset_t& s, pdpoint_t * first, pdpoint_t * last, double prec )
00074 {
00075   search(s,first,last,prec);
00076 };
00077 
00078 void build_sheap( sheap_t& h, sdpoint_t * first, sdpoint_t * last, double prec )
00079 {
00080   search(h,first,last,prec);
00081 };
00082 
00083 
00084   void solve_pheap( pheap_t& h )
00085     {
00086       
00087       while( !h.empty() )
00088         {
00089           pdassc_t a = h.top();
00090           
00091           if (( isextrem(a.pp.first) && isextrem(a.pp.second) ) && 
00092               ( curve(a.pp.first) != curve(a.pp.second) )) 
00093             {
00094               link(a.pp.first,a.pp.second);
00095             };
00096           h.pop();
00097         };
00098     };
00099   
00100 void solve_sheap( sheap_t& h )
00101 {
00102   // dcurve * dummy_curve = new dcurve( point2(), point2(), point2(), point2(),
00103   //                             point3(), point3() );
00104   while( !h.empty() )
00105     {
00106       sdassc_t a = h.top();
00107       //          cout << a.d << endl;
00108       if (( isextrem(a.pp.first) && isextrem(a.pp.second) ) && 
00109           ( curve(a.pp.first) != curve(a.pp.second) )) 
00110         link(a.pp.first,a.pp.second);
00111       h.pop();
00112     };
00113 };
00114 
00115 sdknode * make( sdpoint_t * first, sdpoint_t * last, const dim_cmp<sdpoint_t>& f ) 
00116 {     
00117   if ( last-first >= 1 ) {
00118     if ( last-first > 1 ) { 
00119       unsigned m = (last-first)>>1;
00120       std::nth_element(first, first+m,last,f);
00121       return new sdknode( first+m, 
00122                           make( first, first + m, f.next()), 
00123                           make( first+m+1, last,  f.next()) ); }
00124     else { return new sdknode(first,0,0); };};
00125   return 0; 
00126 };
00127 
00128 pdknode * make( pdpoint_t ** first, pdpoint_t ** last, const dim_cmp<pdpoint_t>& f ) 
00129 {     
00130   if ( last-first >= 1 ) {
00131     if ( last-first > 1 ) { 
00132       unsigned m = (last-first)>>1;
00133       std::nth_element(first, first+m,last,f);
00134       return new pdknode( *(first+m), 
00135                           make( first, first + m, f.next()), 
00136                           make( first+m+1, last,  f.next()) ); }
00137     else { return new pdknode(*first,0,0); };};
00138   return 0; 
00139 };
00140 
00141 
00142 void solve_pset( curves_links_t& links, pset_t& s )
00143 {
00144   while ( !s.empty() )
00145     {
00146       pdassc_t ass(sibbles(*(s.begin())));
00147       pset_iterator it; 
00148       it = s.find( ass  );
00149       if( it  != s.end() )
00150         {
00151           s.erase(s.find(ass));
00152           cpair_t tmp (curves(*(s.begin())));
00153           ppair_t p = (s.begin())->pp;
00154           if ( curve(p.first) != tmp.first ) 
00155             {
00156               links[tmp.second].push_front(p);
00157               std::swap(p.first,p.second);
00158               links[tmp.first].push_front(p);
00159             }
00160           else                  
00161               {
00162                 links[tmp.first].push_front(p);
00163                 std::swap(p.first,p.second);
00164                 links[tmp.second].push_front(p);
00165               };
00166         };
00167       s.erase(s.begin());
00168     };
00169 };
00170 
00171 std::list<dcurve*> * reduce2( std::vector< dcurve * > * conflicts )
00172 {
00173   if ( conflicts->size() == 0 ) return 0;
00174   unsigned   i;
00175   unsigned   endsize  = 4*conflicts->size();
00176   pdpoint_t * ends = new pdpoint_t[endsize];
00177   unsigned c = 0;
00178   for ( i = 0; i < conflicts->size(); i++ )
00179     {
00180       extremums( ends + c, (*conflicts)[i] );
00181       c+= 4;
00182     };
00183   
00184   pset_t s;
00185   build_pset(s,ends, ends + endsize, 0.01 );
00186   
00187   curves_links_t links;
00188   solve_pset(links,s);
00189   
00190   
00191   for (  curves_links_t::iterator it = links.begin(); 
00192          it != links.end(); it++ )
00193     satisfy_links( it );
00194   
00195   delete[] ends;
00196   
00197   std::list< dcurve* > * result = new std::list< dcurve * >();
00198   
00199   for ( i = 0; i < conflicts->size() ; i++ )
00200     {
00201       if ( empty((*conflicts)[i]) ) delete (*conflicts)[i];
00202       else result->push_front( (*conflicts)[i] );
00203     };
00204   
00205   return result;
00206 };
00207 
00208 std::list<dcurve*> * dsearch::reduce( std::vector< dcurve * > * conflicts )
00209 {
00210   unsigned i;
00211   if ( conflicts->size() == 0 ) return 0;
00212   
00213   unsigned   endsize  = 2*conflicts->size();
00214   sdpoint_t * ends = new sdpoint_t[endsize];
00215   
00216   for ( i = 0; i < endsize; i+= 2 )
00217     extremums( ends + i, (*conflicts)[i/2] );
00218       
00219   sheap_t h;
00220   build_sheap(h,ends, ends + endsize, 0.04 );
00221   solve_sheap(h);
00222   delete[] ends;
00223   std::list< dcurve* > * result = new std::list< dcurve * >();
00224   for ( i = 0; i < conflicts->size() ; i++ )
00225     {
00226       if ( empty((*conflicts)[i]) ) delete (*conflicts)[i];
00227       else result->push_front( (*conflicts)[i] );
00228     };
00229   return result;
00230 };
00231 }
00232 } //namespace mmx    
00233   
00234