| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

SolidTicks.h

Go to the documentation of this file.
00001 // $Id: SolidTicks.h,v 1.14 2007/09/20 15:41:06 wouter Exp $ 
00002 // ===========================================================================
00003 #ifndef     DETDESC_SOLIDTICKS_H
00004 #define     DETDESC_SOLIDTICKS_H 1 
00006 #include <cmath>
00007 #include <functional>
00008 #include <algorithm>
00009 // Geometry includes 
00010 #include "GaudiKernel/Point3DTypes.h"
00011 #include "GaudiKernel/Vector3DTypes.h"
00012 #include "GaudiKernel/Plane3DTypes.h"
00013 // DetDesc includes 
00014 #include "DetDesc/ISolid.h" 
00015 #include "DetDesc/SolidMath.h" 
00016 
00036 namespace SolidTicks
00037 {
00038   
00049   template <class SOLID, class aPoint, class aVector>
00050   inline unsigned int  
00051   RemoveAdjancent
00052   ( ISolid::Ticks     & ticks , 
00053     const aPoint      & point , 
00054     const aVector     & vect  , 
00055     const SOLID       & solid )
00056   {
00057     // local typedefs 
00058     typedef std::vector<size_t>     Indexes  ; 
00059     typedef ISolid::Tick            Tick     ; 
00060     typedef ISolid::Ticks::iterator iterator ;
00061     // no abjancent ?
00062     if     ( ticks.size() <  2 ) { ticks.clear() ;    return 0 ; }    // RETURN
00063     else if( ticks.size() == 2 ) 
00064       {
00065         Tick tick1 = ticks.front () ;           // first tick
00066         Tick tick2 = ticks.back  () ;           // last  tick 
00067         Tick tick  = 0.5 * ( tick1 + tick2 ) ;  // middle tick
00068         if( solid.isInside( point + vect * tick ) ) { return 2 ; } // RETURN 
00069         else                        { ticks.clear() ; return 0 ; } // RETURN 
00070       }  
00071     // perform removing of adjancent  ticks
00072     Indexes tmp              ; 
00073     Tick    tickNext = 0.0   ;
00074     Tick    tickPrev = 0.0   ; 
00075     bool    boolPrev = true  ; 
00076     bool    boolNext = true  ; 
00077     for ( iterator it = ticks.begin() ; it != ticks.end() ; ++it ) 
00078       {
00079         // the last point is to be treated in a specific way
00080         if     ( ticks.end   () != it + 1 ) 
00081           { tickNext = 0.5 * ( (*it) + *(it+1) ) ; 
00082           boolNext = solid.isInside( point + vect * tickNext );  }  
00083         // get the index 
00084         unsigned int index = it - ticks.begin();                       
00088         if      ( ticks.end  () == it + 1 ) 
00089           { if( !boolPrev             ) { tmp.push_back( index ) ; } }
00093         else if ( ticks.begin() == it     ) 
00094           { if( !boolNext             ) { tmp.push_back( index ) ; } }
00098         else                                
00099           { if(  boolPrev == boolNext ) { tmp.push_back( index ) ; } }
00101         boolPrev = boolNext; 
00102         tickPrev = tickNext;
00103       }
00104     // remove ticks (from the end!)
00105     Indexes::reverse_iterator cri = tmp.rbegin();
00106     while( cri != tmp.rend() ) { ticks.erase( ticks.begin() + *cri++ );  }  
00107     // get the final answer 
00108     return ticks.size();
00109   };
00110   
00121   template <class SOLID, class aPoint, class aVector>
00122   inline unsigned int  
00123   RemoveAdjancentTicks
00124   ( ISolid::Ticks     & ticks , 
00125     const aPoint  & point , 
00126     const aVector & vect  , 
00127     const SOLID       & solid )
00128   {
00129     //     useful local typedefs 
00130     typedef ISolid::Tick            Tick     ; 
00131     typedef ISolid::Ticks::iterator iterator ;
00132     // (1) sort container  
00133     std::sort( ticks.begin() , ticks.end() ) ; 
00134     // (2) eliminate duplicates and (3) shrink container 
00135     ticks.erase( std::unique( ticks.begin() , ticks.end() )  , ticks.end() ); 
00136     // remove adjancent 
00137     return RemoveAdjancent( ticks , point , vect , solid );
00138   };
00139 
00140 
00155   template <class SOLID, class aPoint, class aVector>
00156   inline unsigned int  
00157   RemoveAdjancentTicks
00158   ( ISolid::Ticks      & ticks   ,
00159     const aPoint   & point   , 
00160     const aVector  & vect    , 
00161     const ISolid::Tick & tickMin , 
00162     const ISolid::Tick & tickMax , 
00163     const SOLID        & solid   )
00164   {
00165     // useful local typedefs 
00166     typedef ISolid::Tick            Tick     ; 
00167     typedef ISolid::Ticks::iterator iterator ;
00168     // valid arguments? 
00169     if( tickMin >= tickMax ) { ticks.clear();            return 0 ; } // RETURN
00170     // remove all garbage what is  less than 'tickMin' 
00171     iterator itMin = 
00172       std::remove_if( ticks.begin () ,
00173                       ticks.end   () ,  
00174                       std::bind2nd( std::less<Tick>    () , tickMin ) );
00175     // remove all garbage what is  larger than 'tickMax' 
00176     iterator itMax = 
00177       std::remove_if( ticks.begin () , 
00178                       itMin          , 
00179                       std::bind2nd( std::greater<Tick> () , tickMax ) );
00180     ticks.erase  ( itMax , ticks.end() ) ;
00181     
00182     // empty ticks! 
00183     if( ticks.empty() )
00184       {
00185         const Tick middle = 0.5 * ( tickMin + tickMax ) ;
00186         if( solid.isInside(  point  + middle * vect ) ) 
00187           {
00188             ticks.push_back( tickMin ) ; 
00189             ticks.push_back( tickMax ) ; 
00190           }
00191         return ticks.size() ;
00192       }
00193     
00194     // first tick 
00195     if( ticks.front () != tickMin ) 
00196       { 
00197         const Tick middle  = 0.5 * ( tickMin      + ticks.front() ) ;
00198         if( solid.isInside   ( point + middle * vect ) )
00199           { ticks.insert     ( ticks.begin() , tickMin ) ; }
00200       }
00201     
00202     // last tick 
00203     if( ticks.back  () != tickMax ) 
00204       { 
00205         const Tick middle  = 0.5 * ( ticks.back() +  tickMax ) ;
00206         if( solid.isInside   ( point + middle * vect ) )
00207           { ticks.push_back  (                 tickMax ) ; }
00208       }
00209     // adjancent are already removed 
00210     return ticks.size () ;
00211   };
00212   
00228   template <class SOLID, class aPoint, class aVector, class TickContainer>
00229   inline unsigned int RemoveAdjacentTicksFast ( TickContainer & ticks , 
00230                                                 const aPoint  & point , 
00231                                                 const aVector & vect  , 
00232                                                 const SOLID   & solid )
00233   {
00234     // only call the expensive method if we find that something is wrong:
00235     typename TickContainer::iterator newend  = std::unique( ticks.begin() , ticks.end() ) ;
00236     if( newend != ticks.end() || ticks.size()%2 != 0 ) {
00237       ticks.erase( newend, ticks.end()) ;
00238       RemoveAdjancent( ticks , point , vect , solid );
00239     }
00240     return ticks.size() ;
00241   } ;
00242 
00254   template <class TickContainer>
00255   unsigned int adjustToTickRange( TickContainer& ticks, const ISolid::Tick & tickMin, const ISolid::Tick & tickMax ) 
00256   {
00257     // useful local typedefs 
00258     typedef ISolid::Tick            Tick     ; 
00259     typedef ISolid::Ticks::iterator iterator ;
00260     if( !ticks.empty() ) {
00261       static ISolid::Ticks validticks ; validticks.clear() ;
00262       // explicitely use that ticks come in pairs
00263       for( typename TickContainer::const_iterator it = ticks.begin() ; it+1 < ticks.end(); it +=2) 
00264         if( *it <= tickMax && *(it+1) >= tickMin ) {
00265           validticks.push_back( std::max( tickMin, *it) ) ;
00266           validticks.push_back( std::min( tickMax, *(it+1)) ) ;
00267         }
00268       ticks.swap(validticks) ;
00269     }
00270     return ticks.size () ;
00271   };
00272 
00273 }; 
00274 
00275 // ============================================================================
00276 // The End 
00277 // ============================================================================
00278 #endif   
00279 // ============================================================================
00280 
00281 
00282 
00283 
00284 
00285 
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:00:13 2011 for DetDesc by doxygen 1.4.7