#include <G4BREPSolidPCone.hh>
Inheritance diagram for G4BREPSolidPCone:
Public Member Functions | |
G4BREPSolidPCone (const G4String &name, G4double start_angle, G4double opening_angle, G4int num_z_planes, G4double z_start, G4double z_values[], G4double RMIN[], G4double RMAX[]) | |
~G4BREPSolidPCone () | |
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 |
void | Reset () const |
G4Polyhedron * | CreatePolyhedron () const |
G4VSolid * | Clone () const |
std::ostream & | StreamInfo (std::ostream &os) const |
G4BREPSolidPCone (__void__ &) | |
G4BREPSolidPCone (const G4BREPSolidPCone &rhs) | |
G4BREPSolidPCone & | operator= (const G4BREPSolidPCone &rhs) |
Data Structures | |
struct | G4BREPPConeParams |
Definition at line 57 of file G4BREPSolidPCone.hh.
G4BREPSolidPCone::G4BREPSolidPCone | ( | const G4String & | name, | |
G4double | start_angle, | |||
G4double | opening_angle, | |||
G4int | num_z_planes, | |||
G4double | z_start, | |||
G4double | z_values[], | |||
G4double | RMIN[], | |||
G4double | RMAX[] | |||
) |
Definition at line 58 of file G4BREPSolidPCone.cc.
References G4BREPSolid::active.
Referenced by Clone().
00066 : G4BREPSolid(name) 00067 { 00068 // Save contructor parameters 00069 // 00070 constructorParams.start_angle = start_angle; 00071 constructorParams.opening_angle = opening_angle; 00072 constructorParams.num_z_planes = num_z_planes; 00073 constructorParams.z_start = z_start; 00074 constructorParams.z_values = 0; 00075 constructorParams.RMIN = 0; 00076 constructorParams.RMAX = 0; 00077 00078 if( num_z_planes > 0 ) 00079 { 00080 constructorParams.z_values = new G4double[num_z_planes]; 00081 constructorParams.RMIN = new G4double[num_z_planes]; 00082 constructorParams.RMAX = new G4double[num_z_planes]; 00083 for( G4int idx = 0; idx < num_z_planes; ++idx ) 00084 { 00085 constructorParams.z_values[idx] = z_values[idx]; 00086 constructorParams.RMIN[idx] = RMIN[idx]; 00087 constructorParams.RMAX[idx] = RMAX[idx]; 00088 } 00089 } 00090 00091 active=1; 00092 InitializePCone(); 00093 }
G4BREPSolidPCone::~G4BREPSolidPCone | ( | ) |
Definition at line 107 of file G4BREPSolidPCone.cc.
00108 { 00109 if( constructorParams.num_z_planes > 0 ) 00110 { 00111 delete [] constructorParams.z_values; 00112 delete [] constructorParams.RMIN; 00113 delete [] constructorParams.RMAX; 00114 } 00115 }
G4BREPSolidPCone::G4BREPSolidPCone | ( | __void__ & | ) |
Definition at line 95 of file G4BREPSolidPCone.cc.
00096 : G4BREPSolid(a) 00097 { 00098 constructorParams.start_angle = 0.; 00099 constructorParams.opening_angle = 0.; 00100 constructorParams.num_z_planes = 0; 00101 constructorParams.z_start = 0.; 00102 constructorParams.z_values = 0; 00103 constructorParams.RMIN = 0; 00104 constructorParams.RMAX = 0; 00105 }
G4BREPSolidPCone::G4BREPSolidPCone | ( | const G4BREPSolidPCone & | rhs | ) |
Definition at line 117 of file G4BREPSolidPCone.cc.
References constructorParams.
00118 : G4BREPSolid(rhs) 00119 { 00120 constructorParams.start_angle = rhs.constructorParams.start_angle; 00121 constructorParams.opening_angle = rhs.constructorParams.opening_angle; 00122 constructorParams.num_z_planes = rhs.constructorParams.num_z_planes; 00123 constructorParams.z_start = rhs.constructorParams.z_start; 00124 constructorParams.z_values = 0; 00125 constructorParams.RMIN = 0; 00126 constructorParams.RMAX = 0; 00127 G4int nplanes = constructorParams.num_z_planes; 00128 if( nplanes > 0 ) 00129 { 00130 constructorParams.z_values = new G4double[nplanes]; 00131 constructorParams.RMIN = new G4double[nplanes]; 00132 constructorParams.RMAX = new G4double[nplanes]; 00133 for( G4int idx = 0; idx < nplanes; ++idx ) 00134 { 00135 constructorParams.z_values[idx] = rhs.constructorParams.z_values[idx]; 00136 constructorParams.RMIN[idx] = rhs.constructorParams.RMIN[idx]; 00137 constructorParams.RMAX[idx] = rhs.constructorParams.RMAX[idx]; 00138 } 00139 } 00140 00141 InitializePCone(); 00142 }
G4VSolid * G4BREPSolidPCone::Clone | ( | ) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 1048 of file G4BREPSolidPCone.cc.
References G4BREPSolidPCone().
01049 { 01050 return new G4BREPSolidPCone(*this); 01051 }
G4Polyhedron * G4BREPSolidPCone::CreatePolyhedron | ( | ) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 1150 of file G4BREPSolidPCone.cc.
01151 { 01152 return new G4PolyhedronPcon( constructorParams.start_angle, 01153 constructorParams.opening_angle, 01154 constructorParams.num_z_planes, 01155 constructorParams.z_values, 01156 constructorParams.RMIN, 01157 constructorParams.RMAX ); 01158 }
G4double G4BREPSolidPCone::DistanceToIn | ( | register const G4ThreeVector & | Pt, | |
register const G4ThreeVector & | V | |||
) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 856 of file G4BREPSolidPCone.cc.
References G4Surface::GetDistance(), G4Surface::HowNear(), G4BREPSolid::Intersect(), G4VSolid::kCarTolerance, G4BREPSolid::nb_of_surfaces, Reset(), G4BREPSolid::ShortestDistance, SurfaceNormal(), G4BREPSolid::SurfaceVec, and G4BREPSolid::TestSurfaceBBoxes().
00858 { 00859 // Calculates the distance from a point outside the solid 00860 // to the solid`s boundary along a specified direction vector. 00861 // 00862 // Note : Intersections with boundaries less than the 00863 // tolerance must be ignored if the direction 00864 // is away from the boundary 00865 00866 G4int a; 00867 00868 // Set the surfaces to active again 00869 // 00870 Reset(); 00871 00872 G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25; 00873 G4Vector3D Pttmp(Pt); 00874 G4Vector3D Vtmp(V); 00875 G4Ray r(Pttmp, Vtmp); 00876 00877 // Test if the bounding box of each surface is intersected 00878 // by the ray. If not, the surface become deactive. 00879 // 00880 TestSurfaceBBoxes(r); 00881 00882 ShortestDistance = kInfinity; 00883 00884 for(a=0; a< nb_of_surfaces; a++) 00885 { 00886 if(SurfaceVec[a]->IsActive()) 00887 { 00888 // test if the ray intersect the surface 00889 // 00890 G4Vector3D Norm = SurfaceVec[a]->SurfaceNormal(Pttmp); 00891 G4double hownear = SurfaceVec[a]->HowNear(Pt); 00892 00893 if( (Norm * Vtmp) < 0 && std::fabs(hownear) < sqrHalfTolerance ) 00894 return 0; 00895 00896 if( (SurfaceVec[a]->Intersect(r)) ) 00897 { 00898 // if more than 1 surface is intersected, 00899 // take the nearest one 00900 G4double distance = SurfaceVec[a]->GetDistance(); 00901 00902 if( distance < ShortestDistance ) 00903 { 00904 if( distance > sqrHalfTolerance ) 00905 { 00906 ShortestDistance = distance; 00907 } 00908 } 00909 } 00910 } 00911 } 00912 00913 // Be careful ! 00914 // SurfaceVec->Distance is in fact the squared distance 00915 // 00916 if(ShortestDistance != kInfinity) 00917 return( std::sqrt(ShortestDistance) ); 00918 else 00919 // no intersection 00920 // 00921 return kInfinity; 00922 }
G4double G4BREPSolidPCone::DistanceToIn | ( | const G4ThreeVector & | ) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 812 of file G4BREPSolidPCone.cc.
References G4BREPSolid::nb_of_surfaces, Reset(), and G4BREPSolid::SurfaceVec.
00813 { 00814 // Calculates the shortest distance ("safety") from a point 00815 // outside the solid to any boundary of this solid. 00816 // Return 0 if the point is already inside. 00817 00818 G4double *dists = new G4double[nb_of_surfaces]; 00819 G4int a; 00820 00821 // Set the surfaces to active again 00822 // 00823 Reset(); 00824 00825 // Compute the shortest distance of the point to each surfaces 00826 // Be careful : it's a signed value 00827 // 00828 for(a=0; a< nb_of_surfaces; a++) 00829 dists[a] = SurfaceVec[a]->HowNear(Pt); 00830 00831 G4double Dist = kInfinity; 00832 00833 // if dists[] is positive, the point is outside 00834 // so take the shortest of the shortest positive distances 00835 // dists[] can be equal to 0 : point on a surface 00836 // ( Problem with the G4FPlane : there is no inside and no outside... 00837 // So, to test if the point is inside to return 0, utilize the Inside 00838 // function. But I don`t know if it is really needed because dToIn is 00839 // called only if the point is outside ) 00840 // 00841 for(a = 0; a < nb_of_surfaces; a++) 00842 if( std::fabs(Dist) > std::fabs(dists[a]) ) 00843 //if( dists[a] >= 0) 00844 Dist = dists[a]; 00845 00846 delete[] dists; 00847 00848 if(Dist == kInfinity) 00849 // the point is inside the solid or on a surface 00850 // 00851 return 0; 00852 else 00853 return std::fabs(Dist); 00854 }
G4double G4BREPSolidPCone::DistanceToOut | ( | const G4ThreeVector & | ) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 1005 of file G4BREPSolidPCone.cc.
References G4BREPSolid::nb_of_surfaces, Reset(), and G4BREPSolid::SurfaceVec.
01006 { 01007 // Calculates the shortest distance ("safety") from a point 01008 // inside the solid to any boundary of this solid. 01009 // Return 0 if the point is already outside. 01010 01011 G4double *dists = new G4double[nb_of_surfaces]; 01012 G4int a; 01013 01014 // Set the surfaces to active again 01015 Reset(); 01016 01017 // calcul of the shortest distance of the point to each surfaces 01018 // Be careful : it's a signed value 01019 // 01020 for(a=0; a< nb_of_surfaces; a++) 01021 dists[a] = SurfaceVec[a]->HowNear(Pt); 01022 01023 G4double Dist = kInfinity; 01024 01025 // if dists[] is negative, the point is inside 01026 // so take the shortest of the shortest negative distances 01027 // dists[] can be equal to 0 : point on a surface 01028 // ( Problem with the G4FPlane : there is no inside and no outside... 01029 // So, to test if the point is outside to return 0, utilize the Inside 01030 // function. But I don`t know if it is really needed because dToOut is 01031 // called only if the point is inside ) 01032 01033 for(a = 0; a < nb_of_surfaces; a++) 01034 if( std::fabs(Dist) > std::fabs(dists[a]) ) 01035 //if( dists[a] <= 0) 01036 Dist = dists[a]; 01037 01038 delete[] dists; 01039 01040 if(Dist == kInfinity) 01041 // the point is ouside the solid or on a surface 01042 // 01043 return 0; 01044 else 01045 return std::fabs(Dist); 01046 }
G4double G4BREPSolidPCone::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 924 of file G4BREPSolidPCone.cc.
References G4Surface::GetDistance(), G4Surface::HowNear(), G4BREPSolid::Intersect(), G4VSolid::kCarTolerance, G4BREPSolid::nb_of_surfaces, Reset(), G4BREPSolid::ShortestDistance, SurfaceNormal(), G4BREPSolid::SurfaceVec, and G4BREPSolid::TestSurfaceBBoxes().
00929 { 00930 // Calculates the distance from a point inside the solid 00931 // to the solid`s boundary along a specified direction vector. 00932 // Return 0 if the point is already outside. 00933 // 00934 // Note : If the shortest distance to a boundary is less 00935 // than the tolerance, it is ignored. This allows 00936 // for a point within a tolerant boundary to leave 00937 // immediately 00938 00939 // Set the surfaces to active again 00940 // 00941 Reset(); 00942 00943 const G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25; 00944 G4Vector3D Ptv = G4Vector3D( Pt ); 00945 G4int a; 00946 00947 // I don`t understand this line 00948 // 00949 if(validNorm) 00950 *validNorm=false; 00951 00952 G4Vector3D Pttmp(Pt); 00953 G4Vector3D Vtmp(V); 00954 00955 G4Ray r(Pttmp, Vtmp); 00956 00957 // Test if the bounding box of each surface is intersected 00958 // by the ray. If not, the surface become deactive. 00959 // 00960 TestSurfaceBBoxes(r); 00961 00962 ShortestDistance = kInfinity; 00963 00964 for(a=0; a< nb_of_surfaces; a++) 00965 { 00966 if( SurfaceVec[a]->IsActive() ) 00967 { 00968 G4Vector3D Norm = SurfaceVec[a]->SurfaceNormal(Pttmp); 00969 G4double hownear = SurfaceVec[a]->HowNear(Pt); 00970 00971 if( (Norm * Vtmp) > 0 && std::fabs( hownear ) < sqrHalfTolerance ) 00972 return 0; 00973 00974 // test if the ray intersect the surface 00975 // 00976 if( SurfaceVec[a]->Intersect(r) ) 00977 { 00978 // if more than 1 surface is intersected, 00979 // take the nearest one 00980 // 00981 G4double distance = SurfaceVec[a]->GetDistance(); 00982 00983 if( distance < ShortestDistance ) 00984 { 00985 if( distance > sqrHalfTolerance ) 00986 { 00987 ShortestDistance = distance; 00988 } 00989 } 00990 } 00991 } 00992 } 00993 00994 // Be careful ! 00995 // SurfaceVec->Distance is in fact the squared distance 00996 // 00997 if(ShortestDistance != kInfinity) 00998 return std::sqrt(ShortestDistance); 00999 else 01000 // if no intersection is founded, the point is outside 01001 // 01002 return 0; 01003 }
void G4BREPSolidPCone::Initialize | ( | ) | [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 665 of file G4BREPSolidPCone.cc.
References G4BREPSolid::AxisBox, G4BREPSolid::Box, G4BREPSolid::CalcBBoxes(), G4BREPSolid::CheckSurfaceNormals(), G4BREPSolid::IsConvex(), and G4BREPSolid::ShortestDistance.
00666 { 00667 // Computes the bounding box for solids and surfaces 00668 // Converts concave planes to convex 00669 // 00670 ShortestDistance=1000000; 00671 CheckSurfaceNormals(); 00672 00673 if(!Box || !AxisBox) 00674 IsConvex(); 00675 00676 CalcBBoxes(); 00677 }
EInside G4BREPSolidPCone::Inside | ( | register const G4ThreeVector & | Pt | ) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 679 of file G4BREPSolidPCone.cc.
References G4BREPSolid::GetBBox(), G4VSolid::kCarTolerance, kInside, kOutside, kSurface, G4BREPSolid::nb_of_surfaces, Reset(), G4Surface::SurfaceNormal(), G4BREPSolid::SurfaceVec, and G4BREPSolid::TestSurfaceBBoxes().
00680 { 00681 // This function find if the point Pt is inside, 00682 // outside or on the surface of the solid 00683 00684 G4Vector3D v(1, 0, 0.01); 00685 //G4Vector3D v(1, 0, 0); // This will miss the planar surface perp. to Z axis 00686 //G4Vector3D v(0, 0, 1); // This works, however considered as hack not a fix 00687 G4Vector3D Pttmp(Pt); 00688 G4Vector3D Vtmp(v); 00689 G4Ray r(Pttmp, Vtmp); 00690 00691 // Check if point is inside the PCone bounding box 00692 // 00693 if( !GetBBox()->Inside(Pttmp) ) 00694 { 00695 return kOutside; 00696 } 00697 00698 // Set the surfaces to active again 00699 // 00700 Reset(); 00701 00702 // Test if the bounding box of each surface is intersected 00703 // by the ray. If not, the surface is deactivated. 00704 // 00705 TestSurfaceBBoxes(r); 00706 00707 G4double dist = kInfinity; 00708 G4bool isIntersected = false; 00709 G4int WhichSurface = 0; 00710 00711 const G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25; 00712 00713 // Chech if the point is on the surface, otherwise 00714 // find the nearest intersected suface. If there are not intersections the 00715 // point is outside 00716 00717 for(G4int a=0; a < nb_of_surfaces; a++) 00718 { 00719 G4Surface* surface = SurfaceVec[a]; 00720 00721 if( surface->IsActive() ) 00722 { 00723 G4double hownear = surface->HowNear(Pt); 00724 00725 if( std::fabs( hownear ) < sqrHalfTolerance ) 00726 { 00727 return kSurface; 00728 } 00729 00730 if( surface->Intersect(r) ) 00731 { 00732 isIntersected = true; 00733 hownear = surface->GetDistance(); 00734 00735 if ( std::fabs( hownear ) < dist ) 00736 { 00737 dist = hownear; 00738 WhichSurface = a; 00739 } 00740 } 00741 } 00742 } 00743 00744 if ( !isIntersected ) 00745 { 00746 return kOutside; 00747 } 00748 00749 // Find the point of intersection on the surface and the normal 00750 // !!!! be carefull the distance is std::sqrt(dist) !!!! 00751 00752 dist = std::sqrt( dist ); 00753 G4Vector3D IntersectionPoint = Pttmp + dist*Vtmp; 00754 G4Vector3D Normal = 00755 SurfaceVec[WhichSurface]->SurfaceNormal( IntersectionPoint ); 00756 00757 G4double dot = Normal*Vtmp; 00758 00759 return ( (dot > 0) ? kInside : kOutside ); 00760 }
G4BREPSolidPCone & G4BREPSolidPCone::operator= | ( | const G4BREPSolidPCone & | rhs | ) |
Definition at line 145 of file G4BREPSolidPCone.cc.
References constructorParams, and G4BREPSolid::operator=().
00146 { 00147 // Check assignment to self 00148 // 00149 if (this == &rhs) { return *this; } 00150 00151 // Copy base class data 00152 // 00153 G4BREPSolid::operator=(rhs); 00154 00155 // Copy data 00156 // 00157 constructorParams.start_angle = rhs.constructorParams.start_angle; 00158 constructorParams.opening_angle = rhs.constructorParams.opening_angle; 00159 constructorParams.num_z_planes = rhs.constructorParams.num_z_planes; 00160 constructorParams.z_start = rhs.constructorParams.z_start; 00161 G4int nplanes = constructorParams.num_z_planes; 00162 if( nplanes > 0 ) 00163 { 00164 delete [] constructorParams.z_values; 00165 delete [] constructorParams.RMIN; 00166 delete [] constructorParams.RMAX; 00167 constructorParams.z_values = new G4double[nplanes]; 00168 constructorParams.RMIN = new G4double[nplanes]; 00169 constructorParams.RMAX = new G4double[nplanes]; 00170 for( G4int idx = 0; idx < nplanes; ++idx ) 00171 { 00172 constructorParams.z_values[idx] = rhs.constructorParams.z_values[idx]; 00173 constructorParams.RMIN[idx] = rhs.constructorParams.RMIN[idx]; 00174 constructorParams.RMAX[idx] = rhs.constructorParams.RMAX[idx]; 00175 } 00176 } 00177 00178 InitializePCone(); 00179 00180 return *this; 00181 }
void G4BREPSolidPCone::Reset | ( | ) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 1083 of file G4BREPSolidPCone.cc.
References G4BREPSolid::Active(), G4BREPSolid::nb_of_surfaces, G4BREPSolid::ShortestDistance, G4BREPSolid::StartInside(), and G4BREPSolid::SurfaceVec.
Referenced by DistanceToIn(), DistanceToOut(), and Inside().
01084 { 01085 Active(1); 01086 ((G4BREPSolidPCone*)this)->intersectionDistance=kInfinity; 01087 StartInside(0); 01088 for(register int a=0;a<nb_of_surfaces;a++) 01089 SurfaceVec[a]->Reset(); 01090 ShortestDistance = kInfinity; 01091 }
std::ostream & G4BREPSolidPCone::StreamInfo | ( | std::ostream & | os | ) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 1053 of file G4BREPSolidPCone.cc.
References G4BREPSolid::StreamInfo().
01054 { 01055 // Streams solid contents to output stream. 01056 01057 G4BREPSolid::StreamInfo( os ) 01058 << "\n start_angle: " << constructorParams.start_angle 01059 << "\n opening_angle: " << constructorParams.opening_angle 01060 << "\n num_z_planes: " << constructorParams.num_z_planes 01061 << "\n z_start: " << constructorParams.z_start 01062 << "\n z_values: "; 01063 G4int idx; 01064 for( idx = 0; idx < constructorParams.num_z_planes; idx++ ) 01065 { 01066 os << constructorParams.z_values[idx] << " "; 01067 } 01068 os << "\n RMIN: "; 01069 for( idx = 0; idx < constructorParams.num_z_planes; idx++ ) 01070 { 01071 os << constructorParams.RMIN[idx] << " "; 01072 } 01073 os << "\n RMAX: "; 01074 for( idx = 0; idx < constructorParams.num_z_planes; idx++ ) 01075 { 01076 os << constructorParams.RMAX[idx] << " "; 01077 } 01078 os << "\n-----------------------------------------------------------\n"; 01079 01080 return os; 01081 }
G4ThreeVector G4BREPSolidPCone::SurfaceNormal | ( | const G4ThreeVector & | ) | const [virtual] |
Reimplemented from G4BREPSolid.
Definition at line 763 of file G4BREPSolidPCone.cc.
References G4Surface::GetClosestHit(), G4VSolid::kCarTolerance, G4BREPSolid::nb_of_surfaces, G4Surface::SurfaceNormal(), and G4BREPSolid::SurfaceVec.
Referenced by DistanceToIn(), and DistanceToOut().
00764 { 00765 // This function calculates the normal of the closest surface 00766 // at a point on the surface 00767 // Note : the sense of the normal depends on the sense of the surface 00768 00769 G4int isurf; 00770 G4bool normflag = false; 00771 00772 const G4double sqrHalfTolerance = kCarTolerance*kCarTolerance*0.25; 00773 00774 // Determine if the point is on the surface 00775 // 00776 G4double minDist = kInfinity; 00777 G4int normSurface = 0; 00778 for(isurf = 0; isurf < nb_of_surfaces; isurf++) 00779 { 00780 G4double dist = std::fabs(SurfaceVec[isurf]->HowNear(Pt)); 00781 if( minDist > dist ) 00782 { 00783 minDist = dist; 00784 normSurface = isurf; 00785 } 00786 if( dist < sqrHalfTolerance) 00787 { 00788 // the point is on this surface 00789 // 00790 normflag = true; 00791 break; 00792 } 00793 } 00794 00795 // Calculate the normal at this point, if the point is on the 00796 // surface, otherwise compute the normal to the closest surface 00797 // 00798 if ( normflag ) // point on surface 00799 { 00800 G4ThreeVector norm = SurfaceVec[isurf]->SurfaceNormal(Pt); 00801 return norm.unit(); 00802 } 00803 else // point not on surface 00804 { 00805 G4Surface* nSurface = SurfaceVec[normSurface]; 00806 G4ThreeVector hitPt = nSurface->GetClosestHit(); 00807 G4ThreeVector hitNorm = nSurface->SurfaceNormal(hitPt); 00808 return hitNorm.unit(); 00809 } 00810 }