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: G4VCSGface.hh 67011 2013-01-29 16:17:41Z gcosmo $ 00028 // 00029 // 00030 // -------------------------------------------------------------------- 00031 // GEANT 4 class header file 00032 // 00033 // 00034 // G4VCSGface 00035 // 00036 // Class description: 00037 // 00038 // Definition of the virtual base class G4VCSGface, one side (or face) 00039 // of a CSG-like solid. It should be possible to build a CSG entirely out of 00040 // connecting CSG faces. 00041 // 00042 // Each face has an inside and outside surface, the former represents 00043 // the inside of the volume, the latter, the outside. 00044 // 00045 // Virtual members: 00046 // 00047 // ------------------------------------------------------------------- 00048 // Intersect( const G4ThreeVector &p, const G4ThreeVector &v, 00049 // G4bool outGoing, G4double surfTolerance, 00050 // G4double &distance, G4double &distFromSurface, 00051 // G4ThreeVector &normal, G4bool &allBehind ); 00052 // 00053 // p - (in) position 00054 // v - (in) direction (assumed to be a unit vector) 00055 // outgoing - (in) true, to consider only inside surfaces 00056 // false, to consider only outside surfaces 00057 // distance - (out) distance to intersection 00058 // distFromSurface - (out) distance from surface (along surface normal), 00059 // < 0 if the point is in front of the surface 00060 // normal - (out) normal of surface at intersection point 00061 // allBehind - (out) true, if entire surface is behind normal 00062 // 00063 // return value = true if there is an intersection, 00064 // false if there is no intersection 00065 // (all output arguments undefined) 00066 // 00067 // Determine the distance along a line to the face. 00068 // 00069 // ------------------------------------------------------------------- 00070 // Distance( const G4ThreeVector &p, const G4bool outgoing ); 00071 // 00072 // p - (in) position 00073 // outgoing - (in) true, to consider only inside surfaces 00074 // false, to consider only outside surfaces 00075 // 00076 // return value = distance to closest surface satisifying requirements 00077 // or kInfinity if no such surface exists 00078 // 00079 // Determine the distance of a point from either the inside or outside 00080 // surfaces of the face. 00081 // 00082 // ------------------------------------------------------------------- 00083 // Inside( const G4ThreeVector &p, const G4double tolerance, 00084 // G4double *bestDistance ); 00085 // 00086 // p - (in) position 00087 // tolerance - (in) tolerance defining the bounds of the "kSurface", 00088 // nominally equal to kCarTolerance/2 00089 // bestDistance - (out) distance to closest surface (in or out) 00090 // 00091 // return value = kInside if the point is closest to the inside surface 00092 // kOutside if the point is closest to the outside surface 00093 // kSurface if the point is withing tolerance of the surface 00094 // 00095 // Determine whether a point is inside, outside, or on the surface of 00096 // the face. 00097 // 00098 // ------------------------------------------------------------------- 00099 // Normal( const G4ThreeVector &p, G4double *bestDistance ); 00100 // 00101 // p - (in) position 00102 // bestDistance - (out) distance to closest surface (in or out) 00103 // 00104 // return value = the normal of the surface nearest the point 00105 // 00106 // Return normal of surface closest to the point. 00107 // 00108 // ------------------------------------------------------------------- 00109 // Extent( const G4ThreeVector axis ); 00110 // 00111 // axis - (in) unit vector defining direction 00112 // 00113 // return value = the largest point along the given axis of the 00114 // the face's extent. 00115 // 00116 // ------------------------------------------------------------------- 00117 // CalculateExtent( const EAxis pAxis, 00118 // const G4VoxelLimit &pVoxelLimit, 00119 // const G4AffineTransform &pTransform, 00120 // G4double &min, G4double &max ) 00121 // 00122 // pAxis - (in) The x,y, or z axis in which to check 00123 // the shapes 3D extent against 00124 // pVoxelLimit - (in) Limits along x, y, and/or z axes 00125 // pTransform - (in) A coordinate transformation on which 00126 // to apply to the shape before testing 00127 // min - (out) If the face has any point on its 00128 // surface after tranformation and limits 00129 // along pAxis that is smaller than the value 00130 // of min, than it is used to replace min. 00131 // Undefined if the return value is false. 00132 // max - (out) Same as min, except for the largest 00133 // point. 00134 // Undefined if the return value is false. 00135 // 00136 // return value = true if anything remains of the face 00137 // 00138 // Calculate the extent of the face for the voxel navigator. 00139 // In analogy with CalculateExtent for G4VCSGfaceted, this is 00140 // done in the following steps: 00141 // 00142 // 1. Transform the face using pTranform, an arbitrary 3D 00143 // rotation/offset/reflection 00144 // 2. Clip the face to those boundaries as specified in 00145 // pVoxelLimit. This may include limits in any number 00146 // of x, y, or z axes. 00147 // 3. For each part of the face that remains (there could 00148 // be many separate pieces in general): 00149 // 4. Check to see if the piece overlaps the currently 00150 // existing limits along axis pAxis. For 00151 // pVoxelLimit.IsLimited(pAxis) = false, there are 00152 // no limits. 00153 // 5. For a piece that does overlap, update min/max 00154 // accordingly (within confines of pre-existing 00155 // limits) along the direction pAxis. 00156 // 6. If min/max were updated, return true 00157 // 00158 // ------------------------------------------------------------------- 00159 // G3VCSGface *Clone() 00160 // 00161 // This method is invoked by G4CSGfaceted during the copy constructor 00162 // or the assignment operator. Its purpose is to return a pointer 00163 // (of type G4VCSGface) to a duplicate copy of the face. 00164 // The implementation is straight forward for inherited classes. Example: 00165 // 00166 // G4VCSGface G4PolySideFace::Clone() { return new G4PolySideFace(*this); } 00167 // 00168 // Of course, this assumes the copy constructor of G4PolySideFace is 00169 // correctly implemented. 00170 // 00171 // Implementation notes: 00172 // * distance. 00173 // The meaning of distance includes the boundaries of the face. 00174 // For example, for a rectangular, planer face: 00175 // 00176 // A | B | C 00177 // | | 00178 // -------+--------------+----- 00179 // D | I | E 00180 // | | 00181 // -------+--------------+----- 00182 // F | G | H 00183 // | | 00184 // 00185 // A, C, F, and H: closest distance is the distance to 00186 // the adjacent corner. 00187 // 00188 // B, D, E, and G: closest distance is the distance to 00189 // the adjacent line. 00190 // 00191 // I: normal distance to plane 00192 // 00193 // For non-planer faces, one can use the normal to decide when 00194 // a point falls off the edge and then act accordingly. 00195 // 00196 // 00197 // Usage: 00198 // 00199 // A CSG shape can be defined by putting together any number of generic 00200 // faces, as long as the faces cover the entire surface of the shape 00201 // without overlapping. 00202 // 00203 // G4VSolid::CalculateExtent 00204 // 00205 // Define unit vectors along the specified transform axis. 00206 // Use the inverse of the specified coordinate transformation to rotate 00207 // these unit vectors. Loop over each face, call face->Extent, and save 00208 // the maximum value. 00209 // 00210 // G4VSolid::Inside 00211 // 00212 // To decide if a point is inside, outside, or on the surface of the shape, 00213 // loop through all faces, and find the answer from face->Inside which gives 00214 // a value of "bestDistance" smaller than any other. While looping, if any 00215 // face->Inside returns kSurface, this value can be returned immediately. 00216 // 00217 // EInside answer; 00218 // G4VCSGface *face = faces; 00219 // G4double best = kInfinity; 00220 // do { 00221 // G4double distance; 00222 // EInside result = (*face)->Inside( p, kCarTolerance/2, distance ); 00223 // if (result == kSurface) return kSurface; 00224 // if (distance < best) { 00225 // best = distance; 00226 // answer = result; 00227 // } 00228 // } while( ++face < faces + numFaces ); 00229 // 00230 // return(answer); 00231 // 00232 // G4VSolid::SurfaceNormal 00233 // 00234 // Loop over all faces, call face->Normal, and return the normal to the face 00235 // that is closest to the point. 00236 // 00237 // G4VSolid::DistanceToIn(p) 00238 // 00239 // Loop over all faces, invoking face->Distance with outgoing = false, 00240 // and save the answer that is smallest. 00241 // 00242 // G4VSolid::DistanceToIn(p,v) 00243 // 00244 // Loop over all faces, invoking face->Intersect with outgoing = false, 00245 // and save the answer that is smallest. 00246 // 00247 // G4VSolid::DistanceToOut(p) 00248 // 00249 // Loop over all faces, invoking face->Distance with outgoing = true, 00250 // and save the answer that is smallest. 00251 // 00252 // G4VSolid::DistanceToOut(p,v) 00253 // 00254 // Loop over all faces, invoking face->Intersect with outgoing = true, 00255 // and save the answer that is smallest. If there is more than one answer, 00256 // or if allBehind is false for the one answer, return validNorm as false. 00257 00258 // Author: 00259 // David C. Williams (davidw@scipp.ucsc.edu) 00260 // -------------------------------------------------------------------- 00261 #ifndef G4VCSGface_hh 00262 #define G4VCSGface_hh 00263 00264 #include "G4Types.hh" 00265 #include "G4ThreeVector.hh" 00266 #include "geomdefs.hh" 00267 #include "G4VSolid.hh" 00268 00269 class G4VoxelLimits; 00270 class G4AffineTransform; 00271 class G4SolidExtentList; 00272 00273 class G4VCSGface 00274 { 00275 public: // with description 00276 00277 G4VCSGface() {} 00278 virtual ~G4VCSGface() {} 00279 00280 virtual G4bool Intersect( const G4ThreeVector &p, const G4ThreeVector &v, 00281 G4bool outgoing, G4double surfTolerance, 00282 G4double &distance, G4double &distFromSurface, 00283 G4ThreeVector &normal, G4bool &allBehind ) = 0; 00284 00285 virtual G4double Distance( const G4ThreeVector &p, G4bool outgoing ) = 0; 00286 00287 virtual EInside Inside( const G4ThreeVector &p, G4double tolerance, 00288 G4double *bestDistance ) = 0; 00289 00290 virtual G4ThreeVector Normal( const G4ThreeVector &p, 00291 G4double *bestDistance ) = 0; 00292 00293 virtual G4double Extent( const G4ThreeVector axis ) = 0; 00294 00295 virtual void CalculateExtent( const EAxis axis, 00296 const G4VoxelLimits &voxelLimit, 00297 const G4AffineTransform &tranform, 00298 G4SolidExtentList &extentList ) = 0; 00299 00300 virtual G4VCSGface* Clone() = 0; 00301 00302 virtual G4double SurfaceArea( ) = 0; 00303 virtual G4ThreeVector GetPointOnFace() = 0; 00304 }; 00305 00306 #endif