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

#include <G4ExtrudedSolid.hh>

+ Inheritance diagram for G4ExtrudedSolid:

Classes

struct  ZSection
 

Public Member Functions

 G4ExtrudedSolid (const G4String &pName, const std::vector< G4TwoVector > &polygon, const std::vector< ZSection > &zsections)
 
 G4ExtrudedSolid (const G4String &pName, const std::vector< G4TwoVector > &polygon, G4double halfZ, const G4TwoVector &off1=G4TwoVector(0., 0.), G4double scale1=1., const G4TwoVector &off2=G4TwoVector(0., 0.), G4double scale2=1.)
 
 ~G4ExtrudedSolid () override
 
G4int GetNofVertices () const
 
G4TwoVector GetVertex (G4int index) const
 
std::vector< G4TwoVectorGetPolygon () const
 
G4int GetNofZSections () const
 
ZSection GetZSection (G4int index) const
 
std::vector< ZSectionGetZSections () const
 
EInside Inside (const G4ThreeVector &p) const override
 
G4ThreeVector SurfaceNormal (const G4ThreeVector &p) const override
 
G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const override
 
G4double DistanceToIn (const G4ThreeVector &p) const override
 
G4double DistanceToOut (const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const override
 
G4double DistanceToOut (const G4ThreeVector &p) const override
 
void BoundingLimits (G4ThreeVector &pMin, G4ThreeVector &pMax) const override
 
G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const override
 
G4GeometryType GetEntityType () const override
 
G4VSolidClone () const override
 
std::ostream & StreamInfo (std::ostream &os) const override
 
 G4ExtrudedSolid (__void__ &)
 
 G4ExtrudedSolid (const G4ExtrudedSolid &rhs)
 
G4ExtrudedSolidoperator= (const G4ExtrudedSolid &rhs)
 
- Public Member Functions inherited from G4TessellatedSolid
 G4TessellatedSolid ()
 
 ~G4TessellatedSolid () override
 
 G4TessellatedSolid (const G4String &name)
 
 G4TessellatedSolid (__void__ &)
 
 G4TessellatedSolid (const G4TessellatedSolid &ts)
 
G4TessellatedSolidoperator= (const G4TessellatedSolid &right)
 
G4TessellatedSolidoperator+= (const G4TessellatedSolid &right)
 
G4bool AddFacet (G4VFacet *aFacet)
 
G4VFacetGetFacet (G4int i) const
 
G4int GetNumberOfFacets () const
 
G4int GetFacetIndex (const G4ThreeVector &p) const
 
EInside Inside (const G4ThreeVector &p) const override
 
G4ThreeVector SurfaceNormal (const G4ThreeVector &p) const override
 
G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const override
 
G4double DistanceToIn (const G4ThreeVector &p) const override
 
G4double DistanceToOut (const G4ThreeVector &p) const override
 
G4double DistanceToOut (const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm, G4bool *validNorm, G4ThreeVector *norm) const override
 
virtual G4bool Normal (const G4ThreeVector &p, G4ThreeVector &n) const
 
virtual G4double SafetyFromOutside (const G4ThreeVector &p, G4bool aAccurate=false) const
 
virtual G4double SafetyFromInside (const G4ThreeVector &p, G4bool aAccurate=false) const
 
G4GeometryType GetEntityType () const override
 
std::ostream & StreamInfo (std::ostream &os) const override
 
G4VSolidClone () const override
 
G4ThreeVector GetPointOnSurface () const override
 
G4double GetSurfaceArea () override
 
G4double GetCubicVolume () override
 
void SetSolidClosed (const G4bool t)
 
G4bool GetSolidClosed () const
 
G4int CheckStructure () const
 
void SetMaxVoxels (G4int max)
 
G4VoxelizerGetVoxels ()
 
G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const override
 
void BoundingLimits (G4ThreeVector &pMin, G4ThreeVector &pMax) const override
 
G4double GetMinXExtent () const
 
G4double GetMaxXExtent () const
 
G4double GetMinYExtent () const
 
G4double GetMaxYExtent () const
 
G4double GetMinZExtent () const
 
G4double GetMaxZExtent () const
 
G4PolyhedronCreatePolyhedron () const override
 
G4PolyhedronGetPolyhedron () const override
 
void DescribeYourselfTo (G4VGraphicsScene &scene) const override
 
G4VisExtent GetExtent () const override
 
G4int AllocatedMemoryWithoutVoxels ()
 
G4int AllocatedMemory ()
 
void DisplayAllocatedMemory ()
 
- 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 ComputeDimensions (G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
 
void DumpInfo () 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
 

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
 
- Protected Attributes inherited from G4TessellatedSolid
G4double kCarToleranceHalf
 
- Protected Attributes inherited from G4VSolid
G4double kCarTolerance
 

Detailed Description

Definition at line 71 of file G4ExtrudedSolid.hh.

Constructor & Destructor Documentation

◆ G4ExtrudedSolid() [1/4]

G4ExtrudedSolid::G4ExtrudedSolid ( const G4String & pName,
const std::vector< G4TwoVector > & polygon,
const std::vector< ZSection > & zsections )

Definition at line 66 of file G4ExtrudedSolid.cc.

69 : G4TessellatedSolid(pName),
70 fNv(polygon.size()),
71 fNz(zsections.size()),
72 fIsConvex(false),
73 fGeometryType("G4ExtrudedSolid"),
74 fSolidType(0)
75{
76 // General constructor
77
78 // First check input parameters
79
80 if (fNv < 3)
81 {
82 std::ostringstream message;
83 message << "Number of vertices in polygon < 3 - " << pName;
84 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
85 FatalErrorInArgument, message);
86 }
87
88 if (fNz < 2)
89 {
90 std::ostringstream message;
91 message << "Number of z-sides < 2 - " << pName;
92 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
93 FatalErrorInArgument, message);
94 }
95
96 for ( std::size_t i=0; i<fNz-1; ++i )
97 {
98 if ( zsections[i].fZ > zsections[i+1].fZ )
99 {
100 std::ostringstream message;
101 message << "Z-sections have to be ordered by z value (z0 < z1 < z2...) - "
102 << pName;
103 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
104 FatalErrorInArgument, message);
105 }
106 if ( std::fabs( zsections[i+1].fZ - zsections[i].fZ ) < kCarToleranceHalf )
107 {
108 std::ostringstream message;
109 message << "Z-sections with the same z position are not supported - "
110 << pName;
111 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0001",
112 FatalException, message);
113 }
114 }
115
116 // Copy polygon
117 //
118 fPolygon = polygon;
119
120 // Remove collinear and coincident vertices, if any
121 //
122 std::vector<G4int> removedVertices;
123 G4GeomTools::RemoveRedundantVertices(fPolygon,removedVertices,
124 2*kCarTolerance);
125 if (!removedVertices.empty())
126 {
127 std::size_t nremoved = removedVertices.size();
128 std::ostringstream message;
129 message << "The following "<< nremoved
130 << " vertices have been removed from polygon in " << pName
131 << "\nas collinear or coincident with other vertices: "
132 << removedVertices[0];
133 for (std::size_t i=1; i<nremoved; ++i) message << ", " << removedVertices[i];
134 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids1001",
135 JustWarning, message);
136 }
137
138 fNv = fPolygon.size();
139 if (fNv < 3)
140 {
141 std::ostringstream message;
142 message << "Number of vertices in polygon after removal < 3 - " << pName;
143 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
144 FatalErrorInArgument, message);
145 }
146
147 // Check if polygon vertices are defined clockwise
148 // (the area is positive if polygon vertices are defined anti-clockwise)
149 //
150 if (G4GeomTools::PolygonArea(fPolygon) > 0.)
151 {
152 // Polygon vertices are defined anti-clockwise, we revert them
153 // G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids1001",
154 // JustWarning,
155 // "Polygon vertices defined anti-clockwise, reverting polygon");
156 std::reverse(fPolygon.begin(),fPolygon.end());
157 }
158
159 // Copy z-sections
160 //
161 fZSections = zsections;
162
163 G4bool result = MakeFacets();
164 if (!result)
165 {
166 std::ostringstream message;
167 message << "Making facets failed - " << pName;
168 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0003",
169 FatalException, message);
170 }
171 fIsConvex = G4GeomTools::IsConvex(fPolygon);
172
173 ComputeProjectionParameters();
174
175 // Check if the solid is a right prism, if so then set lateral planes
176 //
177 if ((fNz == 2)
178 && (fZSections[0].fScale == 1) && (fZSections[1].fScale == 1)
179 && (fZSections[0].fOffset == G4TwoVector(0,0))
180 && (fZSections[1].fOffset == G4TwoVector(0,0)))
181 {
182 fSolidType = (fIsConvex) ? 1 : 2; // 1 - convex, 2 - non-convex right prism
183 ComputeLateralPlanes();
184 }
185}
@ JustWarning
@ FatalException
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::Hep2Vector G4TwoVector
bool G4bool
Definition G4Types.hh:86
static void RemoveRedundantVertices(G4TwoVectorList &polygon, std::vector< G4int > &iout, G4double tolerance=0.0)
static G4double PolygonArea(const G4TwoVectorList &polygon)
static G4bool IsConvex(const G4TwoVectorList &polygon)
G4double kCarTolerance
Definition G4VSolid.hh:299

