Geant4_10
USphere.hh
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 // USphere
12 //
13 // Class description:
14 //
15 // A USphere is, in the general case, a section of a spherical shell,
16 // between specified phi and theta angles
17 //
18 // The phi and theta segments are described by a starting angle,
19 // and the +ve delta angle for the shape.
20 // If the delta angle is >=2*UUtils::kPi, or >=UUtils::kPi the shape is treated as
21 // continuous in phi or theta respectively.
22 //
23 // Theta must lie between 0-UUtils::kPi (incl).
24 //
25 // Member Data:
26 //
27 // fRmin inner radius
28 // fRmax outer radius
29 //
30 // fSPhi starting angle of the segment in radians
31 // fDPhi delta angle of the segment in radians
32 //
33 // fSTheta starting angle of the segment in radians
34 // fDTheta delta angle of the segment in radians
35 //
36 //
37 // Note:
38 // Internally fSPhi & fDPhi are adjusted so that fDPhi<=2PI,
39 // and fDPhi+fSPhi<=2PI. This enables simpler comparisons to be
40 // made with (say) Phi of a point.
41 //
42 // 19.10.12 Marek Gayer
43 // Created from original implementation in Geant4
44 // --------------------------------------------------------------------
45 
46 #ifndef USphere_HH
47 #define USphere_HH
48 
49 #include <sstream>
50 
51 #include "VUSolid.hh"
52 
53 class UVisExtent;
54 
55 class USphere : public VUSolid
56 {
57  public: // with description
58 
59  USphere(const std::string& pName,
60  double pRmin, double pRmax,
61  double pSPhi, double pDPhi,
62  double pSTheta, double pDTheta);
63  //
64  // Constructs a sphere or sphere shell section
65  // with the given name and dimensions
66 
67  ~USphere();
68  //
69  // Destructor
70 
71  // Accessors
72 
73  inline double GetInnerRadius() const;
74  inline double GetOuterRadius() const;
75  inline double GetStartPhiAngle() const;
76  inline double GetDeltaPhiAngle() const;
77  inline double GetStartThetaAngle() const;
78  inline double GetDeltaThetaAngle() const;
79 
80  // Modifiers
81 
82  inline void SetInnerRadius(double newRMin);
83  inline void SetOuterRadius(double newRmax);
84  inline void SetStartPhiAngle(double newSphi, bool trig = true);
85  inline void SetDeltaPhiAngle(double newDphi);
86  inline void SetStartThetaAngle(double newSTheta);
87  inline void SetDeltaThetaAngle(double newDTheta);
88 
89  // Methods for solid
90 
91  inline double Capacity();
92  double SurfaceArea();
93 
94 
95  VUSolid::EnumInside Inside(const UVector3& p) const;
96 
97  bool Normal(const UVector3& p, UVector3& n) const;
98 
99  double DistanceToIn(const UVector3& p, const UVector3& v, double aPstep = UUtils::kInfinity) const;
100 
101  double SafetyFromOutside(const UVector3& p, bool aAccurate = false) const;
102 
103  double DistanceToOut(const UVector3& p, const UVector3& v, UVector3& n, bool& validNorm, double aPstep = UUtils::kInfinity) const;
104 
105 
106  double SafetyFromInside(const UVector3& p, bool aAccurate = false) const;
107 
109 
110  UVector3 GetPointOnSurface() const;
111 
112  VUSolid* Clone() const;
113 
114  std::ostream& StreamInfo(std::ostream& os) const;
115 
116  // Visualisation functions
117 
118  UVisExtent GetExtent() const;
119 
120 
121 
122  public: // without description
123 
124  void Extent(UVector3& aMin, UVector3& aMax) const;
125 
126  void GetParametersList(int /*aNumber*/, double* /*aArray*/) const;
127 
128 
129  virtual void ComputeBBox(UBBox* /*aBox*/, bool /*aStore = false*/) {}
130 
131  USphere(const USphere& rhs);
132  USphere& operator=(const USphere& rhs);
133  // Copy constructor and assignment operator.
134 
135  // Old access functions
136 
137  inline double GetRmin() const;
138  inline double GetRmax() const;
139  inline double GetSPhi() const;
140  inline double GetDPhi() const;
141  inline double GetSTheta() const;
142  inline double GetDTheta() const;
143  inline double GetInsideRadius() const;
144  inline void SetInsideRadius(double newRmin);
145 
146  private:
147 
148  double fCubicVolume;
149  double fSurfaceArea;
150  inline void Initialize();
151  //
152  // Reset relevant values to zero
153 
154  inline void CheckThetaAngles(double sTheta, double dTheta);
155  inline void CheckSPhiAngle(double sPhi);
156  inline void CheckDPhiAngle(double dPhi);
157  inline void CheckPhiAngles(double sPhi, double dPhi);
158  //
159  // Reset relevant flags and angle values
160 
161  inline void InitializePhiTrigonometry();
162  inline void InitializeThetaTrigonometry();
163  //
164  // Recompute relevant trigonometric values and cache them
165 
166  UVector3 ApproxSurfaceNormal(const UVector3& p) const;
167  //
168  // Algorithm for SurfaceNormal() following the original
169  // specification for points not on the surface
170 
171  private:
172 
173  // Used by distanceToOut
174  //
175  enum ESide {kNull, kRMin, kRMax, kSPhi, kEPhi, kSTheta, kETheta};
176 
177  // used by normal
178  //
179  enum ENorm {kNRMin, kNRMax, kNSPhi, kNEPhi, kNSTheta, kNETheta};
180 
181  double fRminTolerance, kTolerance, kAngTolerance,
182  kRadTolerance, fEpsilon;
183  //
184  // Radial and angular tolerances
185 
186  double fRmin, fRmax, fSPhi, fDPhi, fSTheta, fDTheta;
187  //
188  // Radial and angular dimensions
189 
190  double sinCPhi, cosCPhi, cosHDPhiOT, cosHDPhiIT,
191  sinSPhi, cosSPhi, sinEPhi, cosEPhi, hDPhi, cPhi, ePhi;
192  //
193  // Cached trigonometric values for Phi angle
194 
195  double sinSTheta, cosSTheta, sinETheta, cosETheta,
196  tanSTheta, tanSTheta2, tanETheta, tanETheta2, eTheta;
197  //
198  // Cached trigonometric values for Theta angle
199 
200  bool fFullPhiSphere, fFullThetaSphere, fFullSphere;
201  //
202  // Flags for identification of section, shell or full sphere
203 };
204 
205 inline
207 {
208  return fRmin;
209 }
210 
211 inline
213 {
214  return fRmin;
215 }
216 
217 inline
219 {
220  return fRmax;
221 }
222 
223 inline
225 {
226  return fSPhi;
227 }
228 
229 inline
231 {
232  return fDPhi;
233 }
234 
235 inline
237 {
238  return fSTheta;
239 }
240 
242 {
243  return fDTheta;
244 }
245 
246 inline
247 void USphere::Initialize()
248 {
249  fCubicVolume = 0.;
250  fSurfaceArea = 0.;
251 }
252 
253 inline
254 void USphere::InitializePhiTrigonometry()
255 {
256  hDPhi = 0.5 * fDPhi; // half delta phi
257  cPhi = fSPhi + hDPhi;
258  ePhi = fSPhi + fDPhi;
259 
260  sinCPhi = std::sin(cPhi);
261  cosCPhi = std::cos(cPhi);
262  cosHDPhiIT = std::cos(hDPhi - 0.5 * kAngTolerance); // inner/outer tol half dphi
263  cosHDPhiOT = std::cos(hDPhi + 0.5 * kAngTolerance);
264  sinSPhi = std::sin(fSPhi);
265  cosSPhi = std::cos(fSPhi);
266  sinEPhi = std::sin(ePhi);
267  cosEPhi = std::cos(ePhi);
268 }
269 
270 inline
271 void USphere::InitializeThetaTrigonometry()
272 {
273  eTheta = fSTheta + fDTheta;
274 
275  sinSTheta = std::sin(fSTheta);
276  cosSTheta = std::cos(fSTheta);
277  sinETheta = std::sin(eTheta);
278  cosETheta = std::cos(eTheta);
279 
280  tanSTheta = std::tan(fSTheta);
281  tanSTheta2 = tanSTheta * tanSTheta;
282  tanETheta = std::tan(eTheta);
283  tanETheta2 = tanETheta * tanETheta;
284 }
285 
286 inline
287 void USphere::CheckThetaAngles(double sTheta, double dTheta)
288 {
289  if ((sTheta < 0) || (sTheta > UUtils::kPi))
290  {
291  std::ostringstream message;
292  message << "sTheta outside 0-PI range." << std::endl
293  << "Invalid starting Theta angle for solid: " << GetName();
294  UUtils::Exception("USphere::CheckThetaAngles()", "GeomSolids0002",
295  FatalError, 1, message.str().c_str());
296  }
297  else
298  {
299  fSTheta = sTheta;
300  }
301  if (dTheta + sTheta >= UUtils::kPi)
302  {
303  fDTheta = UUtils::kPi - sTheta;
304  }
305  else if (dTheta > 0)
306  {
307  fDTheta = dTheta;
308  }
309  else
310  {
311  std::ostringstream message;
312  message << "Invalid dTheta." << std::endl
313  << "Negative delta-Theta (" << dTheta << "), for solid: "
314  << GetName();
315  UUtils::Exception("USphere::CheckThetaAngles()", "GeomSolids0002",
316  FatalError, 1, message.str().c_str());
317  }
318  if (fDTheta - fSTheta < UUtils::kPi)
319  {
320  fFullThetaSphere = false;
321  }
322  else
323  {
324  fFullThetaSphere = true ;
325  }
326  fFullSphere = fFullPhiSphere && fFullThetaSphere;
327 
328  InitializeThetaTrigonometry();
329 }
330 
331 inline
332 void USphere::CheckSPhiAngle(double sPhi)
333 {
334  // Ensure fSphi in 0-2PI or -2PI-0 range if shape crosses 0
335 
336  if (sPhi < 0)
337  {
338  fSPhi = 2 * UUtils::kPi - std::fmod(std::fabs(sPhi), 2 * UUtils::kPi);
339  }
340  else
341  {
342  fSPhi = std::fmod(sPhi, 2 * UUtils::kPi) ;
343  }
344  if (fSPhi + fDPhi > 2 * UUtils::kPi)
345  {
346  fSPhi -= 2 * UUtils::kPi ;
347  }
348 }
349 
350 inline
351 void USphere::CheckDPhiAngle(double dPhi)
352 {
353  fFullPhiSphere = true;
354  if (dPhi >= 2 * UUtils::kPi - kAngTolerance * 0.5)
355  {
356  fDPhi = 2 * UUtils::kPi;
357  fSPhi = 0;
358  }
359  else
360  {
361  fFullPhiSphere = false;
362  if (dPhi > 0)
363  {
364  fDPhi = dPhi;
365  }
366  else
367  {
368  std::ostringstream message;
369  message << "Invalid dphi." << std::endl
370  << "Negative delta-Phi (" << dPhi << "), for solid: "
371  << GetName();
372  UUtils::Exception("USphere::CheckDPhiAngle()", "GeomSolids0002",
373  FatalError, 1, message.str().c_str());
374  }
375  }
376 }
377 
378 inline
379 void USphere::CheckPhiAngles(double sPhi, double dPhi)
380 {
381  CheckDPhiAngle(dPhi);
382  //if (!fFullPhiSphere && sPhi) { CheckSPhiAngle(sPhi); }
383  if (!fFullPhiSphere)
384  {
385  CheckSPhiAngle(sPhi);
386  }
387  fFullSphere = fFullPhiSphere && fFullThetaSphere;
388 
389  InitializePhiTrigonometry();
390 }
391 
392 inline
393 void USphere::SetInsideRadius(double newRmin)
394 {
395  fRmin = newRmin;
396  fRminTolerance = (fRmin) ? std::max(kRadTolerance, fEpsilon * fRmin) : 0;
397  Initialize();
398 }
399 
400 inline
401 void USphere::SetInnerRadius(double newRmin)
402 {
403  SetInsideRadius(newRmin);
404 }
405 
406 inline
407 void USphere::SetOuterRadius(double newRmax)
408 {
409  fRmax = newRmax;
410  kTolerance = std::max(kRadTolerance, fEpsilon * fRmax);
411  Initialize();
412 }
413 
414 inline
415 void USphere::SetStartPhiAngle(double newSPhi, bool compute)
416 {
417  // Flag 'compute' can be used to explicitely avoid recomputation of
418  // trigonometry in case SetDeltaPhiAngle() is invoked afterwards
419 
420  CheckSPhiAngle(newSPhi);
421  fFullPhiSphere = false;
422  if (compute)
423  {
424  InitializePhiTrigonometry();
425  }
426  Initialize();
427 }
428 
429 inline
430 void USphere::SetDeltaPhiAngle(double newDPhi)
431 {
432  CheckPhiAngles(fSPhi, newDPhi);
433  Initialize();
434 }
435 
436 inline
437 void USphere::SetStartThetaAngle(double newSTheta)
438 {
439  CheckThetaAngles(newSTheta, fDTheta);
440  Initialize();
441 }
442 
443 inline
444 void USphere::SetDeltaThetaAngle(double newDTheta)
445 {
446  CheckThetaAngles(fSTheta, newDTheta);
447  Initialize();
448 }
449 
450 // Old access functions
451 
452 inline
453 double USphere::GetRmin() const
454 {
455  return GetInsideRadius();
456 }
457 
458 inline
459 double USphere::GetRmax() const
460 {
461  return GetOuterRadius();
462 }
463 
464 inline
465 double USphere::GetSPhi() const
466 {
467  return GetStartPhiAngle();
468 }
469 
470 inline
471 double USphere::GetDPhi() const
472 {
473  return GetDeltaPhiAngle();
474 }
475 
476 inline
477 double USphere::GetSTheta() const
478 {
479  return GetStartThetaAngle();
480 }
481 
482 inline
483 double USphere::GetDTheta() const
484 {
485  return GetDeltaThetaAngle();
486 }
487 
488 inline
490 {
491  if (fCubicVolume != 0.)
492  {
493  ;
494  }
495  else
496  {
497  fCubicVolume = fDPhi * (std::cos(fSTheta) - std::cos(fSTheta + fDTheta)) *
498  (fRmax * fRmax * fRmax - fRmin * fRmin * fRmin) / 3.;
499  }
500  return fCubicVolume;
501 }
502 
503 #endif
double GetInsideRadius() const
Definition: USphere.hh:206
~USphere()
Definition: USphere.cc:70
double GetDPhi() const
Definition: USphere.hh:471
double GetInnerRadius() const
Definition: USphere.hh:212
void SetStartPhiAngle(double newSphi, bool trig=true)
Definition: USphere.hh:415
const std::string & GetName() const
Definition: VUSolid.hh:103
void SetStartThetaAngle(double newSTheta)
Definition: USphere.hh:437
const char * p
Definition: xmltok.h:285
VUSolid::EnumInside Inside(const UVector3 &p) const
Definition: USphere.cc:164
void Extent(UVector3 &aMin, UVector3 &aMax) const
Definition: USphere.cc:2983
double DistanceToOut(const UVector3 &p, const UVector3 &v, UVector3 &n, bool &validNorm, double aPstep=UUtils::kInfinity) const
Definition: USphere.cc:1651
void SetInnerRadius(double newRMin)
Definition: USphere.hh:401
void SetDeltaThetaAngle(double newDTheta)
Definition: USphere.hh:444
double GetDeltaThetaAngle() const
Definition: USphere.hh:241
USphere & operator=(const USphere &rhs)
Definition: USphere.cc:103
double GetOuterRadius() const
Definition: USphere.hh:218
double DistanceToIn(const UVector3 &p, const UVector3 &v, double aPstep=UUtils::kInfinity) const
Definition: USphere.cc:611
UVector3 GetPointOnSurface() const
Definition: USphere.cc:2838
ENorm
Definition: G4Cons.cc:72
double SafetyFromOutside(const UVector3 &p, bool aAccurate=false) const
Definition: USphere.cc:1546
Char_t n[5]
UGeometryType GetEntityType() const
Definition: USphere.cc:2796
double GetDTheta() const
Definition: USphere.hh:483
UVisExtent GetExtent() const
EnumInside
Definition: VUSolid.hh:23
double GetSTheta() const
Definition: USphere.hh:477
tuple v
Definition: test.py:18
double Capacity()
Definition: USphere.hh:489
USphere(const std::string &pName, double pRmin, double pRmax, double pSPhi, double pDPhi, double pSTheta, double pDTheta)
Definition: USphere.cc:34
void SetInsideRadius(double newRmin)
Definition: USphere.hh:393
void GetParametersList(int, double *) const
Definition: USphere.cc:2989
T max(const T t1, const T t2)
brief Return the largest of the two arguments
void SetDeltaPhiAngle(double newDphi)
Definition: USphere.hh:430
double GetStartThetaAngle() const
Definition: USphere.hh:236
VUSolid * Clone() const
Definition: USphere.cc:2805
void SetOuterRadius(double newRmax)
Definition: USphere.hh:407
std::ostream & StreamInfo(std::ostream &os) const
Definition: USphere.cc:2814
virtual void ComputeBBox(UBBox *, bool)
Definition: USphere.hh:129
std::string UGeometryType
Definition: UTypes.hh:70
bool Normal(const UVector3 &p, UVector3 &n) const
Definition: USphere.cc:273
double GetSPhi() const
Definition: USphere.hh:465
double GetStartPhiAngle() const
Definition: USphere.hh:224
ESide
Definition: G4Cons.cc:68
void Exception(const char *originOfException, const char *exceptionCode, ExceptionSeverity severity, int level, const char *description)
Definition: UUtils.cc:177
double GetRmin() const
Definition: USphere.hh:453
double GetRmax() const
Definition: USphere.hh:459
double GetDeltaPhiAngle() const
Definition: USphere.hh:230
double SafetyFromInside(const UVector3 &p, bool aAccurate=false) const
Definition: USphere.cc:2557
double SurfaceArea()
Definition: USphere.cc:2935