G4VoxelLimits.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 // class G4VoxelLimits
00030 // 
00031 // Implementation
00032 //
00033 // History:
00034 //
00035 // 14.03.02 V. Grichine, cosmetics
00036 // 13.07.95 P.Kent Initial version
00037 // --------------------------------------------------------------------
00038 
00039 #include "G4VoxelLimits.hh"
00040 
00041 #include "G4ios.hh"
00042 
00044 //
00045 // Empty constructor and destructor
00046 //
00047 
00048 G4VoxelLimits::G4VoxelLimits()
00049  : fxAxisMin(-kInfinity),fxAxisMax(kInfinity),
00050    fyAxisMin(-kInfinity),fyAxisMax(kInfinity),
00051    fzAxisMin(-kInfinity),fzAxisMax(kInfinity)
00052 {
00053 }
00054 
00055 G4VoxelLimits::~G4VoxelLimits()
00056 {
00057 }
00058 
00060 //
00061 // Further restrict limits
00062 // No checks for illegal restrictions
00063 //
00064 
00065 void G4VoxelLimits::AddLimit( const EAxis pAxis, 
00066                               const G4double pMin,
00067                               const G4double pMax )
00068 {
00069   if ( pAxis == kXAxis )
00070   {
00071     if ( pMin > fxAxisMin ) fxAxisMin = pMin ;    
00072     if ( pMax < fxAxisMax ) fxAxisMax = pMax ;    
00073   }
00074   else if ( pAxis == kYAxis )
00075   {
00076     if ( pMin > fyAxisMin ) fyAxisMin = pMin ;    
00077     if ( pMax < fyAxisMax ) fyAxisMax = pMax ;
00078   }
00079   else
00080   { 
00081     assert( pAxis == kZAxis ) ;
00082 
00083     if ( pMin > fzAxisMin ) fzAxisMin = pMin ;
00084     if ( pMax < fzAxisMax ) fzAxisMax = pMax ;
00085   }
00086 }
00087 
00089 //
00090 // ClipToLimits
00091 //
00092 // Clip the line segment pStart->pEnd to the volume described by the
00093 // current limits. Return true if the line remains after clipping,
00094 // else false, and leave the vectors in an undefined state.
00095 //
00096 // Process:
00097 //
00098 // Use Cohen-Sutherland clipping in 3D
00099 // [Fundamentals of Interactive Computer Graphics,Foley & Van Dam]
00100 //
00101 
00102 G4bool G4VoxelLimits::ClipToLimits( G4ThreeVector& pStart,
00103                                     G4ThreeVector& pEnd      ) const
00104 {
00105   G4int sCode, eCode ;
00106   G4bool remainsAfterClip ;
00107     
00108   // Determine if line is trivially inside (both outcodes==0) or outside
00109   // (logical AND of outcodes !=0)
00110 
00111   sCode = OutCode(pStart) ;
00112   eCode = OutCode(pEnd)   ;
00113 
00114   if ( sCode & eCode )
00115   {
00116     // Trivially outside, no intersection with region
00117 
00118     remainsAfterClip = false;
00119   }
00120   else if ( sCode == 0 && eCode == 0 )
00121   {
00122     // Trivially inside, no intersections
00123 
00124     remainsAfterClip = true ;
00125   }
00126   else
00127   {
00128     // Line segment *may* cut volume boundaries
00129     // At most, one end point is inside
00130 
00131     G4double x1, y1, z1, x2, y2, z2 ;
00132 
00133     x1 = pStart.x() ;
00134     y1 = pStart.y() ;
00135     z1 = pStart.z() ;
00136 
00137     x2 = pEnd.x() ;
00138     y2 = pEnd.y() ;
00139     z2 = pEnd.z() ;
00140     /*
00141     if( std::abs(x1-x2) < kCarTolerance*kCarTolerance)
00142     {
00143       G4cout<<"x1 = "<<x1<<"\t"<<"x2 = "<<x2<<G4endl; 
00144     }   
00145     if( std::abs(y1-y2) < kCarTolerance*kCarTolerance)
00146     {
00147       G4cout<<"y1 = "<<y1<<"\t"<<"y2 = "<<y2<<G4endl; 
00148     }   
00149     if( std::abs(z1-z2) < kCarTolerance*kCarTolerance)
00150     {
00151       G4cout<<"z1 = "<<z1<<"\t"<<"z2 = "<<z2<<G4endl; 
00152     } 
00153     */  
00154     while ( sCode != eCode )
00155     {
00156       // Copy vectors to work variables x1-z1,x2-z2
00157       // Ensure x1-z1 lies outside volume, swapping vectors and outcodes
00158       // if necessary
00159 
00160       if ( sCode )
00161       {
00162         if ( sCode & 0x01 )  // Clip against fxAxisMin
00163         {
00164           z1 += (fxAxisMin-x1)*(z2-z1)/(x2-x1);
00165           y1 += (fxAxisMin-x1)*(y2-y1)/(x2-x1);
00166           x1  = fxAxisMin;
00167         }
00168         else if ( sCode & 0x02 ) // Clip against fxAxisMax
00169         {
00170           z1 += (fxAxisMax-x1)*(z2-z1)/(x2-x1);
00171           y1 += (fxAxisMax-x1)*(y2-y1)/(x2-x1);
00172           x1  = fxAxisMax ;
00173         }
00174         else if ( sCode & 0x04 )  // Clip against fyAxisMin
00175         {
00176           x1 += (fyAxisMin-y1)*(x2-x1)/(y2-y1);
00177           z1 += (fyAxisMin-y1)*(z2-z1)/(y2-y1);
00178           y1  = fyAxisMin;
00179         }
00180         else if ( sCode & 0x08 )  // Clip against fyAxisMax
00181         {
00182           x1 += (fyAxisMax-y1)*(x2-x1)/(y2-y1);
00183           z1 += (fyAxisMax-y1)*(z2-z1)/(y2-y1);
00184           y1  = fyAxisMax;
00185         }
00186         else if ( sCode & 0x10 )  // Clip against fzAxisMin
00187         {
00188           x1 += (fzAxisMin-z1)*(x2-x1)/(z2-z1);
00189           y1 += (fzAxisMin-z1)*(y2-y1)/(z2-z1);
00190           z1  = fzAxisMin;
00191         }
00192         else if ( sCode & 0x20 )  // Clip against fzAxisMax
00193         {
00194           x1 += (fzAxisMax-z1)*(x2-x1)/(z2-z1);
00195           y1 += (fzAxisMax-z1)*(y2-y1)/(z2-z1);
00196           z1  = fzAxisMax;
00197         }
00198       }
00199       if ( eCode )  // Clip 2nd end: repeat of 1st, but 1<>2
00200       {
00201         if ( eCode & 0x01 )  // Clip against fxAxisMin
00202         {
00203           z2 += (fxAxisMin-x2)*(z1-z2)/(x1-x2);
00204           y2 += (fxAxisMin-x2)*(y1-y2)/(x1-x2);
00205           x2  = fxAxisMin;
00206         }
00207         else if ( eCode & 0x02 )  // Clip against fxAxisMax
00208         {
00209           z2 += (fxAxisMax-x2)*(z1-z2)/(x1-x2);
00210           y2 += (fxAxisMax-x2)*(y1-y2)/(x1-x2);
00211           x2  = fxAxisMax;
00212         }
00213         else if ( eCode & 0x04 )  // Clip against fyAxisMin
00214         {
00215           x2 += (fyAxisMin-y2)*(x1-x2)/(y1-y2);
00216           z2 += (fyAxisMin-y2)*(z1-z2)/(y1-y2);
00217           y2  = fyAxisMin;
00218         }
00219         else if (eCode&0x08)  // Clip against fyAxisMax
00220         {
00221           x2 += (fyAxisMax-y2)*(x1-x2)/(y1-y2);
00222           z2 += (fyAxisMax-y2)*(z1-z2)/(y1-y2);
00223           y2  = fyAxisMax;
00224         }
00225         else if ( eCode & 0x10 )  // Clip against fzAxisMin
00226         {
00227           x2 += (fzAxisMin-z2)*(x1-x2)/(z1-z2);
00228           y2 += (fzAxisMin-z2)*(y1-y2)/(z1-z2);
00229           z2  = fzAxisMin;
00230         }
00231         else if ( eCode & 0x20 )  // Clip against fzAxisMax
00232         {
00233           x2 += (fzAxisMax-z2)*(x1-x2)/(z1-z2);
00234           y2 += (fzAxisMax-z2)*(y1-y2)/(z1-z2);
00235           z2  = fzAxisMax;
00236         }
00237       }
00238       //  G4endl; G4cout<<"x1 = "<<x1<<"\t"<<"x2 = "<<x2<<G4endl<<G4endl;
00239       pStart = G4ThreeVector(x1,y1,z1);
00240       pEnd   = G4ThreeVector(x2,y2,z2);
00241       sCode  = OutCode(pStart);
00242       eCode  = OutCode(pEnd);
00243     }
00244     if ( sCode == 0 && eCode == 0 ) remainsAfterClip = true;
00245     else                            remainsAfterClip = false;
00246   }
00247   return remainsAfterClip;
00248 }
00249 
00251 //
00252 // Calculate the `outcode' for the specified vector:
00253 // The following bits are set:
00254 //   0      pVec.x()<fxAxisMin && IsXLimited()
00255 //   1      pVec.x()>fxAxisMax && IsXLimited()
00256 //   2      pVec.y()<fyAxisMin && IsYLimited()
00257 //   3      pVec.y()>fyAxisMax && IsYLimited()
00258 //   4      pVec.z()<fzAxisMin && IsZLimited()
00259 //   5      pVec.z()>fzAxisMax && IsZLimited()
00260 //
00261 
00262 G4int G4VoxelLimits::OutCode( const G4ThreeVector& pVec ) const
00263 {
00264   G4int code = 0 ;                // The outcode
00265 
00266   if ( IsXLimited() )
00267   {
00268     if ( pVec.x() < fxAxisMin ) code |= 0x01 ;
00269     if ( pVec.x() > fxAxisMax ) code |= 0x02 ;
00270   }
00271   if ( IsYLimited() )
00272   {
00273     if ( pVec.y() < fyAxisMin ) code |= 0x04 ;
00274     if ( pVec.y() > fyAxisMax ) code |= 0x08 ;
00275   }
00276   if (IsZLimited())
00277   {
00278     if ( pVec.z() < fzAxisMin ) code |= 0x10 ;
00279     if ( pVec.z() > fzAxisMax ) code |= 0x20 ;
00280   }
00281   return code;
00282 }
00283 
00285 
00286 std::ostream& operator << (std::ostream& os, const G4VoxelLimits& pLim)
00287 {
00288     os << "{";
00289     if (pLim.IsXLimited())
00290         {
00291             os << "(" << pLim.GetMinXExtent() 
00292                << "," << pLim.GetMaxXExtent() << ") ";
00293         }
00294     else
00295         {
00296             os << "(-,-) ";
00297         }
00298     if (pLim.IsYLimited())
00299         {
00300             os << "(" << pLim.GetMinYExtent() 
00301                << "," << pLim.GetMaxYExtent() << ") ";
00302         }
00303     else
00304         {
00305             os << "(-,-) ";
00306         }
00307     if (pLim.IsZLimited())
00308         {
00309             os << "(" << pLim.GetMinZExtent()
00310                << "," << pLim.GetMaxZExtent() << ")";
00311         }
00312     else
00313         {
00314             os << "(-,-)";
00315         }
00316     os << "}";
00317     return os;
00318 }

Generated on Mon May 27 17:50:18 2013 for Geant4 by  doxygen 1.4.7