Geant4 Cross Reference |
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 42 //////////////////////////////////////////////////////////////////////// 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 55 ////////////////////////////////////////////////////////////////////////// 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 64 ////////////////////////////////////////////////////////////////////////// 65 // 66 // Destructor 67 68 G4UEllipticalCone::~G4UEllipticalCone() = default; 69 70 ////////////////////////////////////////////////////////////////////////// 71 // 72 // Copy constructor 73 74 G4UEllipticalCone::G4UEllipticalCone(const G4UEllipticalCone& rhs) 75 : Base_t(rhs) 76 { } 77 78 ////////////////////////////////////////////////////////////////////////// 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 95 ////////////////////////////////////////////////////////////////////////// 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 129 ////////////////////////////////////////////////////////////////////////// 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 143 ////////////////////////////////////////////////////////////////////////// 144 // 145 // Make a clone of the object 146 147 G4VSolid* G4UEllipticalCone::Clone() const 148 { 149 return new G4UEllipticalCone(*this); 150 } 151 152 ////////////////////////////////////////////////////////////////////////// 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 181 ////////////////////////////////////////////////////////////////////////// 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; 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 242 //////////////////////////////////////////////////////////////////////// 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 253