Referenced by Clone().

◆ G4ExtrudedSolid() [2/4]

G4ExtrudedSolid::G4ExtrudedSolid ( const G4String & pName,
const std::vector< G4TwoVector > & polygon,
G4double halfZ,
const G4TwoVector & off1 = G4TwoVector(0.,0.),
G4double scale1 = 1.,
const G4TwoVector & off2 = G4TwoVector(0.,0.),
G4double scale2 = 1. )

Definition at line 189 of file G4ExtrudedSolid.cc.

194 : G4TessellatedSolid(pName),
195 fNv(polygon.size()),
196 fNz(2),
197 fGeometryType("G4ExtrudedSolid")
198{
199 // Special constructor for solid with 2 z-sections
200
201 // First check input parameters
202 //
203 if (fNv < 3)
204 {
205 std::ostringstream message;
206 message << "Number of vertices in polygon < 3 - " << pName;
207 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
208 FatalErrorInArgument, message);
209 }
210
211 // Copy polygon
212 //
213 fPolygon = polygon;
214
215 // Remove collinear and coincident vertices, if any
216 //
217 std::vector<G4int> removedVertices;
218 G4GeomTools::RemoveRedundantVertices(fPolygon,removedVertices,
219 2*kCarTolerance);
220 if (!removedVertices.empty())
221 {
222 std::size_t nremoved = removedVertices.size();
223 std::ostringstream message;
224 message << "The following "<< nremoved
225 << " vertices have been removed from polygon in " << pName
226 << "\nas collinear or coincident with other vertices: "
227 << removedVertices[0];
228 for (std::size_t i=1; i<nremoved; ++i) message << ", " << removedVertices[i];
229 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids1001",
230 JustWarning, message);
231 }
232
233 fNv = fPolygon.size();
234 if (fNv < 3)
235 {
236 std::ostringstream message;
237 message << "Number of vertices in polygon after removal < 3 - " << pName;
238 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
239 FatalErrorInArgument, message);
240 }
241
242 // Check if polygon vertices are defined clockwise
243 // (the area is positive if polygon vertices are defined anti-clockwise)
244 //
245 if (G4GeomTools::PolygonArea(fPolygon) > 0.)
246 {
247 // Polygon vertices are defined anti-clockwise, we revert them
248 // G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids1001",
249 // JustWarning,
250 // "Polygon vertices defined anti-clockwise, reverting polygon");
251 std::reverse(fPolygon.begin(),fPolygon.end());
252 }
253
254 // Copy z-sections
255 //
256 fZSections.emplace_back(-dz, off1, scale1);
257 fZSections.emplace_back( dz, off2, scale2);
258
259 G4bool result = MakeFacets();
260 if (!result)
261 {
262 std::ostringstream message;
263 message << "Making facets failed - " << pName;
264 G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0003",
265 FatalException, message);
266 }
267 fIsConvex = G4GeomTools::IsConvex(fPolygon);
268
269 ComputeProjectionParameters();
270
271 // Check if the solid is a right prism, if so then set lateral planes
272 //
273 if ((scale1 == 1) && (scale2 == 1)
274 && (off1 == G4TwoVector(0,0)) && (off2 == G4TwoVector(0,0)))
275 {
276 fSolidType = (fIsConvex) ? 1 : 2; // 1 - convex, 2 - non-convex right prism
277 ComputeLateralPlanes();
278 }
279}

