Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4GenericTrap Class Reference

#include <G4GenericTrap.hh>

+ Inheritance diagram for G4GenericTrap:

Public Member Functions

 G4GenericTrap (const G4String &name, G4double halfZ, const std::vector< G4TwoVector > &vertices)
 
 ~G4GenericTrap ()
 
G4double GetZHalfLength () const
 
G4int GetNofVertices () const
 
G4TwoVector GetVertex (G4int index) const
 
const std::vector< G4TwoVector > & GetVertices () const
 
G4double GetTwistAngle (G4int index) const
 
G4bool IsTwisted () const
 
G4int GetVisSubdivisions () const
 
void SetVisSubdivisions (G4int subdiv)
 
EInside Inside (const G4ThreeVector &p) const
 
G4ThreeVector SurfaceNormal (const G4ThreeVector &p) const
 
G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const
 
G4double DistanceToIn (const G4ThreeVector &p) const
 
G4double DistanceToOut (const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const
 
G4double DistanceToOut (const G4ThreeVector &p) const
 
void BoundingLimits (G4ThreeVector &pMin, G4ThreeVector &pMax) const
 
G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
 
G4GeometryType GetEntityType () const
 
G4VSolidClone () const
 
std::ostream & StreamInfo (std::ostream &os) const
 
G4ThreeVector GetPointOnSurface () const
 
G4double GetCubicVolume ()
 
G4double GetSurfaceArea ()
 
G4PolyhedronGetPolyhedron () const
 
void DescribeYourselfTo (G4VGraphicsScene &scene) const
 
G4VisExtent GetExtent () const
 
G4PolyhedronCreatePolyhedron () const
 
 G4GenericTrap (__void__ &)
 
 G4GenericTrap (const G4GenericTrap &rhs)
 
G4GenericTrapoperator= (const G4GenericTrap &rhs)
 
- Public Member Functions inherited from G4VSolid
 G4VSolid (const G4String &name)
 
virtual ~G4VSolid ()
 
G4bool operator== (const G4VSolid &s) const
 
G4String GetName () const
 
void SetName (const G4String &name)
 
G4double GetTolerance () const
 
virtual void BoundingLimits (G4ThreeVector &pMin, G4ThreeVector &pMax) const
 
virtual G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const =0
 
virtual EInside Inside (const G4ThreeVector &p) const =0
 
virtual G4ThreeVector SurfaceNormal (const G4ThreeVector &p) const =0
 
virtual G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const =0
 
virtual G4double DistanceToIn (const G4ThreeVector &p) const =0
 
virtual G4double DistanceToOut (const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const =0
 
virtual G4double DistanceToOut (const G4ThreeVector &p) const =0
 
virtual void ComputeDimensions (G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
 
virtual G4double GetCubicVolume ()
 
virtual G4double GetSurfaceArea ()
 
virtual G4GeometryType GetEntityType () const =0
 
virtual G4ThreeVector GetPointOnSurface () const
 
virtual G4VSolidClone () const
 
virtual std::ostream & StreamInfo (std::ostream &os) const =0
 
void DumpInfo () const
 
virtual void DescribeYourselfTo (G4VGraphicsScene &scene) const =0
 
virtual G4VisExtent GetExtent () const
 
virtual G4PolyhedronCreatePolyhedron () const
 
virtual G4PolyhedronGetPolyhedron () const
 
virtual const G4VSolidGetConstituentSolid (G4int no) const
 
virtual G4VSolidGetConstituentSolid (G4int no)
 
virtual const G4DisplacedSolidGetDisplacedSolidPtr () const
 
virtual G4DisplacedSolidGetDisplacedSolidPtr ()
 
 G4VSolid (__void__ &)
 
 G4VSolid (const G4VSolid &rhs)
 
G4VSolidoperator= (const G4VSolid &rhs)
 
G4double EstimateCubicVolume (G4int nStat, G4double epsilon) const
 
G4double EstimateSurfaceArea (G4int nStat, G4double ell) const
 

Protected Attributes

G4bool fRebuildPolyhedron = false
 
G4PolyhedronfpPolyhedron = nullptr
 
- Protected Attributes inherited from G4VSolid
G4double kCarTolerance
 

Additional Inherited Members

- Protected Member Functions inherited from G4VSolid
void CalculateClippedPolygonExtent (G4ThreeVectorList &pPolygon, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
 
void ClipCrossSection (G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
 
void ClipBetweenSections (G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
 
void ClipPolygon (G4ThreeVectorList &pPolygon, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis) const
 

Detailed Description

Definition at line 79 of file G4GenericTrap.hh.

Constructor & Destructor Documentation

◆ G4GenericTrap() [1/3]

G4GenericTrap::G4GenericTrap ( const G4String name,
G4double  halfZ,
const std::vector< G4TwoVector > &  vertices 
)

Definition at line 65 of file G4GenericTrap.cc.

67 : G4VSolid(name), fDz(halfZ), fVertices(),
68 fMinBBoxVector(G4ThreeVector(0,0,0)), fMaxBBoxVector(G4ThreeVector(0,0,0))
69{
70 // General constructor
71 const G4double min_length=5*1.e-6;
72 G4double length = 0.;
73 G4int k=0;
74 G4String errorDescription = "InvalidSetup in \" ";
75 errorDescription += name;
76 errorDescription += "\"";
77
78 halfCarTolerance = kCarTolerance*0.5;
79
80 // Check vertices size
81
82 if ( G4int(vertices.size()) != fgkNofVertices )
83 {
84 G4Exception("G4GenericTrap::G4GenericTrap()", "GeomSolids0002",
85 FatalErrorInArgument, "Number of vertices != 8");
86 }
87
88 // Check dZ
89 //
90 if (halfZ < kCarTolerance)
91 {
92 G4Exception("G4GenericTrap::G4GenericTrap()", "GeomSolids0002",
93 FatalErrorInArgument, "dZ is too small or negative");
94 }
95
96 // Check Ordering and Copy vertices
97 //
98 if(CheckOrder(vertices))
99 {
100 for (G4int i=0; i<fgkNofVertices; ++i) {fVertices.push_back(vertices[i]);}
101 }
102 else
103 {
104 for (auto i=0; i <4; ++i) {fVertices.push_back(vertices[3-i]);}
105 for (auto i=0; i <4; ++i) {fVertices.push_back(vertices[7-i]);}
106 }
107
108 // Check length of segments and Adjust
109 //
110 for (auto j=0; j<2; ++j)
111 {
112 for (auto i=1; i<4; ++i)
113 {
114 k = j*4+i;
115 length = (fVertices[k]-fVertices[k-1]).mag();
116 if ( ( length < min_length) && ( length > kCarTolerance ) )
117 {
118 std::ostringstream message;
119 message << "Length segment is too small." << G4endl
120 << "Distance between " << fVertices[k-1] << " and "
121 << fVertices[k] << " is only " << length << " mm !";
122 G4Exception("G4GenericTrap::G4GenericTrap()", "GeomSolids1001",
123 JustWarning, message, "Vertices will be collapsed.");
124 fVertices[k]=fVertices[k-1];
125 }
126 }
127 }
128
129 // Compute Twist
130 //
131 for( auto i=0; i<4; ++i) { fTwist[i]=0.; }
132 fIsTwisted = ComputeIsTwisted();
133
134 // Compute Bounding Box
135 //
136 ComputeBBox();
137
138 // If not twisted - create tessellated solid
139 // (an alternative implementation for testing)
140 //
141#ifdef G4TESS_TEST
142 if ( !fIsTwisted ) { fTessellatedSolid = CreateTessellatedSolid(); }
143#endif
144}
@ JustWarning
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4double kCarTolerance
Definition: G4VSolid.hh:302
const char * name(G4int ptype)

◆ ~G4GenericTrap()

G4GenericTrap::~G4GenericTrap ( )

Definition at line 158 of file G4GenericTrap.cc.

159{
160 delete fTessellatedSolid;
161}

◆ G4GenericTrap() [2/3]

G4GenericTrap::G4GenericTrap ( __void__ &  a)

Definition at line 148 of file G4GenericTrap.cc.

149 : G4VSolid(a), halfCarTolerance(0.), fDz(0.), fVertices(),
150 fMinBBoxVector(G4ThreeVector(0,0,0)), fMaxBBoxVector(G4ThreeVector(0,0,0))
151{
152 // Fake default constructor - sets only member data and allocates memory
153 // for usage restricted to object persistency.
154}

◆ G4GenericTrap() [3/3]

G4GenericTrap::G4GenericTrap ( const G4GenericTrap rhs)

Definition at line 165 of file G4GenericTrap.cc.

166 : G4VSolid(rhs),
167 halfCarTolerance(rhs.halfCarTolerance),
168 fDz(rhs.fDz), fVertices(rhs.fVertices),
169 fIsTwisted(rhs.fIsTwisted),
170 fMinBBoxVector(rhs.fMinBBoxVector), fMaxBBoxVector(rhs.fMaxBBoxVector),
171 fVisSubdivisions(rhs.fVisSubdivisions),
172 fSurfaceArea(rhs.fSurfaceArea), fCubicVolume(rhs.fCubicVolume)
173{
174 for (auto i=0; i<4; ++i) { fTwist[i] = rhs.fTwist[i]; }
175#ifdef G4TESS_TEST
176 if (rhs.fTessellatedSolid && !fIsTwisted )
177 { fTessellatedSolid = CreateTessellatedSolid(); }
178#endif
179}

Member Function Documentation

◆ BoundingLimits()

void G4GenericTrap::BoundingLimits ( G4ThreeVector pMin,
G4ThreeVector pMax 
) const
virtual

Reimplemented from G4VSolid.

Definition at line 1176 of file G4GenericTrap.cc.

1178{
1179 pMin = GetMinimumBBox();
1180 pMax = GetMaximumBBox();
1181
1182 // Check correctness of the bounding box
1183 //
1184 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
1185 {
1186 std::ostringstream message;
1187 message << "Bad bounding box (min >= max) for solid: "
1188 << GetName() << " !"
1189 << "\npMin = " << pMin
1190 << "\npMax = " << pMax;
1191 G4Exception("G4GenericTrap::BoundingLimits()", "GeomMgt0001",
1192 JustWarning, message);
1193 DumpInfo();
1194 }
1195}
double z() const
double x() const
double y() const
G4String GetName() const
void DumpInfo() const

Referenced by CalculateExtent().

◆ CalculateExtent()

G4bool G4GenericTrap::CalculateExtent ( const EAxis  pAxis,
const G4VoxelLimits pVoxelLimit,
const G4AffineTransform pTransform,
G4double pmin,
G4double pmax 
) const
virtual

Implements G4VSolid.

Definition at line 1200 of file G4GenericTrap.cc.

1204{
1205 G4ThreeVector bmin, bmax;
1206 G4bool exist;
1207
1208 // Check bounding box (bbox)
1209 //
1210 BoundingLimits(bmin,bmax);
1211 G4BoundingEnvelope bbox(bmin,bmax);
1212#ifdef G4BBOX_EXTENT
1213 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
1214#endif
1215 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
1216 {
1217 return exist = (pMin < pMax) ? true : false;
1218 }
1219
1220 // Set bounding envelope (benv) and calculate extent
1221 //
1222 // To build the bounding envelope with plane faces each side face of
1223 // the trapezoid is subdivided in triangles. Subdivision is done by
1224 // duplication of vertices in the bases in a way that the envelope be
1225 // a convex polyhedron (some faces of the envelope can be degenerate)
1226 //
1227 G4double dz = GetZHalfLength();
1228 G4ThreeVectorList baseA(8), baseB(8);
1229 for (G4int i=0; i<4; ++i)
1230 {
1231 G4TwoVector va = GetVertex(i);
1232 G4TwoVector vb = GetVertex(i+4);
1233 baseA[2*i].set(va.x(),va.y(),-dz);
1234 baseB[2*i].set(vb.x(),vb.y(), dz);
1235 }
1236 for (G4int i=0; i<4; ++i)
1237 {
1238 G4int k1=2*i, k2=(2*i+2)%8;
1239 G4double ax = (baseA[k2].x()-baseA[k1].x());
1240 G4double ay = (baseA[k2].y()-baseA[k1].y());
1241 G4double bx = (baseB[k2].x()-baseB[k1].x());
1242 G4double by = (baseB[k2].y()-baseB[k1].y());
1243 G4double znorm = ax*by - ay*bx;
1244 baseA[k1+1] = (znorm < 0.0) ? baseA[k2] : baseA[k1];
1245 baseB[k1+1] = (znorm < 0.0) ? baseB[k1] : baseB[k2];
1246 }
1247
1248 std::vector<const G4ThreeVectorList *> polygons(2);
1249 polygons[0] = &baseA;
1250 polygons[1] = &baseB;
1251
1252 G4BoundingEnvelope benv(bmin,bmax,polygons);
1253 exist = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
1254 return exist;
1255}
std::vector< G4ThreeVector > G4ThreeVectorList
bool G4bool
Definition: G4Types.hh:86
double x() const
double y() const
G4double GetZHalfLength() const
G4TwoVector GetVertex(G4int index) const
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const

◆ Clone()

G4VSolid * G4GenericTrap::Clone ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 1266 of file G4GenericTrap.cc.

1267{
1268 return new G4GenericTrap(*this);
1269}

◆ CreatePolyhedron()

G4Polyhedron * G4GenericTrap::CreatePolyhedron ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 2041 of file G4GenericTrap.cc.

2042{
2043
2044#ifdef G4TESS_TEST
2045 if ( fTessellatedSolid != nullptr )
2046 {
2047 return fTessellatedSolid->CreatePolyhedron();
2048 }
2049#endif
2050
2051 // Approximation of Twisted Side
2052 // Construct extra Points, if Twisted Side
2053 //
2054 G4PolyhedronArbitrary* polyhedron;
2055 size_t nVertices, nFacets;
2056
2057 G4int subdivisions=0;
2058 G4int i;
2059 if(fIsTwisted)
2060 {
2061 if ( GetVisSubdivisions()!= 0 )
2062 {
2063 subdivisions=GetVisSubdivisions();
2064 }
2065 else
2066 {
2067 // Estimation of Number of Subdivisions for smooth visualisation
2068 //
2069 G4double maxTwist=0.;
2070 for(i=0; i<4; ++i)
2071 {
2072 if(GetTwistAngle(i)>maxTwist) { maxTwist=GetTwistAngle(i); }
2073 }
2074
2075 // Computes bounding vectors for the shape
2076 //
2077 G4double Dx,Dy;
2078 G4ThreeVector minVec = GetMinimumBBox();
2079 G4ThreeVector maxVec = GetMaximumBBox();
2080 Dx = 0.5*(maxVec.x()- minVec.y());
2081 Dy = 0.5*(maxVec.y()- minVec.y());
2082 if (Dy > Dx) { Dx=Dy; }
2083
2084 subdivisions=8*G4int(maxTwist/(Dx*Dx*Dx)*fDz);
2085 if (subdivisions<4) { subdivisions=4; }
2086 if (subdivisions>30) { subdivisions=30; }
2087 }
2088 }
2089 G4int sub4=4*subdivisions;
2090 nVertices = 8+subdivisions*4;
2091 nFacets = 6+subdivisions*4;
2092 G4double cf=1./(subdivisions+1);
2093 polyhedron = new G4PolyhedronArbitrary (nVertices, nFacets);
2094
2095 // Add Vertex
2096 //
2097 for (i=0; i<4; ++i)
2098 {
2099 polyhedron->AddVertex(G4ThreeVector(fVertices[i].x(),
2100 fVertices[i].y(),-fDz));
2101 }
2102 for( i=0; i<subdivisions; ++i)
2103 {
2104 for(G4int j=0;j<4;j++)
2105 {
2106 G4TwoVector u=fVertices[j]+cf*(i+1)*( fVertices[j+4]-fVertices[j]);
2107 polyhedron->AddVertex(G4ThreeVector(u.x(),u.y(),-fDz+cf*2*fDz*(i+1)));
2108 }
2109 }
2110 for (i=4; i<8; ++i)
2111 {
2112 polyhedron->AddVertex(G4ThreeVector(fVertices[i].x(),
2113 fVertices[i].y(),fDz));
2114 }
2115
2116 // Add Facets
2117 //
2118 polyhedron->AddFacet(1,4,3,2); //Z-plane
2119 for (i=0; i<subdivisions+1; ++i)
2120 {
2121 G4int is=i*4;
2122 polyhedron->AddFacet(5+is,8+is,4+is,1+is);
2123 polyhedron->AddFacet(8+is,7+is,3+is,4+is);
2124 polyhedron->AddFacet(7+is,6+is,2+is,3+is);
2125 polyhedron->AddFacet(6+is,5+is,1+is,2+is);
2126 }
2127 polyhedron->AddFacet(5+sub4,6+sub4,7+sub4,8+sub4); //Z-plane
2128
2129 polyhedron->SetReferences();
2130 polyhedron->InvertFacets();
2131
2132 return (G4Polyhedron*) polyhedron;
2133}
G4double GetTwistAngle(G4int index) const
G4int GetVisSubdivisions() const
void AddFacet(const G4int iv1, const G4int iv2, const G4int iv3, const G4int iv4=0)
void AddVertex(const G4ThreeVector &v)
virtual G4Polyhedron * CreatePolyhedron() const

Referenced by GetPolyhedron().

◆ DescribeYourselfTo()

void G4GenericTrap::DescribeYourselfTo ( G4VGraphicsScene scene) const
virtual

Implements G4VSolid.

Definition at line 2006 of file G4GenericTrap.cc.

2007{
2008
2009#ifdef G4TESS_TEST
2010 if ( fTessellatedSolid )
2011 {
2012 return fTessellatedSolid->DescribeYourselfTo(scene);
2013 }
2014#endif
2015
2016 scene.AddSolid(*this);
2017}
virtual void DescribeYourselfTo(G4VGraphicsScene &scene) const
virtual void AddSolid(const G4Box &)=0

◆ DistanceToIn() [1/2]

G4double G4GenericTrap::DistanceToIn ( const G4ThreeVector p) const
virtual

Implements G4VSolid.

Definition at line 800 of file G4GenericTrap.cc.

801{
802 // Computes the closest distance from given point to this shape
803
804#ifdef G4TESS_TEST
805 if ( fTessellatedSolid )
806 {
807 return fTessellatedSolid->DistanceToIn(p);
808 }
809#endif
810
811 G4double safz = std::fabs(p.z())-fDz;
812 if(safz<0) { safz=0; }
813
814 G4int iseg;
815 G4double safe = safz;
816 G4double safxy = safz;
817
818 for (iseg=0; iseg<4; ++iseg)
819 {
820 safxy = SafetyToFace(p,iseg);
821 if (safxy>safe) { safe=safxy; }
822 }
823
824 return safe;
825}
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const

◆ DistanceToIn() [2/2]

G4double G4GenericTrap::DistanceToIn ( const G4ThreeVector p,
const G4ThreeVector v 
) const
virtual

Implements G4VSolid.

Definition at line 732 of file G4GenericTrap.cc.

734{
735#ifdef G4TESS_TEST
736 if ( fTessellatedSolid )
737 {
738 return fTessellatedSolid->DistanceToIn(p, v);
739 }
740#endif
741
742 G4double dist[5];
744
745 // Check lateral faces
746 //
747 G4int i;
748 for (i=0; i<4; ++i)
749 {
750 dist[i]=DistToPlane(p, v, i);
751 }
752
753 // Check Z planes
754 //
755 dist[4]=kInfinity;
756 if (std::fabs(p.z())>fDz-halfCarTolerance)
757 {
758 if (v.z())
759 {
760 G4ThreeVector pt;
761 if (p.z()>0)
762 {
763 dist[4] = (fDz-p.z())/v.z();
764 }
765 else
766 {
767 dist[4] = (-fDz-p.z())/v.z();
768 }
769 if (dist[4]<-halfCarTolerance)
770 {
771 dist[4]=kInfinity;
772 }
773 else
774 {
775 if(dist[4]<halfCarTolerance)
776 {
777 if(p.z()>0) { n=G4ThreeVector(0,0,1); }
778 else { n=G4ThreeVector(0,0,-1); }
779 if (n.dot(v)<0) { dist[4]=0.; }
780 else { dist[4]=kInfinity; }
781 }
782 pt=p+dist[4]*v;
783 if (Inside(pt)==kOutside) { dist[4]=kInfinity; }
784 }
785 }
786 }
787 G4double distmin = dist[0];
788 for (i=1; i<5 ; ++i)
789 {
790 if (dist[i] < distmin) { distmin = dist[i]; }
791 }
792
793 if (distmin<halfCarTolerance) { distmin=0.; }
794
795 return distmin;
796}
EInside Inside(const G4ThreeVector &p) const
@ kOutside
Definition: geomdefs.hh:68

◆ DistanceToOut() [1/2]

G4double G4GenericTrap::DistanceToOut ( const G4ThreeVector p) const
virtual

Implements G4VSolid.

Definition at line 1149 of file G4GenericTrap.cc.

1150{
1151
1152#ifdef G4TESS_TEST
1153 if ( fTessellatedSolid )
1154 {
1155 return fTessellatedSolid->DistanceToOut(p);
1156 }
1157#endif
1158
1159 G4double safz = fDz-std::fabs(p.z());
1160 if (safz<0) { safz = 0; }
1161
1162 G4double safe = safz;
1163 G4double safxy = safz;
1164
1165 for (G4int iseg=0; iseg<4; ++iseg)
1166 {
1167 safxy = std::fabs(SafetyToFace(p,iseg));
1168 if (safxy < safe) { safe = safxy; }
1169 }
1170
1171 return safe;
1172}
virtual G4double DistanceToOut(const G4ThreeVector &p) const

◆ DistanceToOut() [2/2]

G4double G4GenericTrap::DistanceToOut ( const G4ThreeVector p,
const G4ThreeVector v,
const G4bool  calcNorm = false,
G4bool validNorm = nullptr,
G4ThreeVector n = nullptr 
) const
virtual

Implements G4VSolid.

Definition at line 904 of file G4GenericTrap.cc.

909{
910#ifdef G4TESS_TEST
911 if ( fTessellatedSolid )
912 {
913 return fTessellatedSolid->DistanceToOut(p, v, calcNorm, validNorm, n);
914 }
915#endif
916
917 G4double distmin;
918 G4bool lateral_cross = false;
919 ESide side = kUndef;
920
921 if (calcNorm) { *validNorm = true; } // All normals are valid
922
923 if (v.z() < 0)
924 {
925 distmin=(-fDz-p.z())/v.z();
926 if (calcNorm) { side=kMZ; *n=G4ThreeVector(0,0,-1); }
927 }
928 else
929 {
930 if (v.z() > 0)
931 {
932 distmin = (fDz-p.z())/v.z();
933 if (calcNorm) { side=kPZ; *n=G4ThreeVector(0,0,1); }
934 }
935 else { distmin = kInfinity; }
936 }
937
938 G4double dz2 =0.5/fDz;
939 G4double xa,xb,xc,xd;
940 G4double ya,yb,yc,yd;
941
942 for (G4int ipl=0; ipl<4; ++ipl)
943 {
944 G4int j = (ipl+1)%4;
945 xa=fVertices[ipl].x();
946 ya=fVertices[ipl].y();
947 xb=fVertices[ipl+4].x();
948 yb=fVertices[ipl+4].y();
949 xc=fVertices[j].x();
950 yc=fVertices[j].y();
951 xd=fVertices[4+j].x();
952 yd=fVertices[4+j].y();
953
954 if ( ((std::fabs(xb-xd)+std::fabs(yb-yd))<halfCarTolerance)
955 || ((std::fabs(xa-xc)+std::fabs(ya-yc))<halfCarTolerance) )
956 {
957 G4double q=DistToTriangle(p,v,ipl) ;
958 if ( (q>=0) && (q<distmin) )
959 {
960 distmin=q;
961 lateral_cross=true;
962 side=ESide(ipl+1);
963 }
964 continue;
965 }
966 G4double tx1 =dz2*(xb-xa);
967 G4double ty1 =dz2*(yb-ya);
968 G4double tx2 =dz2*(xd-xc);
969 G4double ty2 =dz2*(yd-yc);
970 G4double dzp =fDz+p.z();
971 G4double xs1 =xa+tx1*dzp;
972 G4double ys1 =ya+ty1*dzp;
973 G4double xs2 =xc+tx2*dzp;
974 G4double ys2 =yc+ty2*dzp;
975 G4double dxs =xs2-xs1;
976 G4double dys =ys2-ys1;
977 G4double dtx =tx2-tx1;
978 G4double dty =ty2-ty1;
979 G4double a = (dtx*v.y()-dty*v.x()+(tx1*ty2-tx2*ty1)*v.z())*v.z();
980 G4double b = dxs*v.y()-dys*v.x()+(dtx*p.y()-dty*p.x()+ty2*xs1-ty1*xs2
981 + tx1*ys2-tx2*ys1)*v.z();
982 G4double c=dxs*p.y()-dys*p.x()+xs1*ys2-xs2*ys1;
983 G4double q=kInfinity;
984
985 if (std::fabs(a) < kCarTolerance)
986 {
987 if (std::fabs(b) < kCarTolerance) { continue; }
988 q=-c/b;
989
990 // Check for Point on the Surface
991 //
992 if ((q > -halfCarTolerance) && (q < distmin))
993 {
994 if (q < halfCarTolerance)
995 {
996 if (NormalToPlane(p,ipl).dot(v)<0.) { continue; }
997 }
998 distmin =q;
999 lateral_cross=true;
1000 side=ESide(ipl+1);
1001 }
1002 continue;
1003 }
1004 G4double d=b*b-4*a*c;
1005 if (d >= 0.)
1006 {
1007 if (a > 0) { q=0.5*(-b-std::sqrt(d))/a; }
1008 else { q=0.5*(-b+std::sqrt(d))/a; }
1009
1010 // Check for Point on the Surface
1011 //
1012 if (q > -halfCarTolerance )
1013 {
1014 if (q < distmin)
1015 {
1016 if(q < halfCarTolerance)
1017 {
1018 if (NormalToPlane(p,ipl).dot(v)<0.) // Check second root
1019 {
1020 if (a > 0) { q=0.5*(-b+std::sqrt(d))/a; }
1021 else { q=0.5*(-b-std::sqrt(d))/a; }
1022 if (( q > halfCarTolerance) && (q < distmin))
1023 {
1024 distmin=q;
1025 lateral_cross = true;
1026 side=ESide(ipl+1);
1027 }
1028 continue;
1029 }
1030 }
1031 distmin = q;
1032 lateral_cross = true;
1033 side=ESide(ipl+1);
1034 }
1035 }
1036 else
1037 {
1038 if (a > 0) { q=0.5*(-b+std::sqrt(d))/a; }
1039 else { q=0.5*(-b-std::sqrt(d))/a; }
1040
1041 // Check for Point on the Surface
1042 //
1043 if ((q > -halfCarTolerance) && (q < distmin))
1044 {
1045 if (q < halfCarTolerance)
1046 {
1047 if (NormalToPlane(p,ipl).dot(v)<0.) // Check second root
1048 {
1049 if (a > 0) { q=0.5*(-b-std::sqrt(d))/a; }
1050 else { q=0.5*(-b+std::sqrt(d))/a; }
1051 if ( ( q > halfCarTolerance) && (q < distmin) )
1052 {
1053 distmin=q;
1054 lateral_cross = true;
1055 side=ESide(ipl+1);
1056 }
1057 continue;
1058 }
1059 }
1060 distmin =q;
1061 lateral_cross = true;
1062 side=ESide(ipl+1);
1063 }
1064 }
1065 }
1066 }
1067 if (!lateral_cross) // Make sure that track crosses the top or bottom
1068 {
1069 if (distmin >= kInfinity) { distmin=kCarTolerance; }
1070 G4ThreeVector pt=p+distmin*v;
1071
1072 // Check if propagated point is in the polygon
1073 //
1074 G4int i=0;
1075 if (v.z()>0.) { i=4; }
1076 std::vector<G4TwoVector> xy;
1077 for ( G4int j=0; j<4; j++) { xy.push_back(fVertices[i+j]); }
1078
1079 // Check Inside
1080 //
1081 if (InsidePolygone(pt,xy)==kOutside)
1082 {
1083 if(calcNorm)
1084 {
1085 if (v.z()>0) {side= kPZ; *n = G4ThreeVector(0,0,1);}
1086 else { side=kMZ; *n = G4ThreeVector(0,0,-1);}
1087 }
1088 return 0.;
1089 }
1090 else
1091 {
1092 if(v.z()>0) {side=kPZ;}
1093 else {side=kMZ;}
1094 }
1095 }
1096
1097 if (calcNorm)
1098 {
1099 G4ThreeVector pt=p+v*distmin;
1100 switch (side)
1101 {
1102 case kXY0:
1103 *n=NormalToPlane(pt,0);
1104 break;
1105 case kXY1:
1106 *n=NormalToPlane(pt,1);
1107 break;
1108 case kXY2:
1109 *n=NormalToPlane(pt,2);
1110 break;
1111 case kXY3:
1112 *n=NormalToPlane(pt,3);
1113 break;
1114 case kPZ:
1115 *n=G4ThreeVector(0,0,1);
1116 break;
1117 case kMZ:
1118 *n=G4ThreeVector(0,0,-1);
1119 break;
1120 default:
1121 DumpInfo();
1122 std::ostringstream message;
1123 G4int oldprc = message.precision(16);
1124 message << "Undefined side for valid surface normal to solid." << G4endl
1125 << "Position:" << G4endl
1126 << " p.x() = " << p.x()/mm << " mm" << G4endl
1127 << " p.y() = " << p.y()/mm << " mm" << G4endl
1128 << " p.z() = " << p.z()/mm << " mm" << G4endl
1129 << "Direction:" << G4endl
1130 << " v.x() = " << v.x() << G4endl
1131 << " v.y() = " << v.y() << G4endl
1132 << " v.z() = " << v.z() << G4endl
1133 << "Proposed distance :" << G4endl
1134 << " distmin = " << distmin/mm << " mm";
1135 message.precision(oldprc);
1136 G4Exception("G4GenericTrap::DistanceToOut(p,v,..)",
1137 "GeomSolids1002", JustWarning, message);
1138 break;
1139 }
1140 }
1141
1142 if (distmin<halfCarTolerance) { distmin=0.; }
1143
1144 return distmin;
1145}
ESide
Definition: G4Cons.cc:61
double dot(const Hep3Vector &) const

◆ GetCubicVolume()

G4double G4GenericTrap::GetCubicVolume ( )
virtual

Reimplemented from G4VSolid.

Definition at line 1423 of file G4GenericTrap.cc.

1424{
1425 if (fCubicVolume == 0.0)
1426 {
1427 if(fIsTwisted)
1428 {
1429 fCubicVolume = G4VSolid::GetCubicVolume();
1430 }
1431 else
1432 {
1433 // Set vertices
1434 G4ThreeVector v0(fVertices[0].x(),fVertices[0].y(),-fDz);
1435 G4ThreeVector v1(fVertices[1].x(),fVertices[1].y(),-fDz);
1436 G4ThreeVector v2(fVertices[2].x(),fVertices[2].y(),-fDz);
1437 G4ThreeVector v3(fVertices[3].x(),fVertices[3].y(),-fDz);
1438 G4ThreeVector v4(fVertices[4].x(),fVertices[4].y(), fDz);
1439 G4ThreeVector v5(fVertices[5].x(),fVertices[5].y(), fDz);
1440 G4ThreeVector v6(fVertices[6].x(),fVertices[6].y(), fDz);
1441 G4ThreeVector v7(fVertices[7].x(),fVertices[7].y(), fDz);
1442
1443 // Find Cubic Volume
1444 fCubicVolume = GetFaceCubicVolume(v0,v1,v2,v3) // -fDz plane
1445 + GetFaceCubicVolume(v1,v0,v4,v5) // Lat plane
1446 + GetFaceCubicVolume(v2,v1,v5,v6) // Lat plane
1447 + GetFaceCubicVolume(v3,v2,v6,v7) // Lat plane
1448 + GetFaceCubicVolume(v0,v3,v7,v4) // Lat plane
1449 + GetFaceCubicVolume(v7,v6,v5,v4); // +fDz plane
1450 }
1451 }
1452 return fCubicVolume;
1453}
virtual G4double GetCubicVolume()
Definition: G4VSolid.cc:176

◆ GetEntityType()

G4GeometryType G4GenericTrap::GetEntityType ( ) const
virtual

Implements G4VSolid.

Definition at line 1259 of file G4GenericTrap.cc.

1260{
1261 return G4String("G4GenericTrap");
1262}

Referenced by StreamInfo().

◆ GetExtent()

G4VisExtent G4GenericTrap::GetExtent ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 2021 of file G4GenericTrap.cc.

2022{
2023 // Computes bounding vectors for the shape
2024
2025#ifdef G4TESS_TEST
2026 if ( fTessellatedSolid != nullptr )
2027 {
2028 return fTessellatedSolid->GetExtent();
2029 }
2030#endif
2031
2032 G4ThreeVector minVec = GetMinimumBBox();
2033 G4ThreeVector maxVec = GetMaximumBBox();
2034 return G4VisExtent (minVec.x(), maxVec.x(),
2035 minVec.y(), maxVec.y(),
2036 minVec.z(), maxVec.z());
2037}
virtual G4VisExtent GetExtent() const

◆ GetNofVertices()

G4int G4GenericTrap::GetNofVertices ( ) const
inline

◆ GetPointOnSurface()

G4ThreeVector G4GenericTrap::GetPointOnSurface ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 1296 of file G4GenericTrap.cc.

1297{
1298
1299#ifdef G4TESS_TEST
1300 if ( fTessellatedSolid )
1301 {
1302 return fTessellatedSolid->GetPointOnSurface();
1303 }
1304#endif
1305
1306 G4ThreeVector point;
1307 G4TwoVector u,v,w;
1308 G4double rand,area,chose,cf,lambda0,lambda1,alfa,beta,zp;
1309 G4int ipl,j;
1310
1311 std::vector<G4ThreeVector> vertices;
1312 for (auto i=0; i<4; ++i)
1313 {
1314 vertices.push_back(G4ThreeVector(fVertices[i].x(),fVertices[i].y(),-fDz));
1315 }
1316 for (auto i=4; i<8; ++i)
1317 {
1318 vertices.push_back(G4ThreeVector(fVertices[i].x(),fVertices[i].y(),fDz));
1319 }
1320
1321 // Surface Area of Planes(only estimation for twisted)
1322 //
1323 G4double Surface0=GetFaceSurfaceArea(vertices[0],vertices[1],
1324 vertices[2],vertices[3]);//-fDz plane
1325 G4double Surface1=GetFaceSurfaceArea(vertices[0],vertices[1],
1326 vertices[5],vertices[4]);// Lat plane
1327 G4double Surface2=GetFaceSurfaceArea(vertices[3],vertices[0],
1328 vertices[4],vertices[7]);// Lat plane
1329 G4double Surface3=GetFaceSurfaceArea(vertices[2],vertices[3],
1330 vertices[7],vertices[6]);// Lat plane
1331 G4double Surface4=GetFaceSurfaceArea(vertices[2],vertices[1],
1332 vertices[5],vertices[6]);// Lat plane
1333 G4double Surface5=GetFaceSurfaceArea(vertices[4],vertices[5],
1334 vertices[6],vertices[7]);// fDz plane
1335 rand = G4UniformRand();
1336 area = Surface0+Surface1+Surface2+Surface3+Surface4+Surface5;
1337 chose = rand*area;
1338
1339 if ( ( chose < Surface0)
1340 || ( chose > (Surface0+Surface1+Surface2+Surface3+Surface4)) )
1341 { // fDz or -fDz Plane
1342 ipl = G4int(G4UniformRand()*4);
1343 j = (ipl+1)%4;
1344 if(chose < Surface0)
1345 {
1346 zp = -fDz;
1347 u = fVertices[ipl]; v = fVertices[j];
1348 w = fVertices[(ipl+3)%4];
1349 }
1350 else
1351 {
1352 zp = fDz;
1353 u = fVertices[ipl+4]; v = fVertices[j+4];
1354 w = fVertices[(ipl+3)%4+4];
1355 }
1356 alfa = G4UniformRand();
1357 beta = G4UniformRand();
1358 lambda1=alfa*beta;
1359 lambda0=alfa-lambda1;
1360 v = v-u;
1361 w = w-u;
1362 v = u+lambda0*v+lambda1*w;
1363 }
1364 else // Lateral Plane Twisted or Not
1365 {
1366 if (chose < Surface0+Surface1) { ipl=0; }
1367 else if (chose < Surface0+Surface1+Surface2) { ipl=1; }
1368 else if (chose < Surface0+Surface1+Surface2+Surface3) { ipl=2; }
1369 else { ipl=3; }
1370 j = (ipl+1)%4;
1371 zp = -fDz+G4UniformRand()*2*fDz;
1372 cf = 0.5*(fDz-zp)/fDz;
1373 u = fVertices[ipl+4]+cf*( fVertices[ipl]-fVertices[ipl+4]);
1374 v = fVertices[j+4]+cf*(fVertices[j]-fVertices[j+4]);
1375 v = u+(v-u)*G4UniformRand();
1376 }
1377 point=G4ThreeVector(v.x(),v.y(),zp);
1378
1379 return point;
1380}
#define G4UniformRand()
Definition: Randomize.hh:52
virtual G4ThreeVector GetPointOnSurface() const

◆ GetPolyhedron()

G4Polyhedron * G4GenericTrap::GetPolyhedron ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 1980 of file G4GenericTrap.cc.

1981{
1982
1983#ifdef G4TESS_TEST
1984 if ( fTessellatedSolid )
1985 {
1986 return fTessellatedSolid->GetPolyhedron();
1987 }
1988#endif
1989
1990 if ( (fpPolyhedron == nullptr)
1994 {
1995 G4AutoLock l(&polyhedronMutex);
1996 delete fpPolyhedron;
1998 fRebuildPolyhedron = false;
1999 l.unlock();
2000 }
2001 return fpPolyhedron;
2002}
G4Polyhedron * CreatePolyhedron() const
G4bool fRebuildPolyhedron
G4Polyhedron * fpPolyhedron
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
virtual G4Polyhedron * GetPolyhedron() const
static G4int GetNumberOfRotationSteps()

◆ GetSurfaceArea()

G4double G4GenericTrap::GetSurfaceArea ( )
virtual

Reimplemented from G4VSolid.

Definition at line 1384 of file G4GenericTrap.cc.

1385{
1386 // Set vertices
1387 G4ThreeVector v0(fVertices[0].x(),fVertices[0].y(),-fDz);
1388 G4ThreeVector v1(fVertices[1].x(),fVertices[1].y(),-fDz);
1389 G4ThreeVector v2(fVertices[2].x(),fVertices[2].y(),-fDz);
1390 G4ThreeVector v3(fVertices[3].x(),fVertices[3].y(),-fDz);
1391 G4ThreeVector v4(fVertices[4].x(),fVertices[4].y(), fDz);
1392 G4ThreeVector v5(fVertices[5].x(),fVertices[5].y(), fDz);
1393 G4ThreeVector v6(fVertices[6].x(),fVertices[6].y(), fDz);
1394 G4ThreeVector v7(fVertices[7].x(),fVertices[7].y(), fDz);
1395
1396 // Find Surface Area
1397 if (fSurfaceArea == 0.0)
1398 {
1399 if(fIsTwisted)
1400 {
1401 fSurfaceArea = GetFaceSurfaceArea(v0,v1,v2,v3) // -fDz plane
1402 + GetTwistedFaceSurfaceArea(v1,v0,v4,v5) // Lat plane
1403 + GetTwistedFaceSurfaceArea(v2,v1,v5,v6) // Lat plane
1404 + GetTwistedFaceSurfaceArea(v3,v2,v6,v7) // Lat plane
1405 + GetTwistedFaceSurfaceArea(v0,v3,v7,v4) // Lat plane
1406 + GetFaceSurfaceArea(v7,v6,v5,v4); // +fDz plane
1407 }
1408 else
1409 {
1410 fSurfaceArea = GetFaceSurfaceArea(v0,v1,v2,v3) // -fDz plane
1411 + GetFaceSurfaceArea(v1,v0,v4,v5) // Lat plane
1412 + GetFaceSurfaceArea(v2,v1,v5,v6) // Lat plane
1413 + GetFaceSurfaceArea(v3,v2,v6,v7) // Lat plane
1414 + GetFaceSurfaceArea(v0,v3,v7,v4) // Lat plane
1415 + GetFaceSurfaceArea(v7,v6,v5,v4); // +fDz plane
1416 }
1417 }
1418 return fSurfaceArea;
1419}

◆ GetTwistAngle()

G4double G4GenericTrap::GetTwistAngle ( G4int  index) const
inline

Referenced by CreatePolyhedron(), and SurfaceNormal().

◆ GetVertex()

G4TwoVector G4GenericTrap::GetVertex ( G4int  index) const
inline

Referenced by CalculateExtent().

◆ GetVertices()

const std::vector< G4TwoVector > & G4GenericTrap::GetVertices ( ) const
inline

◆ GetVisSubdivisions()

G4int G4GenericTrap::GetVisSubdivisions ( ) const
inline

Referenced by CreatePolyhedron().

◆ GetZHalfLength()

G4double G4GenericTrap::GetZHalfLength ( ) const
inline

◆ Inside()

EInside G4GenericTrap::Inside ( const G4ThreeVector p) const
virtual

Implements G4VSolid.

Definition at line 318 of file G4GenericTrap.cc.

319{
320 // Test if point is inside this shape
321
322#ifdef G4TESS_TEST
323 if ( fTessellatedSolid )
324 {
325 return fTessellatedSolid->Inside(p);
326 }
327#endif
328
329 EInside innew=kOutside;
330 std::vector<G4TwoVector> xy;
331
332 if (std::fabs(p.z()) <= fDz+halfCarTolerance) // First check Z range
333 {
334 // Compute intersection between Z plane containing point and the shape
335 //
336 G4double cf = 0.5*(fDz-p.z())/fDz;
337 for (auto i=0; i<4; ++i)
338 {
339 xy.push_back(fVertices[i+4]+cf*( fVertices[i]-fVertices[i+4]));
340 }
341
342 innew=InsidePolygone(p,xy);
343
344 if( (innew==kInside) || (innew==kSurface) )
345 {
346 if(std::fabs(p.z()) > fDz-halfCarTolerance) { innew=kSurface; }
347 }
348 }
349 return innew;
350}
virtual EInside Inside(const G4ThreeVector &p) const
EInside
Definition: geomdefs.hh:67
@ kInside
Definition: geomdefs.hh:70
@ kSurface
Definition: geomdefs.hh:69

Referenced by DistanceToIn().

◆ IsTwisted()

G4bool G4GenericTrap::IsTwisted ( ) const
inline

◆ operator=()

G4GenericTrap & G4GenericTrap::operator= ( const G4GenericTrap rhs)

Definition at line 183 of file G4GenericTrap.cc.

184{
185 // Check assignment to self
186 //
187 if (this == &rhs) { return *this; }
188
189 // Copy base class data
190 //
192
193 // Copy data
194 //
195 halfCarTolerance = rhs.halfCarTolerance;
196 fDz = rhs.fDz; fVertices = rhs.fVertices;
197 fIsTwisted = rhs.fIsTwisted; fTessellatedSolid = nullptr;
198 fMinBBoxVector = rhs.fMinBBoxVector; fMaxBBoxVector = rhs.fMaxBBoxVector;
199 fVisSubdivisions = rhs.fVisSubdivisions;
200 fSurfaceArea = rhs.fSurfaceArea; fCubicVolume = rhs.fCubicVolume;
201
202 for (auto i=0; i<4; ++i) { fTwist[i] = rhs.fTwist[i]; }
203#ifdef G4TESS_TEST
204 if (rhs.fTessellatedSolid && !fIsTwisted )
205 { delete fTessellatedSolid; fTessellatedSolid = CreateTessellatedSolid(); }
206#endif
207 fRebuildPolyhedron = false;
208 delete fpPolyhedron; fpPolyhedron = nullptr;
209
210 return *this;
211}
G4VSolid & operator=(const G4VSolid &rhs)
Definition: G4VSolid.cc:98

◆ SetVisSubdivisions()

void G4GenericTrap::SetVisSubdivisions ( G4int  subdiv)
inline

◆ StreamInfo()

std::ostream & G4GenericTrap::StreamInfo ( std::ostream &  os) const
virtual

Implements G4VSolid.

Definition at line 1273 of file G4GenericTrap.cc.

1274{
1275 G4int oldprc = os.precision(16);
1276 os << "-----------------------------------------------------------\n"
1277 << " *** Dump for solid - " << GetName() << " *** \n"
1278 << " =================================================== \n"
1279 << " Solid geometry type: " << GetEntityType() << G4endl
1280 << " half length Z: " << fDz/mm << " mm \n"
1281 << " list of vertices:\n";
1282
1283 for ( G4int i=0; i<fgkNofVertices; ++i )
1284 {
1285 os << std::setw(5) << "#" << i
1286 << " vx = " << fVertices[i].x()/mm << " mm"
1287 << " vy = " << fVertices[i].y()/mm << " mm" << G4endl;
1288 }
1289 os.precision(oldprc);
1290
1291 return os;
1292}
G4GeometryType GetEntityType() const

◆ SurfaceNormal()

G4ThreeVector G4GenericTrap::SurfaceNormal ( const G4ThreeVector p) const
virtual

Implements G4VSolid.

Definition at line 354 of file G4GenericTrap.cc.

355{
356 // Calculate side nearest to p, and return normal
357 // If two sides are equidistant, sum of the Normal is returned
358
359#ifdef G4TESS_TEST
360 if ( fTessellatedSolid )
361 {
362 return fTessellatedSolid->SurfaceNormal(p);
363 }
364#endif
365
366 G4ThreeVector lnorm, sumnorm(0.,0.,0.), apprnorm(0.,0.,1.),
367 p0, p1, p2, r1, r2, r3, r4;
368 G4int noSurfaces = 0;
369 G4double distxy,distz;
370 G4bool zPlusSide=false;
371
372 distz = fDz-std::fabs(p.z());
373 if (distz < halfCarTolerance)
374 {
375 if(p.z()>0)
376 {
377 zPlusSide=true;
378 sumnorm=G4ThreeVector(0,0,1);
379 }
380 else
381 {
382 sumnorm=G4ThreeVector(0,0,-1);
383 }
384 ++noSurfaces;
385 }
386
387 // Check lateral planes
388 //
389 std:: vector<G4TwoVector> vertices;
390 G4double cf = 0.5*(fDz-p.z())/fDz;
391 for (auto i=0; i<4; ++i)
392 {
393 vertices.push_back(fVertices[i+4]+cf*(fVertices[i]-fVertices[i+4]));
394 }
395
396 // Compute distance for lateral planes
397 //
398 for (G4int q=0; q<4; ++q)
399 {
400 p0=G4ThreeVector(vertices[q].x(),vertices[q].y(),p.z());
401 if(zPlusSide)
402 {
403 p1=G4ThreeVector(fVertices[q].x(),fVertices[q].y(),-fDz);
404 }
405 else
406 {
407 p1=G4ThreeVector(fVertices[q+4].x(),fVertices[q+4].y(),fDz);
408 }
409 p2=G4ThreeVector(vertices[(q+1)%4].x(),vertices[(q+1)%4].y(),p.z());
410
411 // Collapsed vertices
412 //
413 if ( (p2-p0).mag2() < kCarTolerance )
414 {
415 if ( std::fabs(p.z()+fDz) > kCarTolerance )
416 {
417 p2=G4ThreeVector(fVertices[(q+1)%4].x(),fVertices[(q+1)%4].y(),-fDz);
418 }
419 else
420 {
421 p2=G4ThreeVector(fVertices[(q+1)%4+4].x(),fVertices[(q+1)%4+4].y(),fDz);
422 }
423 }
424 lnorm = (p1-p0).cross(p2-p0);
425 lnorm = lnorm.unit();
426 if(zPlusSide) { lnorm=-lnorm; }
427
428 // Adjust Normal for Twisted Surface
429 //
430 if ( (fIsTwisted) && (GetTwistAngle(q)!=0) )
431 {
432 G4double normP=(p2-p0).mag();
433 if(normP)
434 {
435 G4double proj=(p-p0).dot(p2-p0)/normP;
436 if(proj<0) { proj=0; }
437 if(proj>normP) { proj=normP; }
438 G4int j=(q+1)%4;
439 r1=G4ThreeVector(fVertices[q+4].x(),fVertices[q+4].y(),fDz);
440 r2=G4ThreeVector(fVertices[j+4].x(),fVertices[j+4].y(),fDz);
441 r3=G4ThreeVector(fVertices[q].x(),fVertices[q].y(),-fDz);
442 r4=G4ThreeVector(fVertices[j].x(),fVertices[j].y(),-fDz);
443 r1=r1+proj*(r2-r1)/normP;
444 r3=r3+proj*(r4-r3)/normP;
445 r2=r1-r3;
446 r4=r2.cross(p2-p0); r4=r4.unit();
447 lnorm=r4;
448 }
449 } // End if fIsTwisted
450
451 distxy=std::fabs((p0-p).dot(lnorm));
452 if ( distxy<halfCarTolerance )
453 {
454 ++noSurfaces;
455
456 // Negative sign for Normal is taken for Outside Normal
457 //
458 sumnorm=sumnorm+lnorm;
459 }
460
461 // For ApproxSurfaceNormal
462 //
463 if (distxy<distz)
464 {
465 distz=distxy;
466 apprnorm=lnorm;
467 }
468 } // End for loop
469
470 // Calculate final Normal, add Normal in the Corners and Touching Sides
471 //
472 if ( noSurfaces == 0 )
473 {
474#ifdef G4SPECSDEBUG
475 G4Exception("G4GenericTrap::SurfaceNormal(p)", "GeomSolids1002",
476 JustWarning, "Point p is not on surface !?" );
477#endif
478 sumnorm=apprnorm;
479 // Add Approximative Surface Normal Calculation?
480 }
481 else if ( noSurfaces == 1 ) { ; }
482 else { sumnorm = sumnorm.unit(); }
483
484 return sumnorm ;
485}
Hep3Vector unit() const
Hep3Vector cross(const Hep3Vector &) const
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const

Member Data Documentation

◆ fpPolyhedron

G4Polyhedron* G4GenericTrap::fpPolyhedron = nullptr
mutableprotected

Definition at line 199 of file G4GenericTrap.hh.

Referenced by GetPolyhedron(), and operator=().

◆ fRebuildPolyhedron

G4bool G4GenericTrap::fRebuildPolyhedron = false
mutableprotected

Definition at line 198 of file G4GenericTrap.hh.

Referenced by GetPolyhedron(), and operator=().


The documentation for this class was generated from the following files: