#include <G4BREPSolidPolyhedra.hh>
Inheritance diagram for G4BREPSolidPolyhedra:
Public Member Functions | |
G4BREPSolidPolyhedra (const G4String &name, G4double phi1, G4double dphi, G4int sides, G4int num_z_planes, G4double z_start, G4double z_values[], G4double RMIN[], G4double RMAX[]) | |
~G4BREPSolidPolyhedra () | |
void | Initialize () |
EInside | Inside (register const G4ThreeVector &Pt) const |
G4ThreeVector | SurfaceNormal (const G4ThreeVector &) const |
G4double | DistanceToIn (const G4ThreeVector &) const |
G4double | DistanceToIn (register const G4ThreeVector &Pt, register const G4ThreeVector &V) const |
G4double | DistanceToOut (register const G4ThreeVector &Pt, register const G4ThreeVector &V, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const |
G4double | DistanceToOut (const G4ThreeVector &) const |
G4VSolid * | Clone () const |
std::ostream & | StreamInfo (std::ostream &os) const |
G4Polyhedron * | CreatePolyhedron () const |
void | Reset () const |
G4BREPSolidPolyhedra (__void__ &) | |
G4BREPSolidPolyhedra (const G4BREPSolidPolyhedra &rhs) | |
G4BREPSolidPolyhedra & | operator= (const G4BREPSolidPolyhedra &rhs) |
Data Structures | |
struct | G4BREPPolyhedraParams |
Definition at line 59 of file G4BREPSolidPolyhedra.hh.
G4BREPSolidPolyhedra::G4BREPSolidPolyhedra | ( | const G4String & | name, | |
G4double | phi1, | |||
G4double | dphi, | |||
G4int | sides, | |||
G4int | num_z_planes, | |||
G4double | z_start, | |||
G4double | z_values[], | |||
G4double | RMIN[], | |||
G4double | RMAX[] | |||
) |
Definition at line 71 of file G4BREPSolidPolyhedra.cc.
References G4BREPSolid::active, G4endl, G4Exception(), and JustWarning.
Referenced by Clone().
00080 : G4BREPSolid(name) 00081 { 00082 // Store the original parameters, to be used in visualisation 00083 // Note radii are not scaled because this BREP uses the radius of the 00084 // circumscribed circle and also graphics_reps/G4Polyhedron uses the 00085 // radius of the circumscribed circle. 00086 00087 // Save contructor parameters 00088 // 00089 constructorParams.start_angle = start_angle; 00090 constructorParams.opening_angle = opening_angle; 00091 constructorParams.sides = sides; 00092 constructorParams.num_z_planes = num_z_planes; 00093 constructorParams.z_start = z_start; 00094 constructorParams.z_values = 0; 00095 constructorParams.RMIN = 0; 00096 constructorParams.RMAX = 0; 00097 00098 if( num_z_planes > 0 ) 00099 { 00100 constructorParams.z_values = new G4double[num_z_planes]; 00101 constructorParams.RMIN = new G4double[num_z_planes]; 00102 constructorParams.RMAX = new G4double[num_z_planes]; 00103 for( G4int idx = 0; idx < num_z_planes; ++idx ) 00104 { 00105 constructorParams.z_values[idx] = z_values[idx]; 00106 constructorParams.RMIN[idx] = RMIN[idx]; 00107 constructorParams.RMAX[idx] = RMAX[idx]; 00108 } 00109 } 00110 00111 // z_values[0] should be equal to z_start, for consistency 00112 // with what the constructor does. 00113 // Otherwise the z_values that are shifted by (z_values[0] - z_start) , 00114 // because z_values are only used in the form 00115 // length = z_values[d+1] - z_values[d]; // JA Apr 2, 97 00116 00117 if( z_values[0] != z_start ) 00118 { 00119 std::ostringstream message; 00120 message << "Construction Error. z_values[0] must be equal to z_start!" 00121 << G4endl 00122 << " Wrong solid parameters: " 00123 << " z_values[0]= " << z_values[0] << " is not equal to " 00124 << " z_start= " << z_start << "."; 00125 G4Exception( "G4BREPSolidPolyhedra::G4BREPSolidPolyhedra()", 00126 "GeomSolids1002", JustWarning, message ); 00127 if( num_z_planes <= 0 ) { constructorParams.z_values = new G4double[1]; } 00128 constructorParams.z_values[0]= z_start; 00129 } 00130 00131 active=1; 00132 InitializePolyhedra(); 00133 }
G4BREPSolidPolyhedra::~G4BREPSolidPolyhedra | ( | ) |
Definition at line 148 of file G4BREPSolidPolyhedra.cc.
00149 { 00150 if( constructorParams.num_z_planes > 0 ) 00151 { 00152 delete [] constructorParams.z_values; 00153 delete [] constructorParams.RMIN; 00154 delete [] constructorParams.RMAX; 00155 } 00156 }
G4BREPSolidPolyhedra::G4BREPSolidPolyhedra | ( | __void__ & | ) |
Definition at line 135 of file G4BREPSolidPolyhedra.cc.
00136 : G4BREPSolid(a) 00137 { 00138 constructorParams.start_angle = 0.; 00139 constructorParams.opening_angle = 0.; 00140 constructorParams.sides = 0; 00141 constructorParams.num_z_planes = 0; 00142 constructorParams.z_start = 0.; 00143 constructorParams.z_values = 0; 00144 constructorParams.RMIN = 0; 00145 constructorParams.RMAX = 0; 00146 }
G4BREPSolidPolyhedra::G4BREPSolidPolyhedra | ( | const G4BREPSolidPolyhedra & | rhs | ) |
Definition at line 158 of file G4BREPSolidPolyhedra.cc.
References constructorParams.
00159 : G4BREPSolid(rhs) 00160 { 00161 constructorParams.start_angle = rhs.constructorParams.start_angle; 00162 constructorParams.opening_angle = rhs.constructorParams.opening_angle; 00163 constructorParams.sides = rhs.constructorParams.sides; 00164 constructorParams.num_z_planes = rhs.constructorParams.num_z_planes; 00165 constructorParams.z_start = rhs.constructorParams.z_start; 00166 constructorParams.z_values = 0; 00167 constructorParams.RMIN = 0; 00168 constructorParams.RMAX = 0; 00169 G4int num_z_planes = constructorParams.num_z_planes; 00170 if( num_z_planes > 0 ) 00171 { 00172 constructorParams.z_values = new G4double[num_z_planes]; 00173 constructorParams.RMIN = new G4double[num_z_planes]; 00174 constructorParams.RMAX = new G4double[num_z_planes]; 00175 for( G4int idx = 0; idx < num_z_planes; ++idx ) 00176 { 00177 constructorParams.z_values[idx] = rhs.constructorParams.z_values[idx]; 00178 constructorParams.RMIN[idx] = rhs.constructorParams.RMIN[idx]; 00179 constructorParams.RMAX[idx] = rhs.constructorParams.RMAX[idx]; 00180 } 00181 } 00182 00183 InitializePolyhedra(); 00184 }
G4VSolid * G4BREPSolidPolyhedra::Clone | ( | ) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 1340 of file G4BREPSolidPolyhedra.cc.
References G4BREPSolidPolyhedra().
01341 { 01342 return new G4BREPSolidPolyhedra(*this); 01343 }
G4Polyhedron * G4BREPSolidPolyhedra::CreatePolyhedron | ( | ) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 1517 of file G4BREPSolidPolyhedra.cc.
01518 { 01519 return new G4PolyhedronPgon( constructorParams.start_angle, 01520 constructorParams.opening_angle, 01521 constructorParams.sides, 01522 constructorParams.num_z_planes, 01523 constructorParams.z_values, 01524 constructorParams.RMIN, 01525 constructorParams.RMAX); 01526 }
G4double G4BREPSolidPolyhedra::DistanceToIn | ( | register const G4ThreeVector & | Pt, | |
register const G4ThreeVector & | V | |||
) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 1106 of file G4BREPSolidPolyhedra.cc.
References G4BREPSolid::Intersect(), G4VSolid::kCarTolerance, G4BREPSolid::nb_of_surfaces, Reset(), G4BREPSolid::ShortestDistance, G4Surface::SurfaceNormal(), G4BREPSolid::SurfaceVec, and G4BREPSolid::TestSurfaceBBoxes().
01108 { 01109 // Calculates the distance from a point outside the solid 01110 // to the solid`s boundary along a specified direction vector. 01111 // 01112 // Note : Intersections with boundaries less than the 01113 // tolerance must be ignored if the direction 01114 // is away from the boundary 01115 01116 G4int a; 01117 01118 // Set the surfaces to active again 01119 // 01120 Reset(); 01121 01122 const G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25; 01123 G4Vector3D Pttmp(Pt); 01124 G4Vector3D Vtmp(V); 01125 G4Ray r(Pttmp, Vtmp); 01126 01127 // Test if the bounding box of each surface is intersected 01128 // by the ray. If not, the surface become deactive. 01129 // 01130 TestSurfaceBBoxes(r); 01131 01132 ShortestDistance = kInfinity; 01133 01134 for(a=0; a< nb_of_surfaces; a++) 01135 { 01136 if( SurfaceVec[a]->IsActive() ) 01137 { 01138 // test if the ray intersect the surface 01139 // 01140 if( SurfaceVec[a]->Intersect(r) ) 01141 { 01142 G4double surfDistance = SurfaceVec[a]->GetDistance(); 01143 01144 // if more than 1 surface is intersected, 01145 // take the nearest one 01146 // 01147 if( surfDistance < ShortestDistance ) 01148 { 01149 if( surfDistance > sqrHalfTolerance ) 01150 { 01151 ShortestDistance = surfDistance; 01152 } 01153 else 01154 { 01155 // the point is within the boundary 01156 // ignore it if the direction is away from the boundary 01157 // 01158 G4Vector3D Norm = SurfaceVec[a]->SurfaceNormal(Pttmp); 01159 01160 if( (Norm * Vtmp) < 0 ) 01161 { 01162 ShortestDistance = surfDistance; 01163 // ShortestDistance = surfDistance==0 01164 // ? sqrHalfTolerance 01165 // : surfDistance; 01166 } 01167 } 01168 } 01169 } 01170 } 01171 } 01172 01173 // Be careful ! 01174 // SurfaceVec->Distance is in fact the squared distance 01175 // 01176 if(ShortestDistance != kInfinity) 01177 { 01178 return std::sqrt(ShortestDistance); 01179 } 01180 else // no intersection 01181 { 01182 return kInfinity; 01183 } 01184 }
G4double G4BREPSolidPolyhedra::DistanceToIn | ( | const G4ThreeVector & | ) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 1057 of file G4BREPSolidPolyhedra.cc.
References G4BREPSolid::nb_of_surfaces, Reset(), and G4BREPSolid::SurfaceVec.
01058 { 01059 // Calculates the shortest distance ("safety") from a point 01060 // outside the solid to any boundary of this solid. 01061 // Return 0 if the point is already inside. 01062 01063 G4double *dists = new G4double[nb_of_surfaces]; 01064 G4int a; 01065 01066 // Set the surfaces to active again 01067 // 01068 Reset(); 01069 01070 // compute the shortest distance of the point to each surfaces 01071 // Be careful : it's a signed value 01072 // 01073 for(a=0; a< nb_of_surfaces; a++) 01074 dists[a] = SurfaceVec[a]->HowNear(Pt); 01075 01076 G4double Dist = kInfinity; 01077 01078 // if dists[] is positive, the point is outside 01079 // so take the shortest of the shortest positive distances 01080 // dists[] can be equal to 0 : point on a surface 01081 // ( Problem with the G4FPlane : there is no inside and no outside... 01082 // So, to test if the point is inside to return 0, utilize the Inside 01083 // function. But I don`t know if it is really needed because dToIn is 01084 // called only if the point is outside ) 01085 // 01086 for(a = 0; a < nb_of_surfaces; a++) 01087 if( std::fabs(Dist) > std::fabs(dists[a]) ) 01088 //if( dists[a] >= 0) 01089 Dist = dists[a]; 01090 01091 delete[] dists; 01092 01093 if(Dist == kInfinity) 01094 { 01095 // the point is inside the solid or on a surface 01096 // 01097 return 0; 01098 } 01099 else 01100 { 01101 return std::fabs(Dist); 01102 } 01103 }
G4double G4BREPSolidPolyhedra::DistanceToOut | ( | const G4ThreeVector & | ) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 1285 of file G4BREPSolidPolyhedra.cc.
References G4BREPSolid::nb_of_surfaces, Reset(), and G4BREPSolid::SurfaceVec.
01286 { 01287 // Calculates the shortest distance ("safety") from a point 01288 // inside the solid to any boundary of this solid. 01289 // Return 0 if the point is already outside. 01290 01291 G4double *dists = new G4double[nb_of_surfaces]; 01292 G4int a; 01293 01294 // Set the surfaces to active again 01295 // 01296 Reset(); 01297 01298 // calculate the shortest distance of the point to each surfaces 01299 // Be careful : it's a signed value 01300 // 01301 for(a=0; a< nb_of_surfaces; a++) 01302 { 01303 dists[a] = SurfaceVec[a]->HowNear(Pt); 01304 } 01305 01306 G4double Dist = kInfinity; 01307 01308 // if dists[] is negative, the point is inside 01309 // so take the shortest of the shortest negative distances 01310 // dists[] can be equal to 0 : point on a surface 01311 // ( Problem with the G4FPlane : there is no inside and no outside... 01312 // So, to test if the point is outside to return 0, utilize the Inside 01313 // function. But I don`t know if it is really needed because dToOut is 01314 // called only if the point is inside ) 01315 01316 for(a = 0; a < nb_of_surfaces; a++) 01317 { 01318 if( std::fabs(Dist) > std::fabs(dists[a]) ) 01319 { 01320 //if( dists[a] <= 0) 01321 Dist = dists[a]; 01322 } 01323 } 01324 01325 delete[] dists; 01326 01327 if(Dist == kInfinity) 01328 { 01329 // the point is ouside the solid or on a surface 01330 // 01331 return 0; 01332 } 01333 else 01334 { 01335 // return Dist; 01336 return std::fabs(Dist); 01337 } 01338 }
G4double G4BREPSolidPolyhedra::DistanceToOut | ( | register const G4ThreeVector & | Pt, | |
register const G4ThreeVector & | V, | |||
const G4bool | calcNorm = false , |
|||
G4bool * | validNorm = 0 , |
|||
G4ThreeVector * | n = 0 | |||
) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 1187 of file G4BREPSolidPolyhedra.cc.
References G4BREPSolid::Intersect(), G4VSolid::kCarTolerance, G4BREPSolid::nb_of_surfaces, Reset(), G4BREPSolid::ShortestDistance, G4BREPSolid::SurfaceVec, and G4BREPSolid::TestSurfaceBBoxes().
01192 { 01193 // Calculates the distance from a point inside the solid 01194 // to the solid`s boundary along a specified direction vector. 01195 // Return 0 if the point is already outside (even number of 01196 // intersections greater than the tolerance). 01197 // 01198 // Note : If the shortest distance to a boundary is less 01199 // than the tolerance, it is ignored. This allows 01200 // for a point within a tolerant boundary to leave 01201 // immediately 01202 01203 G4int parity = 0; 01204 01205 // Set the surfaces to active again 01206 // 01207 Reset(); 01208 01209 const G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25; 01210 G4Vector3D Ptv = Pt; 01211 G4int a; 01212 01213 // I don`t understand this line 01214 // 01215 if(validNorm) 01216 *validNorm=false; 01217 01218 G4Vector3D Pttmp(Pt); 01219 G4Vector3D Vtmp(V); 01220 01221 G4Ray r(Pttmp, Vtmp); 01222 01223 // Test if the bounding box of each surface is intersected 01224 // by the ray. If not, the surface become deactive. 01225 // 01226 TestSurfaceBBoxes(r); 01227 01228 ShortestDistance = kInfinity; // this is actually the square of the distance 01229 01230 for(a=0; a< nb_of_surfaces; a++) 01231 { 01232 G4double surfDistance = SurfaceVec[a]->GetDistance(); 01233 01234 if(SurfaceVec[a]->IsActive()) 01235 { 01236 G4int intersects = SurfaceVec[a]->Intersect(r); 01237 01238 // test if the ray intersects the surface 01239 // 01240 if( intersects != 0 ) 01241 { 01242 parity += 1; 01243 01244 // if more than 1 surface is intersected, take the nearest one 01245 // 01246 if( surfDistance < ShortestDistance ) 01247 { 01248 if( surfDistance > sqrHalfTolerance ) 01249 { 01250 ShortestDistance = surfDistance; 01251 } 01252 else 01253 { 01254 // the point is within the boundary: ignore it 01255 // 01256 parity -= 1; 01257 } 01258 } 01259 } 01260 } 01261 } 01262 01263 G4double distance = 0.; 01264 01265 // Be careful ! 01266 // SurfaceVec->Distance is in fact the squared distance 01267 // 01268 // This condition was changed in order to give not zero answer 01269 // when particle is passing the border of two Touching Surfaces 01270 // and the distance to this surfaces is not zero. 01271 // parity is for the points on the boundary, 01272 // parity is counting only surfDistance<kCarTolerance/2. 01273 // 01274 // if((ShortestDistance != kInfinity) && (parity&1)) 01275 // 01276 // 01277 if((ShortestDistance != kInfinity) || (parity&1)) 01278 { 01279 distance = std::sqrt(ShortestDistance); 01280 } 01281 01282 return distance; 01283 }
void G4BREPSolidPolyhedra::Initialize | ( | ) | [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 906 of file G4BREPSolidPolyhedra.cc.
References G4BREPSolid::AxisBox, G4BREPSolid::Box, G4BREPSolid::CalcBBoxes(), G4BREPSolid::CheckSurfaceNormals(), G4BREPSolid::IsConvex(), and G4BREPSolid::ShortestDistance.
00907 { 00908 // Calc bounding box for solids and surfaces 00909 // Convert concave planes to convex 00910 // 00911 ShortestDistance=1000000; 00912 CheckSurfaceNormals(); 00913 if(!Box || !AxisBox) 00914 IsConvex(); 00915 00916 CalcBBoxes(); 00917 }
EInside G4BREPSolidPolyhedra::Inside | ( | register const G4ThreeVector & | Pt | ) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 929 of file G4BREPSolidPolyhedra.cc.
References G4BREPSolid::GetBBox(), G4Surface::GetDistance(), G4VSolid::kCarTolerance, kInside, kOutside, kSurface, G4BREPSolid::nb_of_surfaces, Reset(), G4BREPSolid::SurfaceVec, and G4BREPSolid::TestSurfaceBBoxes().
00930 { 00931 // This function find if the point Pt is inside, 00932 // outside or on the surface of the solid 00933 00934 const G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25; 00935 00936 G4Vector3D v(1, 0, 0.01); 00937 G4Vector3D Pttmp(Pt); 00938 G4Vector3D Vtmp(v); 00939 G4Ray r(Pttmp, Vtmp); 00940 00941 // Check if point is inside the Polyhedra bounding box 00942 // 00943 if( !GetBBox()->Inside(Pttmp) ) 00944 { 00945 return kOutside; 00946 } 00947 00948 // Set the surfaces to active again 00949 // 00950 Reset(); 00951 00952 // Test if the bounding box of each surface is intersected 00953 // by the ray. If not, the surface is deactivated. 00954 // 00955 TestSurfaceBBoxes(r); 00956 00957 G4int hits=0, samehit=0; 00958 00959 for(G4int a=0; a < nb_of_surfaces; a++) 00960 { 00961 G4Surface* surface = SurfaceVec[a]; 00962 00963 if(surface->IsActive()) 00964 { 00965 // count the number of intersections. 00966 // if this number is odd, the start of the ray is 00967 // inside the volume bounded by the surfaces, so 00968 // increment the number of intersection by 1 if the 00969 // point is not on the surface and if this intersection 00970 // was not found before 00971 // 00972 if( (surface->Intersect(r)) & 1 ) 00973 { 00974 // test if the point is on the surface 00975 // 00976 if(surface->GetDistance() < sqrHalfTolerance) 00977 { 00978 return kSurface; 00979 } 00980 // test if this intersection was found before 00981 // 00982 for(G4int i=0; i<a; i++) 00983 { 00984 if(surface->GetDistance() == SurfaceVec[i]->GetDistance()) 00985 { 00986 samehit++; 00987 break; 00988 } 00989 } 00990 00991 // count the number of surfaces intersected by the ray 00992 // 00993 if(!samehit) 00994 { 00995 hits++; 00996 } 00997 } 00998 } 00999 } 01000 01001 // if the number of surfaces intersected is odd, 01002 // the point is inside the solid 01003 // 01004 return ( (hits&1) ? kInside : kOutside ); 01005 }
G4BREPSolidPolyhedra & G4BREPSolidPolyhedra::operator= | ( | const G4BREPSolidPolyhedra & | rhs | ) |
Definition at line 187 of file G4BREPSolidPolyhedra.cc.
References constructorParams, and G4BREPSolid::operator=().
00188 { 00189 // Check assignment to self 00190 // 00191 if (this == &rhs) { return *this; } 00192 00193 // Copy base class data 00194 // 00195 G4BREPSolid::operator=(rhs); 00196 00197 // Copy data 00198 // 00199 constructorParams.start_angle = rhs.constructorParams.start_angle; 00200 constructorParams.opening_angle = rhs.constructorParams.opening_angle; 00201 constructorParams.sides = rhs.constructorParams.sides; 00202 constructorParams.num_z_planes = rhs.constructorParams.num_z_planes; 00203 constructorParams.z_start = rhs.constructorParams.z_start; 00204 G4int num_z_planes = constructorParams.num_z_planes; 00205 if( num_z_planes > 0 ) 00206 { 00207 delete [] constructorParams.z_values; 00208 delete [] constructorParams.RMIN; 00209 delete [] constructorParams.RMAX; 00210 constructorParams.z_values = new G4double[num_z_planes]; 00211 constructorParams.RMIN = new G4double[num_z_planes]; 00212 constructorParams.RMAX = new G4double[num_z_planes]; 00213 for( G4int idx = 0; idx < num_z_planes; ++idx ) 00214 { 00215 constructorParams.z_values[idx] = rhs.constructorParams.z_values[idx]; 00216 constructorParams.RMIN[idx] = rhs.constructorParams.RMIN[idx]; 00217 constructorParams.RMAX[idx] = rhs.constructorParams.RMAX[idx]; 00218 } 00219 } 00220 00221 InitializePolyhedra(); 00222 00223 return *this; 00224 }
void G4BREPSolidPolyhedra::Reset | ( | ) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 919 of file G4BREPSolidPolyhedra.cc.
References G4BREPSolid::Active(), G4BREPSolid::nb_of_surfaces, G4BREPSolid::ShortestDistance, G4BREPSolid::StartInside(), and G4BREPSolid::SurfaceVec.
Referenced by DistanceToIn(), DistanceToOut(), and Inside().
00920 { 00921 Active(1); 00922 ((G4BREPSolidPolyhedra*)this)->intersectionDistance=kInfinity; 00923 StartInside(0); 00924 for(register G4int a=0;a<nb_of_surfaces;a++) 00925 SurfaceVec[a]->Reset(); 00926 ShortestDistance = kInfinity; 00927 }
std::ostream & G4BREPSolidPolyhedra::StreamInfo | ( | std::ostream & | os | ) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 1345 of file G4BREPSolidPolyhedra.cc.
References G4BREPSolid::StreamInfo().
01346 { 01347 // Streams solid contents to output stream. 01348 01349 G4BREPSolid::StreamInfo( os ) 01350 << "\n start_angle: " << constructorParams.start_angle 01351 << "\n opening_angle: " << constructorParams.opening_angle 01352 << "\n sides: " << constructorParams.sides 01353 << "\n num_z_planes: " << constructorParams.num_z_planes 01354 << "\n z_start: " << constructorParams.z_start 01355 << "\n z_values: "; 01356 G4int idx; 01357 for( idx = 0; idx < constructorParams.num_z_planes; idx++ ) 01358 { 01359 os << constructorParams.z_values[idx] << " "; 01360 } 01361 os << "\n RMIN: "; 01362 for( idx = 0; idx < constructorParams.num_z_planes; idx++ ) 01363 { 01364 os << constructorParams.RMIN[idx] << " "; 01365 } 01366 os << "\n RMAX: "; 01367 for( idx = 0; idx < constructorParams.num_z_planes; idx++ ) 01368 { 01369 os << constructorParams.RMAX[idx] << " "; 01370 } 01371 os << "\n-----------------------------------------------------------\n"; 01372 01373 return os; 01374 }
G4ThreeVector G4BREPSolidPolyhedra::SurfaceNormal | ( | const G4ThreeVector & | ) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 1008 of file G4BREPSolidPolyhedra.cc.
References G4FPlane::GetSrfPoint(), G4VSolid::kCarTolerance, G4BREPSolid::nb_of_surfaces, G4FPlane::SurfaceNormal(), and G4BREPSolid::SurfaceVec.
01009 { 01010 // This function calculates the normal of the closest surface 01011 // to the given point 01012 // Note : the sense of the normal depends on the sense of the surface 01013 01014 G4int iplane; 01015 G4bool normflag = false; 01016 const G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25; 01017 01018 // Determine if the point is on the surface 01019 // 01020 G4double minDist = kInfinity; 01021 G4int normPlane = 0; 01022 for(iplane = 0; iplane < nb_of_surfaces; iplane++) 01023 { 01024 G4double dist = std::fabs(SurfaceVec[iplane]->HowNear(Pt)); 01025 if( minDist > dist ) 01026 { 01027 minDist = dist; 01028 normPlane = iplane; 01029 } 01030 if( dist < sqrHalfTolerance) 01031 { 01032 // the point is on this surface, so take this as the 01033 // the surface to consider for computing the normal 01034 // 01035 normflag = true; 01036 break; 01037 } 01038 } 01039 01040 // Calculate the normal at this point, if the point is on the 01041 // surface, otherwise compute the normal to the closest surface 01042 // 01043 if ( normflag ) // point on surface 01044 { 01045 G4ThreeVector norm = SurfaceVec[iplane]->SurfaceNormal(Pt); 01046 return norm.unit(); 01047 } 01048 else // point not on surface 01049 { 01050 G4FPlane* nPlane = (G4FPlane*)(SurfaceVec[normPlane]); 01051 G4ThreeVector hitPt = nPlane->GetSrfPoint(); 01052 G4ThreeVector hitNorm = nPlane->SurfaceNormal(hitPt); 01053 return hitNorm.unit(); 01054 } 01055 }