◆ ~G4ExtrudedSolid()

G4ExtrudedSolid::~G4ExtrudedSolid ( )
override

Definition at line 322 of file G4ExtrudedSolid.cc.

323{
324 // Destructor
325}

◆ G4ExtrudedSolid() [3/4]

G4ExtrudedSolid::G4ExtrudedSolid ( __void__ & a)

Definition at line 283 of file G4ExtrudedSolid.cc.

284 : G4TessellatedSolid(a), fGeometryType("G4ExtrudedSolid")
285{
286 // Fake default constructor - sets only member data and allocates memory
287 // for usage restricted to object persistency.
288}

◆ G4ExtrudedSolid() [4/4]

G4ExtrudedSolid::G4ExtrudedSolid ( const G4ExtrudedSolid & rhs)
default

Member Function Documentation

◆ BoundingLimits()

void G4ExtrudedSolid::BoundingLimits ( G4ThreeVector & pMin,
G4ThreeVector & pMax ) const
overridevirtual

Reimplemented from G4VSolid.

Definition at line 1361 of file G4ExtrudedSolid.cc.

1363{
1364 G4double xmin0 = kInfinity, xmax0 = -kInfinity;
1365 G4double ymin0 = kInfinity, ymax0 = -kInfinity;
1366
1367 for (G4int i=0; i<GetNofVertices(); ++i)
1368 {
1369 G4double x = fPolygon[i].x();
1370 if (x < xmin0) xmin0 = x;
1371 if (x > xmax0) xmax0 = x;
1372 G4double y = fPolygon[i].y();
1373 if (y < ymin0) ymin0 = y;
1374 if (y > ymax0) ymax0 = y;
1375 }
1376
1377 G4double xmin = kInfinity, xmax = -kInfinity;
1378 G4double ymin = kInfinity, ymax = -kInfinity;
1379
1380 G4int nsect = GetNofZSections();
1381 for (G4int i=0; i<nsect; ++i)
1382 {
1383 ZSection zsect = GetZSection(i);
1384 G4double dx = zsect.fOffset.x();
1385 G4double dy = zsect.fOffset.y();
1386 G4double scale = zsect.fScale;
1387 xmin = std::min(xmin,xmin0*scale+dx);
1388 xmax = std::max(xmax,xmax0*scale+dx);
1389 ymin = std::min(ymin,ymin0*scale+dy);
1390 ymax = std::max(ymax,ymax0*scale+dy);
1391 }
1392
1393 G4double zmin = GetZSection(0).fZ;
1394 G4double zmax = GetZSection(nsect-1).fZ;
1395
1396 pMin.set(xmin,ymin,zmin);
1397 pMax.set(xmax,ymax,zmax);
1398
1399 // Check correctness of the bounding box
1400 //
1401 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
1402 {
1403 std::ostringstream message;
1404 message << "Bad bounding box (min >= max) for solid: "
1405 << GetName() << " !"
1406 << "\npMin = " << pMin
1407 << "\npMax = " << pMax;
1408 G4Exception("G4ExtrudedSolid::BoundingLimits()",
1409 "GeomMgt0001", JustWarning, message);
1410 DumpInfo();
1411 }
1412}
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
double z() const
double x() const
double y() const
void set(double x, double y, double z)
ZSection GetZSection(G4int index) const
G4int GetNofZSections() const
G4int GetNofVertices() const
G4String GetName() const
void DumpInfo() const

