Geant4  10.00.p02
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 81641 2014-06-04 09:11:38Z 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  rz->ReverseOrder();
195 
196  else if (rzArea < -kCarTolerance)
197  {
198  std::ostringstream message;
199  message << "Illegal input parameters - " << GetName() << G4endl
200  << " R/Z cross section is zero or near zero: " << rzArea;
201  G4Exception("G4Polycone::Create()", "GeomSolids0002",
202  FatalErrorInArgument, message);
203  }
204 
206  || (!rz->RemoveRedundantVertices( kCarTolerance )) )
207  {
208  std::ostringstream message;
209  message << "Illegal input parameters - " << GetName() << G4endl
210  << " Too few unique R/Z values !";
211  G4Exception("G4Polycone::Create()", "GeomSolids0002",
212  FatalErrorInArgument, message);
213  }
214 
215  if (rz->CrossesItself(1/kInfinity))
216  {
217  std::ostringstream message;
218  message << "Illegal input parameters - " << GetName() << G4endl
219  << " R/Z segments cross !";
220  G4Exception("G4Polycone::Create()", "GeomSolids0002",
221  FatalErrorInArgument, message);
222  }
223 
224  numCorner = rz->NumVertices();
225 
226  //
227  // Phi opening? Account for some possible roundoff, and interpret
228  // nonsense value as representing no phi opening
229  //
230  if (phiTotal <= 0 || phiTotal > twopi-1E-10)
231  {
232  phiIsOpen = false;
233  startPhi = 0;
234  endPhi = twopi;
235  }
236  else
237  {
238  phiIsOpen = true;
239 
240  //
241  // Convert phi into our convention
242  //
243  startPhi = phiStart;
244  while( startPhi < 0 ) startPhi += twopi;
245 
246  endPhi = phiStart+phiTotal;
247  while( endPhi < startPhi ) endPhi += twopi;
248  }
249 
250  //
251  // Allocate corner array.
252  //
254 
255  //
256  // Copy corners
257  //
258  G4ReduciblePolygonIterator iterRZ(rz);
259 
260  G4PolyconeSideRZ *next = corners;
261  iterRZ.Begin();
262  do
263  {
264  next->r = iterRZ.GetA();
265  next->z = iterRZ.GetB();
266  } while( ++next, iterRZ.Next() );
267 
268  //
269  // Allocate face pointer array
270  //
272  faces = new G4VCSGface*[numFace];
273 
274  //
275  // Construct conical faces
276  //
277  // But! Don't construct a face if both points are at zero radius!
278  //
279  G4PolyconeSideRZ *corner = corners,
280  *prev = corners + numCorner-1,
281  *nextNext;
282  G4VCSGface **face = faces;
283  do
284  {
285  next = corner+1;
286  if (next >= corners+numCorner) next = corners;
287  nextNext = next+1;
288  if (nextNext >= corners+numCorner) nextNext = corners;
289 
290  if (corner->r < 1/kInfinity && next->r < 1/kInfinity) continue;
291 
292  //
293  // We must decide here if we can dare declare one of our faces
294  // as having a "valid" normal (i.e. allBehind = true). This
295  // is never possible if the face faces "inward" in r.
296  //
297  G4bool allBehind;
298  if (corner->z > next->z)
299  {
300  allBehind = false;
301  }
302  else
303  {
304  //
305  // Otherwise, it is only true if the line passing
306  // through the two points of the segment do not
307  // split the r/z cross section
308  //
309  allBehind = !rz->BisectedBy( corner->r, corner->z,
310  next->r, next->z, kCarTolerance );
311  }
312 
313  *face++ = new G4PolyconeSide( prev, corner, next, nextNext,
314  startPhi, endPhi-startPhi, phiIsOpen, allBehind );
315  } while( prev=corner, corner=next, corner > corners );
316 
317  if (phiIsOpen)
318  {
319  //
320  // Construct phi open edges
321  //
322  *face++ = new G4PolyPhiFace( rz, startPhi, 0, endPhi );
323  *face++ = new G4PolyPhiFace( rz, endPhi, 0, startPhi );
324  }
325 
326  //
327  // We might have dropped a face or two: recalculate numFace
328  //
329  numFace = face-faces;
330 
331  //
332  // Make enclosingCylinder
333  //
335  new G4EnclosingCylinder( rz, phiIsOpen, phiStart, phiTotal );
336 }
337 
338 
339 //
340 // Fake default constructor - sets only member data and allocates memory
341 // for usage restricted to object persistency.
342 //
344  : G4VCSGfaceted(a), startPhi(0.), endPhi(0.), phiIsOpen(false),
345  numCorner(0), corners(0),original_parameters(0),
346  enclosingCylinder(0)
347 {
348 }
349 
350 
351 //
352 // Destructor
353 //
355 {
356  delete [] corners;
357  delete original_parameters;
358  delete enclosingCylinder;
359 }
360 
361 
362 //
363 // Copy constructor
364 //
366  : G4VCSGfaceted( source )
367 {
368  CopyStuff( source );
369 }
370 
371 
372 //
373 // Assignment operator
374 //
376 {
377  if (this == &source) return *this;
378 
379  G4VCSGfaceted::operator=( source );
380 
381  delete [] corners;
383 
384  delete enclosingCylinder;
385 
386  CopyStuff( source );
387 
388  return *this;
389 }
390 
391 
392 //
393 // CopyStuff
394 //
395 void G4Polycone::CopyStuff( const G4Polycone &source )
396 {
397  //
398  // Simple stuff
399  //
400  startPhi = source.startPhi;
401  endPhi = source.endPhi;
402  phiIsOpen = source.phiIsOpen;
403  numCorner = source.numCorner;
404 
405  //
406  // The corner array
407  //
409 
410  G4PolyconeSideRZ *corn = corners,
411  *sourceCorn = source.corners;
412  do
413  {
414  *corn = *sourceCorn;
415  } while( ++sourceCorn, ++corn < corners+numCorner );
416 
417  //
418  // Original parameters
419  //
420  if (source.original_parameters)
421  {
424  }
425 
426  //
427  // Enclosing cylinder
428  //
430 
432 }
433 
434 
435 //
436 // Reset
437 //
439 {
440  //
441  // Clear old setup
442  //
444  delete [] corners;
445  delete enclosingCylinder;
446 
447  //
448  // Rebuild polycone
449  //
450  G4ReduciblePolygon *rz =
457  delete rz;
458 
459  return 0;
460 }
461 
462 
463 //
464 // Inside
465 //
466 // This is an override of G4VCSGfaceted::Inside, created in order
467 // to speed things up by first checking with G4EnclosingCylinder.
468 //
470 {
471  //
472  // Quick test
473  //
474  if (enclosingCylinder->MustBeOutside(p)) return kOutside;
475 
476  //
477  // Long answer
478  //
479  return G4VCSGfaceted::Inside(p);
480 }
481 
482 
483 //
484 // DistanceToIn
485 //
486 // This is an override of G4VCSGfaceted::Inside, created in order
487 // to speed things up by first checking with G4EnclosingCylinder.
488 //
490  const G4ThreeVector &v ) const
491 {
492  //
493  // Quick test
494  //
495  if (enclosingCylinder->ShouldMiss(p,v))
496  return kInfinity;
497 
498  //
499  // Long answer
500  //
501  return G4VCSGfaceted::DistanceToIn( p, v );
502 }
503 
504 
505 //
506 // DistanceToIn
507 //
509 {
510  return G4VCSGfaceted::DistanceToIn(p);
511 }
512 
513 
514 //
515 // ComputeDimensions
516 //
518  const G4int n,
519  const G4VPhysicalVolume* pRep )
520 {
521  p->ComputeDimensions(*this,n,pRep);
522 }
523 
524 //
525 // GetEntityType
526 //
528 {
529  return G4String("G4Polycone");
530 }
531 
532 //
533 // Make a clone of the object
534 //
536 {
537  return new G4Polycone(*this);
538 }
539 
540 //
541 // Stream object contents to an output stream
542 //
543 std::ostream& G4Polycone::StreamInfo( std::ostream& os ) const
544 {
545  G4int oldprc = os.precision(16);
546  os << "-----------------------------------------------------------\n"
547  << " *** Dump for solid - " << GetName() << " ***\n"
548  << " ===================================================\n"
549  << " Solid type: G4Polycone\n"
550  << " Parameters: \n"
551  << " starting phi angle : " << startPhi/degree << " degrees \n"
552  << " ending phi angle : " << endPhi/degree << " degrees \n";
553  G4int i=0;
554 
556  os << " number of Z planes: " << numPlanes << "\n"
557  << " Z values: \n";
558  for (i=0; i<numPlanes; i++)
559  {
560  os << " Z plane " << i << ": "
561  << original_parameters->Z_values[i] << "\n";
562  }
563  os << " Tangent distances to inner surface (Rmin): \n";
564  for (i=0; i<numPlanes; i++)
565  {
566  os << " Z plane " << i << ": "
567  << original_parameters->Rmin[i] << "\n";
568  }
569  os << " Tangent distances to outer surface (Rmax): \n";
570  for (i=0; i<numPlanes; i++)
571  {
572  os << " Z plane " << i << ": "
573  << original_parameters->Rmax[i] << "\n";
574  }
575 
576  os << " number of RZ points: " << numCorner << "\n"
577  << " RZ values (corners): \n";
578  for (i=0; i<numCorner; i++)
579  {
580  os << " "
581  << corners[i].r << ", " << corners[i].z << "\n";
582  }
583  os << "-----------------------------------------------------------\n";
584  os.precision(oldprc);
585 
586  return os;
587 }
588 
589 
590 //
591 // GetPointOnCone
592 //
593 // Auxiliary method for Get Point On Surface
594 //
596  G4double fRmin2, G4double fRmax2,
597  G4double zOne, G4double zTwo,
598  G4double& totArea) const
599 {
600  // declare working variables
601  //
602  G4double Aone, Atwo, Afive, phi, zRand, fDPhi, cosu, sinu;
603  G4double rRand1, rmin, rmax, chose, rone, rtwo, qone, qtwo;
604  G4double fDz=(zTwo-zOne)/2., afDz=std::fabs(fDz);
605  G4ThreeVector point, offset=G4ThreeVector(0.,0.,0.5*(zTwo+zOne));
606  fDPhi = endPhi - startPhi;
607  rone = (fRmax1-fRmax2)/(2.*fDz);
608  rtwo = (fRmin1-fRmin2)/(2.*fDz);
609  if(fRmax1==fRmax2){qone=0.;}
610  else{
611  qone = fDz*(fRmax1+fRmax2)/(fRmax1-fRmax2);
612  }
613  if(fRmin1==fRmin2){qtwo=0.;}
614  else{
615  qtwo = fDz*(fRmin1+fRmin2)/(fRmin1-fRmin2);
616  }
617  Aone = 0.5*fDPhi*(fRmax2 + fRmax1)*(sqr(fRmin1-fRmin2)+sqr(zTwo-zOne));
618  Atwo = 0.5*fDPhi*(fRmin2 + fRmin1)*(sqr(fRmax1-fRmax2)+sqr(zTwo-zOne));
619  Afive = fDz*(fRmax1-fRmin1+fRmax2-fRmin2);
620  totArea = Aone+Atwo+2.*Afive;
621 
622  phi = RandFlat::shoot(startPhi,endPhi);
623  cosu = std::cos(phi);
624  sinu = std::sin(phi);
625 
626 
627  if( (startPhi == 0) && (endPhi == twopi) ) { Afive = 0; }
628  chose = RandFlat::shoot(0.,Aone+Atwo+2.*Afive);
629  if( (chose >= 0) && (chose < Aone) )
630  {
631  if(fRmax1 != fRmax2)
632  {
633  zRand = RandFlat::shoot(-1.*afDz,afDz);
634  point = G4ThreeVector (rone*cosu*(qone-zRand),
635  rone*sinu*(qone-zRand), zRand);
636  }
637  else
638  {
639  point = G4ThreeVector(fRmax1*cosu, fRmax1*sinu,
640  RandFlat::shoot(-1.*afDz,afDz));
641 
642  }
643  }
644  else if(chose >= Aone && chose < Aone + Atwo)
645  {
646  if(fRmin1 != fRmin2)
647  {
648  zRand = RandFlat::shoot(-1.*afDz,afDz);
649  point = G4ThreeVector (rtwo*cosu*(qtwo-zRand),
650  rtwo*sinu*(qtwo-zRand), zRand);
651 
652  }
653  else
654  {
655  point = G4ThreeVector(fRmin1*cosu, fRmin1*sinu,
656  RandFlat::shoot(-1.*afDz,afDz));
657  }
658  }
659  else if( (chose >= Aone + Atwo + Afive) && (chose < Aone + Atwo + 2.*Afive) )
660  {
661  zRand = RandFlat::shoot(-1.*afDz,afDz);
662  rmin = fRmin2-((zRand-fDz)/(2.*fDz))*(fRmin1-fRmin2);
663  rmax = fRmax2-((zRand-fDz)/(2.*fDz))*(fRmax1-fRmax2);
664  rRand1 = std::sqrt(RandFlat::shoot()*(sqr(rmax)-sqr(rmin))+sqr(rmin));
665  point = G4ThreeVector (rRand1*std::cos(startPhi),
666  rRand1*std::sin(startPhi), zRand);
667  }
668  else
669  {
670  zRand = RandFlat::shoot(-1.*afDz,afDz);
671  rmin = fRmin2-((zRand-fDz)/(2.*fDz))*(fRmin1-fRmin2);
672  rmax = fRmax2-((zRand-fDz)/(2.*fDz))*(fRmax1-fRmax2);
673  rRand1 = std::sqrt(RandFlat::shoot()*(sqr(rmax)-sqr(rmin))+sqr(rmin));
674  point = G4ThreeVector (rRand1*std::cos(endPhi),
675  rRand1*std::sin(endPhi), zRand);
676 
677  }
678 
679  return point+offset;
680 }
681 
682 
683 //
684 // GetPointOnTubs
685 //
686 // Auxiliary method for GetPoint On Surface
687 //
689  G4double zOne, G4double zTwo,
690  G4double& totArea) const
691 {
692  G4double xRand,yRand,zRand,phi,cosphi,sinphi,chose,
693  aOne,aTwo,aFou,rRand,fDz,fSPhi,fDPhi;
694  fDz = std::fabs(0.5*(zTwo-zOne));
695  fSPhi = startPhi;
696  fDPhi = endPhi-startPhi;
697 
698  aOne = 2.*fDz*fDPhi*fRMax;
699  aTwo = 2.*fDz*fDPhi*fRMin;
700  aFou = 2.*fDz*(fRMax-fRMin);
701  totArea = aOne+aTwo+2.*aFou;
702  phi = RandFlat::shoot(startPhi,endPhi);
703  cosphi = std::cos(phi);
704  sinphi = std::sin(phi);
705  rRand = fRMin + (fRMax-fRMin)*std::sqrt(RandFlat::shoot());
706 
707  if(startPhi == 0 && endPhi == twopi)
708  aFou = 0;
709 
710  chose = RandFlat::shoot(0.,aOne+aTwo+2.*aFou);
711  if( (chose >= 0) && (chose < aOne) )
712  {
713  xRand = fRMax*cosphi;
714  yRand = fRMax*sinphi;
715  zRand = RandFlat::shoot(-1.*fDz,fDz);
716  return G4ThreeVector(xRand, yRand, zRand+0.5*(zTwo+zOne));
717  }
718  else if( (chose >= aOne) && (chose < aOne + aTwo) )
719  {
720  xRand = fRMin*cosphi;
721  yRand = fRMin*sinphi;
722  zRand = RandFlat::shoot(-1.*fDz,fDz);
723  return G4ThreeVector(xRand, yRand, zRand+0.5*(zTwo+zOne));
724  }
725  else if( (chose >= aOne+aTwo) && (chose <aOne+aTwo+aFou) )
726  {
727  xRand = rRand*std::cos(fSPhi+fDPhi);
728  yRand = rRand*std::sin(fSPhi+fDPhi);
729  zRand = RandFlat::shoot(-1.*fDz,fDz);
730  return G4ThreeVector(xRand, yRand, zRand+0.5*(zTwo+zOne));
731  }
732 
733  // else
734 
735  xRand = rRand*std::cos(fSPhi+fDPhi);
736  yRand = rRand*std::sin(fSPhi+fDPhi);
737  zRand = RandFlat::shoot(-1.*fDz,fDz);
738  return G4ThreeVector(xRand, yRand, zRand+0.5*(zTwo+zOne));
739 }
740 
741 
742 //
743 // GetPointOnRing
744 //
745 // Auxiliary method for GetPoint On Surface
746 //
748  G4double fRMin2,G4double fRMax2,
749  G4double zOne) const
750 {
751  G4double xRand,yRand,phi,cosphi,sinphi,rRand1,rRand2,A1,Atot,rCh;
753  cosphi = std::cos(phi);
754  sinphi = std::sin(phi);
755 
756  if(fRMin1==fRMin2)
757  {
758  rRand1 = fRMin1; A1=0.;
759  }
760  else
761  {
762  rRand1 = RandFlat::shoot(fRMin1,fRMin2);
763  A1=std::fabs(fRMin2*fRMin2-fRMin1*fRMin1);
764  }
765  if(fRMax1==fRMax2)
766  {
767  rRand2=fRMax1; Atot=A1;
768  }
769  else
770  {
771  rRand2 = RandFlat::shoot(fRMax1,fRMax2);
772  Atot = A1+std::fabs(fRMax2*fRMax2-fRMax1*fRMax1);
773  }
774  rCh = RandFlat::shoot(0.,Atot);
775 
776  if(rCh>A1) { rRand1=rRand2; }
777 
778  xRand = rRand1*cosphi;
779  yRand = rRand1*sinphi;
780 
781  return G4ThreeVector(xRand, yRand, zOne);
782 }
783 
784 
785 //
786 // GetPointOnCut
787 //
788 // Auxiliary method for Get Point On Surface
789 //
791  G4double fRMin2, G4double fRMax2,
792  G4double zOne, G4double zTwo,
793  G4double& totArea) const
794 { if(zOne==zTwo)
795  {
796  return GetPointOnRing(fRMin1, fRMax1,fRMin2,fRMax2,zOne);
797  }
798  if( (fRMin1 == fRMin2) && (fRMax1 == fRMax2) )
799  {
800  return GetPointOnTubs(fRMin1, fRMax1,zOne,zTwo,totArea);
801  }
802  return GetPointOnCone(fRMin1,fRMax1,fRMin2,fRMax2,zOne,zTwo,totArea);
803 }
804 
805 
806 //
807 // GetPointOnSurface
808 //
810 {
811  G4double Area=0,totArea=0,Achose1=0,Achose2=0,phi,cosphi,sinphi,rRand;
812  G4int i=0;
814 
816  cosphi = std::cos(phi);
817  sinphi = std::sin(phi);
818 
819  rRand = original_parameters->Rmin[0] +
821  * std::sqrt(RandFlat::shoot()) );
822 
823  std::vector<G4double> areas; // (numPlanes+1);
824  std::vector<G4ThreeVector> points; // (numPlanes-1);
825 
826  areas.push_back(pi*(sqr(original_parameters->Rmax[0])
827  -sqr(original_parameters->Rmin[0])));
828 
829  for(i=0; i<numPlanes-1; i++)
830  {
832  * std::sqrt(sqr(original_parameters->Rmin[i]
833  -original_parameters->Rmin[i+1])+
836 
838  * std::sqrt(sqr(original_parameters->Rmax[i]
839  -original_parameters->Rmax[i+1])+
842 
843  Area *= 0.5*(endPhi-startPhi);
844 
845  if(startPhi==0.&& endPhi == twopi)
846  {
847  Area += std::fabs(original_parameters->Z_values[i+1]
852  -original_parameters->Rmin[i+1]);
853  }
854  areas.push_back(Area);
855  totArea += Area;
856  }
857 
858  areas.push_back(pi*(sqr(original_parameters->Rmax[numPlanes-1])-
859  sqr(original_parameters->Rmin[numPlanes-1])));
860 
861  totArea += (areas[0]+areas[numPlanes]);
862  G4double chose = RandFlat::shoot(0.,totArea);
863 
864  if( (chose>=0.) && (chose<areas[0]) )
865  {
866  return G4ThreeVector(rRand*cosphi, rRand*sinphi,
868  }
869 
870  for (i=0; i<numPlanes-1; i++)
871  {
872  Achose1 += areas[i];
873  Achose2 = (Achose1+areas[i+1]);
874  if(chose>=Achose1 && chose<Achose2)
875  {
881  original_parameters->Z_values[i+1], Area);
882  }
883  }
884 
885  rRand = original_parameters->Rmin[numPlanes-1] +
886  ( (original_parameters->Rmax[numPlanes-1]-original_parameters->Rmin[numPlanes-1])
887  * std::sqrt(RandFlat::shoot()) );
888 
889  return G4ThreeVector(rRand*cosphi,rRand*sinphi,
890  original_parameters->Z_values[numPlanes-1]);
891 
892 }
893 
894 //
895 // CreatePolyhedron
896 //
898 {
899  //
900  // This has to be fixed in visualization. Fake it for the moment.
901  //
902 
909 }
910 
912 {
913  G4int numPlanes = (G4int)numCorner;
914  G4bool isConvertible=true;
915  G4double Zmax=rz->Bmax();
916  rz->StartWithZMin();
917 
918  // Prepare vectors for storage
919  //
920  std::vector<G4double> Z;
921  std::vector<G4double> Rmin;
922  std::vector<G4double> Rmax;
923 
924  G4int countPlanes=1;
925  G4int icurr=0;
926  G4int icurl=0;
927 
928  // first plane Z=Z[0]
929  //
930  Z.push_back(corners[0].z);
931  G4double Zprev=Z[0];
932  if (Zprev == corners[1].z)
933  {
934  Rmin.push_back(corners[0].r);
935  Rmax.push_back (corners[1].r);icurr=1;
936  }
937  else if (Zprev == corners[numPlanes-1].z)
938  {
939  Rmin.push_back(corners[numPlanes-1].r);
940  Rmax.push_back (corners[0].r);
941  icurl=numPlanes-1;
942  }
943  else
944  {
945  Rmin.push_back(corners[0].r);
946  Rmax.push_back (corners[0].r);
947  }
948 
949  // next planes until last
950  //
951  G4int inextr=0, inextl=0;
952  for (G4int i=0; i < numPlanes-2; i++)
953  {
954  inextr=1+icurr;
955  inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
956 
957  if((corners[inextr].z >= Zmax) & (corners[inextl].z >= Zmax)) { break; }
958 
959  G4double Zleft = corners[inextl].z;
960  G4double Zright = corners[inextr].z;
961  if(Zright>Zleft)
962  {
963  Z.push_back(Zleft);
964  countPlanes++;
965  G4double difZr=corners[inextr].z - corners[icurr].z;
966  G4double difZl=corners[inextl].z - corners[icurl].z;
967 
968  if(std::fabs(difZl) < kCarTolerance)
969  {
970  if(corners[inextl].r >= corners[icurl].r)
971  {
972  Rmin.push_back(corners[icurl].r);
973  Rmax.push_back(Rmax[countPlanes-2]);
974  Rmax[countPlanes-2]=corners[icurl].r;
975  }
976  else
977  {
978  Rmin.push_back(corners[inextl].r);
979  Rmax.push_back(corners[icurl].r);
980  }
981  }
982  else if (difZl >= kCarTolerance)
983  {
984  Rmin.push_back(corners[inextl].r);
985  Rmax.push_back (corners[icurr].r + (Zleft-corners[icurr].z)/difZr
986  *(corners[inextr].r - corners[icurr].r));
987  }
988  else
989  {
990  isConvertible=false; break;
991  }
992  icurl=(icurl == 0)? numPlanes-1 : icurl-1;
993  }
994  else if(std::fabs(Zright-Zleft)<kCarTolerance) // Zright=Zleft
995  {
996  Z.push_back(Zleft);
997  countPlanes++;
998  icurr++;
999 
1000  icurl=(icurl == 0)? numPlanes-1 : icurl-1;
1001 
1002  Rmin.push_back(corners[inextl].r);
1003  Rmax.push_back (corners[inextr].r);
1004  }
1005  else // Zright<Zleft
1006  {
1007  Z.push_back(Zright);
1008  countPlanes++;
1009 
1010  G4double difZr=corners[inextr].z - corners[icurr].z;
1011  G4double difZl=corners[inextl].z - corners[icurl].z;
1012  if(std::fabs(difZr) < kCarTolerance)
1013  {
1014  if(corners[inextr].r >= corners[icurr].r)
1015  {
1016  Rmin.push_back(corners[icurr].r);
1017  Rmax.push_back(corners[inextr].r);
1018  }
1019  else
1020  {
1021  Rmin.push_back(corners[inextr].r);
1022  Rmax.push_back(corners[icurr].r);
1023  Rmax[countPlanes-2]=corners[inextr].r;
1024  }
1025  icurr++;
1026  } // plate
1027  else if (difZr >= kCarTolerance)
1028  {
1029  if(std::fabs(difZl)<kCarTolerance)
1030  {
1031  Rmax.push_back(corners[inextr].r);
1032  Rmin.push_back (corners[icurr].r);
1033  }
1034  else
1035  {
1036  Rmax.push_back(corners[inextr].r);
1037  Rmin.push_back (corners[icurl].r+(Zright-corners[icurl].z)/difZl
1038  * (corners[inextl].r - corners[icurl].r));
1039  }
1040  icurr++;
1041  }
1042  else
1043  {
1044  isConvertible=false; break;
1045  }
1046  }
1047  } // end for loop
1048 
1049  // last plane Z=Zmax
1050  //
1051  Z.push_back(Zmax);
1052  countPlanes++;
1053  inextr=1+icurr;
1054  inextl=(icurl <= 0)? numPlanes-1 : icurl-1;
1055 
1056  if(corners[inextr].z==corners[inextl].z)
1057  {
1058  Rmax.push_back(corners[inextr].r);
1059  Rmin.push_back(corners[inextl].r);
1060  }
1061  else
1062  {
1063  Rmax.push_back(corners[inextr].r);
1064  Rmin.push_back(corners[inextl].r);
1065  }
1066 
1067  // Set original parameters Rmin,Rmax,Z
1068  //
1069  if(isConvertible)
1070  {
1072  original_parameters->Z_values = new G4double[countPlanes];
1073  original_parameters->Rmin = new G4double[countPlanes];
1074  original_parameters->Rmax = new G4double[countPlanes];
1075 
1076  for(G4int j=0; j < countPlanes; j++)
1077  {
1078  original_parameters->Z_values[j] = Z[j];
1079  original_parameters->Rmax[j] = Rmax[j];
1080  original_parameters->Rmin[j] = Rmin[j];
1081  }
1084  original_parameters->Num_z_planes = countPlanes;
1085 
1086  }
1087  else // Set parameters(r,z) with Rmin==0 as convention
1088  {
1089 #ifdef G4SPECSDEBUG
1090  std::ostringstream message;
1091  message << "Polycone " << GetName() << G4endl
1092  << "cannot be converted to Polycone with (Rmin,Rmaz,Z) parameters!";
1093  G4Exception("G4Polycone::SetOriginalParameters()", "GeomSolids0002",
1094  JustWarning, message);
1095 #endif
1097  original_parameters->Z_values = new G4double[numPlanes];
1098  original_parameters->Rmin = new G4double[numPlanes];
1099  original_parameters->Rmax = new G4double[numPlanes];
1100 
1101  for(G4int j=0; j < numPlanes; j++)
1102  {
1104  original_parameters->Rmax[j] = corners[j].r;
1105  original_parameters->Rmin[j] = 0.0;
1106  }
1109  original_parameters->Num_z_planes = numPlanes;
1110  }
1111  return isConvertible;
1112 }
1113 
1114 #endif
G4String GetName() const
G4bool CrossesItself(G4double tolerance)
G4Polyhedron * CreatePolyhedron() const
Definition: G4Polycone.cc:897
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:517
G4Polyhedron * fpPolyhedron
static const G4double kInfinity
Definition: geomdefs.hh:42
CLHEP::Hep3Vector G4ThreeVector
G4ThreeVector GetPointOnSurface() const
Definition: G4Polycone.cc:809
G4double Amin() const
G4double z
Definition: TRTMaterials.hh:39
G4double endPhi
Definition: G4Polycone.hh:184
G4ThreeVector GetPointOnRing(G4double fRMin, G4double fRMax, G4double fRMin2, G4double fRMax2, G4double zOne) const
Definition: G4Polycone.cc:747
G4String name
Definition: TRTMaterials.hh:40
const G4double pi
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
Definition: G4Polycone.cc:489
G4double a
Definition: TRTMaterials.hh:39
G4bool MustBeOutside(const G4ThreeVector &p) const
G4PolyconeSideRZ * corners
Definition: G4Polycone.hh:187
int G4int
Definition: G4Types.hh:78
void DumpInfo() const
std::ostream & StreamInfo(std::ostream &os) const
Definition: G4Polycone.cc:543
G4ThreeVector GetPointOnCone(G4double fRmin1, G4double fRmax1, G4double fRmin2, G4double fRmax2, G4double zOne, G4double zTwo, G4double &totArea) const
Definition: G4Polycone.cc:595
G4GeometryType GetEntityType() const
Definition: G4Polycone.cc:527
G4ThreeVector GetPointOnCut(G4double fRMin1, G4double fRMax1, G4double fRMin2, G4double fRMax2, G4double zOne, G4double zTwo, G4double &totArea) const
Definition: G4Polycone.cc:790
G4bool RemoveDuplicateVertices(G4double tolerance)
G4bool RemoveRedundantVertices(G4double tolerance)
G4Polycone & operator=(const G4Polycone &source)
Definition: G4Polycone.cc:375
G4GLOB_DLL std::ostream G4cout
G4int NumVertices() const
G4double Bmax() const
G4double startPhi
Definition: G4Polycone.hh:183
bool G4bool
Definition: G4Types.hh:79
virtual ~G4Polycone()
Definition: G4Polycone.cc:354
void SetOriginalParameters(G4PolyconeHistorical *pars)
EInside Inside(const G4ThreeVector &p) const
Definition: G4Polycone.cc:469
const G4int n
G4bool Reset()
Definition: G4Polycone.cc:438
G4VCSGface ** faces
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
G4VSolid * Clone() const
Definition: G4Polycone.cc:535
void CopyStuff(const G4Polycone &source)
Definition: G4Polycone.cc:395
EInside
Definition: geomdefs.hh:58
G4EnclosingCylinder * enclosingCylinder
Definition: G4Polycone.hh:192
G4ThreeVector GetPointOnTubs(G4double fRMin, G4double fRMax, G4double zOne, G4double zTwo, G4double &totArea) const
Definition: G4Polycone.cc:688
static const double degree
Definition: G4SIunits.hh:125
G4bool BisectedBy(G4double a1, G4double b1, G4double a2, G4double b2, G4double tolerance)
#define G4endl
Definition: G4ios.hh:61
G4double kCarTolerance
Definition: G4VSolid.hh:305
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 EInside Inside(const G4ThreeVector &p) const
G4bool ShouldMiss(const G4ThreeVector &p, const G4ThreeVector &v) const
virtual G4Polyhedron * GetPolyhedron() const