Geant4_10
UPolycone.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * This Software is part of the AIDA Unified Solids Library package *
4 // * See: https://aidasoft.web.cern.ch/USolids *
5 // ********************************************************************
6 //
7 // $Id:$
8 //
9 // --------------------------------------------------------------------
10 //
11 // UPolycone
12 //
13 // 19.04.13 Marek Gayer
14 // Created from original implementation in Geant4
15 // --------------------------------------------------------------------
16 
17 #include "UUtils.hh"
18 #include <string>
19 #include <cmath>
20 #include <sstream>
21 #include "UPolycone.hh"
22 
23 #include "UEnclosingCylinder.hh"
24 #include "UReduciblePolygon.hh"
25 
26 #include "UTubs.hh"
27 #include "UCons.hh"
28 #include "UTransform3D.hh"
29 
30 using namespace std;
31 
33 
34 UPolycone::UPolycone(const std::string& name,
35  double phiStart,
36  double phiTotal,
37  int numZPlanes,
38  const double zPlane[],
39  const double rInner[],
40  const double rOuter[])
41  : VUSolid(name) //, fNumSides(0)
42 {
43  fCubicVolume = 0;
44  fSurfaceArea = 0;
45  Init(phiStart, phiTotal, numZPlanes, zPlane, rInner, rOuter);
46 
47 }
48 
49 UPolycone::UPolycone(const std::string& name,
50  double phiStart,
51  double phiTotal,
52  int numRZ,
53  const double r[],
54  const double z[])
55  : VUSolid(name)
56 {
57  UReduciblePolygon* rz = new UReduciblePolygon(r, z, numRZ);
58 
59  // Create( phiStart, phiTotal, rz );
60 
61  // Set original_parameters struct for consistency
62  //
63 
64  bool convertible = SetOriginalParameters(rz);
65 
66  if (!convertible)
67  {
68  std::ostringstream message;
69  message << "Polycone " << GetName() << "cannot be converted" << std::endl
70  << "to Polycone with (Rmin,Rmaz,Z) parameters! Use GenericPolycone" ;
71  UUtils::Exception("UPolycone::UPolycone()", "GeomSolids0002",
72  FatalError, 1, message.str().c_str());
73  // JustWarning, message, "Use G4GenericPolycone instead!");
74 
75  }
76  else
77  {
78  std::cout << "INFO: Converting polycone " << GetName() << std::endl
79  << "to optimized polycone with (Rmin,Rmaz,Z) parameters !"
80  << std::endl;
81  double* Z, *R1, *R2;
83  Z = new double[num];
84  R1 = new double[num];
85  R2 = new double[num];
86  for (int i = 0; i < num; i++)
87  {
88  Z[i] = fOriginalParameters->fZValues[i];
89  R1[i] = fOriginalParameters->Rmin[i];
90  R2[i] = fOriginalParameters->Rmax[i];
91  }
92 
93  delete(fOriginalParameters);
94  Init(phiStart, phiTotal, num, Z, R1, R2);
95  delete [] R1;
96  delete [] Z;
97  delete [] R2;
98  }
99 
100  delete rz;
101 }
102 
103 
104 //
105 // Constructor (GEANT3 style parameters)
106 //
107 void UPolycone::Init(double phiStart,
108  double phiTotal,
109  int numZPlanes,
110  const double zPlane[],
111  const double rInner[],
112  const double rOuter[])
113 {
114  //Convertion for angles
115 
116  if (phiTotal <= 0 || phiTotal > UUtils::kTwoPi-1E-10)
117  {
118  phiIsOpen=false;
119  startPhi = 0;
120  endPhi = UUtils::kTwoPi;
121  }
122  else
123  {
124  //
125  // Convert phi into our convention
126  //
127  phiIsOpen=true;
128  startPhi = phiStart;
129  while( startPhi < 0 ) startPhi += UUtils::kTwoPi;
130 
131  endPhi = phiStart+phiTotal;
132  while( endPhi < startPhi ) endPhi += UUtils::kTwoPi;
133  }
134  // Set Parameters
138  fOriginalParameters->fNumZPlanes = numZPlanes;
139  fOriginalParameters->fZValues.resize(numZPlanes);
140  fOriginalParameters->Rmin.resize(numZPlanes);
141  fOriginalParameters->Rmax.resize(numZPlanes);
142 
143  double prevZ = 0, prevRmax = 0, prevRmin = 0;
144  int dirZ = 1;
145  if (zPlane[1] < zPlane[0])dirZ = -1;
146 // int curSolid = 0;
147 
148  int i;
149  for (i = 0; i < numZPlanes; i++)
150  {
151  if ((i < numZPlanes - 1) && (zPlane[i] == zPlane[i + 1]))
152  {
153  if ((rInner[i] > rOuter[i + 1])
154  || (rInner[i + 1] > rOuter[i]))
155  {
156 
157  std::ostringstream message;
158  message << "Cannot create a Polycone with no contiguous segments."
159  << std::endl
160  << " Segments are not contiguous !" << std::endl
161  << " rMin[" << i << "] = " << rInner[i]
162  << " -- rMax[" << i + 1 << "] = " << rOuter[i + 1] << std::endl
163  << " rMin[" << i + 1 << "] = " << rInner[i + 1]
164  << " -- rMax[" << i << "] = " << rOuter[i];
165  UUtils::Exception("UPolycone::UPolycone()", "GeomSolids0002",
166  FatalErrorInArguments, 1, message.str().c_str());
167  }
168  }
169 
170 
171 
172  double rMin = rInner[i];
173  double rMax = rOuter[i];
174  double z = zPlane[i];
175 
176  if (i > 0)
177  {
178  if (z > prevZ)
179  {
180  if (dirZ < 0)
181  {
182  std::ostringstream message;
183  message << "Cannot create a Polycone with different Z directions.Use GenericPolycone."
184  << std::endl
185  << " ZPlane is changing direction !" << std::endl
186  << " zPlane[0] = " << zPlane[0]
187  << " -- zPlane[1] = " << zPlane[1] << std::endl
188  << " zPlane[" << i - 1 << "] = " << zPlane[i - 1]
189  << " -- rPlane[" << i << "] = " << zPlane[i];
190  UUtils::Exception("UPolycone::UPolycone()", "GeomSolids0002",
191  FatalErrorInArguments, 1, message.str().c_str());
192 
193 
194 
195  }
196  VUSolid* solid;
197  double dz = (z - prevZ) / 2;
198 
199  bool tubular = (rMin == prevRmin && prevRmax == rMax);
200 
201 // if (fNumSides == 0)
202  {
203  if (tubular)
204  {
205  solid = new UTubs("", rMin, rMax, dz, phiStart, phiTotal);
206  }
207  else
208  {
209  solid = new UCons("", prevRmin, prevRmax, rMin, rMax, dz, phiStart, phiTotal);
210  }
211  }
212 // else
213 // {
214 // solid = new UHedra("", prevRmin, prevRmax, rMin, rMax, dz, phiStart, phiTotal, fNumSides);
215 // }
216 
217  fZs.push_back(z);
218 
219  int zi = fZs.size() - 1;
220  double shift = fZs[zi - 1] + 0.5 * (fZs[zi] - fZs[zi - 1]);
221 
222  UPolyconeSection section;
223  section.shift = shift;
224  section.tubular = tubular;
225  section.solid = solid;
226 // section.left = fZs[zi-1];
227 // section.right = z;
228 
229  fSections.push_back(section);
230  }
231  else
232  {
233  ;// i = i;
234  }
235  }
236  else fZs.push_back(z);
237 
238  fOriginalParameters->fZValues[i] = zPlane[i];
239  fOriginalParameters->Rmin[i] = rInner[i];
240  fOriginalParameters->Rmax[i] = rOuter[i];
241 
242  prevZ = z;
243  prevRmin = rMin;
244  prevRmax = rMax;
245  }
246 
247  fMaxSection = fZs.size() - 2;
248 
249  //
250  // Build RZ polygon using special PCON/PGON GEANT3 constructor
251  //
252  UReduciblePolygon* rz = new UReduciblePolygon(rInner, rOuter, zPlane, numZPlanes);
253 
254  double mxy = rz->Amax();
255 // double alfa = UUtils::kPi / fNumSides;
256 
257  double r = rz->Amax();
258 //
259 // Perform checks of rz values
260 //
261  if (rz->Amin() < 0.0)
262  {
263  std::ostringstream message;
264  message << "Illegal input parameters - " << GetName() << std::endl
265  << " All R values must be >= 0 !";
266  UUtils::Exception("UPolycone::Init()", "GeomSolids0002",
267  FatalErrorInArguments,1, message.str().c_str());
268  }
269 
270 
271  /*
272  if (fNumSides != 0)
273  {
274  // mxy *= std::sqrt(2.0); // this is old and wrong, works only for n = 4
275  // double k = std::tan(alfa) * mxy;
276  double l = mxy / std::cos(alfa);
277  mxy = l;
278  r = l;
279  }
280  */
281 
282  mxy += fgTolerance;
283 
284  box.Set(mxy, mxy, (rz->Bmax() - rz->Bmin()) / 2);
285 
286  //
287  // Make enclosingCylinder
288  //
289 
290  enclosingCylinder = new UEnclosingCylinder(r, rz->Bmax(), rz->Bmin(), phiIsOpen, phiStart, phiTotal);
291 
292  delete rz;
293 }
294 
295 
296 /*
297 //
298 // Constructor (generic parameters)
299 //
300 UPolycone3::UPolycone3( const std::string& name,
301  double phiStart,
302  double phiTotal,
303  int numRZ,
304  const double r[],
305  const double z[] )
306  : VUSolid( name )
307 {
308  UReduciblePolygon *rz = new UReduciblePolygon( r, z, numRZ );
309 
310  box.Set(rz->Amax(), rz->Amax(), (rz->Bmax() - rz->Bmin()) /2);
311 
312  // Set fOriginalParameters struct for consistency
313  //
314  SetOriginalParameters();
315 
316  delete rz;
317 }
318 */
319 
320 
321 //
322 // Destructor
323 //
325 {
326  //delete [] corners;
327  //delete fOriginalParameters;
328 }
329 
330 
331 
332 //
333 // Stream object contents to an output stream
334 //
335 std::ostream& UPolycone::StreamInfo(std::ostream& os) const
336 {
337  int oldprc = os.precision(16);
338  os << "-----------------------------------------------------------\n"
339  << " *** Dump for solid - " << GetName() << " ***\n"
340  << " ===================================================\n"
341  << " Solid type: UPolycone3\n"
342  << " Parameters: \n"
343  << " starting phi angle : " << startPhi / (UUtils::kPi / 180.0) << " degrees \n"
344  << " ending phi angle : " << endPhi / (UUtils::kPi / 180.0) << " degrees \n";
345  int i = 0;
346  int numPlanes = fOriginalParameters->fNumZPlanes;
347  os << " number of Z planes: " << numPlanes << "\n"
348  << " Z values: \n";
349  for (i = 0; i < numPlanes; i++)
350  {
351  os << " Z plane " << i << ": "
352  << fOriginalParameters->fZValues[i] << "\n";
353  }
354  os << " Tangent distances to inner surface (Rmin): \n";
355  for (i = 0; i < numPlanes; i++)
356  {
357  os << " Z plane " << i << ": "
358  << fOriginalParameters->Rmin[i] << "\n";
359  }
360  os << " Tangent distances to outer surface (Rmax): \n";
361  for (i = 0; i < numPlanes; i++)
362  {
363  os << " Z plane " << i << ": "
364  << fOriginalParameters->Rmax[i] << "\n";
365  }
366  os << "-----------------------------------------------------------\n";
367  os.precision(oldprc);
368 
369  return os;
370 }
371 
372 
374 {
375  const UPolyconeSection& section = fSections[index];
376  UVector3 ps(p.x, p.y, p.z - section.shift);
377 
378 // if (fNumSides) return section.solid->Inside(ps);
379 
380  double rMinPlus, rMaxPlus; //, rMinMinus, rMaxMinus;
381  double dz;
382  static double halfTolerance = fgTolerance * 0.5;
383 
384  if (section.tubular)
385  {
386  UTubs* tubs = (UTubs*) section.solid;
387  rMinPlus = tubs->GetRMin() + halfTolerance;
388  rMaxPlus = tubs->GetRMax() + halfTolerance;
389  dz = tubs->GetDz();//GetZHalfLength();
390  }
391  else
392  {
393  UCons* cons = (UCons*) section.solid;
394 
395  double rMax1 = cons->GetRmax1();
396  double rMax2 = cons->GetRmax2();
397  double rMin1 = cons->GetRmin1();
398  double rMin2 = cons->GetRmin2();
399 
400  dz = cons->GetDz();
401  double ratio = (ps.z + dz) / (2 * dz);
402  rMinPlus = rMin1 + (rMin2 - rMin1) * ratio + halfTolerance;
403  rMaxPlus = rMax1 + (rMax2 - rMax1) * ratio + halfTolerance;
404  }
405 
406  double rMinMinus = rMinPlus - fgTolerance;
407  double rMaxMinus = rMaxPlus - fgTolerance;
408 
409  double r2 = p.x * p.x + p.y * p.y;
410 
411  if (r2 < rMinMinus * rMinMinus || r2 > rMaxPlus * rMaxPlus) return eOutside;
412  if (r2 < rMinPlus * rMinPlus || r2 > rMaxMinus * rMaxMinus) return eSurface;
413 
414  if (! phiIsOpen )
415  {
416  if (ps.z < -dz + halfTolerance || ps.z > dz - halfTolerance)
417  return eSurface;
418  return eInside;
419  }
420 
421  if (r2 < 1e-10) return eInside;
422 
423  double phi = std::atan2(p.y, p.x); // * UUtils::kTwoPi;
424  if (phi < 0) phi += UUtils::kTwoPi;
425  double ddp = phi - startPhi;
426  if (ddp < 0) ddp += UUtils::kTwoPi;
427  if (ddp <= endPhi + frTolerance)
428  {
429  if (ps.z < -dz + halfTolerance || ps.z > dz - halfTolerance)
430  return eSurface;
431  if (endPhi - ddp < frTolerance)
432  return eSurface;
433 
434  return eInside;
435  }
436  return eOutside;
437 
438 }
439 
440 
442 {
443  double shift = fZs[0] + box.GetZHalfLength();
444  UVector3 pb(p.x, p.y, p.z - shift);
445  if (box.Inside(pb) == eOutside)
446  return eOutside;
447 
448  static const double htolerance = 0.5 * fgTolerance;
449  int index = GetSection(p.z);
450 
451  EnumInside pos = InsideSection(index, p);
452  if (pos == eInside) return eInside;
453 
454  int nextSection;
455  EnumInside nextPos;
456 
457  if (index > 0 && p.z - fZs[index] < htolerance)
458  {
459  nextSection = index - 1;
460  nextPos = InsideSection(nextSection, p);
461  }
462  else if (index < fMaxSection && fZs[index + 1] - p.z < htolerance)
463  {
464  nextSection = index + 1;
465  nextPos = InsideSection(nextSection, p);
466  }
467  else
468  return pos;
469 
470  if (nextPos == eInside) return eInside;
471 
472  if (pos == eSurface && nextPos == eSurface)
473  {
474  UVector3 n, n2;
475  NormalSection(index, p, n);
476  NormalSection(nextSection, p, n2);
477  if ((n + n2).Mag2() < 1000 * frTolerance)
478  return eInside;
479  }
480 
481  return (nextPos == eSurface || pos == eSurface) ? eSurface : eOutside;
482 
483 // return (res == VUSolid::eOutside) ? nextPos : res;
484 }
485 
486 /*
487 if (p.z < fZs.front() - htolerance || p.z > fZs.back() + htolerance) return VUSolid::eOutside;
488 */
489 
491  const UVector3& v, double) const
492 {
493  double shift = fZs[0] + box.GetZHalfLength();
494  UVector3 pb(p.x, p.y, p.z - shift);
495 
496  double idistance;
497 
498  idistance = box.DistanceToIn(pb, v); // using only box, this appears
499  // to be faster than: idistance = enclosingCylinder->DistanceTo(pb, v);
500  if (idistance >= UUtils::kInfinity) return idistance;
501 
502  // this line can be here or not. not a big difference in performance
503  // TODO: fix enclosingCylinder for polyhedra!!! - the current radius appears to be too small
504 // if (enclosingCylinder->ShouldMiss(p, v)) return UUtils::kInfinity;
505 
506  // this just takes too much time
507 // idistance = enclosingCylinder->DistanceTo(pb, v);
508 // if (idistance == UUtils::kInfinity) return idistance;
509 
510  pb = p + idistance * v;
511  int index = GetSection(pb.z);
512  pb = p;
513  int increment = (v.z > 0) ? 1 : -1;
514  if (std::fabs(v.z) < fgTolerance) increment = 0;
515 
516  double distance = UUtils::kInfinity;
517  do
518  {
519  const UPolyconeSection& section = fSections[index];
520  pb.z -= section.shift;
521  distance = section.solid->DistanceToIn(pb, v);
522  if (distance < UUtils::kInfinity || !increment)
523  break;
524  index += increment;
525  pb.z += section.shift;
526  }
527  while (index >= 0 && index <= fMaxSection);
528 
529  return distance;
530 }
531 
533  UVector3& n, bool& convex, double /*aPstep*/) const
534 {
535  UVector3 pn(p);
537  {
538  const UPolyconeSection& section = fSections[0];
539  pn.z -= section.shift;
540  return section.solid->DistanceToOut(pn, v, n, convex);
541  }
542  int index = GetSection(p.z);
543  double totalDistance = 0;
544  int increment = (v.z > 0) ? 1 : -1;
545 
546 // UVector3 normal;
547  do
548  {
549  const UPolyconeSection& section = fSections[index];
550  if (totalDistance != 0)
551  {
552  pn = p + (totalDistance /*+ 0 * 1e-8*/) * v; // point must be shifted, so it could eventually get into another solid
553  pn.z -= section.shift;
554  if (section.solid->Inside(pn) == eOutside)
555  {
556  //index = index;
557  break;
558  }
559  }
560  else pn.z -= section.shift;
561 
562 // if (totalDistance > 0) totalDistance += 1e-8;
563  double distance = section.solid->DistanceToOut(pn, v, n, convex);
564 
565  /*
566  if (convex == false)
567  {
568  n.Set(0);
569 
570  // ps += distance * v;
571  // section.solid->Normal(ps, n);
572  }
573  */
574 
575  /*
576  double dif = (n2 - n).Mag();
577  if (dif > 0.0000001)
578  n = n;
579  */
580 
581  if (distance == 0)
582  {
583  distance = 0;//distance;
584  break;
585  }
586 // n = normal;
587 
588  totalDistance += distance;
589 
590  index += increment;
591 
592  // pn.z check whether it still relevant
593  }
594  while (index >= 0 && index <= fMaxSection);
595 
596 // pn = p + (totalDistance + 1e-8) * v;
597 
598 // Normal(pn, n);
599 
600 // convex = (DistanceToIn(pn, n) == UUtils::kInfinity);
601  convex = false;
602 
603  return totalDistance;
604 }
605 
606 double UPolycone::SafetyFromInside(const UVector3& p, bool) const
607 {
609  if (index < 0 || index > fMaxSection) return 0;
610 
611  double minSafety = SafetyFromInsideSection(index, p);
612  if (minSafety == UUtils::kInfinity) return 0;
613  if (minSafety < 1e-6) return 0;
614 
615  double zbase = fZs[index + 1];
616  for (int i = index + 1; i <= fMaxSection; ++i)
617  {
618  double dz = fZs[i] - zbase;
619  if (dz >= minSafety) break;
620  double safety = SafetyFromOutsideSection(i, p); // safety from Inside cannot be called in this context, because point is not inside, we have to call SafetyFromOutside for given section
621  if (safety < minSafety) minSafety = safety;
622  }
623 
624  if (index > 0)
625  {
626  zbase = fZs[index - 1];
627  for (int i = index - 1; i >= 0; --i)
628  {
629  double dz = zbase - fZs[i];
630  if (dz >= minSafety) break;
631  double safety = SafetyFromOutsideSection(i, p);
632  if (safety < minSafety) minSafety = safety;
633  }
634  }
635  return minSafety;
636 }
637 
638 
639 double UPolycone::SafetyFromOutside(const UVector3& p, bool aAccurate) const
640 {
641  if (!aAccurate)
643 
644  int index = GetSection(p.z);
645  double minSafety = SafetyFromOutsideSection(index, p);
646  if (minSafety < 1e-6) return minSafety;
647 
648  double zbase = fZs[index + 1];
649  for (int i = index + 1; i <= fMaxSection; ++i)
650  {
651  double dz = fZs[i] - zbase;
652  if (dz >= minSafety) break;
653  double safety = SafetyFromOutsideSection(i, p);
654  if (safety < minSafety) minSafety = safety;
655  }
656 
657  zbase = fZs[index - 1];
658  for (int i = index - 1; i >= 0; --i)
659  {
660  double dz = zbase - fZs[i];
661  if (dz >= minSafety) break;
662  double safety = SafetyFromOutsideSection(i, p);
663  if (safety < minSafety) minSafety = safety;
664  }
665  return minSafety;
666 }
667 
668 bool UPolycone::Normal(const UVector3& p, UVector3& n) const
669 {
670  double htolerance = 0.5 * fgTolerance;
671  int index = GetSection(p.z);
672 
673  EnumInside nextPos;
674  int nextSection;
675 
676  if (index > 0 && p.z - fZs[index] < htolerance)
677  {
678  nextSection = index - 1;
679  nextPos = InsideSection(nextSection, p);
680  }
681  else if (index < fMaxSection && fZs[index + 1] - p.z < htolerance)
682  {
683  nextSection = index + 1;
684  nextPos = InsideSection(nextSection, p);
685  }
686  else
687  {
688  const UPolyconeSection& section = fSections[index];
689  UVector3 ps(p.x, p.y, p.z - section.shift);
690  bool res = section.solid->Normal(ps, n);
691 
692  return res;
693 
694  // the code bellow is not used can be deleted
695 
696  nextPos = section.solid->Inside(ps);
697  if (nextPos == eSurface)
698  {
699  return res;
700  }
701  else
702  {
703  //TODO: here should be implementation for case point was not on surface. We would have to look also at other sections. It is not clear if it is possible to solve this problem at all, since we would need precise safety... If it is outside, than it might be OK, but if it is inside..., than I beleive we do not have precise safety
704 
705  // ... or we should at least warn that this case is not supported. actually,
706  // i do not see any algorithm which would obtain right normal of point closest to surface.;
707 
708  return false;
709  }
710  }
711 
712  // even if it says we are on the surface, actually it do not have to be
713 
714 // "TODO special case when point is on the border of two z-sections",
715 // "we should implement this after safety's";
716 
717  EnumInside pos = InsideSection(index, p);
718 
719  if (nextPos == eInside)
720  {
721  //UVector3 n;
722  NormalSection(index, p, n);
723  return false;
724  }
725 
726  if (pos == eSurface && nextPos == eSurface)
727  {
728  //UVector3 n, n2;
729  UVector3 n2;
730  NormalSection(index, p, n);
731  NormalSection(nextSection, p, n2);
732  if ((n + n2).Mag2() < 1000 * frTolerance)
733  {
734  // "we are inside. see TODO above";
735  NormalSection(index, p, n);
736  return false;
737  }
738  }
739 
740  if (nextPos == eSurface || pos == eSurface)
741  {
742  if (pos != eSurface) index = nextSection;
743  bool res = NormalSection(index, p, n);
744  return res;
745  }
746 
747  NormalSection(index, p, n);
748  // "we are outside. see TODO above";
749  return false;
750 }
751 
752 
753 void UPolycone::Extent(UVector3& aMin, UVector3& aMax) const
754 {
755  double r = enclosingCylinder->radius;
756  aMin.Set(-r, -r, fZs.front());
757  aMax.Set(r, r, fZs.back());
758 }
759 
761 {
762  if (fCubicVolume != 0.)
763  {
764  ;
765  }
766  else
767  {
768  for (int i = 0; i < fMaxSection; i++)
769  {
770  UPolyconeSection& section = fSections[i];
771  fCubicVolume += section.solid->Capacity();
772  }
773  }
774  return fCubicVolume;
775 }
776 
778 {
779  if (fSurfaceArea != 0)
780  {
781  ;
782  }
783  else
784  {
785  double Area = 0, totArea = 0;
786  int i = 0;
787  int numPlanes = fOriginalParameters->fNumZPlanes;
788 
789 
790  std::vector<double> areas; // (numPlanes+1);
791  std::vector<UVector3> points; // (numPlanes-1);
792 
793  areas.push_back(UUtils::kPi * (UUtils::sqr(fOriginalParameters->Rmax[0])
795 
796  for (i = 0; i < numPlanes - 1; i++)
797  {
798  Area = (fOriginalParameters->Rmin[i] + fOriginalParameters->Rmin[i + 1])
799  * std::sqrt(UUtils::sqr(fOriginalParameters->Rmin[i]
800  - fOriginalParameters->Rmin[i + 1]) +
803 
804  Area += (fOriginalParameters->Rmax[i] + fOriginalParameters->Rmax[i + 1])
805  * std::sqrt(UUtils::sqr(fOriginalParameters->Rmax[i]
806  - fOriginalParameters->Rmax[i + 1]) +
809 
810  Area *= 0.5 * (endPhi - startPhi);
811 
812  if (startPhi == 0. && endPhi == 2 * UUtils::kPi)
813  {
814  Area += std::fabs(fOriginalParameters->fZValues[i + 1]
817  + fOriginalParameters->Rmax[i + 1]
819  - fOriginalParameters->Rmin[i + 1]);
820  }
821  areas.push_back(Area);
822  totArea += Area;
823  }
824 
825  areas.push_back(UUtils::kPi * (UUtils::sqr(fOriginalParameters->Rmax[numPlanes - 1]) -
826  UUtils::sqr(fOriginalParameters->Rmin[numPlanes - 1])));
827 
828  totArea += (areas[0] + areas[numPlanes]);
829  fSurfaceArea = totArea;
830 
831  }
832 
833  return fSurfaceArea;
834 }
835 
837 //
838 // GetPointOnSurface
839 //
840 // GetPointOnCone
841 //
842 // Auxiliary method for Get Point On Surface
843 //
844 UVector3 UPolycone::GetPointOnCone(double fRmin1, double fRmax1,
845  double fRmin2, double fRmax2,
846  double zOne, double zTwo,
847  double& totArea) const
848 {
849  // declare working variables
850  //
851  double Aone, Atwo, Afive, phi, zRand, fDPhi, cosu, sinu;
852  double rRand1, rmin, rmax, chose, rone, rtwo, qone, qtwo;
853  double fDz = (zTwo - zOne) / 2., afDz = std::fabs(fDz);
854  UVector3 point, offset = UVector3(0., 0., 0.5 * (zTwo + zOne));
855  fDPhi = endPhi - startPhi;
856  rone = (fRmax1 - fRmax2) / (2.*fDz);
857  rtwo = (fRmin1 - fRmin2) / (2.*fDz);
858  if (fRmax1 == fRmax2)
859  {
860  qone = 0.;
861  }
862  else
863  {
864  qone = fDz * (fRmax1 + fRmax2) / (fRmax1 - fRmax2);
865  }
866  if (fRmin1 == fRmin2)
867  {
868  qtwo = 0.;
869  }
870  else
871  {
872  qtwo = fDz * (fRmin1 + fRmin2) / (fRmin1 - fRmin2);
873  }
874  Aone = 0.5 * fDPhi * (fRmax2 + fRmax1) * (UUtils::sqr(fRmin1 - fRmin2) + UUtils::sqr(zTwo - zOne));
875  Atwo = 0.5 * fDPhi * (fRmin2 + fRmin1) * (UUtils::sqr(fRmax1 - fRmax2) + UUtils::sqr(zTwo - zOne));
876  Afive = fDz * (fRmax1 - fRmin1 + fRmax2 - fRmin2);
877  totArea = Aone + Atwo + 2.*Afive;
878 
879  phi = UUtils::Random(startPhi, endPhi);
880  cosu = std::cos(phi);
881  sinu = std::sin(phi);
882 
883 
884  if ((startPhi == 0) && (endPhi == 2 * UUtils::kPi))
885  {
886  Afive = 0;
887  }
888  chose = UUtils::Random(0., Aone + Atwo + 2.*Afive);
889  if ((chose >= 0) && (chose < Aone))
890  {
891  if (fRmax1 != fRmax2)
892  {
893  zRand = UUtils::Random(-1.*afDz, afDz);
894  point = UVector3(rone * cosu * (qone - zRand),
895  rone * sinu * (qone - zRand), zRand);
896  }
897  else
898  {
899  point = UVector3(fRmax1 * cosu, fRmax1 * sinu,
900  UUtils::Random(-1.*afDz, afDz));
901 
902  }
903  }
904  else if (chose >= Aone && chose < Aone + Atwo)
905  {
906  if (fRmin1 != fRmin2)
907  {
908  zRand = UUtils::Random(-1.*afDz, afDz);
909  point = UVector3(rtwo * cosu * (qtwo - zRand),
910  rtwo * sinu * (qtwo - zRand), zRand);
911 
912  }
913  else
914  {
915  point = UVector3(fRmin1 * cosu, fRmin1 * sinu,
916  UUtils::Random(-1.*afDz, afDz));
917  }
918  }
919  else if ((chose >= Aone + Atwo + Afive) && (chose < Aone + Atwo + 2.*Afive))
920  {
921  zRand = UUtils::Random(-1.*afDz, afDz);
922  rmin = fRmin2 - ((zRand - fDz) / (2.*fDz)) * (fRmin1 - fRmin2);
923  rmax = fRmax2 - ((zRand - fDz) / (2.*fDz)) * (fRmax1 - fRmax2);
924  rRand1 = std::sqrt(UUtils::Random() * (UUtils::sqr(rmax) - UUtils::sqr(rmin)) + UUtils::sqr(rmin));
925  point = UVector3(rRand1 * std::cos(startPhi),
926  rRand1 * std::sin(startPhi), zRand);
927  }
928  else
929  {
930  zRand = UUtils::Random(-1.*afDz, afDz);
931  rmin = fRmin2 - ((zRand - fDz) / (2.*fDz)) * (fRmin1 - fRmin2);
932  rmax = fRmax2 - ((zRand - fDz) / (2.*fDz)) * (fRmax1 - fRmax2);
933  rRand1 = std::sqrt(UUtils::Random() * (UUtils::sqr(rmax) - UUtils::sqr(rmin)) + UUtils::sqr(rmin));
934  point = UVector3(rRand1 * std::cos(endPhi),
935  rRand1 * std::sin(endPhi), zRand);
936 
937  }
938 
939  return point + offset;
940 }
941 
942 
943 //
944 // GetPointOnTubs
945 //
946 // Auxiliary method for GetPoint On Surface
947 //
948 UVector3 UPolycone::GetPointOnTubs(double fRMin, double fRMax,
949  double zOne, double zTwo,
950  double& totArea) const
951 {
952  double xRand, yRand, zRand, phi, cosphi, sinphi, chose,
953  aOne, aTwo, aFou, rRand, fDz, fSPhi, fDPhi;
954  fDz = std::fabs(0.5 * (zTwo - zOne));
955  fSPhi = startPhi;
956  fDPhi = endPhi - startPhi;
957 
958  aOne = 2.*fDz * fDPhi * fRMax;
959  aTwo = 2.*fDz * fDPhi * fRMin;
960  aFou = 2.*fDz * (fRMax - fRMin);
961  totArea = aOne + aTwo + 2.*aFou;
962  phi = UUtils::Random(startPhi, endPhi);
963  cosphi = std::cos(phi);
964  sinphi = std::sin(phi);
965  rRand = fRMin + (fRMax - fRMin) * std::sqrt(UUtils::Random());
966 
967  if (startPhi == 0 && endPhi == 2 * UUtils::kPi)
968  aFou = 0;
969 
970  chose = UUtils::Random(0., aOne + aTwo + 2.*aFou);
971  if ((chose >= 0) && (chose < aOne))
972  {
973  xRand = fRMax * cosphi;
974  yRand = fRMax * sinphi;
975  zRand = UUtils::Random(-1.*fDz, fDz);
976  return UVector3(xRand, yRand, zRand + 0.5 * (zTwo + zOne));
977  }
978  else if ((chose >= aOne) && (chose < aOne + aTwo))
979  {
980  xRand = fRMin * cosphi;
981  yRand = fRMin * sinphi;
982  zRand = UUtils::Random(-1.*fDz, fDz);
983  return UVector3(xRand, yRand, zRand + 0.5 * (zTwo + zOne));
984  }
985  else if ((chose >= aOne + aTwo) && (chose < aOne + aTwo + aFou))
986  {
987  xRand = rRand * std::cos(fSPhi + fDPhi);
988  yRand = rRand * std::sin(fSPhi + fDPhi);
989  zRand = UUtils::Random(-1.*fDz, fDz);
990  return UVector3(xRand, yRand, zRand + 0.5 * (zTwo + zOne));
991  }
992 
993  // else
994 
995  xRand = rRand * std::cos(fSPhi + fDPhi);
996  yRand = rRand * std::sin(fSPhi + fDPhi);
997  zRand = UUtils::Random(-1.*fDz, fDz);
998  return UVector3(xRand, yRand, zRand + 0.5 * (zTwo + zOne));
999 }
1000 
1001 
1002 //
1003 // GetPointOnRing
1004 //
1005 // Auxiliary method for GetPoint On Surface
1006 //
1007 UVector3 UPolycone::GetPointOnRing(double fRMin1, double fRMax1,
1008  double fRMin2, double fRMax2,
1009  double zOne) const
1010 {
1011  double xRand, yRand, phi, cosphi, sinphi, rRand1, rRand2, A1, Atot, rCh;
1012  phi = UUtils::Random(startPhi, endPhi);
1013  cosphi = std::cos(phi);
1014  sinphi = std::sin(phi);
1015 
1016  if (fRMin1 == fRMin2)
1017  {
1018  rRand1 = fRMin1;
1019  A1 = 0.;
1020  }
1021  else
1022  {
1023  rRand1 = UUtils::Random(fRMin1, fRMin2);
1024  A1 = std::fabs(fRMin2 * fRMin2 - fRMin1 * fRMin1);
1025  }
1026  if (fRMax1 == fRMax2)
1027  {
1028  rRand2 = fRMax1;
1029  Atot = A1;
1030  }
1031  else
1032  {
1033  rRand2 = UUtils::Random(fRMax1, fRMax2);
1034  Atot = A1 + std::fabs(fRMax2 * fRMax2 - fRMax1 * fRMax1);
1035  }
1036  rCh = UUtils::Random(0., Atot);
1037 
1038  if (rCh > A1)
1039  {
1040  rRand1 = rRand2;
1041  }
1042 
1043  xRand = rRand1 * cosphi;
1044  yRand = rRand1 * sinphi;
1045 
1046  return UVector3(xRand, yRand, zOne);
1047 }
1048 
1049 
1050 //
1051 // GetPointOnCut
1052 //
1053 // Auxiliary method for Get Point On Surface
1054 //
1055 UVector3 UPolycone::GetPointOnCut(double fRMin1, double fRMax1,
1056  double fRMin2, double fRMax2,
1057  double zOne, double zTwo,
1058  double& totArea) const
1059 {
1060  if (zOne == zTwo)
1061  {
1062  return GetPointOnRing(fRMin1, fRMax1, fRMin2, fRMax2, zOne);
1063  }
1064  if ((fRMin1 == fRMin2) && (fRMax1 == fRMax2))
1065  {
1066  return GetPointOnTubs(fRMin1, fRMax1, zOne, zTwo, totArea);
1067  }
1068  return GetPointOnCone(fRMin1, fRMax1, fRMin2, fRMax2, zOne, zTwo, totArea);
1069 }
1070 
1071 
1072 //
1073 // GetPointOnSurface
1074 //
1076 {
1077  double Area = 0, totArea = 0, Achose1 = 0, Achose2 = 0, phi, cosphi, sinphi, rRand;
1078  int i = 0;
1079  int numPlanes = fOriginalParameters->fNumZPlanes;
1080 
1081  phi = UUtils::Random(startPhi, endPhi);
1082  cosphi = std::cos(phi);
1083  sinphi = std::sin(phi);
1084 
1085  rRand = fOriginalParameters->Rmin[0] +
1087  * std::sqrt(UUtils::Random()));
1088 
1089  std::vector<double> areas; // (numPlanes+1);
1090  std::vector<UVector3> points; // (numPlanes-1);
1091 
1092  areas.push_back(UUtils::kPi * (UUtils::sqr(fOriginalParameters->Rmax[0])
1094 
1095  for (i = 0; i < numPlanes - 1; i++)
1096  {
1097  Area = (fOriginalParameters->Rmin[i] + fOriginalParameters->Rmin[i + 1])
1098  * std::sqrt(UUtils::sqr(fOriginalParameters->Rmin[i]
1099  - fOriginalParameters->Rmin[i + 1]) +
1101  - fOriginalParameters->fZValues[i]));
1102 
1103  Area += (fOriginalParameters->Rmax[i] + fOriginalParameters->Rmax[i + 1])
1104  * std::sqrt(UUtils::sqr(fOriginalParameters->Rmax[i]
1105  - fOriginalParameters->Rmax[i + 1]) +
1107  - fOriginalParameters->fZValues[i]));
1108 
1109  Area *= 0.5 * (endPhi - startPhi);
1110 
1111  if (startPhi == 0. && endPhi == 2 * UUtils::kPi)
1112  {
1113  Area += std::fabs(fOriginalParameters->fZValues[i + 1]
1114  - fOriginalParameters->fZValues[i]) *
1116  + fOriginalParameters->Rmax[i + 1]
1118  - fOriginalParameters->Rmin[i + 1]);
1119  }
1120  areas.push_back(Area);
1121  totArea += Area;
1122  }
1123 
1124  areas.push_back(UUtils::kPi * (UUtils::sqr(fOriginalParameters->Rmax[numPlanes - 1]) -
1125  UUtils::sqr(fOriginalParameters->Rmin[numPlanes - 1])));
1126 
1127  totArea += (areas[0] + areas[numPlanes]);
1128  double chose = UUtils::Random(0., totArea);
1129 
1130  if ((chose >= 0.) && (chose < areas[0]))
1131  {
1132  return UVector3(rRand * cosphi, rRand * sinphi,
1134  }
1135 
1136  for (i = 0; i < numPlanes - 1; i++)
1137  {
1138  Achose1 += areas[i];
1139  Achose2 = (Achose1 + areas[i + 1]);
1140  if (chose >= Achose1 && chose < Achose2)
1141  {
1144  fOriginalParameters->Rmin[i + 1],
1145  fOriginalParameters->Rmax[i + 1],
1147  fOriginalParameters->fZValues[i + 1], Area);
1148  }
1149  }
1150 
1151  rRand = fOriginalParameters->Rmin[numPlanes - 1] +
1152  ((fOriginalParameters->Rmax[numPlanes - 1] - fOriginalParameters->Rmin[numPlanes - 1])
1153  * std::sqrt(UUtils::Random()));
1154 
1155  return UVector3(rRand * cosphi, rRand * sinphi,
1156  fOriginalParameters->fZValues[numPlanes - 1]);
1157 
1158 }
1159 
1160 //
1161 // UPolyconeHistorical stuff
1162 //
1163 
1165  : fStartAngle(0.), fOpeningAngle(0.), fNumZPlanes(0),
1166  fZValues(0), Rmin(0), Rmax(0)
1167 {
1168 }
1169 
1171 {
1172 }
1173 
1176 {
1177  fStartAngle = source.fStartAngle;
1178  fOpeningAngle = source.fOpeningAngle;
1179  fNumZPlanes = source.fNumZPlanes;
1180 
1181  fZValues.resize(fNumZPlanes);
1182  Rmin.resize(fNumZPlanes);
1183  Rmax.resize(fNumZPlanes);
1184 
1185  for (int i = 0; i < fNumZPlanes; i++)
1186  {
1187  fZValues[i] = source.fZValues[i];
1188  Rmin[i] = source.Rmin[i];
1189  Rmax[i] = source.Rmax[i];
1190  }
1191 }
1192 
1195 {
1196  if (&right == this) return *this;
1197 
1198  if (&right)
1199  {
1200  fStartAngle = right.fStartAngle;
1201  fOpeningAngle = right.fOpeningAngle;
1202  fNumZPlanes = right.fNumZPlanes;
1203 
1204  fZValues.resize(fNumZPlanes);
1205  Rmin.resize(fNumZPlanes);
1206  Rmax.resize(fNumZPlanes);
1207 
1208  for (int i = 0; i < fNumZPlanes; i++)
1209  {
1210  fZValues[i] = right.fZValues[i];
1211  Rmin[i] = right.Rmin[i];
1212  Rmax[i] = right.Rmax[i];
1213  }
1214  }
1215  return *this;
1216 }
1217 
1219 {
1220  return new UPolycone(*this);
1221 }
1222 //
1223 // Copy constructor
1224 //
1225 UPolycone::UPolycone(const UPolycone& source): VUSolid(source)
1226 {
1227  CopyStuff(source);
1228 }
1229 
1230 
1231 //
1232 // Assignment operator
1233 //
1235 {
1236  if (this == &source) return *this;
1237 
1238  //VUSolid::operator=( source );
1239 
1240  //delete [] corners;
1241 
1242  delete enclosingCylinder;
1243 
1244  CopyStuff(source);
1245 
1246  return *this;
1247 }
1248 //
1249 // CopyStuff
1250 //
1251 void UPolycone::CopyStuff(const UPolycone& source)
1252 {
1253  //
1254  // Simple stuff
1255  //
1256 
1257  startPhi = source.startPhi;
1258  endPhi = source.endPhi;
1259  phiIsOpen = source.phiIsOpen;
1260  fCubicVolume = source.fCubicVolume;
1261  fSurfaceArea = source.fSurfaceArea;
1262  //
1263  // The array of planes
1264  //
1266  //
1267  // Enclosing cylinder
1268  //
1270 }
1271 //
1272 // Get Entity Type
1273 //
1275 {
1276  return "Polycone";
1277 }
1278 //
1279 // Set Original Parameters
1280 //
1282 {
1283  int numPlanes = (int)numCorner;
1284  bool isConvertible = true;
1285  double Zmax = rz->Bmax();
1286  rz->StartWithZMin();
1287 
1288  // Prepare vectors for storage
1289  //
1290  std::vector<double> Z;
1291  std::vector<double> Rmin;
1292  std::vector<double> Rmax;
1293 
1294  int countPlanes = 1;
1295  int icurr = 0;
1296  int icurl = 0;
1297 
1298  // first plane Z=Z[0]
1299  //
1300  Z.push_back(corners[0].z);
1301  double Zprev = Z[0];
1302  if (Zprev == corners[1].z)
1303  {
1304  Rmin.push_back(corners[0].r);
1305  Rmax.push_back(corners[1].r);
1306  icurr = 1;
1307  }
1308  else if (Zprev == corners[numPlanes - 1].z)
1309  {
1310  Rmin.push_back(corners[numPlanes - 1].r);
1311  Rmax.push_back(corners[0].r);
1312  icurl = numPlanes - 1;
1313  }
1314  else
1315  {
1316  Rmin.push_back(corners[0].r);
1317  Rmax.push_back(corners[0].r);
1318  }
1319 
1320  // next planes until last
1321  //
1322  int inextr = 0, inextl = 0;
1323  for (int i = 0; i < numPlanes - 2; i++)
1324  {
1325  inextr = 1 + icurr;
1326  inextl = (icurl <= 0) ? numPlanes - 1 : icurl - 1;
1327 
1328  if ((corners[inextr].z >= Zmax) & (corners[inextl].z >= Zmax))
1329  {
1330  break;
1331  }
1332 
1333  double Zleft = corners[inextl].z;
1334  double Zright = corners[inextr].z;
1335  if (Zright > Zleft)
1336  {
1337  Z.push_back(Zleft);
1338  countPlanes++;
1339  double difZr = corners[inextr].z - corners[icurr].z;
1340  double difZl = corners[inextl].z - corners[icurl].z;
1341 
1342  if (std::fabs(difZl) < frTolerance)
1343  {
1344  if (corners[inextl].r >= corners[icurl].r)
1345  {
1346  Rmin.push_back(corners[icurl].r);
1347  Rmax.push_back(Rmax[countPlanes - 2]);
1348  Rmax[countPlanes - 2] = corners[icurl].r;
1349  }
1350  else
1351  {
1352  Rmin.push_back(corners[inextl].r);
1353  Rmax.push_back(corners[icurl].r);
1354  }
1355  }
1356  else if (difZl >= frTolerance)
1357  {
1358  Rmin.push_back(corners[inextl].r);
1359  Rmax.push_back(corners[icurr].r + (Zleft - corners[icurr].z) / difZr
1360  * (corners[inextr].r - corners[icurr].r));
1361  }
1362  else
1363  {
1364  isConvertible = false;
1365  break;
1366  }
1367  icurl = (icurl == 0) ? numPlanes - 1 : icurl - 1;
1368  }
1369  else if (std::fabs(Zright - Zleft) < frTolerance) // Zright=Zleft
1370  {
1371  Z.push_back(Zleft);
1372  countPlanes++;
1373  icurr++;
1374 
1375  icurl = (icurl == 0) ? numPlanes - 1 : icurl - 1;
1376 
1377  Rmin.push_back(corners[inextl].r);
1378  Rmax.push_back(corners[inextr].r);
1379  }
1380  else // Zright<Zleft
1381  {
1382  Z.push_back(Zright);
1383  countPlanes++;
1384 
1385  double difZr = corners[inextr].z - corners[icurr].z;
1386  double difZl = corners[inextl].z - corners[icurl].z;
1387  if (std::fabs(difZr) < frTolerance)
1388  {
1389  if (corners[inextr].r >= corners[icurr].r)
1390  {
1391  Rmin.push_back(corners[icurr].r);
1392  Rmax.push_back(corners[inextr].r);
1393  }
1394  else
1395  {
1396  Rmin.push_back(corners[inextr].r);
1397  Rmax.push_back(corners[icurr].r);
1398  Rmax[countPlanes - 2] = corners[inextr].r;
1399  }
1400  icurr++;
1401  } // plate
1402  else if (difZr >= frTolerance)
1403  {
1404  if (std::fabs(difZl) < frTolerance)
1405  {
1406  Rmax.push_back(corners[inextr].r);
1407  Rmin.push_back(corners[icurr].r);
1408  }
1409  else
1410  {
1411  Rmax.push_back(corners[inextr].r);
1412  Rmin.push_back(corners[icurl].r + (Zright - corners[icurl].z) / difZl
1413  * (corners[inextl].r - corners[icurl].r));
1414  }
1415  icurr++;
1416  }
1417  else
1418  {
1419  isConvertible = false;
1420  break;
1421  }
1422  }
1423  } // end for loop
1424 
1425  // last plane Z=Zmax
1426  //
1427  Z.push_back(Zmax);
1428  countPlanes++;
1429  inextr = 1 + icurr;
1430  inextl = (icurl <= 0) ? numPlanes - 1 : icurl - 1;
1431 
1432  if (corners[inextr].z == corners[inextl].z)
1433  {
1434  Rmax.push_back(corners[inextr].r);
1435  Rmin.push_back(corners[inextl].r);
1436  }
1437  else
1438  {
1439  Rmax.push_back(corners[inextr].r);
1440  Rmin.push_back(corners[inextl].r);
1441  }
1442 
1443  // Set original parameters Rmin,Rmax,Z
1444  //
1445  if (isConvertible)
1446  {
1448  fOriginalParameters->fZValues.resize(numPlanes);
1449  fOriginalParameters->Rmin.resize(numPlanes);
1450  fOriginalParameters->Rmax.resize(numPlanes);
1451 
1452  for (int j = 0; j < countPlanes; j++)
1453  {
1454  fOriginalParameters->fZValues[j] = Z[j];
1455  fOriginalParameters->Rmax[j] = Rmax[j];
1456  fOriginalParameters->Rmin[j] = Rmin[j];
1457  }
1460  fOriginalParameters->fNumZPlanes = countPlanes;
1461 
1462  }
1463  else // Set parameters(r,z) with Rmin==0 as convention
1464  {
1465  std::ostringstream message;
1466  message << "Polycone " << GetName() << std::endl
1467  << "cannot be converted to Polycone with (Rmin,Rmaz,Z) parameters!";
1468  UUtils::Exception("G4Polycone::SetOriginalParameters()", "GeomSolids0002",
1469  Warning, 1, "can not convert");
1470 
1472 
1473  fOriginalParameters->fZValues.resize(numPlanes);
1474  fOriginalParameters->Rmin.resize(numPlanes);
1475  fOriginalParameters->Rmax.resize(numPlanes);
1476 
1477  for (int j = 0; j < numPlanes; j++)
1478  {
1480  fOriginalParameters->Rmax[j] = corners[j].r;
1481  fOriginalParameters->Rmin[j] = 0.0;
1482  }
1485  fOriginalParameters->fNumZPlanes = numPlanes;
1486  }
1487  return isConvertible;
1488 }
1489 //
1490 // Reset
1491 //
1493 {
1494  //
1495  // Clear old setup
1496  //
1497  delete enclosingCylinder;
1498 
1499  fCubicVolume = 0;
1500  fSurfaceArea = 0;
1501  double phiStart=fOriginalParameters->fStartAngle;
1502  double* Z, *R1, *R2;
1503  int num = fOriginalParameters->fNumZPlanes;
1504  Z = new double[num];
1505  R1 = new double[num];
1506  R2 = new double[num];
1507  for (int i = 0; i < num; i++)
1508  {
1509  Z[i] = fOriginalParameters->fZValues[i];
1510  R1[i] = fOriginalParameters->Rmin[i];
1511  R2[i] = fOriginalParameters->Rmax[i];
1512  }
1513 
1514  Init(phiStart, phiStart+ fOriginalParameters->fOpeningAngle, num, Z, R1, R2);
1515  delete [] R1;
1516  delete [] Z;
1517  delete [] R2;
1518 
1519 }
Definition: UTubs.hh:47
double SafetyFromOutside(const UVector3 &p) const
double GetRMin() const
double Amin() const
double GetRmin1() const
double DistanceToIn(const UVector3 &p, const UVector3 &v, double aPstep=UUtils::kInfinity) const
Definition: UPolycone.cc:490
std::vector< double > Rmin
Definition: UPolycone.hh:64
static double frTolerance
Definition: VUSolid.hh:31
double GetRmax2() const
std::vector< double > fZValues
Definition: UPolycone.hh:63
Int_t index
Definition: macro.C:9
UVector3 GetPointOnTubs(double fRMin, double fRMax, double zOne, double zTwo, double &totArea) const
Definition: UPolycone.cc:948
double SafetyFromInsideSection(int index, const UVector3 &p) const
Definition: UPolycone.hh:263
bool NormalSection(int index, const UVector3 &p, UVector3 &n) const
Definition: UPolycone.hh:279
int GetSection(double z) const
Definition: UPolycone.hh:287
typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData)
const std::string & GetName() const
Definition: VUSolid.hh:103
double fCubicVolume
Definition: UPolycone.hh:221
static double fgTolerance
Definition: VUSolid.hh:30
const char * p
Definition: xmltok.h:285
void CopyStuff(const UPolycone &source)
Definition: UPolycone.cc:1251
std::vector< UPolyconeSection > fSections
Definition: UPolycone.hh:258
UVector3 GetPointOnCut(double fRMin1, double fRMax1, double fRMin2, double fRMax2, double zOne, double zTwo, double &totArea) const
Definition: UPolycone.cc:1055
const XML_Char * name
Definition: expat.h:151
std::ostream & StreamInfo(std::ostream &os) const
Definition: UPolycone.cc:335
UPolyconeHistorical & operator=(const UPolyconeHistorical &right)
Definition: UPolycone.cc:1194
virtual bool Normal(const UVector3 &aPoint, UVector3 &aNormal) const =0
double GetRMax() const
virtual EnumInside Inside(const UVector3 &aPoint) const =0
double x
Definition: UVector3.hh:136
Definition: UBox.hh:33
Definition: UCons.hh:49
int numCorner
Definition: UPolycone.hh:218
VUSolid::EnumInside Inside(const UVector3 &p) const
Definition: UPolycone.cc:441
std::vector< double > Rmax
Definition: UPolycone.hh:65
int fMaxSection
Definition: UPolycone.hh:259
bool Normal(const UVector3 &aPoint, UVector3 &aNormal) const
Definition: UPolycone.cc:668
Char_t n[5]
static int BinarySearch(const std::vector< T > &vec, T value)
Definition: UVoxelizer.hh:58
double SafetyFromOutsideSection(int index, const UVector3 &p) const
Definition: UPolycone.hh:271
double GetDz() const
bool phiIsOpen
Definition: UPolycone.hh:217
virtual double DistanceToIn(const UVector3 &aPoint, const UVector3 &aDirection, double aPstep=UUtils::kInfinity) const =0
UVector3 GetPointOnSurface() const
Definition: UPolycone.cc:1075
Float_t Z
Definition: plot.C:39
void Init(double phiStart, double phiTotal, int numZPlanes, const double zPlane[], const double rInner[], const double rOuter[])
Definition: UPolycone.cc:107
double endPhi
Definition: UPolycone.hh:216
UPolyconeHistorical * fOriginalParameters
Definition: UPolycone.hh:220
double GetDz() const
UPolyconeSideRZ * corners
Definition: UPolycone.hh:219
UGeometryType GetEntityType() const
Definition: UPolycone.cc:1274
void Reset()
Definition: UPolycone.cc:1492
double Bmin() const
EnumInside
Definition: VUSolid.hh:23
tuple v
Definition: test.py:18
double DistanceToIn(const UVector3 &aPoint, const UVector3 &aDirection, double aPstep=UUtils::kInfinity) const
Definition: UBox.cc:117
double SurfaceArea()
Definition: UPolycone.cc:777
T sqr(const T &x)
Definition: UUtils.hh:142
double Capacity()
Definition: UPolycone.cc:760
double GetZHalfLength() const
Definition: UBox.hh:124
double Amax() const
jump r
Definition: plot.C:36
void SetOriginalParameters()
Definition: UPolycone.hh:224
VUSolid::EnumInside InsideSection(int index, const UVector3 &p) const
Definition: UPolycone.cc:373
void Set(double xx, double yy, double zz)
Definition: UVector3.hh:245
double GetRmax1() const
double SafetyFromOutside(const UVector3 &aPoint, bool aAccurate=false) const
Definition: UPolycone.cc:639
double fSurfaceArea
Definition: UPolycone.hh:222
VUSolid * Clone() const
Definition: UPolycone.cc:1218
double SafetyFromInside(const UVector3 &aPoint, bool aAccurate=false) const
Definition: UPolycone.cc:606
void Set(double dx, double dy, double dz)
Definition: UBox.cc:43
tuple z
Definition: test.py:28
int Zmax
std::string UGeometryType
Definition: UTypes.hh:70
EnumInside Inside(const UVector3 &aPoint) const
Definition: UBox.cc:97
UVector3 GetPointOnRing(double fRMin, double fRMax, double fRMin2, double fRMax2, double zOne) const
Definition: UPolycone.cc:1007
double Bmax() const
UVector3 GetPointOnCone(double fRmin1, double fRmax1, double fRmin2, double fRmax2, double zOne, double zTwo, double &totArea) const
Definition: UPolycone.cc:844
virtual double DistanceToOut(const UVector3 &aPoint, const UVector3 &aDirection, UVector3 &aNormalVector, bool &aConvex, double aPstep=UUtils::kInfinity) const =0
virtual ~UPolycone()
Definition: UPolycone.cc:324
UPolycone & operator=(const UPolycone &source)
Definition: UPolycone.cc:1234
void Exception(const char *originOfException, const char *exceptionCode, ExceptionSeverity severity, int level, const char *description)
Definition: UUtils.cc:177
double z
Definition: UVector3.hh:138
double startPhi
Definition: UPolycone.hh:215
UBox box
Definition: UPolycone.cc:32
std::vector< double > fZs
Definition: UPolycone.hh:257
UEnclosingCylinder * enclosingCylinder
Definition: UPolycone.hh:246
void Extent(UVector3 &aMin, UVector3 &aMax) const
Definition: UPolycone.cc:753
double Random(double min=0.0, double max=1.0)
Definition: UUtils.cc:69
double DistanceToOut(const UVector3 &aPoint, const UVector3 &aDirection, UVector3 &aNormalVector, bool &aConvex, double aPstep=UUtils::kInfinity) const
Definition: UPolycone.cc:532
double y
Definition: UVector3.hh:137
UPolycone(const std::string &name)
Definition: UPolycone.hh:81
virtual double Capacity()=0
Definition: VUSolid.cc:199
double GetRmin2() const