Referenced by CalculateExtent().

◆ CalculateExtent()

G4bool G4ExtrudedSolid::CalculateExtent ( const EAxis pAxis,
const G4VoxelLimits & pVoxelLimit,
const G4AffineTransform & pTransform,
G4double & pMin,
G4double & pMax ) const
overridevirtual

Implements G4VSolid.

Definition at line 1418 of file G4ExtrudedSolid.cc.

1422{
1423 G4ThreeVector bmin, bmax;
1424 G4bool exist;
1425
1426 // Check bounding box (bbox)
1427 //
1428 BoundingLimits(bmin,bmax);
1429 G4BoundingEnvelope bbox(bmin,bmax);
1430#ifdef G4BBOX_EXTENT
1431 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
1432#endif
1433 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
1434 {
1435 return exist = pMin < pMax;
1436 }
1437
1438 // To find the extent, the base polygon is subdivided in triangles.
1439 // The extent is calculated as cumulative extent of the parts
1440 // formed by extrusion of the triangles
1441 //
1442 G4TwoVectorList triangles;
1443 G4double eminlim = pVoxelLimit.GetMinExtent(pAxis);
1444 G4double emaxlim = pVoxelLimit.GetMaxExtent(pAxis);
1445
1446 // triangulate the base polygon
1447 if (!G4GeomTools::TriangulatePolygon(fPolygon,triangles))
1448 {
1449 std::ostringstream message;
1450 message << "Triangulation of the base polygon has failed for solid: "
1451 << GetName() << " !"
1452 << "\nExtent has been calculated using boundary box";
1453 G4Exception("G4ExtrudedSolid::CalculateExtent()",
1454 "GeomMgt1002",JustWarning,message);
1455 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
1456 }
1457
1458 // allocate vector lists
1459 G4int nsect = GetNofZSections();
1460 std::vector<const G4ThreeVectorList *> polygons;
1461 polygons.resize(nsect);
1462 for (G4int k=0; k<nsect; ++k) { polygons[k] = new G4ThreeVectorList(3); }
1463
1464 // main loop along triangles
1465 pMin = kInfinity;
1466 pMax = -kInfinity;
1467 G4int ntria = (G4int)triangles.size()/3;
1468 for (G4int i=0; i<ntria; ++i)
1469 {
1470 G4int i3 = i*3;
1471 for (G4int k=0; k<nsect; ++k) // extrude triangle
1472 {
1473 ZSection zsect = GetZSection(k);
1474 G4double z = zsect.fZ;
1475 G4double dx = zsect.fOffset.x();
1476 G4double dy = zsect.fOffset.y();
1477 G4double scale = zsect.fScale;
1478
1479 auto ptr = const_cast<G4ThreeVectorList*>(polygons[k]);
1480 auto iter = ptr->begin();
1481 G4double x0 = triangles[i3+0].x()*scale+dx;
1482 G4double y0 = triangles[i3+0].y()*scale+dy;
1483 iter->set(x0,y0,z);
1484 iter++;
1485 G4double x1 = triangles[i3+1].x()*scale+dx;
1486 G4double y1 = triangles[i3+1].y()*scale+dy;
1487 iter->set(x1,y1,z);
1488 iter++;
1489 G4double x2 = triangles[i3+2].x()*scale+dx;
1490 G4double y2 = triangles[i3+2].y()*scale+dy;
1491 iter->set(x2,y2,z);
1492 }
1493
1494 // set sub-envelope and adjust extent
1495 G4double emin,emax;
1496 G4BoundingEnvelope benv(polygons);
1497 if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax)) continue;
1498 if (emin < pMin) pMin = emin;
1499 if (emax > pMax) pMax = emax;
1500 if (eminlim > pMin && emaxlim < pMax) break; // max possible extent
1501 }
1502 // free memory
1503 for (G4int k=0; k<nsect; ++k) { delete polygons[k]; polygons[k]=nullptr;}
1504 return (pMin < pMax);
1505}
std::vector< G4ThreeVector > G4ThreeVectorList
std::vector< G4TwoVector > G4TwoVectorList
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const override
static G4bool TriangulatePolygon(const G4TwoVectorList &polygon, G4TwoVectorList &result)
G4double GetMinExtent(const EAxis pAxis) const
G4double GetMaxExtent(const EAxis pAxis) const

◆ Clone()

G4VSolid * G4ExtrudedSolid::Clone ( ) const
overridevirtual

Reimplemented from G4VSolid.

Definition at line 840 of file G4ExtrudedSolid.cc.

841{
842 return new G4ExtrudedSolid(*this);
843}
G4ExtrudedSolid(const G4String &pName, const std::vector< G4TwoVector > &polygon, const std::vector< ZSection > &zsections)

◆ DistanceToIn() [1/2]

G4double G4ExtrudedSolid::DistanceToIn ( const G4ThreeVector & p) const
overridevirtual

