00001
00002 #ifndef _CYL_GEOM_HH_
00003 #define _CYL_GEOM_HH_
00004
00013 #include <set>
00014 #include <list>
00015 #include <vector>
00016 #include <cmath>
00017
00018 namespace JetGeom {
00019
00021 class point_t : public std::pair<float , float>{
00022 public:
00023 point_t(float x, float y){first = x; second = y;}
00024 };
00025 class point_set_t : public std::set<point_t> {};
00026 class point_vect_t : public std::vector<point_t> {};
00027
00028 typedef std::list<point_t> point_list_t;
00029
00030
00033 class line_t {
00034 public:
00035
00039 line_t(float cx, float cy, float cc, bool to_r) : m_cx(cx),m_cy(cy),m_cc(cc), m_oriented_r(to_r) {};
00041 line_t(point_t p1, point_t p2);
00042
00043 float m_cx, m_cy, m_cc;
00044 bool m_oriented_r;
00045
00046
00047 bool is_above(point_t &p);
00048 bool is_below(point_t &p);
00049
00050 bool is_left(point_t &p) {return m_oriented_r ? is_above(p) : is_below(p);};
00051 bool is_right(point_t &p) {return m_oriented_r ? is_below(p) : is_above(p);};
00052
00053 void phi_shift(float dphi) {m_cc = m_cc - m_cy*dphi;}
00054
00055 point_t intercept_y(float y);
00056 point_t intercept_x(float x);
00057
00058 };
00059
00060
00061
00062
00065 template< class inT, class ouT>
00066 void findConvexHull(inT &inSet, ouT &outSet );
00068 template<class ouT>
00069 void findConvexHull(point_set_t &inSet, ouT &outSet );
00070
00071 template< class inT>
00072 void _findConvexHull(point_set_t &inSet, inT &outSet );
00073
00074
00075 void testHullLine(point_list_t &hull, point_t p);
00076
00077
00078 template<class T>
00079 float polygon_area(T& line);
00080
00081 template<class T>
00082 float polygon_lenght(T& line);
00083
00084
00085
00086
00087
00088
00089
00094 template <class T>
00095 float getMeanPhi(T &set);
00097 template<class T>
00098 float max_deltaR(point_t p, T& set);
00099
00100
00102 template<class T , class T2>
00103 void recenter_set(T &inSet, T2 &outSet, float phicenter);
00106 template<class T , class T2>
00107 void recenter_set(T &inSet, T2 &outSet);
00108
00109
00111 inline float in_mPI_pPI(float phi);
00113 inline void fix2pi(point_t &p);
00115 inline float deltaR(point_t &p1, point_t &p2);
00116 inline float deltaR2(point_t &p1, point_t &p2);
00117
00118 inline float deltaPhi(point_t &p1, point_t &p2);
00119 inline float deltaPhi(float phi1, float phi2);
00120
00121
00122
00123
00124
00125
00126 void listToSet(point_list_t &inList, point_set_t &outSet);
00127 template<class T>
00128 void clear_delete(T &container);
00129 template<class T>
00130 void delete_content(T &container);
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 #ifndef G__DICTIONARY
00141
00142
00143 template<class T>
00144 void clear_delete(T &container){
00145 typedef typename T::iterator it_t;
00146 it_t it = container.begin();
00147 it_t itE = container.end();
00148 for(; it != itE; ++it) delete *it;
00149 container.clear();
00150 }
00151 template<class T>
00152 void delete_content(T &container){
00153 typedef typename T::iterator it_t;
00154 it_t it = container.begin();
00155 it_t itE = container.end();
00156 for(; it != itE; ++it) delete *it;
00157 }
00158
00159 template<class T>
00160 float max_deltaR(point_t p, T& set){
00161 typedef typename T::iterator it_t;
00162 it_t it = set.begin();
00163 it_t itE = set.end();
00164 float r=0;
00165 for(; it != itE; ++it){
00166 float t = deltaR(p, *it);
00167 if(t>r) r=t;
00168 }
00169 return r;
00170 }
00171
00172 template<class T>
00173 float polygon_area(T& line){
00174 typedef typename T::iterator it_t;
00175 it_t it = line.begin();
00176 it_t itE = line.end();
00177 float a=0;
00178 for(; it != itE; ++it){
00179 it_t itp=it;
00180 itp++;
00181 if(itp == itE) itp = line.begin();
00182 a += ( (*it).first*(*itp).second - (*itp).first*(*it).second );
00183 }
00184 return a/2;
00185 }
00186
00187 template<class T>
00188 float polygon_lenght(T &line){
00189 typedef typename T::iterator it_t;
00190 it_t it = line.begin();
00191 it_t itE = line.end();
00192 float a=0;
00193 for(; it != itE; ++it){
00194 it_t itp=it;
00195 itp++;
00196 if(itp == itE) itp = line.begin();
00197 a += deltaR(*it,*itp);
00198 }
00199 return a;
00200 }
00201
00202 inline float abs_dphi(float phi1, float phi2){
00203 float d = fabs(phi1 - phi2);
00204 return d < M_PI ? d: fabs(d-2*M_PI);
00205 }
00206 inline float deltaPhi(float phi1, float phi2){
00207 return in_mPI_pPI(phi1-phi2);
00208 }
00209 inline float deltaPhi(point_t &p1, point_t &p2){
00210 return deltaPhi(p1.second,p2.second);
00211 }
00212 inline float in_mPI_pPI(float phi){
00213 while(phi < -M_PI) phi += 2*M_PI;
00214 while(phi >= M_PI) phi -= 2*M_PI;
00215 return phi;
00216 }
00217 inline void fix2pi(point_t &p){
00218 while(p.second < -M_PI) p.second += 2*M_PI;
00219 while(p.second >= M_PI) p.second -= 2*M_PI;
00220 }
00221
00222 inline point_t recenter(const point_t &p, const point_t ¢er){
00223 point_t n(p.first, p.second - center.second);
00224 fix2pi(n);
00225 return n;
00226 }
00227 inline point_t recenter(const point_t &p, float phicenter){
00228 point_t n(p.first, p.second - phicenter);
00229 fix2pi(n);
00230 return n;
00231 }
00232 inline float deltaR2(point_t &p1, point_t &p2){
00233 return (p1.first-p2.first)*(p1.first-p2.first) +
00234 abs_dphi(p1.second,p2.second)*abs_dphi(p1.second,p2.second) ;
00235 }
00236 inline float deltaR(point_t &p1, point_t &p2){
00237 return sqrt( deltaR2(p1,p2) );
00238 }
00239
00240 template<class T , class T2>
00241 void recenter_set(T &inSet, T2 &outSet, float phicenter){
00242 typedef typename T::iterator it_t;
00243 typedef typename T2::iterator it_t2;
00244 it_t it = inSet.begin();
00245 it_t itE = inSet.end();
00246 it_t2 it2 = outSet.begin();
00247 for(; it!= itE; ++it){
00248 it2 = outSet.insert(it2,recenter(*it,phicenter));
00249 }
00250 }
00251 template<class T , class T2>
00252 void recenter_set(T &inSet, T2 &outSet){
00253 float phicenter = getMeanPhi(inSet);
00254 if (phicenter <-9) return;
00255 recenter_set(inSet,outSet,phicenter);
00256 }
00257
00258 template <class T>
00259 float getMeanPhi(T &set){
00260
00261 typedef typename T::iterator it_t;
00262 it_t it = set.begin();
00263 it_t end = set.end();
00264 point_t fp = (*it);
00265 float max= 0,min=0, mean=0;
00266 int n=0;
00267 for(; it!= end; ++it){
00268 float phi = recenter((*it),fp).second;
00269 if( phi >0){
00270 max = phi>max ? phi : max;
00271 }else{
00272 min = phi<min ? phi : min;
00273 }
00274 mean+=phi; n++;
00275 }
00276 if ( (max-min) <= (M_PI) )
00277 return in_mPI_pPI(mean/n+fp.second);
00278 else return -10;
00279 }
00280
00281
00282
00283 inline line_t::line_t(point_t p1, point_t p2){
00284 m_cy = p1.first - p2.first;
00285 m_cx = p2.second - p1.second;
00286 m_cc = -(m_cx*p1.first+m_cy*p1.second);
00287 m_oriented_r = (p1.first < p2.first);
00288 }
00289
00290 inline bool line_t::is_above(point_t &p){
00291 return ( (m_cy!=0) && ( p.second >= - (m_cx*p.first+m_cc)/m_cy) );
00292 }
00293
00294 inline bool line_t::is_below(point_t &p){
00295 return ( (m_cy!=0) && ( p.second <= - (m_cx*p.first+m_cc)/m_cy) ) ;
00296 }
00297
00298 inline point_t line_t::intercept_y(float y){
00299 if(m_cx==0) return point_t(-99999,y);
00300 return point_t( (-m_cc - m_cy*y)/m_cx , y);
00301 }
00302
00303 inline point_t line_t::intercept_x(float x){
00304 if(m_cy==0) return point_t(x,-99999);
00305 return point_t( x, (-m_cc - m_cx*x)/m_cy );
00306 }
00307
00308
00309
00310
00311
00312 template< class inT, class ouT>
00313 void findConvexHull(inT &inSet, ouT &outSet ){
00314 point_set_t rset;
00315 typedef typename inT::iterator it_t;
00316 it_t it = inSet.begin();
00317 it_t itE = inSet.end();
00318 for(; it!=itE; ++it) rset.insert(*it);
00319 _findConvexHull(rset,outSet);
00320 }
00321
00322 template<class ouT>
00323 void findConvexHull(point_set_t &inSet, ouT &outSet ){
00324 _findConvexHull(inSet, outSet);
00325 }
00326
00327 template <class T>
00328 void _findConvexHull(point_set_t &inSet, T &outSet ){
00329
00330 if(inSet.size()<4){
00331 outSet.insert(outSet.begin(), inSet.begin(), inSet.end() );
00332 return;
00333 }
00334
00335 point_set_t::iterator s_it = inSet.begin();
00336 point_t point00 = (*s_it);
00337 point_t point01= point00;
00338 while(point01.first == point00.first){
00339 ++s_it;
00340 point01 = *s_it;
00341 }
00342 --s_it; point01 = *s_it;
00343
00344 s_it = inSet.end(); --s_it;
00345 point_t point11 = (*s_it);
00346 point_t point10= point11;
00347 while(point10.first == point11.first){
00348 --s_it;
00349 point10 = *s_it;
00350 }
00351 ++s_it; point10 = *s_it;
00352
00353
00354 line_t lmin(point00, point10);
00355
00356 line_t lmax(point01, point11);
00357
00358
00359 point_list_t lowPoints, upPoints;
00360
00361 s_it = inSet.begin();
00362 if(point00 == point01 ){
00363 lowPoints.push_back(point00);
00364 upPoints.push_back(point00);
00365 s_it++;
00366 }
00367
00368 point_set_t::iterator s_itE = inSet.end();
00369 s_itE--;
00370 for(; s_it!= s_itE; ++s_it){
00371 point_t p = *s_it;
00372
00373 if( lmin.is_below(p)) {
00374 lowPoints.push_back(p);
00375 continue;
00376 }
00377 if( lmax.is_above(p)) {
00378 upPoints.push_front(p);
00379 }
00380
00381 }
00382
00383 if(point11 == point10 ){
00384 lowPoints.push_back(point11);
00385 upPoints.push_front(point11);
00386 s_it++;
00387 }else{
00388 lowPoints.push_back(point10);
00389 upPoints.push_front(point00);
00390 }
00391
00392
00393
00394
00395 point_list_t lowHull;
00396 point_list_t::iterator it = lowPoints.begin();
00397 point_list_t::iterator itE = lowPoints.end();
00398 lowHull.push_back(point00);
00399 ++it;
00400 lowHull.push_back(*it);
00401 ++it;
00402 unsigned int nn = lowPoints.size();
00403 if(nn>2){
00404
00405 while(it!=itE){
00406 testHullLine(lowHull, *it);
00407 ++it;
00408 }
00409 }
00410
00411 point_list_t upHull;
00412 it = upPoints.begin();
00413 itE = upPoints.end();
00414 upHull.push_back(point11);
00415 ++it;
00416 upHull.push_back(*it);
00417 ++it;
00418 if(upPoints.size()>2){
00419
00420 while(it!=itE){
00421 testHullLine(upHull, *it);
00422 ++it;
00423 }
00424 }
00425
00426
00427
00428 outSet.insert(outSet.begin(), lowHull.begin(), lowHull.end() );
00429 outSet.insert((outSet.end()), ++(upHull.begin()), --(upHull.end()) );
00430
00431
00432
00433 }
00434
00435
00436 #endif //DICT
00437
00438
00439 }
00440 #endif
00441