Geant4  10.02.p03
G4Polycone.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 //
27 // $Id: G4Polycone.cc 102297 2017-01-20 13:33:54Z gcosmo $
28 //
29 //
30 // --------------------------------------------------------------------
31 // GEANT 4 class source file
32 //
33 //
34 // G4Polycone.cc
35 //
36 // Implementation of a CSG polycone
37 //
38 // --------------------------------------------------------------------
39 
40 #include "G4Polycone.hh"
41 
42 #if !defined(G4GEOM_USE_UPOLYCONE)
43 
44 #include "G4PolyconeSide.hh"
45 #include "G4PolyPhiFace.hh"
46 
47 #include "Randomize.hh"
48 
49 #include "G4EnclosingCylinder.hh"
50 #include "G4ReduciblePolygon.hh"
51 #include "G4VPVParameterisation.hh"
52 
53 using namespace CLHEP;
54 
55 //
56 // Constructor (GEANT3 style parameters)
57 //
59  G4double phiStart,
60  G4double phiTotal,
61  G4int numZPlanes,
62  const G4double zPlane[],
63  const G4double rInner[],
64  const G4double rOuter[] )
65  : G4VCSGfaceted( name )
66 {
67  //
68  // Some historical ugliness
69  //
71 
72  original_parameters->Start_angle = phiStart;
74  original_parameters->Num_z_planes = numZPlanes;
75  original_parameters->Z_values = new G4double[numZPlanes];
76  original_parameters->Rmin = new G4double[numZPlanes];
77  original_parameters->Rmax = new G4double[numZPlanes];
78 
79  G4int i;
80  for (i=0; i<numZPlanes; i++)
81  {
82  if(rInner[i]>rOuter[i])
83  {
84  DumpInfo();
85  std::ostringstream message;
86  message << "Cannot create a Polycone with rInner > rOuter for the same Z"
87  << G4endl
88  << " rInner > rOuter for the same Z !" << G4endl
89  << " rMin[" << i << "] = " << rInner[i]
90  << " -- rMax[" << i << "] = " << rOuter[i];
91  G4Exception("G4Polycone::G4Polycone()", "GeomSolids0002",
92  FatalErrorInArgument, message);
93  }
94  if (( i < numZPlanes-1) && ( zPlane[i] == zPlane[i+1] ))
95  {
96  if( (rInner[i] > rOuter[i+1])
97  ||(rInner[i+1] > rOuter[i]) )
98  {
99  DumpInfo();
100  std::ostringstream message;
101  message << "Cannot create a Polycone with no contiguous segments."
102  << G4endl
103  << " Segments are not contiguous !" << G4endl
104  << " rMin[" << i << "] = " << rInner[i]
105  << " -- rMax[" << i+1 << "] = " << rOuter[i+1] << G4endl
106  << " rMin[" << i+1 << "] = " << rInner[i+1]
107  << " -- rMax[" << i << "] = " << rOuter[i];
108  G4Exception("G4Polycone::G4Polycone()", "GeomSolids0002",
109  FatalErrorInArgument, message);
110  }
111  }
112  original_parameters->Z_values[i] = zPlane[i];
113  original_parameters->Rmin[i] = rInner[i];
114  original_parameters->Rmax[i] = rOuter[i];
115  }
116 
117  //
118  // Build RZ polygon using special PCON/PGON GEANT3 constructor
119  //
120  G4ReduciblePolygon *rz =
121  new G4ReduciblePolygon( rInner, rOuter, zPlane, numZPlanes );
122 
123  //
124  // Do the real work
125  //
126  Create( phiStart, phiTotal, rz );
127 
128  delete rz;
129 }
130 
131 
132 //
133 // Constructor (generic parameters)
134 //
136  G4double phiStart,
137  G4double phiTotal,
138  G4int numRZ,
139  const G4double r[],
140  const G4double z[] )
141  : G4VCSGfaceted( name )
142 {
143 
144  G4ReduciblePolygon *rz = new G4ReduciblePolygon( r, z, numRZ );
145 
146  Create( phiStart, phiTotal, rz );
147 
148  // Set original_parameters struct for consistency
149  //
150 
151  G4bool convertible=SetOriginalParameters(rz);
152 
153  if(!convertible)
154  {
155  std::ostringstream message;
156  message << "Polycone " << GetName() << "cannot be converted" << G4endl
157  << "to Polycone with (Rmin,Rmaz,Z) parameters!";
158  G4Exception("G4Polycone::G4Polycone()", "GeomSolids0002",
159  FatalException, message, "Use G4GenericPolycone instead!");
160  }
161  else
162  {
163  G4cout << "INFO: Converting polycone " << GetName() << G4endl
164  << "to optimized polycone with (Rmin,Rmaz,Z) parameters !"
165  << G4endl;
166  }
167  delete rz;
168 }
169 
170 
171 // Create
172 //
173 // Generic create routine, called by each constructor after
174 // conversion of arguments
175 //
177  G4double phiTotal,
178  G4ReduciblePolygon *rz )
179 {
180  //
181  // Perform checks of rz values
182  //
183  if (rz->Amin() < 0.0)
184  {
185  std::ostringstream message;
186  message << "Illegal input parameters - " << GetName() << G4endl
187  << " All R values must be >= 0 !";
188  G4Exception("G4Polycone::Create()", "GeomSolids0002",
189  FatalErrorInArgument, message);
190  }
191 
192  G4double rzArea = rz->Area();
193  if (rzArea < -kCarTolerance)
194  {
195  rz->ReverseOrder();
196  }
197  else if (rzArea < kCarTolerance)
198  {
199  std::ostringstream message;
200  message << "Illegal input parameters - " << GetName() << G4endl
201  << " R/Z cross section is zero or near zero: " << rzArea;
202  G4Exception("G4Polycone::Create()", "GeomSolids0002",
203  FatalErrorInArgument, message);
204  }
205 
207  || (!rz->RemoveRedundantVertices( kCarTolerance )) )
208  {
209  std::ostringstream message;
210  message << "Illegal input parameters - " << GetName() << G4endl
211  << " Too few unique R/Z values !";
212  G4Exception("G4Polycone::Create()", "GeomSolids0002",
213  FatalErrorInArgument, message);
214  }
215 
216  if (rz->CrossesItself(1/kInfinity))
217  {
218  std::ostringstream message;
219  message << "Illegal input parameters - " << GetName() << G4endl
220  << " R/Z segments cross !";
221  G4Exception("G4Polycone::Create()", "GeomSolids0002",
222  FatalErrorInArgument, message);
223  }
224 
225  numCorner = rz->NumVertices();
226 
227  //
228  // Phi opening? Account for some possible roundoff, and interpret
229  // nonsense value as representing no phi opening
230  //
231  if (phiTotal <= 0 || phiTotal > twopi-1E-10)
232  {
233  phiIsOpen = false;
234  startPhi = 0;
235  endPhi = twopi;
236  }
237  else
238  {
239  phiIsOpen = true;
240 
241  //
242  // Convert phi into our convention
243  //
244  startPhi = phiStart;
245  while( startPhi < 0 ) // Loop checking, 13.08.2015, G.Cosmo
246  startPhi += twopi;
247 
248  endPhi = phiStart+phiTotal;
249  while( endPhi < startPhi ) // Loop checking, 13.08.2015, G.Cosmo
250  endPhi += twopi;
251  }
252 
253  //
254  // Allocate corner array.
255  //
257 
258  //
259  // Copy corners
260  //
261  G4ReduciblePolygonIterator iterRZ(rz);
262 
263  G4PolyconeSideRZ *next = corners;
264  iterRZ.Begin();
265  do // Loop checking, 13.08.2015, G.Cosmo
266  {
267  next->r = iterRZ.GetA();
268  next->z = iterRZ.GetB();
269  } while( ++next, iterRZ.Next() );
270 
271  //
272  // Allocate face pointer array
273  //
275  faces = new G4VCSGface*[numFace];
276 
277  //
278  // Construct conical faces
279  //
280  // But! Don't construct a face if both points are at zero radius!
281  //
282  G4PolyconeSideRZ *corner = corners,
283  *prev = corners + numCorner-1,
284  *nextNext;
285  G4VCSGface **face = faces;
286  do // Loop checking, 13.08.2015, G.Cosmo
287  {
288  next = corner+1;
289  if (next >= corners+numCorner) next = corners;
290  nextNext = next+1;
291  if (nextNext >= corners+numCorner) nextNext = corners;
292 
293  if (corner->r < 1/kInfinity && next->r < 1/kInfinity) continue;
294 
295  //
296  // We must decide here if we can dare declare one of our faces
297  // as having a "valid" normal (i.e. allBehind = true). This
298  // is never possible if the face faces "inward" in r.
299  //
300  G4bool allBehind;
301  if (corner->z > next->z)
302  {
303  allBehind = false;
304  }
305  else
306  {
307  //
308  // Otherwise, it is only true if the line passing
309  // through the two points of the segment do not
310  // split the r/z cross section
311  //
312  allBehind = !rz->BisectedBy( corner->r, corner->z,
313  next->r, next->z, kCarTolerance );
314  }
315 
316  *face++ = new G4PolyconeSide( prev, corner, next, nextNext,
317  startPhi, endPhi-startPhi, phiIsOpen, allBehind );
318  } while( prev=corner, corner=next, corner > corners );
319 
320  if (phiIsOpen)
321  {
322  //
323  // Construct phi open edges
324  //
325  *face++ = new G4PolyPhiFace( rz, startPhi, 0, endPhi );
326  *face++ = new G4PolyPhiFace( rz, endPhi, 0, startPhi );
327  }
328 
329  //
330  // We might have dropped a face or two: recalculate numFace
331  //
332  numFace = face-faces;
333 
334  //
335  // Make enclosingCylinder
336  //
338  new G4EnclosingCylinder( rz, phiIsOpen, phiStart, phiTotal );
339 }
340 
341 
342 //
343 // Fake default constructor - sets only member data and allocates memory
344 // for usage restricted to object persistency.
345 //
347  : G4VCSGfaceted(a), startPhi(0.), endPhi(0.), phiIsOpen(false),
350 {
351 }
352 
353 
354 //
355 // Destructor
356 //
358 {
359  delete [] corners;
360  delete original_parameters;
361  delete enclosingCylinder;
362 }
363 
364 
365 //
366 // Copy constructor
367 //
369  : G4VCSGfaceted( source )
370 {
371  CopyStuff( source );
372 }
373 
374 
375 //
376 // Assignment operator
377 //
379 {
380  if (this == &source) return *this;
381 
382  G4VCSGfaceted::operator=( source );
383 
384  delete [] corners;
386 
387  delete enclosingCylinder;
388 
389  CopyStuff( source );
390 
391  return *this;
392 }
393 
394 
395 //
396 // CopyStuff
397 //
398 void G4Polycone::CopyStuff( const G4Polycone &source )
399 {
400  //
401  // Simple stuff
402  //
403  startPhi = source.startPhi;
404  endPhi = source.endPhi;
405  phiIsOpen = source.phiIsOpen;
406  numCorner = source.numCorner;
407 
408  //
409  // The corner array
410  //
412 
413  G4PolyconeSideRZ *corn = corners,
414  *sourceCorn = source.corners;
415  do // Loop checking, 13.08.2015, G.Cosmo
416  {
417  *corn = *sourceCorn;
418  } while( ++sourceCorn, ++corn < corners+numCorner );
419 
420  //
421  // Original parameters
422  //
423  if (source.original_parameters)
424  {
427  }
428 
429  //
430  // Enclosing cylinder
431  //
433 
434  fRebuildPolyhedron = false;
435  fpPolyhedron = 0;
436 }
437 
438 
439 //
440 // Reset
441 //
443 {
444  //
445  // Clear old setup
446  //
448  delete [] corners;
449  delete enclosingCylinder;
450 
451  //
452  // Rebuild polycone
453  //
454  G4ReduciblePolygon *rz =
461  delete rz;
462 
463  return 0;
464 }
465 
466 
467 //
468 // Inside
469 //
470 // This is an override of G4VCSGfaceted::Inside, created in order
471 // to speed things up by first checking with G4EnclosingCylinder.
472 //
474 {
475  //
476  // Quick test
477  //
478  if (enclosingCylinder->MustBeOutside(p)) return kOutside;
479 
480  //
481  // Long answer
482  //
483  return G4VCSGfaceted::Inside(p);
484 }
485 
486 
487 //
488 // DistanceToIn
489 //
490 // This is an override of G4VCSGfaceted::Inside, created in order
491 // to speed things up by first checking with G4EnclosingCylinder.
492 //
494  const G4ThreeVector &v ) const
495 {
496  //
497  // Quick test
498  //
499  if (enclosingCylinder->ShouldMiss(p,v))
500  return kInfinity;
501 
502  //
503  // Long answer
504  //
505  return G4VCSGfaceted::DistanceToIn( p, v );
506 }
507 
508 
509 //
510 // DistanceToIn
511 //
513 {
514  return G4VCSGfaceted::DistanceToIn(p);
515 }
516 
517 
518 //
519 // ComputeDimensions
520 //
522  const G4int n,
523  const G4VPhysicalVolume* pRep )
524 {
525  p->ComputeDimensions(*this,n,pRep);
526 }
527 
528 //
529 // GetEntityType
530 //
532 {
533  return G4String("G4Polycone");
534 }
535 
536 //
537 // Make a clone of the object
538 //
540 {
541  return new G4Polycone(*this);
542 }
543 
544 //
545 // Stream object contents to an output stream
546 //
547 std::ostream& G4Polycone::StreamInfo( std::ostream& os ) const
548 {
549  G4int oldprc = os.precision(16);
550  os << "-----------------------------------------------------------\n"
551  << " *** Dump for solid - " << GetName() << " ***\n"
552  << " ===================================================\n"
553  << " Solid type: G4Polycone\n"
554  << " Parameters: \n"
555  << " starting phi angle : " << startPhi/degree << " degrees \n"
556  << " ending phi angle : " << endPhi/degree << " degrees \n";
557  G4int i=0;
558 
560  os << " number of Z planes: " << numPlanes << "\n"
561  << " Z values: \n";
562  for (i=0; i<numPlanes; i++)
563  {
564  os << " Z plane " << i << ": "
565  << original_parameters->Z_values[i] << "\n";
566  }
567  os << " Tangent distances to inner surface (Rmin): \n";
568  for (i=0; i<numPlanes; i++)
569  {
570  os << " Z plane " << i << ": "
571  << original_parameters->Rmin[i] << "\n";
572  }
573  os << " Tangent distances to outer surface (Rmax): \n";
574  for (i=0; i<numPlanes; i++)
575  {
576  os << " Z plane " << i << ": "
577  << original_parameters->Rmax[i] << "\n";
578  }
579 
580  os << " number of RZ points: " << numCorner << "\n"
581  << " RZ values (corners): \n";
582  for (i=0; i<numCorner; i++)
583  {
584  os << " "
585  << corners[i].r << ", " << corners[i].z << "\n";
586  }
587  os << "-----------------------------------------------------------\n";
588  os.precision(oldprc);
589 
590  return os;
591 }
592 
593 
594 //
595 // GetPointOnCone
596 //
597 // Auxiliary method for Get Point On Surface
598 //
600  G4double fRmin2, G4double fRmax2,
601  G4double zOne, G4double zTwo,
602  G4double& totArea) const
603 {
604  // declare working variables
605  //
606  G4double Aone, Atwo, Afive, phi, zRand, fDPhi, cosu, sinu;
607  G4double rRand1, rmin, rmax, chose, rone, rtwo, qone, qtwo;
608  G4double fDz=(zTwo-zOne)/2., afDz=std::fabs(fDz);
609  G4ThreeVector point, offset=G4ThreeVector(0.,0.,0.5*(zTwo+zOne));
610  fDPhi = endPhi - startPhi;
611  rone = (fRmax1-fRmax2)/(2.*fDz);
612  rtwo = (fRmin1-fRmin2)/(2.*fDz);
613  if(fRmax1==fRmax2){qone=0.;}
614  else{
615  qone = fDz*(fRmax1+fRmax2)/(fRmax1-fRmax2);
616  }
617  if(fRmin1==fRmin2){qtwo=0.;}
618  else{
619  qtwo = fDz*(fRmin1+fRmin2)/(fRmin1-fRmin2);
620  }
621  Aone = 0.5*fDPhi*(fRmax2 + fRmax1)*(sqr(fRmin1-fRmin2)+sqr(zTwo-zOne));
622  Atwo = 0.5*fDPhi*(fRmin2 + fRmin1)*(sqr(fRmax1-fRmax2)+sqr(zTwo-zOne));
623  Afive = fDz*(fRmax1-fRmin1+fRmax2-fRmin2);
624  totArea = Aone+Atwo+2.*Afive;
625 
626  phi = G4RandFlat::shoot(startPhi,endPhi);
627  cosu = std::cos(phi);
628  sinu = std::sin(phi);
629 
630 
631  if( (startPhi == 0) && (endPhi == twopi) ) { Afive = 0; }
632  chose = G4RandFlat::shoot(0.,Aone+Atwo+2.*Afive);
633  if( (chose >= 0) && (chose < Aone) )
634  {
635  if(fRmax1 != fRmax2)
636  {
637  zRand = G4RandFlat::shoot(-1.*afDz,afDz);
638  point = G4ThreeVector (rone*cosu*(qone-zRand),
639  rone*sinu*(qone-zRand), zRand);
640  }
641  else
642  {
643  point = G4ThreeVector(fRmax1*cosu, fRmax1*sinu,
644  G4RandFlat::shoot(-1.*afDz,afDz));
645 
646  }
647  }
648  else if(chose >= Aone && chose < Aone + Atwo)
649  {
650  if(fRmin1 != fRmin2)
651  {
652  zRand = G4RandFlat::shoot(-1.*afDz,afDz);
653  point = G4ThreeVector (rtwo*cosu*(qtwo-zRand),
654  rtwo*sinu*(qtwo-zRand), zRand);
655 
656  }
657  else
658  {
659  point = G4ThreeVector(fRmin1*cosu, fRmin1*sinu,
660  G4RandFlat::shoot(-1.*afDz,afDz));
661  }
662  }
663  else if( (chose >= Aone + Atwo + Afive) && (chose < Aone + Atwo + 2.*Afive) )
664  {
665  zRand = G4RandFlat::shoot(-1.*afDz,afDz);
666  rmin = fRmin2-((zRand-fDz)/(2.*fDz))*(fRmin1-fRmin2);
667  rmax = fRmax2-((zRand-fDz)/(2.*fDz))*(fRmax1-fRmax2);
668  rRand1 = std::sqrt(G4RandFlat::shoot()*(sqr(rmax)-sqr(rmin))+sqr(rmin));
669  point = G4ThreeVector (rRand1*std::cos(startPhi),
670  rRand1*std::sin(startPhi), zRand);
671  }
672  else
673  {
674  zRand = G4RandFlat::shoot(-1.*afDz,afDz);
675  rmin = fRmin2-((zRand-fDz)/(2.*fDz))*(fRmin1-fRmin2);
676  rmax = fRmax2-((zRand-fDz)/(2.*fDz))*(fRmax1-fRmax2);
677  rRand1 = std::sqrt(G4RandFlat::shoot()*(sqr(rmax)-sqr(rmin))+sqr(rmin));
678  point = G4ThreeVector (rRand1*std::cos(endPhi),
679  rRand1*std::sin(endPhi), zRand);
680 
681  }
682 
683  return point+offset;
684 }
685 
686 
687 //
688 // GetPointOnTubs
689 //
690 // Auxiliary method for GetPoint On Surface
691 //
693  G4double zOne, G4double zTwo,
694  G4double& totArea) const
695 {
696  G4double xRand,yRand,zRand,phi,cosphi,sinphi,chose,
697  aOne,aTwo,aFou,rRand,fDz,fSPhi,fDPhi;
698  fDz = std::fabs(0.5*(zTwo-zOne));
699  fSPhi = startPhi;
700  fDPhi = endPhi-startPhi;
701 
702  aOne = 2.*fDz*fDPhi*fRMax;
703  aTwo = 2.*fDz*fDPhi*fRMin;
704  aFou = 2.*fDz*(fRMax-fRMin);
705  totArea = aOne+aTwo+2.*aFou;
706  phi = G4RandFlat::shoot(startPhi,endPhi);
707  cosphi = std::cos(phi);
708  sinphi = std::sin(phi);
709  rRand = fRMin + (fRMax-fRMin)*std::sqrt(G4RandFlat::shoot());
710 
711  if(startPhi == 0 && endPhi == twopi)
712  aFou = 0;
713 
714  chose = G4RandFlat::shoot(0.,aOne+aTwo+2.*aFou);
715  if( (chose >= 0) && (chose < aOne) )
716  {
717  xRand = fRMax*cosphi;
718  yRand = fRMax*sinphi;
719  zRand = G4RandFlat::shoot(-1.*fDz,fDz);
720  return G4ThreeVector(xRand, yRand, zRand+0.5*(zTwo+zOne));
721  }
722  else if( (chose >= aOne) && (chose < aOne + aTwo) )
723  {
724  xRand = fRMin*cosphi;
725  yRand = fRMin*sinphi;
726  zRand = G4RandFlat::shoot(-1.*fDz,fDz);
727  return G4ThreeVector(xRand, yRand, zRand+0.5*(zTwo+zOne));
728  }
729  else if( (chose >= aOne+aTwo) && (chose <aOne+aTwo+aFou) )
730  {
731  xRand = rRand*std::cos(fSPhi+fDPhi);
732  yRand = rRand*std::sin(fSPhi+fDPhi);
733  zRand = G4RandFlat::shoot(-1.*fDz,fDz);
734  return G4ThreeVector(xRand, yRand, zRand+0.5*(zTwo+zOne));
735  }
736 
737  // else
738 
739  xRand = rRand*std::cos(fSPhi+fDPhi);
740  yRand = rRand*std::sin(fSPhi+fDPhi);
741  zRand = G4RandFlat::shoot(-1.*fDz,fDz);
742  return G4ThreeVector(xRand, yRand, zRand+0.5*(zTwo+zOne));
743 }
744 
745 
746 //
747 // GetPointOnRing
748 //
749 // Auxiliary method for GetPoint On Surface
750 //
752  G4double fRMin2,G4double fRMax2,
753  G4double zOne) const
754 {
755  G4double xRand,yRand,phi,cosphi,sinphi,rRand1,rRand2,A1,Atot,rCh;
757  cosphi = std::cos(phi);
758  sinphi = std::sin(phi);
759 
760  if(fRMin1==fRMin2)
761  {
762  rRand1 = fRMin1; A1=0.;
763  }
764  else
765  {
766  rRand1 = G4RandFlat::shoot(fRMin1,fRMin2);
767  A1=std::fabs(fRMin2*fRMin2-fRMin1*fRMin1);
768  }
769  if(fRMax1==fRMax2)
770  {
771  rRand2=fRMax1; Atot=A1;
772  }
773  else
774  {
775  rRand2 = G4RandFlat::shoot(fRMax1,fRMax2);
776  Atot = A1+std::fabs(fRMax2*fRMax2-fRMax1*fRMax1);
777  }
778  rCh = G4RandFlat::shoot(0.,Atot);
779 
780  if(rCh>A1) { rRand1=rRand2; }
781 
782  xRand = rRand1*cosphi;
783  yRand = rRand1*sinphi;
784 
785  return G4ThreeVector(xRand, yRand, zOne);
786 }
787 
788 
789 //
790 // GetPointOnCut
791 //
792 // Auxiliary method for Get Point On Surface
793 //
795  G4double fRMin2, G4double fRMax2,
796  G4double zOne, G4double zTwo,
797  G4double& totArea) const
798 { if(zOne==zTwo)
799  {
800  return GetPointOnRing(fRMin1, fRMax1,fRMin2,fRMax2,zOne);
801  }
802  if( (fRMin1 == fRMin2) && (fRMax1 == fRMax2) )
803  {
804  return GetPointOnTubs(fRMin1, fRMax1,zOne,zTwo,totArea);
805  }
806  return GetPointOnCone(fRMin1,fRMax1,fRMin2,fRMax2,zOne,zTwo,totArea);
807 }
808 
809 
810 //
811 // GetPointOnSurface
812 //
814 {
815  G4double Area=0,totArea=0,Achose1=0,Achose2=0,phi,cosphi,sinphi,rRand;
816  G4int i=0;
818 
820  cosphi = std::cos(phi);
821  sinphi = std::sin(phi);
822 
823  rRand = original_parameters->Rmin[0] +
825  * std::sqrt(G4RandFlat::shoot()) );
826 
827  std::vector<G4double> areas; // (numPlanes+1);
828  std::vector<G4ThreeVector> points; // (numPlanes-1);
829 
830  areas.push_back(pi*(sqr(original_parameters->Rmax[0])
831  -sqr(original_parameters->Rmin[0])));
832 
833  for(i=0; i<numPlanes-1; i++)
834  {
836  * std::sqrt(sqr(original_parameters->Rmin[i]
837  -original_parameters->Rmin[i+1])+
840 
842  * std::sqrt(sqr(original_parameters->Rmax[i]
843  -original_parameters->Rmax[i+1])+
846 
847  Area *= 0.5*(endPhi-startPhi);
848 
849  if(startPhi==0.&& endPhi == twopi)
850  {
851  Area += std::fabs(original_parameters->Z_values[i+1]
856  -original_parameters->Rmin[i+1]);
857  }
858  areas.push_back(Area);
859  totArea += Area;
860  }
861 
862  areas.push_back(pi*(sqr(original_parameters->Rmax[numPlanes-1])-
863  sqr(original_parameters->Rmin[numPlanes-1])));
864 
865  totArea += (areas[0]+areas[numPlanes]);
866  G4double chose = G4RandFlat::shoot(0.,totArea);
867 
868  if( (chose>=0.) && (chose<areas[0]) )
869  {
870  return G4ThreeVector(rRand*cosphi, rRand*sinphi,
872  }
873 
874  for (i=0; i<numPlanes-1; i++)
875  {
876  Achose1 += areas[i];
877  Achose2 = (Achose1+areas[i+1]);
878  if(chose>=Achose1 && chose<Achose2)
879  {
885  original_parameters->Z_values[i+1], Area);
886  }
887  }
888 
889  rRand = original_parameters->Rmin[numPlanes-1] +
890  ( (original_parameters->Rmax[numPlanes-1]-original_parameters->Rmin[numPlanes-1])
891  * std::sqrt(G4RandFlat::shoot()) );
892 
893  return G4ThreeVector(rRand*cosphi,rRand*sinphi,
894  original_parameters->Z_values[numPlanes-1]);
895 
896 }
897 
898 //
899 // CreatePolyhedron
900 //
902 {
903  //
904  // This has to be fixed in visualization. Fake it for the moment.
905  //
906 
913 }
914 
916 {
917  G4int numPlanes = (G4int)numCorner;
918  G4bool isConvertible=true;
919  G4double Zmax=rz->Bmax();
920  rz->StartWithZMin();
921 
922  // Prepare vectors for storage
923  //
924  std::vector<G4double> Z;
925  std::vector<G4double> Rmin;
926  std::vector<G4double> Rmax;
927 
928  G4int countPlanes=1;
929  G4int icurr=0;
930  G4int icurl=0;
931 
932  // first plane Z=Z[0]
933  //
934  Z.push_back(corners[0].z);
935  G4double Zprev=Z[0];
936  if (Zprev == corners[1].z)
937  {
938  Rmin.push_back(corners[0].r);
939  Rmax.push_back (corners[1].r);icurr=1;
940  }
941  else if (Zprev == corners[numPlanes-1].z)
942  {
943  Rmin.push_back(corners[numPlanes-1].r);
944  Rmax.push_back (corners[0].r);
945  icurl=numPlanes-1;
946  }
947  else
948  {
949  Rmin.push_back(corners[0].r);
950  Rmax.push_back (corners[0].r);
951  }
952 
953  // next planes until last
954  //
955  G4int inextr=0, inextl=0;
956  for (G4int i=0; i < numPlanes-2; i++)
957  {
958  inextr=1+icurr;
959  inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
960 
961  if((corners[inextr].z >= Zmax) & (corners[inextl].z >= Zmax)) { break; }
962 
963  G4double Zleft = corners[inextl].z;
964  G4double Zright = corners[inextr].z;
965  if(Zright > Zleft) // Next plane will be Zleft
966  {
967  Z.push_back(Zleft);
968  countPlanes++;
969  G4double difZr=corners[inextr].z - corners[icurr].z;
970  G4double difZl=corners[inextl].z - corners[icurl].z;
971 
972  if(std::fabs(difZl) < kCarTolerance)
973  {
974  if(std::fabs(difZr) < kCarTolerance)
975  {
976  Rmin.push_back(corners[inextl].r);
977  Rmax.push_back(corners[icurr].r);
978  }
979  else
980  {
981  Rmin.push_back(corners[inextl].r);
982  Rmax.push_back(corners[icurr].r + (Zleft-corners[icurr].z)/difZr
983  *(corners[inextr].r - corners[icurr].r));
984  }
985  }
986  else if (difZl >= kCarTolerance)
987  {
988  if(std::fabs(difZr) < kCarTolerance)
989  {
990  Rmin.push_back(corners[icurl].r);
991  Rmax.push_back(corners[icurr].r);
992  }
993  else
994  {
995  Rmin.push_back(corners[icurl].r);
996  Rmax.push_back(corners[icurr].r + (Zleft-corners[icurr].z)/difZr
997  *(corners[inextr].r - corners[icurr].r));
998  }
999  }
1000  else
1001  {
1002  isConvertible=false; break;
1003  }
1004  icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1005  }
1006  else if(std::fabs(Zright-Zleft)<kCarTolerance) // Zright=Zleft
1007  {
1008  Z.push_back(Zleft);
1009  countPlanes++;
1010  icurr++;
1011 
1012  icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1013 
1014  Rmin.push_back(corners[inextl].r);
1015  Rmax.push_back(corners[inextr].r);
1016  }
1017  else // Zright<Zleft
1018  {
1019  Z.push_back(Zright);
1020  countPlanes++;
1021 
1022  G4double difZr=corners[inextr].z - corners[icurr].z;
1023  G4double difZl=corners[inextl].z - corners[icurl].z;
1024  if(std::fabs(difZr) < kCarTolerance)
1025  {
1026  if(std::fabs(difZl) < kCarTolerance)
1027  {
1028  Rmax.push_back(corners[inextr].r);
1029  Rmin.push_back(corners[icurr].r);
1030  }
1031  else
1032  {
1033  Rmin.push_back(corners[icurl].r + (Zright-corners[icurl].z)/difZl
1034  *(corners[inextl].r - corners[icurl].r));
1035  Rmax.push_back(corners[inextr].r);
1036  }
1037  icurr++;
1038  } // plate
1039  else if (difZr >= kCarTolerance)
1040  {
1041  if(std::fabs(difZl) < kCarTolerance)
1042  {
1043  Rmax.push_back(corners[inextr].r);
1044  Rmin.push_back (corners[icurr].r);
1045  }
1046  else
1047  {
1048  Rmax.push_back(corners[inextr].r);
1049  Rmin.push_back (corners[icurl].r+(Zright-corners[icurl].z)/difZl
1050  * (corners[inextl].r - corners[icurl].r));
1051  }
1052  icurr++;
1053  }
1054  else
1055  {
1056  isConvertible=false; break;
1057  }
1058  }
1059  } // end for loop
1060 
1061  // last plane Z=Zmax
1062  //
1063  Z.push_back(Zmax);
1064  countPlanes++;
1065  inextr=1+icurr;
1066  inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1067 
1068  Rmax.push_back(corners[inextr].r);
1069  Rmin.push_back(corners[inextl].r);
1070 
1071  // Set original parameters Rmin,Rmax,Z
1072  //
1073  if(isConvertible)
1074  {
1076  original_parameters->Z_values = new G4double[countPlanes];
1077  original_parameters->Rmin = new G4double[countPlanes];
1078  original_parameters->Rmax = new G4double[countPlanes];
1079 
1080  for(G4int j=0; j < countPlanes; j++)
1081  {
1082  original_parameters->Z_values[j] = Z[j];
1083  original_parameters->Rmax[j] = Rmax[j];
1084  original_parameters->Rmin[j] = Rmin[j];
1085  }
1088  original_parameters->Num_z_planes = countPlanes;
1089 
1090  }
1091  else // Set parameters(r,z) with Rmin==0 as convention
1092  {
1093 #ifdef G4SPECSDEBUG
1094  std::ostringstream message;
1095  message << "Polycone " << GetName() << G4endl
1096  << "cannot be converted to Polycone with (Rmin,Rmaz,Z) parameters!";
1097  G4Exception("G4Polycone::SetOriginalParameters()", "GeomSolids0002",
1098  JustWarning, message);
1099 #endif
1101  original_parameters->Z_values = new G4double[numPlanes];
1102  original_parameters->Rmin = new G4double[numPlanes];
1103  original_parameters->Rmax = new G4double[numPlanes];
1104 
1105  for(G4int j=0; j < numPlanes; j++)
1106  {
1108  original_parameters->Rmax[j] = corners[j].r;
1109  original_parameters->Rmin[j] = 0.0;
1110  }
1113  original_parameters->Num_z_planes = numPlanes;
1114  }
1115  return isConvertible;
1116 }
1117 
1118 #endif
G4Polyhedron * CreatePolyhedron() const
Definition: G4Polycone.cc:901
G4bool CrossesItself(G4double tolerance)
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
Definition: G4Polycone.cc:493
ThreeVector shoot(const G4int Ap, const G4int Af)
G4VCSGfaceted & operator=(const G4VCSGfaceted &source)
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
Definition: G4Polycone.cc:521
G4bool fRebuildPolyhedron
G4Polyhedron * fpPolyhedron
static const G4double kInfinity
Definition: geomdefs.hh:42
CLHEP::Hep3Vector G4ThreeVector
G4double endPhi
Definition: G4Polycone.hh:184
G4bool ShouldMiss(const G4ThreeVector &p, const G4ThreeVector &v) const
G4String name
Definition: TRTMaterials.hh:40
G4ThreeVector GetPointOnRing(G4double fRMin, G4double fRMax, G4double fRMin2, G4double fRMax2, G4double zOne) const
Definition: G4Polycone.cc:751
G4PolyconeSideRZ * corners
Definition: G4Polycone.hh:187
int G4int
Definition: G4Types.hh:78
G4String GetName() const
G4double Bmax() const
void DumpInfo() const
G4bool RemoveDuplicateVertices(G4double tolerance)
virtual EInside Inside(const G4ThreeVector &p) const
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4bool RemoveRedundantVertices(G4double tolerance)
Char_t n[5]
G4Polycone & operator=(const G4Polycone &source)
Definition: G4Polycone.cc:378
G4GLOB_DLL std::ostream G4cout
G4bool MustBeOutside(const G4ThreeVector &p) const
Float_t Z
G4double startPhi
Definition: G4Polycone.hh:183
bool G4bool
Definition: G4Types.hh:79
static const double twopi
Definition: G4SIunits.hh:75
G4VSolid * Clone() const
Definition: G4Polycone.cc:539
virtual ~G4Polycone()
Definition: G4Polycone.cc:357
void SetOriginalParameters(G4PolyconeHistorical *pars)
G4ThreeVector GetPointOnCut(G4double fRMin1, G4double fRMax1, G4double fRMin2, G4double fRMax2, G4double zOne, G4double zTwo, G4double &totArea) const
Definition: G4Polycone.cc:794
G4ThreeVector GetPointOnSurface() const
Definition: G4Polycone.cc:813
G4GeometryType GetEntityType() const
Definition: G4Polycone.cc:531
G4bool Reset()
Definition: G4Polycone.cc:442
G4VCSGface ** faces
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
EInside Inside(const G4ThreeVector &p) const
Definition: G4Polycone.cc:473
void CopyStuff(const G4Polycone &source)
Definition: G4Polycone.cc:398
static const double pi
Definition: G4SIunits.hh:74
EInside
Definition: geomdefs.hh:58
G4EnclosingCylinder * enclosingCylinder
Definition: G4Polycone.hh:192
Definition: DoubConv.h:18
G4double Amin() const
G4int NumVertices() const
static const double degree
Definition: G4SIunits.hh:143
std::ostream & StreamInfo(std::ostream &os) const
Definition: G4Polycone.cc:547
G4bool BisectedBy(G4double a1, G4double b1, G4double a2, G4double b2, G4double tolerance)
int Zmax
G4ThreeVector GetPointOnTubs(G4double fRMin, G4double fRMax, G4double zOne, G4double zTwo, G4double &totArea) const
Definition: G4Polycone.cc:692
#define G4endl
Definition: G4ios.hh:61
G4ThreeVector GetPointOnCone(G4double fRmin1, G4double fRmax1, G4double fRmin2, G4double fRmax2, G4double zOne, G4double zTwo, G4double &totArea) const
Definition: G4Polycone.cc:599
G4double kCarTolerance
Definition: G4VSolid.hh:304
G4Polycone(const G4String &name, G4double phiStart, G4double phiTotal, G4int numZPlanes, const G4double zPlane[], const G4double rInner[], const G4double rOuter[])
Definition: G4Polycone.cc:58
G4bool phiIsOpen
Definition: G4Polycone.hh:185
G4int numCorner
Definition: G4Polycone.hh:186
void Create(G4double phiStart, G4double phiTotal, G4ReduciblePolygon *rz)
Definition: G4Polycone.cc:176
T sqr(const T &x)
Definition: templates.hh:145
double G4double
Definition: G4Types.hh:76
G4PolyconeHistorical * original_parameters
Definition: G4Polycone.hh:188
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const