Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4GenericPolycone.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4GenericPolycone implementation
27//
28// Authors: T.Nikitina, G.Cosmo - CERN
29// --------------------------------------------------------------------
30
31#include "G4GenericPolycone.hh"
32
33#if !defined(G4GEOM_USE_UGENERICPOLYCONE)
34
35#include "G4PolyconeSide.hh"
36#include "G4PolyPhiFace.hh"
37
38#include "G4GeomTools.hh"
39#include "G4VoxelLimits.hh"
40#include "G4AffineTransform.hh"
41#include "G4BoundingEnvelope.hh"
42
43#include "G4QuickRand.hh"
44
45#include "G4Polyhedron.hh"
47#include "G4ReduciblePolygon.hh"
49
50namespace
51{
52 G4Mutex surface_elementsMutex = G4MUTEX_INITIALIZER;
53}
54
55using namespace CLHEP;
56
57// Constructor (generic parameters)
58//
60 G4double phiStart,
61 G4double phiTotal,
62 G4int numRZ,
63 const G4double r[],
64 const G4double z[] )
65 : G4VCSGfaceted( name )
66{
67
68 G4ReduciblePolygon *rz = new G4ReduciblePolygon( r, z, numRZ );
69
70 Create( phiStart, phiTotal, rz );
71
72 // Set original_parameters struct for consistency
73 //
74 //SetOriginalParameters(rz);
75
76 delete rz;
77}
78
79// Create
80//
81// Generic create routine, called by each constructor after
82// conversion of arguments
83//
85 G4double phiTotal,
87{
88 //
89 // Perform checks of rz values
90 //
91 if (rz->Amin() < 0.0)
92 {
93 std::ostringstream message;
94 message << "Illegal input parameters - " << GetName() << G4endl
95 << " All R values must be >= 0 !";
96 G4Exception("G4GenericPolycone::Create()", "GeomSolids0002",
97 FatalErrorInArgument, message);
98 }
99
100 G4double rzArea = rz->Area();
101 if (rzArea < -kCarTolerance)
102 {
103 rz->ReverseOrder();
104 }
105 else if (rzArea < kCarTolerance)
106 {
107 std::ostringstream message;
108 message << "Illegal input parameters - " << GetName() << G4endl
109 << " R/Z cross section is zero or near zero: " << rzArea;
110 G4Exception("G4GenericPolycone::Create()", "GeomSolids0002",
111 FatalErrorInArgument, message);
112 }
113
116 {
117 std::ostringstream message;
118 message << "Illegal input parameters - " << GetName() << G4endl
119 << " Too few unique R/Z values !";
120 G4Exception("G4GenericPolycone::Create()", "GeomSolids0002",
121 FatalErrorInArgument, message);
122 }
123
124 if (rz->CrossesItself(1/kInfinity))
125 {
126 std::ostringstream message;
127 message << "Illegal input parameters - " << GetName() << G4endl
128 << " R/Z segments cross !";
129 G4Exception("G4GenericPolycone::Create()", "GeomSolids0002",
130 FatalErrorInArgument, message);
131 }
132
133 numCorner = rz->NumVertices();
134
135 //
136 // Phi opening? Account for some possible roundoff, and interpret
137 // nonsense value as representing no phi opening
138 //
139 if (phiTotal <= 0 || phiTotal > twopi-1E-10)
140 {
141 phiIsOpen = false;
142 startPhi = 0;
143 endPhi = twopi;
144 }
145 else
146 {
147 phiIsOpen = true;
148
149 //
150 // Convert phi into our convention
151 //
152 startPhi = phiStart;
153 while( startPhi < 0 ) // Loop checking, 13.08.2015, G.Cosmo
154 startPhi += twopi;
155
156 endPhi = phiStart+phiTotal;
157 while( endPhi < startPhi ) // Loop checking, 13.08.2015, G.Cosmo
158 endPhi += twopi;
159 }
160
161 //
162 // Allocate corner array.
163 //
165
166 //
167 // Copy corners
168 //
170
172 iterRZ.Begin();
173 do // Loop checking, 13.08.2015, G.Cosmo
174 {
175 next->r = iterRZ.GetA();
176 next->z = iterRZ.GetB();
177 } while( ++next, iterRZ.Next() );
178
179 //
180 // Allocate face pointer array
181 //
183 faces = new G4VCSGface*[numFace];
184
185 //
186 // Construct conical faces
187 //
188 // But! Don't construct a face if both points are at zero radius!
189 //
190 G4PolyconeSideRZ *corner = corners,
191 *prev = corners + numCorner-1,
192 *nextNext;
193 G4VCSGface** face = faces;
194 do // Loop checking, 13.08.2015, G.Cosmo
195 {
196 next = corner+1;
197 if (next >= corners+numCorner) next = corners;
198 nextNext = next+1;
199 if (nextNext >= corners+numCorner) nextNext = corners;
200
201 if (corner->r < 1/kInfinity && next->r < 1/kInfinity) continue;
202
203 //
204 // We must decide here if we can dare declare one of our faces
205 // as having a "valid" normal (i.e. allBehind = true). This
206 // is never possible if the face faces "inward" in r.
207 //
208 G4bool allBehind;
209 if (corner->z > next->z)
210 {
211 allBehind = false;
212 }
213 else
214 {
215 //
216 // Otherwise, it is only true if the line passing
217 // through the two points of the segment do not
218 // split the r/z cross section
219 //
220 allBehind = !rz->BisectedBy( corner->r, corner->z,
221 next->r, next->z, kCarTolerance );
222 }
223
224 *face++ = new G4PolyconeSide( prev, corner, next, nextNext,
225 startPhi, endPhi-startPhi, phiIsOpen, allBehind );
226 } while( prev=corner, corner=next, corner > corners );
227
228 if (phiIsOpen)
229 {
230 //
231 // Construct phi open edges
232 //
233 *face++ = new G4PolyPhiFace( rz, startPhi, 0, endPhi );
234 *face++ = new G4PolyPhiFace( rz, endPhi, 0, startPhi );
235 }
236
237 //
238 // We might have dropped a face or two: recalculate numFace
239 //
240 numFace = (G4int)(face-faces);
241
242 //
243 // Make enclosingCylinder
244 //
246 new G4EnclosingCylinder( rz, phiIsOpen, phiStart, phiTotal );
247}
248
249// Fake default constructor - sets only member data and allocates memory
250// for usage restricted to object persistency.
251//
253 : G4VCSGfaceted(a), startPhi(0.), endPhi(0.), numCorner(0)
254{
255}
256
257// Destructor
258//
260{
261 delete [] corners;
262 delete enclosingCylinder;
263 delete fElements;
264 delete fpPolyhedron;
265 corners = nullptr;
266 enclosingCylinder = nullptr;
267 fElements = nullptr;
268 fpPolyhedron = nullptr;
269}
270
271// Copy constructor
272//
274 : G4VCSGfaceted( source )
275{
276 CopyStuff( source );
277}
278
279// Assignment operator
280//
283{
284 if (this == &source) return *this;
285
286 G4VCSGfaceted::operator=( source );
287
288 delete [] corners;
289 // if (original_parameters) delete original_parameters;
290
291 delete enclosingCylinder;
292
293 CopyStuff( source );
294
295 return *this;
296}
297
298// CopyStuff
299//
301{
302 //
303 // Simple stuff
304 //
305 startPhi = source.startPhi;
306 endPhi = source.endPhi;
307 phiIsOpen = source.phiIsOpen;
308 numCorner = source.numCorner;
309
310 //
311 // The corner array
312 //
314
316 *sourceCorn = source.corners;
317 do // Loop checking, 13.08.2015, G.Cosmo
318 {
319 *corn = *sourceCorn;
320 } while( ++sourceCorn, ++corn < corners+numCorner );
321
322 //
323 // Enclosing cylinder
324 //
326
327 //
328 // Surface elements
329 //
330 delete fElements;
331 fElements = nullptr;
332
333 // Polyhedron
334 //
335 fRebuildPolyhedron = false;
336 delete fpPolyhedron;
337 fpPolyhedron = nullptr;
338}
339
340// Reset
341//
343{
344 std::ostringstream message;
345 message << "Solid " << GetName() << " built using generic construct."
346 << G4endl << "Not applicable to the generic construct !";
347 G4Exception("G4GenericPolycone::Reset()", "GeomSolids1001",
348 JustWarning, message, "Parameters NOT resetted.");
349 return true;
350}
351
352// Inside
353//
354// This is an override of G4VCSGfaceted::Inside, created in order
355// to speed things up by first checking with G4EnclosingCylinder.
356//
358{
359 //
360 // Quick test
361 //
363
364 //
365 // Long answer
366 //
367 return G4VCSGfaceted::Inside(p);
368}
369
370// DistanceToIn
371//
372// This is an override of G4VCSGfaceted::Inside, created in order
373// to speed things up by first checking with G4EnclosingCylinder.
374//
376 const G4ThreeVector& v ) const
377{
378 //
379 // Quick test
380 //
382 return kInfinity;
383
384 //
385 // Long answer
386 //
387 return G4VCSGfaceted::DistanceToIn( p, v );
388}
389
390// DistanceToIn
391//
393{
395}
396
397// BoundingLimits
398//
399// Get bounding box
400//
401void
403 G4ThreeVector& pMax) const
404{
405 G4double rmin = kInfinity, rmax = -kInfinity;
406 G4double zmin = kInfinity, zmax = -kInfinity;
407
408 for (G4int i=0; i<GetNumRZCorner(); ++i)
409 {
410 G4PolyconeSideRZ corner = GetCorner(i);
411 if (corner.r < rmin) rmin = corner.r;
412 if (corner.r > rmax) rmax = corner.r;
413 if (corner.z < zmin) zmin = corner.z;
414 if (corner.z > zmax) zmax = corner.z;
415 }
416
417 if (IsOpen())
418 {
419 G4TwoVector vmin,vmax;
420 G4GeomTools::DiskExtent(rmin,rmax,
423 vmin,vmax);
424 pMin.set(vmin.x(),vmin.y(),zmin);
425 pMax.set(vmax.x(),vmax.y(),zmax);
426 }
427 else
428 {
429 pMin.set(-rmax,-rmax, zmin);
430 pMax.set( rmax, rmax, zmax);
431 }
432
433 // Check correctness of the bounding box
434 //
435 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
436 {
437 std::ostringstream message;
438 message << "Bad bounding box (min >= max) for solid: "
439 << GetName() << " !"
440 << "\npMin = " << pMin
441 << "\npMax = " << pMax;
442 G4Exception("GenericG4Polycone::BoundingLimits()", "GeomMgt0001",
443 JustWarning, message);
444 DumpInfo();
445 }
446}
447
448// CalculateExtent
449//
450// Calculate extent under transform and specified limit
451//
452G4bool
454 const G4VoxelLimits& pVoxelLimit,
455 const G4AffineTransform& pTransform,
456 G4double& pMin, G4double& pMax) const
457{
458 G4ThreeVector bmin, bmax;
459 G4bool exist;
460
461 // Check bounding box (bbox)
462 //
463 BoundingLimits(bmin,bmax);
464 G4BoundingEnvelope bbox(bmin,bmax);
465#ifdef G4BBOX_EXTENT
466 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
467#endif
468 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
469 {
470 return exist = (pMin < pMax) ? true : false;
471 }
472
473 // To find the extent, RZ contour of the polycone is subdivided
474 // in triangles. The extent is calculated as cumulative extent of
475 // all sub-polycones formed by rotation of triangles around Z
476 //
477 G4TwoVectorList contourRZ;
478 G4TwoVectorList triangles;
479 G4double eminlim = pVoxelLimit.GetMinExtent(pAxis);
480 G4double emaxlim = pVoxelLimit.GetMaxExtent(pAxis);
481
482 // get RZ contour, ensure anticlockwise order of corners
483 for (G4int i=0; i<GetNumRZCorner(); ++i)
484 {
485 G4PolyconeSideRZ corner = GetCorner(i);
486 contourRZ.push_back(G4TwoVector(corner.r,corner.z));
487 }
488 G4double area = G4GeomTools::PolygonArea(contourRZ);
489 if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
490
491 // triangulate RZ countour
492 if (!G4GeomTools::TriangulatePolygon(contourRZ,triangles))
493 {
494 std::ostringstream message;
495 message << "Triangulation of RZ contour has failed for solid: "
496 << GetName() << " !"
497 << "\nExtent has been calculated using boundary box";
498 G4Exception("G4GenericPolycone::CalculateExtent()",
499 "GeomMgt1002", JustWarning, message);
500 return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
501 }
502
503 // set trigonometric values
504 const G4int NSTEPS = 24; // number of steps for whole circle
505 G4double astep = twopi/NSTEPS; // max angle for one step
506
507 G4double sphi = GetStartPhi();
508 G4double ephi = GetEndPhi();
509 G4double dphi = IsOpen() ? ephi-sphi : twopi;
510 G4int ksteps = (dphi <= astep) ? 1 : (G4int)((dphi-deg)/astep) + 1;
511 G4double ang = dphi/ksteps;
512
513 G4double sinHalf = std::sin(0.5*ang);
514 G4double cosHalf = std::cos(0.5*ang);
515 G4double sinStep = 2.*sinHalf*cosHalf;
516 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
517
518 G4double sinStart = GetSinStartPhi();
519 G4double cosStart = GetCosStartPhi();
520 G4double sinEnd = GetSinEndPhi();
521 G4double cosEnd = GetCosEndPhi();
522
523 // define vectors and arrays
524 std::vector<const G4ThreeVectorList *> polygons;
525 polygons.resize(ksteps+2);
526 G4ThreeVectorList pols[NSTEPS+2];
527 for (G4int k=0; k<ksteps+2; ++k) pols[k].resize(6);
528 for (G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
529 G4double r0[6],z0[6]; // contour with original edges of triangle
530 G4double r1[6]; // shifted radii of external edges of triangle
531
532 // main loop along triangles
533 pMin = kInfinity;
534 pMax =-kInfinity;
535 G4int ntria = (G4int)triangles.size()/3;
536 for (G4int i=0; i<ntria; ++i)
537 {
538 G4int i3 = i*3;
539 for (G4int k=0; k<3; ++k)
540 {
541 G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3;
542 G4int k2 = k*2;
543 // set contour with original edges of triangle
544 r0[k2+0] = triangles[e0].x(); z0[k2+0] = triangles[e0].y();
545 r0[k2+1] = triangles[e1].x(); z0[k2+1] = triangles[e1].y();
546 // set shifted radii
547 r1[k2+0] = r0[k2+0];
548 r1[k2+1] = r0[k2+1];
549 if (z0[k2+1] - z0[k2+0] <= 0) continue;
550 r1[k2+0] /= cosHalf;
551 r1[k2+1] /= cosHalf;
552 }
553
554 // rotate countour, set sequence of 6-sided polygons
555 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
556 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
557 for (G4int j=0; j<6; ++j)
558 {
559 pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
560 }
561 for (G4int k=1; k<ksteps+1; ++k)
562 {
563 for (G4int j=0; j<6; ++j)
564 {
565 pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
566 }
567 G4double sinTmp = sinCur;
568 sinCur = sinCur*cosStep + cosCur*sinStep;
569 cosCur = cosCur*cosStep - sinTmp*sinStep;
570 }
571 for (G4int j=0; j<6; ++j)
572 {
573 pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
574 }
575
576 // set sub-envelope and adjust extent
577 G4double emin,emax;
578 G4BoundingEnvelope benv(polygons);
579 if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax)) continue;
580 if (emin < pMin) pMin = emin;
581 if (emax > pMax) pMax = emax;
582 if (eminlim > pMin && emaxlim < pMax) return true; // max possible extent
583 }
584 return (pMin < pMax);
585}
586
587// GetEntityType
588//
590{
591 return G4String("G4GenericPolycone");
592}
593
594// Clone
595//
596// Make a clone of the object
597//
599{
600 return new G4GenericPolycone(*this);
601}
602
603// StreamInfo
604//
605// Stream object contents to an output stream
606//
607std::ostream& G4GenericPolycone::StreamInfo( std::ostream& os ) const
608{
609 G4long oldprc = os.precision(16);
610 os << "-----------------------------------------------------------\n"
611 << " *** Dump for solid - " << GetName() << " ***\n"
612 << " ===================================================\n"
613 << " Solid type: G4GenericPolycone\n"
614 << " Parameters: \n"
615 << " starting phi angle : " << startPhi/degree << " degrees \n"
616 << " ending phi angle : " << endPhi/degree << " degrees \n";
617 G4int i=0;
618
619 os << " number of RZ points: " << numCorner << "\n"
620 << " RZ values (corners): \n";
621 for (i=0; i<numCorner; i++)
622 {
623 os << " "
624 << corners[i].r << ", " << corners[i].z << "\n";
625 }
626 os << "-----------------------------------------------------------\n";
627 os.precision(oldprc);
628
629 return os;
630}
631
632//////////////////////////////////////////////////////////////////////////
633//
634// Return volume
635
637{
638 if (fCubicVolume == 0.)
639 {
640 G4double total = 0.;
641 G4int nrz = GetNumRZCorner();
642 G4PolyconeSideRZ a = GetCorner(nrz - 1);
643 for (G4int i=0; i<nrz; ++i)
644 {
646 total += (b.r*b.r + b.r*a.r + a.r*a.r)*(b.z - a.z);
647 a = b;
648 }
649 fCubicVolume = std::abs(total)*(GetEndPhi() - GetStartPhi())/6.;
650 }
651 return fCubicVolume;
652}
653
654//////////////////////////////////////////////////////////////////////////
655//
656// Return surface area
657
659{
660 if (fSurfaceArea == 0.)
661 {
662 // phi cut area
663 G4int nrz = GetNumRZCorner();
664 G4double scut = 0.;
665 if (IsOpen())
666 {
667 G4PolyconeSideRZ a = GetCorner(nrz - 1);
668 for (G4int i=0; i<nrz; ++i)
669 {
671 scut += a.r*b.z - a.z*b.r;
672 a = b;
673 }
674 scut = std::abs(scut);
675 }
676 // lateral surface area
677 G4double slat = 0;
678 G4PolyconeSideRZ a = GetCorner(nrz - 1);
679 for (G4int i=0; i<nrz; ++i)
680 {
682 G4double h = std::sqrt((b.r - a.r)*(b.r - a.r) + (b.z - a.z)*(b.z - a.z));
683 slat += (b.r + a.r)*h;
684 a = b;
685 }
686 slat *= (GetEndPhi() - GetStartPhi())/2.;
687 fSurfaceArea = scut + slat;
688 }
689 return fSurfaceArea;
690}
691
692//////////////////////////////////////////////////////////////////////////
693//
694// Set vector of surface elements, auxiliary method for sampling
695// random points on surface
696
698{
699 fElements = new std::vector<G4GenericPolycone::surface_element>;
700 G4double sarea = 0.;
701 G4int nrz = GetNumRZCorner();
702
703 // set lateral surface elements
704 G4double dphi = GetEndPhi() - GetStartPhi();
705 G4int ia = nrz - 1;
706 for (G4int ib=0; ib<nrz; ++ib)
707 {
711 selem.i0 = ia;
712 selem.i1 = ib;
713 selem.i2 = -1;
714 ia = ib;
715 if (a.r == 0. && b.r == 0.) continue;
716 G4double h = std::sqrt((b.r - a.r)*(b.r - a.r) + (b.z - a.z)*(b.z - a.z));
717 sarea += 0.5*dphi*(b.r + a.r)*h;
718 selem.area = sarea;
719 fElements->push_back(selem);
720 }
721
722 // set elements for phi cuts
723 if (IsOpen())
724 {
725 G4TwoVectorList contourRZ;
726 std::vector<G4int> triangles;
727 for (G4int i=0; i<nrz; ++i)
728 {
729 G4PolyconeSideRZ corner = GetCorner(i);
730 contourRZ.push_back(G4TwoVector(corner.r, corner.z));
731 }
732 G4GeomTools::TriangulatePolygon(contourRZ, triangles);
733 G4int ntria = (G4int)triangles.size();
734 for (G4int i=0; i<ntria; i+=3)
735 {
737 selem.i0 = triangles[i];
738 selem.i1 = triangles[i+1];
739 selem.i2 = triangles[i+2];
740 G4PolyconeSideRZ a = GetCorner(selem.i0);
741 G4PolyconeSideRZ b = GetCorner(selem.i1);
742 G4PolyconeSideRZ c = GetCorner(selem.i2);
743 G4double stria =
744 std::abs(G4GeomTools::TriangleArea(a.r, a.z, b.r, b.z, c.r, c.z));
745 sarea += stria;
746 selem.area = sarea;
747 fElements->push_back(selem); // start phi
748 sarea += stria;
749 selem.area = sarea;
750 selem.i0 += nrz;
751 fElements->push_back(selem); // end phi
752 }
753 }
754}
755
756//////////////////////////////////////////////////////////////////////////
757//
758// Generate random point on surface
759
761{
762 // Set surface elements
763 if (!fElements)
764 {
765 G4AutoLock l(&surface_elementsMutex);
767 l.unlock();
768 }
769
770 // Select surface element
772 selem = fElements->back();
773 G4double select = selem.area*G4QuickRand();
774 auto it = std::lower_bound(fElements->begin(), fElements->end(), select,
776 -> G4bool { return x.area < val; });
777
778 // Generate random point
779 G4double r = 0, z = 0, phi = 0;
780 G4double u = G4QuickRand();
781 G4double v = G4QuickRand();
782 G4int i0 = (*it).i0;
783 G4int i1 = (*it).i1;
784 G4int i2 = (*it).i2;
785 if (i2 < 0) // lateral surface
786 {
789 if (p1.r < p0.r)
790 {
791 p0 = GetCorner(i1);
792 p1 = GetCorner(i0);
793 }
794 if (p1.r - p0.r < kCarTolerance) // cylindrical surface
795 {
796 r = (p1.r - p0.r)*u + p0.r;
797 z = (p1.z - p0.z)*u + p0.z;
798 }
799 else // conical surface
800 {
801 r = std::sqrt(p1.r*p1.r*u + p0.r*p0.r*(1. - u));
802 z = p0.z + (p1.z - p0.z)*(r - p0.r)/(p1.r - p0.r);
803 }
804 phi = (GetEndPhi() - GetStartPhi())*v + GetStartPhi();
805 }
806 else // phi cut
807 {
808 G4int nrz = GetNumRZCorner();
809 phi = (i0 < nrz) ? GetStartPhi() : GetEndPhi();
810 if (i0 >= nrz) { i0 -= nrz; }
814 if (u + v > 1.) { u = 1. - u; v = 1. - v; }
815 r = (p1.r - p0.r)*u + (p2.r - p0.r)*v + p0.r;
816 z = (p1.z - p0.z)*u + (p2.z - p0.z)*v + p0.z;
817 }
818 return G4ThreeVector(r*std::cos(phi), r*std::sin(phi), z);
819}
820
821//////////////////////////////////////////////////////////////////////////
822//
823// CreatePolyhedron
824
826{
827 std::vector<G4TwoVector> rz(numCorner);
828 for (G4int i = 0; i < numCorner; ++i)
829 rz[i].set(corners[i].r, corners[i].z);
830 return new G4PolyhedronPcon(startPhi, endPhi - startPhi, rz);
831}
832
833#endif
std::vector< G4ThreeVector > G4ThreeVectorList
@ JustWarning
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
std::vector< G4TwoVector > G4TwoVectorList
Definition: G4GeomTools.hh:42
G4double G4QuickRand()
Definition: G4QuickRand.hh:34
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:85
std::mutex G4Mutex
Definition: G4Threading.hh:81
CLHEP::Hep3Vector G4ThreeVector
CLHEP::Hep2Vector G4TwoVector
Definition: G4TwoVector.hh:36
double G4double
Definition: G4Types.hh:83
long G4long
Definition: G4Types.hh:87
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
double x() const
double y() const
double z() const
double x() const
double y() const
void set(double x, double y, double z)
G4bool BoundingBoxVsVoxelLimits(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool ShouldMiss(const G4ThreeVector &p, const G4ThreeVector &v) const
G4bool MustBeOutside(const G4ThreeVector &p) const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4bool IsOpen() const
void SetSurfaceElements() const
G4PolyconeSideRZ * corners
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
G4EnclosingCylinder * enclosingCylinder
G4double GetStartPhi() const
void CopyStuff(const G4GenericPolycone &source)
G4GenericPolycone & operator=(const G4GenericPolycone &source)
G4double GetEndPhi() const
G4int GetNumRZCorner() const
G4GeometryType GetEntityType() const
G4VSolid * Clone() const
G4double GetCosEndPhi() const
G4double GetSinStartPhi() const
G4PolyconeSideRZ GetCorner(G4int index) const
G4ThreeVector GetPointOnSurface() const
G4double GetSinEndPhi() const
std::ostream & StreamInfo(std::ostream &os) const
void Create(G4double phiStart, G4double phiTotal, G4ReduciblePolygon *rz)
G4GenericPolycone(const G4String &name, G4double phiStart, G4double phiTotal, G4int numRZ, const G4double r[], const G4double z[])
G4Polyhedron * CreatePolyhedron() const
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
G4double GetCosStartPhi() const
std::vector< surface_element > * fElements
EInside Inside(const G4ThreeVector &p) const
static G4bool DiskExtent(G4double rmin, G4double rmax, G4double startPhi, G4double delPhi, G4TwoVector &pmin, G4TwoVector &pmax)
Definition: G4GeomTools.cc:390
static G4bool TriangulatePolygon(const G4TwoVectorList &polygon, G4TwoVectorList &result)
Definition: G4GeomTools.cc:193
static G4double TriangleArea(G4double Ax, G4double Ay, G4double Bx, G4double By, G4double Cx, G4double Cy)
Definition: G4GeomTools.cc:41
static G4double PolygonArea(const G4TwoVectorList &polygon)
Definition: G4GeomTools.cc:76
G4bool BisectedBy(G4double a1, G4double b1, G4double a2, G4double b2, G4double tolerance)
G4double Amin() const
G4bool RemoveDuplicateVertices(G4double tolerance)
G4int NumVertices() const
G4bool RemoveRedundantVertices(G4double tolerance)
G4bool CrossesItself(G4double tolerance)
G4VCSGfaceted & operator=(const G4VCSGfaceted &source)
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4double fCubicVolume
virtual EInside Inside(const G4ThreeVector &p) const
G4VCSGface ** faces
G4Polyhedron * fpPolyhedron
G4bool fRebuildPolyhedron
G4double fSurfaceArea
G4String GetName() const
void DumpInfo() const
G4double kCarTolerance
Definition: G4VSolid.hh:299
G4double GetMinExtent(const EAxis pAxis) const
G4double GetMaxExtent(const EAxis pAxis) const
EAxis
Definition: geomdefs.hh:54
EInside
Definition: geomdefs.hh:67
@ kOutside
Definition: geomdefs.hh:68
Definition: DoubConv.h:17