Implements G4VSolid.

Definition at line 1209 of file G4ExtrudedSolid.cc.

1210{
1211 switch (fSolidType)
1212 {
1213 case 1: // convex right prism
1214 {
1215 G4double dist = std::max(fZSections[0].fZ-p.z(),p.z()-fZSections[1].fZ);
1216 std::size_t np = fPlanes.size();
1217 for (std::size_t i=0; i<np; ++i)
1218 {
1219 G4double dd = fPlanes[i].a*p.x() + fPlanes[i].b*p.y() + fPlanes[i].d;
1220 if (dd > dist) dist = dd;
1221 }
1222 return (dist > 0) ? dist : 0.;
1223 }
1224 case 2: // non-convex right prism
1225 {
1226 G4bool in = PointInPolygon(p);
1227 if (in)
1228 {
1229 G4double distz= std::max(fZSections[0].fZ-p.z(),p.z()-fZSections[1].fZ);
1230 return (distz > 0) ? distz : 0;
1231 }
1232 else
1233 {
1234 G4double distz= std::max(fZSections[0].fZ-p.z(),p.z()-fZSections[1].fZ);
1235 G4double dd = DistanceToPolygonSqr(p);
1236 if (distz > 0) dd += distz*distz;
1237 return std::sqrt(dd);
1238 }
1239 }
1240 }
1241
1242 // General case: use tessellated solid
1244}
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const override

◆ DistanceToIn() [2/2]

G4double G4ExtrudedSolid::DistanceToIn ( const G4ThreeVector & p,
const G4ThreeVector & v ) const
overridevirtual

Implements G4VSolid.

Definition at line 1148 of file G4ExtrudedSolid.cc.

1150{
1151 G4double z0 = fZSections[0].fZ;
1152 G4double z1 = fZSections[fNz-1].fZ;
1153 if ((p.z() <= z0 + kCarToleranceHalf) && v.z() <= 0) return kInfinity;
1154 if ((p.z() >= z1 - kCarToleranceHalf) && v.z() >= 0) return kInfinity;
1155
1156 switch (fSolidType)
1157 {
1158 case 1: // convex right prism
1159 {
1160 // Intersection with Z planes
1161 //
1162 G4double dz = (z1 - z0)*0.5;
1163 G4double pz = p.z() - dz - z0;
1164
1165 G4double invz = (v.z() == 0) ? DBL_MAX : -1./v.z();
1166 G4double ddz = (invz < 0) ? dz : -dz;
1167 G4double tzmin = (pz + ddz)*invz;
1168 G4double tzmax = (pz - ddz)*invz;
1169
1170 // Intersection with lateral planes
1171 //
1172 std::size_t np = fPlanes.size();
1173 G4double txmin = tzmin, txmax = tzmax;
1174 for (std::size_t i=0; i<np; ++i)
1175 {
1176 G4double cosa = fPlanes[i].a*v.x()+fPlanes[i].b*v.y();
1177 G4double dist = fPlanes[i].a*p.x()+fPlanes[i].b*p.y()+fPlanes[i].d;
1178 if (dist >= -kCarToleranceHalf)
1179 {
1180 if (cosa >= 0) { return kInfinity; }
1181 G4double tmp = -dist/cosa;
1182 if (txmin < tmp) { txmin = tmp; }
1183 }
1184 else if (cosa > 0)
1185 {
1186 G4double tmp = -dist/cosa;
1187 if (txmax > tmp) { txmax = tmp; }
1188 }
1189 }
1190
1191 // Find distance
1192 //
1193 G4double tmin = txmin, tmax = txmax;
1194 if (tmax <= tmin + kCarToleranceHalf) // touch or no hit
1195 {
1196 return kInfinity;
1197 }
1198 return (tmin < kCarToleranceHalf) ? 0. : tmin;
1199 }
1200 case 2: // non-convex right prism
1201 {
1202 }
1203 }
1205}
#define DBL_MAX
Definition templates.hh:62

◆ DistanceToOut() [1/2]

G4double G4ExtrudedSolid::DistanceToOut ( const G4ThreeVector & p) const
overridevirtual

Implements G4VSolid.

Definition at line 1330 of file G4ExtrudedSolid.cc.

1331{
1332 switch (fSolidType)
1333 {
1334 case 1: // convex right prism
1335 {
1336 G4double dist = std::max(fZSections[0].fZ-p.z(),p.z()-fZSections[1].fZ);
1337 std::size_t np = fPlanes.size();
1338 for (std::size_t i=0; i<np; ++i)
1339 {
1340 G4double dd = fPlanes[i].a*p.x() + fPlanes[i].b*p.y() + fPlanes[i].d;
1341 if (dd > dist) dist = dd;
1342 }
1343 return (dist < 0) ? -dist : 0.;
1344 }
1345 case 2: // non-convex right prism
1346 {
1347 G4double distz = std::max(fZSections[0].fZ-p.z(),p.z()-fZSections[1].fZ);
1348 G4bool in = PointInPolygon(p);
1349 if (distz >= 0 || (!in)) return 0; // point is outside
1350 return std::min(-distz,std::sqrt(DistanceToPolygonSqr(p)));
1351 }
1352 }
1353
1354 // General case: use tessellated solid
1356}
G4double DistanceToOut(const G4ThreeVector &p) const override

