ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4UEllipticalCone.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4UEllipticalCone.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 G4UEllipticalCone wrapper class
27 //
28 // 13-08-2019 Gabriele Cosmo, CERN
29 // --------------------------------------------------------------------
30 
31 #include "G4EllipticalCone.hh"
32 #include "G4UEllipticalCone.hh"
33 
34 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
35 
36 #include "G4AffineTransform.hh"
37 #include "G4VPVParameterisation.hh"
38 #include "G4PhysicalConstants.hh"
39 #include "G4BoundingEnvelope.hh"
40 #include "G4Polyhedron.hh"
41 
43 //
44 // Constructor - check & set half widths
45 
46 
47 G4UEllipticalCone::G4UEllipticalCone(const G4String& pName,
48  G4double a,
49  G4double b,
50  G4double h,
51  G4double cut )
52  : Base_t(pName, a, b, h, cut)
53 { }
54 
56 //
57 // Fake default constructor - sets only member data and allocates memory
58 // for usage restricted to object persistency.
59 
60 G4UEllipticalCone::G4UEllipticalCone( __void__& a )
61  : Base_t(a)
62 { }
63 
65 //
66 // Destructor
67 
68 G4UEllipticalCone::~G4UEllipticalCone() { }
69 
71 //
72 // Copy constructor
73 
74 G4UEllipticalCone::G4UEllipticalCone(const G4UEllipticalCone& rhs)
75  : Base_t(rhs)
76 { }
77 
79 //
80 // Assignment operator
81 
82 G4UEllipticalCone& G4UEllipticalCone::operator = (const G4UEllipticalCone& rhs)
83 {
84  // Check assignment to self
85  //
86  if (this == &rhs) { return *this; }
87 
88  // Copy base class data
89  //
90  Base_t::operator=(rhs);
91 
92  return *this;
93 }
94 
96 //
97 // Accessors
98 
99 G4double G4UEllipticalCone::GetSemiAxisX() const
100 {
101  return Base_t::GetSemiAxisX();
102 }
103 
104 G4double G4UEllipticalCone::GetSemiAxisY() const
105 {
106  return Base_t::GetSemiAxisY();
107 }
108 
109 G4double G4UEllipticalCone::GetZMax() const
110 {
111  return Base_t::GetZMax();
112 }
113 
114 G4double G4UEllipticalCone::GetZTopCut() const
115 {
116  return Base_t::GetZTopCut();
117 }
118 
119 G4double G4UEllipticalCone::GetSemiAxisMax () const
120 {
121  return std::max(GetSemiAxisX(),GetSemiAxisY());
122 }
123 
124 G4double G4UEllipticalCone::GetSemiAxisMin () const
125 {
126  return std::min(GetSemiAxisX(),GetSemiAxisY());
127 }
128 
130 //
131 // Modifiers
132 
133 void G4UEllipticalCone::SetSemiAxis(G4double x, G4double y, G4double z)
134 {
135  Base_t::SetParameters(x, y, z, GetZTopCut());
136 }
137 
138 void G4UEllipticalCone::SetZCut(G4double newzTopCut)
139 {
140  Base_t::SetParameters(GetSemiAxisX(), GetSemiAxisY(), GetZMax(), newzTopCut);
141 }
142 
144 //
145 // Make a clone of the object
146 
147 G4VSolid* G4UEllipticalCone::Clone() const
148 {
149  return new G4UEllipticalCone(*this);
150 }
151 
153 //
154 // Get bounding box
155 
156 void G4UEllipticalCone::BoundingLimits(G4ThreeVector& pMin,
157  G4ThreeVector& pMax) const
158 {
159  G4double zcut = GetZTopCut();
160  G4double height = GetZMax();
161  G4double xmax = GetSemiAxisX()*(height+zcut);
162  G4double ymax = GetSemiAxisY()*(height+zcut);
163  pMin.set(-xmax,-ymax,-zcut);
164  pMax.set( xmax, ymax, zcut);
165 
166  // Check correctness of the bounding box
167  //
168  if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
169  {
170  std::ostringstream message;
171  message << "Bad bounding box (min >= max) for solid: "
172  << GetName() << " !"
173  << "\npMin = " << pMin
174  << "\npMax = " << pMax;
175  G4Exception("G4UEllipticalCone::BoundingLimits()", "GeomMgt0001",
176  JustWarning, message);
177  StreamInfo(G4cout);
178  }
179 }
180 
182 //
183 // Calculate extent under transform and specified limit
184 
185 G4bool
186 G4UEllipticalCone::CalculateExtent(const EAxis pAxis,
187  const G4VoxelLimits& pVoxelLimit,
188  const G4AffineTransform& pTransform,
189  G4double& pMin, G4double& pMax) const
190 {
191  G4ThreeVector bmin,bmax;
192  G4bool exist;
193 
194  // Check bounding box (bbox)
195  //
196  BoundingLimits(bmin,bmax);
197  G4BoundingEnvelope bbox(bmin,bmax);
198 #ifdef G4BBOX_EXTENT
199  return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
200 #endif
201  if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
202  {
203  return exist = (pMin < pMax) ? true : false;
204  }
205 
206  // Set bounding envelope (benv) and calculate extent
207  //
208  static const G4int NSTEPS = 48; // number of steps for whole circle
209  static const G4double ang = twopi/NSTEPS;
210  static const G4double sinHalf = std::sin(0.5*ang);
211  static const G4double cosHalf = std::cos(0.5*ang);
212  static const G4double sinStep = 2.*sinHalf*cosHalf;
213  static const G4double cosStep = 1. - 2.*sinHalf*sinHalf;
214  G4double zcut = bmax.z();
215  G4double height = GetZMax();
216  G4double sxmin = GetSemiAxisX()*(height-zcut)/cosHalf;
217  G4double symin = GetSemiAxisY()*(height-zcut)/cosHalf;
218  G4double sxmax = bmax.x()/cosHalf;
219  G4double symax = bmax.y()/cosHalf;
220 
221  G4double sinCur = sinHalf;
222  G4double cosCur = cosHalf;
223  G4ThreeVectorList baseA(NSTEPS),baseB(NSTEPS);
224  for (G4int k=0; k<NSTEPS; ++k)
225  {
226  baseA[k].set(sxmax*cosCur,symax*sinCur,-zcut);
227  baseB[k].set(sxmin*cosCur,symin*sinCur, zcut);
228 
229  G4double sinTmp = sinCur;
230  sinCur = sinCur*cosStep + cosCur*sinStep;
231  cosCur = cosCur*cosStep - sinTmp*sinStep;
232  }
233 
234  std::vector<const G4ThreeVectorList *> polygons(2);
235  polygons[0] = &baseA;
236  polygons[1] = &baseB;
237  G4BoundingEnvelope benv(bmin,bmax,polygons);
238  exist = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
239  return exist;
240 }
241 
243 //
244 // CreatePolyhedron
245 //
246 G4Polyhedron* G4UEllipticalCone::CreatePolyhedron() const
247 {
248  return new G4PolyhedronEllipticalCone(GetSemiAxisX(), GetSemiAxisY(),
249  GetZMax(), GetZTopCut());
250 }
251 
252 #endif // G4GEOM_USE_USOLIDS