00001 // This file is part of the GenericLAND software library. 00002 // $Id: GLG4TorusStack.hh,v 1.3 2005/09/26 21:34:07 GLG4sim Exp $ 00003 // 00004 // This code partly derived from the intellectual property of 00005 // the RD44 GEANT4 collaboration. 00006 // 00007 // By copying, distributing or modifying the Program (or any work 00008 // based on the Program) you indicate your acceptance of this statement, 00009 // and all its terms, whatever they may be. 00010 // 00011 // 00012 // class GLG4TorusStack 00013 // 00014 // A stack of torii sliced normal to the Z axis, with curved 00015 // sides parallel to the z-axis. Each torus has a certain swept 00016 // radius about which it is centered, and a certain cross-sectional 00017 // radius. A negative cross-sectional radius means to use the "inner" 00018 // surface of the torus as the boundary of the toroid stack. 00019 // A zero cross-sectional radius may be used to indicate a cylinder. 00020 // The complete stack is filled and complete in phi angle. 00021 // The torii are actually specified in terms of the z and "rho" coordinates 00022 // of the edges of the torii and the z coordinate of each segment's plane of 00023 // symmetry; the swept radii ("a") and torii radii ("b") 00024 // are calculated accordingly. 00025 // 00026 // 00027 // Member functions: 00028 // 00029 // As inherited from G4CSGSolid+ 00030 // 00031 // GLG4TorusStack(const G4String &pName ) 00032 // 00033 // Construct an empty TorusStack with the given name. 00034 // 00035 // 00036 // void SetAllParameters 00037 // (G4int n_, // number of Z-segments 00038 // const G4double z_edge_[ ], // n+1 edges of Z-segments 00039 // const double rho_edge_[ ], // n+1 dist. from Z-axis 00040 // const G4double z_o_[ ] ) // z-origins (n total) 00041 // 00042 // Define number of torii in stack and the dimensions of each. 00043 // 00044 // ****************************************************************/ 00045 // 00046 // Protected: 00047 // 00048 // G4ThreeVectorList* 00049 // CreateRotatedVertices(const G4AffineTransform& pTransform) const 00050 // 00051 // Create the List of transformed vertices in the format required 00052 // for G4VSolid:: ClipCrossSection and ClipBetweenSections. 00053 // 00054 // 00055 // 1999.11.22 G.Horton-Smith First version of GLG4TorusStack 00056 00057 00058 #ifndef GLG4TorusStack_HH 00059 #define GLG4TorusStack_HH 00060 00061 #include "G4CSGSolid.hh" 00062 00063 class GLG4TorusStack : public G4CSGSolid { 00064 public: 00065 GLG4TorusStack(const G4String &pName); 00066 00067 virtual ~GLG4TorusStack(); 00068 00069 void SetAllParameters(G4int n, // number of Z-segments 00070 const G4double z_edge[ ], // n+1 edges of Z-segments 00071 const G4double rho_edge[ ],// n+1 dist. from Z-axis 00072 const G4double z_o[ ], // tor z-origins (n total) 00073 GLG4TorusStack *inner=0); // inner TorusStack (opt.) 00074 00075 void ComputeDimensions(G4VPVParameterisation* p, 00076 const G4int n, 00077 const G4VPhysicalVolume* pRep); 00078 00079 G4bool CalculateExtent(const EAxis pAxis, 00080 const G4VoxelLimits& pVoxelLimit, 00081 const G4AffineTransform& pTransform, 00082 G4double& pmin, G4double& pmax) const; 00083 00084 G4double GetN() const { return n ; } 00085 G4double GetZEdge(int i) const { return z_edge[i] ; } 00086 G4double GetZo(int i) const { return z_o[i] ; } 00087 G4double GetA(int i) const { return a[i] ; } 00088 G4double GetB(int i) const { return b[i] ; } 00089 00090 EInside Inside(const G4ThreeVector& p) const; 00091 00092 G4ThreeVector SurfaceNormal( const G4ThreeVector& p) const; 00093 00094 G4double DistanceToIn(const G4ThreeVector& p,const G4ThreeVector& v) const; 00095 G4double DistanceToIn(const G4ThreeVector& p) const; 00096 G4double DistanceToOut(const G4ThreeVector& p,const G4ThreeVector& v, 00097 const G4bool calcNorm=G4bool(false), 00098 G4bool *validNorm=0,G4ThreeVector *n=0) const; 00099 G4double DistanceToOut(const G4ThreeVector& p) const; 00100 00101 // Naming method (pseudo-RTTI : run-time type identification) 00102 virtual G4GeometryType GetEntityType() const 00103 { return G4String("GLG4TorusStack"); } 00104 00105 // Visualisation functions 00106 void DescribeYourselfTo (G4VGraphicsScene& scene) const ; 00107 G4VisExtent GetExtent () const ; 00108 G4Polyhedron* CreatePolyhedron () const ; 00109 G4NURBS* CreateNURBS () const ; 00110 00111 // other generally useful functions -- public so others can use them! 00112 00113 // find first torus intersection -- s == distance from p along v 00114 static G4int FindFirstTorusRoot ( 00115 G4double a, // swept radius 00116 G4double b, // cross-section radius 00117 const G4ThreeVector& p, // start point of ray 00118 const G4ThreeVector& v, // direction of ray 00119 G4double smin, // lower bracket on root 00120 G4double smax, // upper bracket on root 00121 G4bool fEntering, // true if looking for out->in 00122 G4double &sout ) ; // distance to root, if found 00123 00124 // find first root of arbitrary function in bracketed interval 00125 class RootFinder { 00126 public: 00127 virtual void f_and_Df(G4double x, G4double &f, G4double &Df) = 0; 00128 // 00129 // f_and_Df must be overridden by user to be function which sets 00130 // f and Df to the value of the function and the derivative w.r.t. 00131 // x of the function, respectively, for a given x 00132 // 00133 int FindRoot(G4double smin, // lower bound on root 00134 G4double smax, // uppper bound on root 00135 G4double tol, // tolerance on root 00136 G4bool fFindFallingRoot, // true == "want dF<0 at root" 00137 // false == "want dF>0 at root" 00138 G4double &sout); // returned root 00139 // 00140 // FindRoot returns 1 if root found, 0 if no root found. 00141 // 00142 }; 00143 00144 // return integer i such that z[i] <= z_lu < z[i+1] 00145 // or -1 if z_lu < z[0] or z_lu >= z[n-1] 00146 static G4int FindInOrderedList(double z_lu, const double *z, int n); 00147 00148 // a helpful function that doesn't hurt anything to call: 00149 G4int FindNearestSegment(G4double pr, G4double pz) const ; 00150 00151 protected: 00152 00153 G4ThreeVectorList* 00154 CreateRotatedVertices(const G4AffineTransform& pTransform, 00155 G4int& noPolygonVertices) const; 00156 00157 EInside Inside1(const G4ThreeVector& p) const; 00158 00159 int n; // number of Z-segments 00160 double *z_edge; // n+1 edges of Z-segments 00161 double *rho_edge;// n+1 2-d distance from Z-axis at each edge 00162 double *z_o; // z-origins, one for each toroid segment (n total) 00163 double *a; // swept radii, one for each toroid segment (n total) 00164 double *b; // torus radii, one for each toroid segment (n total) 00165 double max_rho; // maxium distance of surface from Z axis 00166 double myRadTolerance; // because Geant4.1.0 default is too small 00167 GLG4TorusStack *inner; // because G4SubtractionSolid is bad 00168 }; 00169 00170 #endif