◆ DistanceToOut() [2/2]

G4double G4ExtrudedSolid::DistanceToOut ( const G4ThreeVector & p,
const G4ThreeVector & v,
const G4bool calcNorm = false,
G4bool * validNorm = nullptr,
G4ThreeVector * n = nullptr ) const
overridevirtual

Implements G4VSolid.

Definition at line 1248 of file G4ExtrudedSolid.cc.

1253{
1254 G4bool getnorm = calcNorm;
1255 if (getnorm) *validNorm = true;
1256
1257 G4double z0 = fZSections[0].fZ;
1258 G4double z1 = fZSections[fNz-1].fZ;
1259 if ((p.z() <= z0 + kCarToleranceHalf) && v.z() < 0)
1260 {
1261 if (getnorm) n->set(0,0,-1);
1262 return 0;
1263 }
1264 if ((p.z() >= z1 - kCarToleranceHalf) && v.z() > 0)
1265 {
1266 if (getnorm) n->set(0,0,1);
1267 return 0;
1268 }
1269
1270 switch (fSolidType)
1271 {
1272 case 1: // convex right prism
1273 {
1274 // Intersection with Z planes
1275 //
1276 G4double dz = (z1 - z0)*0.5;
1277 G4double pz = p.z() - 0.5 * (z0 + z1);
1278
1279 G4double vz = v.z();
1280 G4double tmax = (vz == 0) ? DBL_MAX : (std::copysign(dz,vz) - pz)/vz;
1281 G4int iside = (vz < 0) ? -4 : -2; // little trick: (-4+3)=-1, (-2+3)=+1
1282
1283 // Intersection with lateral planes
1284 //
1285 std::size_t np = fPlanes.size();
1286 for (std::size_t i=0; i<np; ++i)
1287 {
1288 G4double cosa = fPlanes[i].a*v.x()+fPlanes[i].b*v.y();
1289 if (cosa > 0)
1290 {
1291 G4double dist = fPlanes[i].a*p.x()+fPlanes[i].b*p.y()+fPlanes[i].d;
1292 if (dist >= -kCarToleranceHalf)
1293 {
1294 if (getnorm) n->set(fPlanes[i].a, fPlanes[i].b, fPlanes[i].c);
1295 return 0;
1296 }
1297 G4double tmp = -dist/cosa;
1298 if (tmax > tmp) { tmax = tmp; iside = (G4int)i; }
1299 }
1300 }
1301
1302 // Set normal, if required, and return distance
1303 //
1304 if (getnorm)
1305 {
1306 if (iside < 0)
1307 { n->set(0, 0, iside + 3); } // (-4+3)=-1, (-2+3)=+1
1308 else
1309 { n->set(fPlanes[iside].a, fPlanes[iside].b, fPlanes[iside].c); }
1310 }
1311 return tmax;
1312 }
1313 case 2: // non-convex right prism
1314 {
1315 }
1316 }
1317
1318 // Override the base class function to redefine validNorm
1319 // (the solid can be concave)
1320
1321 G4double distOut =
1322 G4TessellatedSolid::DistanceToOut(p, v, calcNorm, validNorm, n);
1323 if (validNorm != nullptr) { *validNorm = fIsConvex; }
1324
1325 return distOut;
1326}

◆ GetEntityType()

G4GeometryType G4ExtrudedSolid::GetEntityType ( ) const
overridevirtual

Implements G4VSolid.

Definition at line 831 of file G4ExtrudedSolid.cc.

832{
833 // Return entity type
834
835 return fGeometryType;
836}

◆ GetNofVertices()

G4int G4ExtrudedSolid::GetNofVertices ( ) const
inline

◆ GetNofZSections()

G4int G4ExtrudedSolid::GetNofZSections ( ) const
inline

◆ GetPolygon()

std::vector< G4TwoVector > G4ExtrudedSolid::GetPolygon ( ) const
inline

◆ GetVertex()

G4TwoVector G4ExtrudedSolid::GetVertex ( G4int index) const
inline

◆ GetZSection()

ZSection G4ExtrudedSolid::GetZSection ( G4int index) const
inline

◆ GetZSections()

std::vector< ZSection > G4ExtrudedSolid::GetZSections ( ) const
inline

◆ Inside()

EInside G4ExtrudedSolid::Inside ( const G4ThreeVector & p) const
overridevirtual

Implements G4VSolid.

Definition at line 847 of file G4ExtrudedSolid.cc.

