ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4UOrb.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4UOrb.cc
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 // Implementation for G4UOrb wrapper class
27 //
28 // 30.10.13 G.Cosmo, CERN/PH
29 // --------------------------------------------------------------------
30 
31 #include "G4Orb.hh"
32 #include "G4UOrb.hh"
33 
34 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
35 
36 #include "G4TwoVector.hh"
37 #include "G4AffineTransform.hh"
38 #include "G4GeometryTolerance.hh"
39 #include "G4BoundingEnvelope.hh"
40 
41 #include "G4VPVParameterisation.hh"
42 #include "G4PhysicalConstants.hh"
43 
44 using namespace CLHEP;
45 
47 //
48 // constructor - check positive radius
49 //
50 
51 G4UOrb::G4UOrb( const G4String& pName, G4double pRmax )
52  : Base_t(pName, pRmax)
53 {
54 }
55 
57 //
58 // Fake default constructor - sets only member data and allocates memory
59 // for usage restricted to object persistency.
60 //
61 G4UOrb::G4UOrb( __void__& a )
62  : Base_t(a)
63 {
64 }
65 
67 //
68 // Destructor
69 
70 G4UOrb::~G4UOrb()
71 {
72 }
73 
75 //
76 // Copy constructor
77 
78 G4UOrb::G4UOrb(const G4UOrb& rhs)
79  : Base_t(rhs)
80 {
81 }
82 
84 //
85 // Assignment operator
86 
87 G4UOrb& G4UOrb::operator = (const G4UOrb& rhs)
88 {
89  // Check assignment to self
90  //
91  if (this == &rhs) { return *this; }
92 
93  // Copy base class data
94  //
95  Base_t::operator=(rhs);
96 
97  return *this;
98 }
99 
101 //
102 // Accessors & modifiers
103 
104 G4double G4UOrb::GetRadius() const
105 {
106  return Base_t::GetRadius();
107 }
108 
109 void G4UOrb::SetRadius(G4double newRmax)
110 {
111  Base_t::SetRadius(newRmax);
112  fRebuildPolyhedron = true;
113 }
114 
115 G4double G4UOrb::GetRadialTolerance() const
116 {
117  return Base_t::GetRadialTolerance();
118 }
119 
121 //
122 // Dispatch to parameterisation for replication mechanism dimension
123 // computation & modification.
124 
125 void G4UOrb::ComputeDimensions( G4VPVParameterisation* p,
126  const G4int n,
127  const G4VPhysicalVolume* pRep )
128 {
129  p->ComputeDimensions(*(G4Orb*)this,n,pRep);
130 }
131 
133 //
134 // Make a clone of the object
135 
136 G4VSolid* G4UOrb::Clone() const
137 {
138  return new G4UOrb(*this);
139 }
140 
142 //
143 // Get bounding box
144 
145 void G4UOrb::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
146 {
147  G4double radius = GetRadius();
148  pMin.set(-radius,-radius,-radius);
149  pMax.set( radius, radius, radius);
150 
151  // Check correctness of the bounding box
152  //
153  if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
154  {
155  std::ostringstream message;
156  message << "Bad bounding box (min >= max) for solid: "
157  << GetName() << " !"
158  << "\npMin = " << pMin
159  << "\npMax = " << pMax;
160  G4Exception("G4UOrb::BoundingLimits()", "GeomMgt0001",
161  JustWarning, message);
162  StreamInfo(G4cout);
163  }
164 }
165 
167 //
168 // Calculate extent under transform and specified limit
169 
170 G4bool
171 G4UOrb::CalculateExtent(const EAxis pAxis,
172  const G4VoxelLimits& pVoxelLimit,
173  const G4AffineTransform& pTransform,
174  G4double& pMin, G4double& pMax) const
175 {
176  G4ThreeVector bmin, bmax;
177  G4bool exist;
178 
179  // Get bounding box
180  BoundingLimits(bmin,bmax);
181 
182  // Check bounding box
183  G4BoundingEnvelope bbox(bmin,bmax);
184 #ifdef G4BBOX_EXTENT
185  if (true) return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
186 #endif
187  if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
188  {
189  return exist = (pMin < pMax) ? true : false;
190  }
191 
192  // Find bounding envelope and calculate extent
193  //
194  static const G4int NTHETA = 8; // number of steps along Theta
195  static const G4int NPHI = 16; // number of steps along Phi
196  static const G4double sinHalfTheta = std::sin(halfpi/NTHETA);
197  static const G4double cosHalfTheta = std::cos(halfpi/NTHETA);
198  static const G4double sinHalfPhi = std::sin(pi/NPHI);
199  static const G4double cosHalfPhi = std::cos(pi/NPHI);
200  static const G4double sinStepTheta = 2.*sinHalfTheta*cosHalfTheta;
201  static const G4double cosStepTheta = 1. - 2.*sinHalfTheta*sinHalfTheta;
202  static const G4double sinStepPhi = 2.*sinHalfPhi*cosHalfPhi;
203  static const G4double cosStepPhi = 1. - 2.*sinHalfPhi*sinHalfPhi;
204 
205  G4double radius = GetRadius();
206  G4double rtheta = radius/cosHalfTheta;
207  G4double rphi = rtheta/cosHalfPhi;
208 
209  // set reference circle
210  G4TwoVector xy[NPHI];
211  G4double sinCurPhi = sinHalfPhi;
212  G4double cosCurPhi = cosHalfPhi;
213  for (G4int k=0; k<NPHI; ++k)
214  {
215  xy[k].set(cosCurPhi,sinCurPhi);
216  G4double sinTmpPhi = sinCurPhi;
217  sinCurPhi = sinCurPhi*cosStepPhi + cosCurPhi*sinStepPhi;
218  cosCurPhi = cosCurPhi*cosStepPhi - sinTmpPhi*sinStepPhi;
219  }
220 
221  // set bounding circles
222  G4ThreeVectorList circles[NTHETA];
223  for (G4int i=0; i<NTHETA; ++i) circles[i].resize(NPHI);
224 
225  G4double sinCurTheta = sinHalfTheta;
226  G4double cosCurTheta = cosHalfTheta;
227  for (G4int i=0; i<NTHETA; ++i)
228  {
229  G4double z = rtheta*cosCurTheta;
230  G4double rho = rphi*sinCurTheta;
231  for (G4int k=0; k<NPHI; ++k)
232  {
233  circles[i][k].set(rho*xy[k].x(),rho*xy[k].y(),z);
234  }
235  G4double sinTmpTheta = sinCurTheta;
236  sinCurTheta = sinCurTheta*cosStepTheta + cosCurTheta*sinStepTheta;
237  cosCurTheta = cosCurTheta*cosStepTheta - sinTmpTheta*sinStepTheta;
238  }
239 
240  // set envelope and calculate extent
241  std::vector<const G4ThreeVectorList *> polygons;
242  polygons.resize(NTHETA);
243  for (G4int i=0; i<NTHETA; ++i) polygons[i] = &circles[i];
244 
245  G4BoundingEnvelope benv(bmin,bmax,polygons);
246  exist = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
247  return exist;
248 }
249 
251 //
252 // Create polyhedron for visualization
253 
254 G4Polyhedron* G4UOrb::CreatePolyhedron() const
255 {
256  return new G4PolyhedronSphere(0., GetRadius(), 0., twopi, 0., pi);
257 }
258 
259 #endif // G4GEOM_USE_USOLIDS