shape_doc 0.1
|
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