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