848{
849 switch (fSolidType)
850 {
851 case 1: // convex right prism
852 {
853 G4double dist = std::max(fZSections[0].fZ-p.z(),p.z()-fZSections[1].fZ);
854 if (dist > kCarToleranceHalf) { return kOutside; }
855
856 std::size_t np = fPlanes.size();
857 for (std::size_t i=0; i<np; ++i)
858 {
859 G4double dd = fPlanes[i].a*p.x() + fPlanes[i].b*p.y() + fPlanes[i].d;
860 if (dd > dist) { dist = dd; }
861 }
862 if (dist > kCarToleranceHalf) { return kOutside; }
863 return (dist > -kCarToleranceHalf) ? kSurface : kInside;
864 }
865 case 2: // non-convex right prism
866 {
867 G4double distz = std::max(fZSections[0].fZ-p.z(),p.z()-fZSections[1].fZ);
868 if (distz > kCarToleranceHalf) { return kOutside; }
869
870 G4bool in = PointInPolygon(p);
871 if (distz > -kCarToleranceHalf && in) { return kSurface; }
872
873 G4double dd = DistanceToPolygonSqr(p) - kCarToleranceHalf*kCarToleranceHalf;
874 if (in)
875 {
876 return (dd >= 0) ? kInside : kSurface;
877 }
878 else
879 {
880 return (dd > 0) ? kOutside : kSurface;
881 }
882 }
883 }
884
885 // Override the base class function as it fails in case of concave polygon.
886 // Project the point in the original polygon scale and check if it is inside
887 // for each triangle.
888
889 // Check first if outside extent
890 //
891 if ( p.x() < GetMinXExtent() - kCarToleranceHalf ||
897 {
898 // G4cout << "G4ExtrudedSolid::Outside extent: " << p << G4endl;
899 return kOutside;
900 }
901
902 // Project point p(z) to the polygon scale p0
903 //
904 G4TwoVector pscaled = ProjectPoint(p);
905
906 // Check if on surface of polygon
907 //
908 for ( G4int i=0; i<(G4int)fNv; ++i )
909 {
910 G4int j = (i+1) % fNv;
911 if ( IsSameLineSegment(pscaled, fPolygon[i], fPolygon[j]) )
912 {
913 // G4cout << "G4ExtrudedSolid::Inside return Surface (on polygon) "
914 // << G4endl;
915
916 return kSurface;
917 }
918 }
919
920 // Now check if inside triangles
921 //
922 auto it = fTriangles.cbegin();
923 G4bool inside = false;
924 do // Loop checking, 13.08.2015, G.Cosmo
925 {
926 if ( IsPointInside(fPolygon[(*it)[0]], fPolygon[(*it)[1]],
927 fPolygon[(*it)[2]], pscaled) ) { inside = true; }
928 ++it;
929 } while ( (!inside) && (it != fTriangles.cend()) );
930
931 if ( inside )
932 {
933 // Check if on surface of z sides
934 //
935 if ( std::fabs( p.z() - fZSections[0].fZ ) < kCarToleranceHalf ||
936 std::fabs( p.z() - fZSections[fNz-1].fZ ) < kCarToleranceHalf )
937 {
938 // G4cout << "G4ExtrudedSolid::Inside return Surface (on z side)"
939 // << G4endl;
940
941 return kSurface;
942 }
943
944 // G4cout << "G4ExtrudedSolid::Inside return Inside" << G4endl;
945
946 return kInside;
947 }
948
949 // G4cout << "G4ExtrudedSolid::Inside return Outside " << G4endl;
950
951 return kOutside;
952}
G4double GetMinYExtent() const
G4double GetMinZExtent() const
G4double GetMaxYExtent() const
G4double GetMaxZExtent() const
G4double GetMaxXExtent() const
G4double GetMinXExtent() const
@ kInside
Definition geomdefs.hh:70
@ kOutside
Definition geomdefs.hh:68
@ kSurface
Definition geomdefs.hh:69

◆ operator=()

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

Definition at line 296 of file G4ExtrudedSolid.cc.

297{
298 // Check assignment to self
299 //
300 if (this == &rhs) { return *this; }
301
302 // Copy base class data
303 //
305
306 // Copy data
307 //
308 fNv = rhs.fNv; fNz = rhs.fNz;
309 fPolygon = rhs.fPolygon; fZSections = rhs.fZSections;
310 fTriangles = rhs.fTriangles; fIsConvex = rhs.fIsConvex;
311 fGeometryType = rhs.fGeometryType;
312 fSolidType = rhs.fSolidType; fPlanes = rhs.fPlanes;
313 fLines = rhs.fLines; fLengths = rhs.fLengths;
314 fKScales = rhs.fKScales; fScale0s = rhs.fScale0s;
315 fKOffsets = rhs.fKOffsets; fOffset0s = rhs.fOffset0s;
316
317 return *this;
318}
G4TessellatedSolid & operator=(const G4TessellatedSolid &right)

◆ StreamInfo()

std::ostream & G4ExtrudedSolid::StreamInfo ( std::ostream & os) const
overridevirtual

Implements G4VSolid.

Definition at line 1509 of file G4ExtrudedSolid.cc.

1510{
1511 G4long oldprc = os.precision(16);
1512 os << "-----------------------------------------------------------\n"
1513 << " *** Dump for solid - " << GetName() << " ***\n"
1514 << " ===================================================\n"
1515 << " Solid geometry type: " << fGeometryType << G4endl;
1516
1517 if ( fIsConvex)
1518 { os << " Convex polygon; list of vertices:" << G4endl; }
1519 else
1520 { os << " Concave polygon; list of vertices:" << G4endl; }
1521
1522 for ( std::size_t i=0; i<fNv; ++i )
1523 {
1524 os << std::setw(5) << "#" << i
1525 << " vx = " << fPolygon[i].x()/mm << " mm"
1526 << " vy = " << fPolygon[i].y()/mm << " mm" << G4endl;
1527 }
1528
1529 os << " Sections:" << G4endl;
1530 for ( std::size_t iz=0; iz<fNz; ++iz )
1531 {
1532 os << " z = " << fZSections[iz].fZ/mm << " mm "
1533 << " x0= " << fZSections[iz].fOffset.x()/mm << " mm "
1534 << " y0= " << fZSections[iz].fOffset.y()/mm << " mm "
1535 << " scale= " << fZSections[iz].fScale << G4endl;
1536 }
1537
1538/*
1539 // Triangles (for debugging)
1540 os << G4endl;
1541 os << " Triangles:" << G4endl;
1542 os << " Triangle # vertex1 vertex2 vertex3" << G4endl;
1543
1544 G4int counter = 0;
1545 std::vector< std::vector<G4int> >::const_iterator it;
1546 for ( it = fTriangles.begin(); it != fTriangles.end(); it++ ) {
1547 std::vector<G4int> triangle = *it;
1548 os << std::setw(10) << counter++
1549 << std::setw(10) << triangle[0] << std::setw(10) << triangle[1]
1550 << std::setw(10) << triangle[2]
1551 << G4endl;
1552 }
1553*/
1554 os.precision(oldprc);
1555
1556 return os;
1557}
long G4long
Definition G4Types.hh:87
#define G4endl
Definition G4ios.hh:67

◆ SurfaceNormal()

G4ThreeVector G4ExtrudedSolid::SurfaceNormal ( const G4ThreeVector & p) const
overridevirtual

Implements G4VSolid.

Definition at line 956 of file G4ExtrudedSolid.cc.

957{
958 G4int nsurf = 0;
959 G4double nx = 0., ny = 0., nz = 0.;
960 switch (fSolidType)
961 {
962 case 1: // convex right prism
963 {
964 if (std::abs(p.z() - fZSections[0].fZ) <= kCarToleranceHalf)
965 {
966 nz = -1; ++nsurf;
967 }
968 if (std::abs(p.z() - fZSections[1].fZ) <= kCarToleranceHalf)
969 {
970 nz = 1; ++nsurf;
971 }
972 for (std::size_t i=0; i<fNv; ++i)
973 {
974 G4double dd = fPlanes[i].a*p.x() + fPlanes[i].b*p.y() + fPlanes[i].d;
975 if (std::abs(dd) > kCarToleranceHalf) continue;
976 nx += fPlanes[i].a;
977 ny += fPlanes[i].b;
978 ++nsurf;
979 }
980 break;
981 }
982 case 2: // non-convex right prism
983 {
984 if (std::abs(p.z() - fZSections[0].fZ) <= kCarToleranceHalf)
985 {
986 nz = -1; ++nsurf;
987 }
988 if (std::abs(p.z() - fZSections[1].fZ) <= kCarToleranceHalf)
989 {
990 nz = 1; ++nsurf;
991 }
992
993 G4double sqrCarToleranceHalf = kCarToleranceHalf*kCarToleranceHalf;
994 for (std::size_t i=0, k=fNv-1; i<fNv; k=i++)
995 {
996 G4double ix = p.x() - fPolygon[i].x();
997 G4double iy = p.y() - fPolygon[i].y();
998 G4double u = fPlanes[i].a*iy - fPlanes[i].b*ix;
999 if (u < 0)
1000 {
1001 if (ix*ix + iy*iy > sqrCarToleranceHalf) continue;
1002 }
1003 else if (u > fLengths[i])
1004 {
1005 G4double kx = p.x() - fPolygon[k].x();
1006 G4double ky = p.y() - fPolygon[k].y();
1007 if (kx*kx + ky*ky > sqrCarToleranceHalf) continue;
1008 }
1009 else
1010 {
1011 G4double dd = fPlanes[i].a*p.x() + fPlanes[i].b*p.y() + fPlanes[i].d;
1012 if (dd*dd > sqrCarToleranceHalf) continue;
1013 }
1014 nx += fPlanes[i].a;
1015 ny += fPlanes[i].b;
1016 ++nsurf;
1017 }
1018 break;
1019 }
1020 default:
1021 {
1023 }
1024 }
1025
1026 // Return normal (right prism)
1027 //
1028 if (nsurf == 1)
1029 {
1030 return { nx,ny,nz };
1031 }
1032 else if (nsurf != 0) // edge or corner
1033 {
1034 return G4ThreeVector(nx,ny,nz).unit();
1035 }
1036 else
1037 {
1038 // Point is not on the surface, compute approximate normal
1039 //
1040#ifdef G4CSGDEBUG
1041 std::ostringstream message;
1042 G4long oldprc = message.precision(16);
1043 message << "Point p is not on surface (!?) of solid: "
1044 << GetName() << G4endl;
1045 message << "Position:\n";
1046 message << " p.x() = " << p.x()/mm << " mm\n";
1047 message << " p.y() = " << p.y()/mm << " mm\n";
1048 message << " p.z() = " << p.z()/mm << " mm";
1049 G4cout.precision(oldprc) ;
1050 G4Exception("G4TesselatedSolid::SurfaceNormal(p)", "GeomSolids1002",
1051 JustWarning, message );
1052 DumpInfo();
1053#endif
1054 return ApproxSurfaceNormal(p);
1055 }
1056}
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
Hep3Vector unit() const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const override

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