Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // Implementation for G4UCutTubs wrapper class << 27 // 26 // 28 // 07.07.17 G.Cosmo, CERN/PH << 27 // $Id:$ >> 28 // >> 29 // >> 30 // Implementation for G4UCutTubs wrapper class 29 // ------------------------------------------- 31 // -------------------------------------------------------------------- 30 32 31 #include "G4CutTubs.hh" 33 #include "G4CutTubs.hh" 32 #include "G4UCutTubs.hh" 34 #include "G4UCutTubs.hh" 33 35 34 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G 36 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) ) 35 37 36 #include "G4GeomTools.hh" 38 #include "G4GeomTools.hh" 37 #include "G4AffineTransform.hh" 39 #include "G4AffineTransform.hh" 38 #include "G4VPVParameterisation.hh" 40 #include "G4VPVParameterisation.hh" 39 #include "G4BoundingEnvelope.hh" 41 #include "G4BoundingEnvelope.hh" 40 42 41 using namespace CLHEP; 43 using namespace CLHEP; 42 44 43 ////////////////////////////////////////////// 45 ///////////////////////////////////////////////////////////////////////// 44 // 46 // 45 // Constructor - check parameters, convert ang 47 // Constructor - check parameters, convert angles so 0<sphi+dpshi<=2_PI 46 // - note if pdphi>2PI then reset 48 // - note if pdphi>2PI then reset to 2PI 47 49 48 G4UCutTubs::G4UCutTubs( const G4String& pName, 50 G4UCutTubs::G4UCutTubs( const G4String& pName, 49 G4double pRMin, 51 G4double pRMin, G4double pRMax, 50 G4double pDz, 52 G4double pDz, 51 G4double pSPhi, 53 G4double pSPhi, G4double pDPhi, 52 const G4ThreeVec << 54 G4ThreeVector pLowNorm, 53 const G4ThreeVec << 55 G4ThreeVector pHighNorm ) 54 : Base_t(pName, pRMin, pRMax, pDz, pSPhi, pD 56 : Base_t(pName, pRMin, pRMax, pDz, pSPhi, pDPhi, 55 pLowNorm.x(), pLowNorm.y(), pLowNor 57 pLowNorm.x(), pLowNorm.y(), pLowNorm.z(), 56 pHighNorm.x(), pHighNorm.y(), pHigh 58 pHighNorm.x(), pHighNorm.y(), pHighNorm.z()) 57 { 59 { 58 } 60 } 59 61 60 ////////////////////////////////////////////// 62 /////////////////////////////////////////////////////////////////////// 61 // 63 // 62 // Fake default constructor - sets only member 64 // Fake default constructor - sets only member data and allocates memory 63 // for usage restri 65 // for usage restricted to object persistency. 64 // 66 // 65 G4UCutTubs::G4UCutTubs( __void__& a ) 67 G4UCutTubs::G4UCutTubs( __void__& a ) 66 : Base_t(a) 68 : Base_t(a) 67 { 69 { 68 } 70 } 69 71 70 ////////////////////////////////////////////// 72 ////////////////////////////////////////////////////////////////////////// 71 // 73 // 72 // Destructor 74 // Destructor 73 75 74 G4UCutTubs::~G4UCutTubs() = default; << 76 G4UCutTubs::~G4UCutTubs() >> 77 { >> 78 } 75 79 76 ////////////////////////////////////////////// 80 ////////////////////////////////////////////////////////////////////////// 77 // 81 // 78 // Copy constructor 82 // Copy constructor 79 83 80 G4UCutTubs::G4UCutTubs(const G4UCutTubs& rhs) 84 G4UCutTubs::G4UCutTubs(const G4UCutTubs& rhs) 81 : Base_t(rhs) 85 : Base_t(rhs) 82 { 86 { 83 } 87 } 84 88 85 ////////////////////////////////////////////// 89 ////////////////////////////////////////////////////////////////////////// 86 // 90 // 87 // Assignment operator 91 // Assignment operator 88 92 89 G4UCutTubs& G4UCutTubs::operator = (const G4UC 93 G4UCutTubs& G4UCutTubs::operator = (const G4UCutTubs& rhs) 90 { 94 { 91 // Check assignment to self 95 // Check assignment to self 92 // 96 // 93 if (this == &rhs) { return *this; } 97 if (this == &rhs) { return *this; } 94 98 95 // Copy base class data 99 // Copy base class data 96 // 100 // 97 Base_t::operator=(rhs); 101 Base_t::operator=(rhs); 98 102 99 return *this; 103 return *this; 100 } 104 } 101 105 102 ////////////////////////////////////////////// 106 ///////////////////////////////////////////////////////////////////////// 103 // 107 // 104 // Accessors and modifiers 108 // Accessors and modifiers 105 109 106 G4double G4UCutTubs::GetInnerRadius() const 110 G4double G4UCutTubs::GetInnerRadius() const 107 { 111 { 108 return rmin(); 112 return rmin(); 109 } 113 } 110 G4double G4UCutTubs::GetOuterRadius() const 114 G4double G4UCutTubs::GetOuterRadius() const 111 { 115 { 112 return rmax(); 116 return rmax(); 113 } 117 } 114 G4double G4UCutTubs::GetZHalfLength() const 118 G4double G4UCutTubs::GetZHalfLength() const 115 { 119 { 116 return z(); 120 return z(); 117 } 121 } 118 G4double G4UCutTubs::GetStartPhiAngle() const 122 G4double G4UCutTubs::GetStartPhiAngle() const 119 { 123 { 120 return sphi(); 124 return sphi(); 121 } 125 } 122 G4double G4UCutTubs::GetDeltaPhiAngle() const 126 G4double G4UCutTubs::GetDeltaPhiAngle() const 123 { 127 { 124 return dphi(); 128 return dphi(); 125 } 129 } 126 G4double G4UCutTubs::GetSinStartPhi() const 130 G4double G4UCutTubs::GetSinStartPhi() const 127 { 131 { 128 return std::sin(GetStartPhiAngle()); 132 return std::sin(GetStartPhiAngle()); 129 } 133 } 130 G4double G4UCutTubs::GetCosStartPhi() const 134 G4double G4UCutTubs::GetCosStartPhi() const 131 { 135 { 132 return std::cos(GetStartPhiAngle()); 136 return std::cos(GetStartPhiAngle()); 133 } 137 } 134 G4double G4UCutTubs::GetSinEndPhi() const 138 G4double G4UCutTubs::GetSinEndPhi() const 135 { 139 { 136 return std::sin(GetStartPhiAngle()+GetDeltaP 140 return std::sin(GetStartPhiAngle()+GetDeltaPhiAngle()); 137 } 141 } 138 G4double G4UCutTubs::GetCosEndPhi() const 142 G4double G4UCutTubs::GetCosEndPhi() const 139 { 143 { 140 return std::cos(GetStartPhiAngle()+GetDeltaP 144 return std::cos(GetStartPhiAngle()+GetDeltaPhiAngle()); 141 } 145 } 142 G4ThreeVector G4UCutTubs::GetLowNorm () const 146 G4ThreeVector G4UCutTubs::GetLowNorm () const 143 { 147 { 144 U3Vector lc = BottomNormal(); 148 U3Vector lc = BottomNormal(); 145 return {lc.x(), lc.y(), lc.z()}; << 149 return G4ThreeVector(lc.x(), lc.y(), lc.z()); 146 } 150 } 147 G4ThreeVector G4UCutTubs::GetHighNorm () const 151 G4ThreeVector G4UCutTubs::GetHighNorm () const 148 { 152 { 149 U3Vector hc = TopNormal(); 153 U3Vector hc = TopNormal(); 150 return {hc.x(), hc.y(), hc.z()}; << 154 return G4ThreeVector(hc.x(), hc.y(), hc.z()); 151 } 155 } 152 156 153 void G4UCutTubs::SetInnerRadius(G4double newRM 157 void G4UCutTubs::SetInnerRadius(G4double newRMin) 154 { 158 { 155 SetRMin(newRMin); 159 SetRMin(newRMin); 156 fRebuildPolyhedron = true; 160 fRebuildPolyhedron = true; 157 } 161 } 158 void G4UCutTubs::SetOuterRadius(G4double newRM 162 void G4UCutTubs::SetOuterRadius(G4double newRMax) 159 { 163 { 160 SetRMax(newRMax); 164 SetRMax(newRMax); 161 fRebuildPolyhedron = true; 165 fRebuildPolyhedron = true; 162 } 166 } 163 void G4UCutTubs::SetZHalfLength(G4double newDz 167 void G4UCutTubs::SetZHalfLength(G4double newDz) 164 { 168 { 165 SetDz(newDz); 169 SetDz(newDz); 166 fRebuildPolyhedron = true; 170 fRebuildPolyhedron = true; 167 } 171 } 168 void G4UCutTubs::SetStartPhiAngle(G4double new 172 void G4UCutTubs::SetStartPhiAngle(G4double newSPhi, G4bool) 169 { 173 { 170 SetSPhi(newSPhi); 174 SetSPhi(newSPhi); 171 fRebuildPolyhedron = true; 175 fRebuildPolyhedron = true; 172 } 176 } 173 void G4UCutTubs::SetDeltaPhiAngle(G4double new 177 void G4UCutTubs::SetDeltaPhiAngle(G4double newDPhi) 174 { 178 { 175 SetDPhi(newDPhi); 179 SetDPhi(newDPhi); 176 fRebuildPolyhedron = true; 180 fRebuildPolyhedron = true; 177 } 181 } 178 182 179 ////////////////////////////////////////////// 183 ///////////////////////////////////////////////////////////////////////// 180 // 184 // 181 // Make a clone of the object 185 // Make a clone of the object 182 186 183 G4VSolid* G4UCutTubs::Clone() const 187 G4VSolid* G4UCutTubs::Clone() const 184 { 188 { 185 return new G4UCutTubs(*this); 189 return new G4UCutTubs(*this); 186 } 190 } 187 191 188 ////////////////////////////////////////////// 192 ////////////////////////////////////////////////////////////////////////// 189 // 193 // 190 // Get bounding box 194 // Get bounding box 191 195 192 void G4UCutTubs::BoundingLimits(G4ThreeVector& 196 void G4UCutTubs::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const 193 { 197 { 194 static G4bool checkBBox = true; 198 static G4bool checkBBox = true; 195 199 196 G4double rmin = GetInnerRadius(); 200 G4double rmin = GetInnerRadius(); 197 G4double rmax = GetOuterRadius(); 201 G4double rmax = GetOuterRadius(); 198 G4double dz = GetZHalfLength(); 202 G4double dz = GetZHalfLength(); 199 G4double dphi = GetDeltaPhiAngle(); 203 G4double dphi = GetDeltaPhiAngle(); 200 204 201 G4double sinSphi = GetSinStartPhi(); 205 G4double sinSphi = GetSinStartPhi(); 202 G4double cosSphi = GetCosStartPhi(); 206 G4double cosSphi = GetCosStartPhi(); 203 G4double sinEphi = GetSinEndPhi(); 207 G4double sinEphi = GetSinEndPhi(); 204 G4double cosEphi = GetCosEndPhi(); 208 G4double cosEphi = GetCosEndPhi(); 205 209 206 G4ThreeVector norm; 210 G4ThreeVector norm; 207 G4double mag, topx, topy, dists, diste; 211 G4double mag, topx, topy, dists, diste; 208 G4bool iftop; 212 G4bool iftop; 209 213 210 // Find Zmin 214 // Find Zmin 211 // 215 // 212 G4double zmin; 216 G4double zmin; 213 norm = GetLowNorm(); 217 norm = GetLowNorm(); 214 mag = std::sqrt(norm.x()*norm.x() + norm.y( 218 mag = std::sqrt(norm.x()*norm.x() + norm.y()*norm.y()); 215 topx = (mag == 0) ? 0 : -rmax*norm.x()/mag; 219 topx = (mag == 0) ? 0 : -rmax*norm.x()/mag; 216 topy = (mag == 0) ? 0 : -rmax*norm.y()/mag; 220 topy = (mag == 0) ? 0 : -rmax*norm.y()/mag; 217 dists = sinSphi*topx - cosSphi*topy; 221 dists = sinSphi*topx - cosSphi*topy; 218 diste = -sinEphi*topx + cosEphi*topy; 222 diste = -sinEphi*topx + cosEphi*topy; 219 if (dphi > pi) 223 if (dphi > pi) 220 { 224 { 221 iftop = true; 225 iftop = true; 222 if (dists > 0 && diste > 0)iftop = false; 226 if (dists > 0 && diste > 0)iftop = false; 223 } 227 } 224 else 228 else 225 { 229 { 226 iftop = false; 230 iftop = false; 227 if (dists <= 0 && diste <= 0) iftop = true 231 if (dists <= 0 && diste <= 0) iftop = true; 228 } 232 } 229 if (iftop) 233 if (iftop) 230 { 234 { 231 zmin = -(norm.x()*topx + norm.y()*topy)/no 235 zmin = -(norm.x()*topx + norm.y()*topy)/norm.z() - dz; 232 } 236 } 233 else 237 else 234 { 238 { 235 G4double z1 = -rmin*(norm.x()*cosSphi + no 239 G4double z1 = -rmin*(norm.x()*cosSphi + norm.y()*sinSphi)/norm.z() - dz; 236 G4double z2 = -rmin*(norm.x()*cosEphi + no 240 G4double z2 = -rmin*(norm.x()*cosEphi + norm.y()*sinEphi)/norm.z() - dz; 237 G4double z3 = -rmax*(norm.x()*cosSphi + no 241 G4double z3 = -rmax*(norm.x()*cosSphi + norm.y()*sinSphi)/norm.z() - dz; 238 G4double z4 = -rmax*(norm.x()*cosEphi + no 242 G4double z4 = -rmax*(norm.x()*cosEphi + norm.y()*sinEphi)/norm.z() - dz; 239 zmin = std::min(std::min(std::min(z1,z2),z 243 zmin = std::min(std::min(std::min(z1,z2),z3),z4); 240 } 244 } 241 245 242 // Find Zmax 246 // Find Zmax 243 // 247 // 244 G4double zmax; 248 G4double zmax; 245 norm = GetHighNorm(); 249 norm = GetHighNorm(); 246 mag = std::sqrt(norm.x()*norm.x() + norm.y( 250 mag = std::sqrt(norm.x()*norm.x() + norm.y()*norm.y()); 247 topx = (mag == 0) ? 0 : -rmax*norm.x()/mag; 251 topx = (mag == 0) ? 0 : -rmax*norm.x()/mag; 248 topy = (mag == 0) ? 0 : -rmax*norm.y()/mag; 252 topy = (mag == 0) ? 0 : -rmax*norm.y()/mag; 249 dists = sinSphi*topx - cosSphi*topy; 253 dists = sinSphi*topx - cosSphi*topy; 250 diste = -sinEphi*topx + cosEphi*topy; 254 diste = -sinEphi*topx + cosEphi*topy; 251 if (dphi > pi) 255 if (dphi > pi) 252 { 256 { 253 iftop = true; 257 iftop = true; 254 if (dists > 0 && diste > 0) iftop = false; 258 if (dists > 0 && diste > 0) iftop = false; 255 } 259 } 256 else 260 else 257 { 261 { 258 iftop = false; 262 iftop = false; 259 if (dists <= 0 && diste <= 0) iftop = true 263 if (dists <= 0 && diste <= 0) iftop = true; 260 } 264 } 261 if (iftop) 265 if (iftop) 262 { 266 { 263 zmax = -(norm.x()*topx + norm.y()*topy)/no 267 zmax = -(norm.x()*topx + norm.y()*topy)/norm.z() + dz; 264 } 268 } 265 else 269 else 266 { 270 { 267 G4double z1 = -rmin*(norm.x()*cosSphi + no 271 G4double z1 = -rmin*(norm.x()*cosSphi + norm.y()*sinSphi)/norm.z() + dz; 268 G4double z2 = -rmin*(norm.x()*cosEphi + no 272 G4double z2 = -rmin*(norm.x()*cosEphi + norm.y()*sinEphi)/norm.z() + dz; 269 G4double z3 = -rmax*(norm.x()*cosSphi + no 273 G4double z3 = -rmax*(norm.x()*cosSphi + norm.y()*sinSphi)/norm.z() + dz; 270 G4double z4 = -rmax*(norm.x()*cosEphi + no 274 G4double z4 = -rmax*(norm.x()*cosEphi + norm.y()*sinEphi)/norm.z() + dz; 271 zmax = std::max(std::max(std::max(z1,z2),z 275 zmax = std::max(std::max(std::max(z1,z2),z3),z4); 272 } 276 } 273 277 274 // Find bounding box 278 // Find bounding box 275 // 279 // 276 if (GetDeltaPhiAngle() < twopi) 280 if (GetDeltaPhiAngle() < twopi) 277 { 281 { 278 G4TwoVector vmin,vmax; 282 G4TwoVector vmin,vmax; 279 G4GeomTools::DiskExtent(rmin,rmax, 283 G4GeomTools::DiskExtent(rmin,rmax, 280 GetSinStartPhi(),G 284 GetSinStartPhi(),GetCosStartPhi(), 281 GetSinEndPhi(),Get 285 GetSinEndPhi(),GetCosEndPhi(), 282 vmin,vmax); 286 vmin,vmax); 283 pMin.set(vmin.x(),vmin.y(), zmin); 287 pMin.set(vmin.x(),vmin.y(), zmin); 284 pMax.set(vmax.x(),vmax.y(), zmax); 288 pMax.set(vmax.x(),vmax.y(), zmax); 285 } 289 } 286 else 290 else 287 { 291 { 288 pMin.set(-rmax,-rmax, zmin); 292 pMin.set(-rmax,-rmax, zmin); 289 pMax.set( rmax, rmax, zmax); 293 pMax.set( rmax, rmax, zmax); 290 } 294 } 291 295 292 // Check correctness of the bounding box 296 // Check correctness of the bounding box 293 // 297 // 294 if (pMin.x() >= pMax.x() || pMin.y() >= pMax 298 if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z()) 295 { 299 { 296 std::ostringstream message; 300 std::ostringstream message; 297 message << "Bad bounding box (min >= max) 301 message << "Bad bounding box (min >= max) for solid: " 298 << GetName() << " !" 302 << GetName() << " !" 299 << "\npMin = " << pMin 303 << "\npMin = " << pMin 300 << "\npMax = " << pMax; 304 << "\npMax = " << pMax; 301 G4Exception("G4CUutTubs::BoundingLimits()" 305 G4Exception("G4CUutTubs::BoundingLimits()", "GeomMgt0001", 302 JustWarning, message); 306 JustWarning, message); 303 StreamInfo(G4cout); 307 StreamInfo(G4cout); 304 } 308 } 305 309 306 // Check consistency of bounding boxes 310 // Check consistency of bounding boxes 307 // 311 // 308 if (checkBBox) 312 if (checkBBox) 309 { 313 { 310 U3Vector vmin, vmax; 314 U3Vector vmin, vmax; 311 Extent(vmin,vmax); 315 Extent(vmin,vmax); 312 if (std::abs(pMin.x()-vmin.x()) > kCarTole 316 if (std::abs(pMin.x()-vmin.x()) > kCarTolerance || 313 std::abs(pMin.y()-vmin.y()) > kCarTole 317 std::abs(pMin.y()-vmin.y()) > kCarTolerance || 314 std::abs(pMin.z()-vmin.z()) > kCarTole 318 std::abs(pMin.z()-vmin.z()) > kCarTolerance || 315 std::abs(pMax.x()-vmax.x()) > kCarTole 319 std::abs(pMax.x()-vmax.x()) > kCarTolerance || 316 std::abs(pMax.y()-vmax.y()) > kCarTole 320 std::abs(pMax.y()-vmax.y()) > kCarTolerance || 317 std::abs(pMax.z()-vmax.z()) > kCarTole 321 std::abs(pMax.z()-vmax.z()) > kCarTolerance) 318 { 322 { 319 std::ostringstream message; 323 std::ostringstream message; 320 message << "Inconsistency in bounding bo 324 message << "Inconsistency in bounding boxes for solid: " 321 << GetName() << " !" 325 << GetName() << " !" 322 << "\nBBox min: wrapper = " << p 326 << "\nBBox min: wrapper = " << pMin << " solid = " << vmin 323 << "\nBBox max: wrapper = " << p 327 << "\nBBox max: wrapper = " << pMax << " solid = " << vmax; 324 G4Exception("G4UCutTubs::BoundingLimits( 328 G4Exception("G4UCutTubs::BoundingLimits()", "GeomMgt0001", 325 JustWarning, message); 329 JustWarning, message); 326 checkBBox = false; 330 checkBBox = false; 327 } 331 } 328 } 332 } 329 } 333 } 330 334 331 ////////////////////////////////////////////// 335 ////////////////////////////////////////////////////////////////////////// 332 // 336 // 333 // Calculate extent under transform and specif 337 // Calculate extent under transform and specified limit 334 338 335 G4bool 339 G4bool 336 G4UCutTubs::CalculateExtent(const EAxis pAxis, 340 G4UCutTubs::CalculateExtent(const EAxis pAxis, 337 const G4VoxelLimit 341 const G4VoxelLimits& pVoxelLimit, 338 const G4AffineTran 342 const G4AffineTransform& pTransform, 339 G4double& pM 343 G4double& pMin, G4double& pMax) const 340 { 344 { 341 G4ThreeVector bmin, bmax; 345 G4ThreeVector bmin, bmax; 342 G4bool exist; 346 G4bool exist; 343 347 344 // Get bounding box 348 // Get bounding box 345 BoundingLimits(bmin,bmax); 349 BoundingLimits(bmin,bmax); 346 350 347 // Check bounding box 351 // Check bounding box 348 G4BoundingEnvelope bbox(bmin,bmax); 352 G4BoundingEnvelope bbox(bmin,bmax); 349 #ifdef G4BBOX_EXTENT 353 #ifdef G4BBOX_EXTENT 350 if (true) return bbox.CalculateExtent(pAxis, 354 if (true) return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax); 351 #endif 355 #endif 352 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVox 356 if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax)) 353 { 357 { 354 return exist = pMin < pMax; << 358 return exist = (pMin < pMax) ? true : false; 355 } 359 } 356 360 357 // Get parameters of the solid 361 // Get parameters of the solid 358 G4double rmin = GetInnerRadius(); 362 G4double rmin = GetInnerRadius(); 359 G4double rmax = GetOuterRadius(); 363 G4double rmax = GetOuterRadius(); 360 G4double dphi = GetDeltaPhiAngle(); 364 G4double dphi = GetDeltaPhiAngle(); 361 G4double zmin = bmin.z(); 365 G4double zmin = bmin.z(); 362 G4double zmax = bmax.z(); 366 G4double zmax = bmax.z(); 363 367 364 // Find bounding envelope and calculate exte 368 // Find bounding envelope and calculate extent 365 // 369 // 366 const G4int NSTEPS = 24; // numbe 370 const G4int NSTEPS = 24; // number of steps for whole circle 367 G4double astep = twopi/NSTEPS; // max a 371 G4double astep = twopi/NSTEPS; // max angle for one step 368 G4int ksteps = (dphi <= astep) ? 1 : (G4i 372 G4int ksteps = (dphi <= astep) ? 1 : (G4int)((dphi-deg)/astep) + 1; 369 G4double ang = dphi/ksteps; 373 G4double ang = dphi/ksteps; 370 374 371 G4double sinHalf = std::sin(0.5*ang); 375 G4double sinHalf = std::sin(0.5*ang); 372 G4double cosHalf = std::cos(0.5*ang); 376 G4double cosHalf = std::cos(0.5*ang); 373 G4double sinStep = 2.*sinHalf*cosHalf; 377 G4double sinStep = 2.*sinHalf*cosHalf; 374 G4double cosStep = 1. - 2.*sinHalf*sinHalf; 378 G4double cosStep = 1. - 2.*sinHalf*sinHalf; 375 G4double rext = rmax/cosHalf; 379 G4double rext = rmax/cosHalf; 376 380 377 // bounding envelope for full cylinder consi 381 // bounding envelope for full cylinder consists of two polygons, 378 // in other cases it is a sequence of quadri 382 // in other cases it is a sequence of quadrilaterals 379 if (rmin == 0 && dphi == twopi) 383 if (rmin == 0 && dphi == twopi) 380 { 384 { 381 G4double sinCur = sinHalf; 385 G4double sinCur = sinHalf; 382 G4double cosCur = cosHalf; 386 G4double cosCur = cosHalf; 383 387 384 G4ThreeVectorList baseA(NSTEPS),baseB(NSTE 388 G4ThreeVectorList baseA(NSTEPS),baseB(NSTEPS); 385 for (G4int k=0; k<NSTEPS; ++k) 389 for (G4int k=0; k<NSTEPS; ++k) 386 { 390 { 387 baseA[k].set(rext*cosCur,rext*sinCur,zmi 391 baseA[k].set(rext*cosCur,rext*sinCur,zmin); 388 baseB[k].set(rext*cosCur,rext*sinCur,zma 392 baseB[k].set(rext*cosCur,rext*sinCur,zmax); 389 393 390 G4double sinTmp = sinCur; 394 G4double sinTmp = sinCur; 391 sinCur = sinCur*cosStep + cosCur*sinStep 395 sinCur = sinCur*cosStep + cosCur*sinStep; 392 cosCur = cosCur*cosStep - sinTmp*sinStep 396 cosCur = cosCur*cosStep - sinTmp*sinStep; 393 } 397 } 394 std::vector<const G4ThreeVectorList *> pol 398 std::vector<const G4ThreeVectorList *> polygons(2); 395 polygons[0] = &baseA; 399 polygons[0] = &baseA; 396 polygons[1] = &baseB; 400 polygons[1] = &baseB; 397 G4BoundingEnvelope benv(bmin,bmax,polygons 401 G4BoundingEnvelope benv(bmin,bmax,polygons); 398 exist = benv.CalculateExtent(pAxis,pVoxelL 402 exist = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax); 399 } 403 } 400 else 404 else 401 { 405 { 402 G4double sinStart = GetSinStartPhi(); 406 G4double sinStart = GetSinStartPhi(); 403 G4double cosStart = GetCosStartPhi(); 407 G4double cosStart = GetCosStartPhi(); 404 G4double sinEnd = GetSinEndPhi(); 408 G4double sinEnd = GetSinEndPhi(); 405 G4double cosEnd = GetCosEndPhi(); 409 G4double cosEnd = GetCosEndPhi(); 406 G4double sinCur = sinStart*cosHalf + cos 410 G4double sinCur = sinStart*cosHalf + cosStart*sinHalf; 407 G4double cosCur = cosStart*cosHalf - sin 411 G4double cosCur = cosStart*cosHalf - sinStart*sinHalf; 408 412 409 // set quadrilaterals 413 // set quadrilaterals 410 G4ThreeVectorList pols[NSTEPS+2]; 414 G4ThreeVectorList pols[NSTEPS+2]; 411 for (G4int k=0; k<ksteps+2; ++k) pols[k].r 415 for (G4int k=0; k<ksteps+2; ++k) pols[k].resize(4); 412 pols[0][0].set(rmin*cosStart,rmin*sinStart 416 pols[0][0].set(rmin*cosStart,rmin*sinStart,zmax); 413 pols[0][1].set(rmin*cosStart,rmin*sinStart 417 pols[0][1].set(rmin*cosStart,rmin*sinStart,zmin); 414 pols[0][2].set(rmax*cosStart,rmax*sinStart 418 pols[0][2].set(rmax*cosStart,rmax*sinStart,zmin); 415 pols[0][3].set(rmax*cosStart,rmax*sinStart 419 pols[0][3].set(rmax*cosStart,rmax*sinStart,zmax); 416 for (G4int k=1; k<ksteps+1; ++k) 420 for (G4int k=1; k<ksteps+1; ++k) 417 { 421 { 418 pols[k][0].set(rmin*cosCur,rmin*sinCur,z 422 pols[k][0].set(rmin*cosCur,rmin*sinCur,zmax); 419 pols[k][1].set(rmin*cosCur,rmin*sinCur,z 423 pols[k][1].set(rmin*cosCur,rmin*sinCur,zmin); 420 pols[k][2].set(rext*cosCur,rext*sinCur,z 424 pols[k][2].set(rext*cosCur,rext*sinCur,zmin); 421 pols[k][3].set(rext*cosCur,rext*sinCur,z 425 pols[k][3].set(rext*cosCur,rext*sinCur,zmax); 422 426 423 G4double sinTmp = sinCur; 427 G4double sinTmp = sinCur; 424 sinCur = sinCur*cosStep + cosCur*sinStep 428 sinCur = sinCur*cosStep + cosCur*sinStep; 425 cosCur = cosCur*cosStep - sinTmp*sinStep 429 cosCur = cosCur*cosStep - sinTmp*sinStep; 426 } 430 } 427 pols[ksteps+1][0].set(rmin*cosEnd,rmin*sin 431 pols[ksteps+1][0].set(rmin*cosEnd,rmin*sinEnd,zmax); 428 pols[ksteps+1][1].set(rmin*cosEnd,rmin*sin 432 pols[ksteps+1][1].set(rmin*cosEnd,rmin*sinEnd,zmin); 429 pols[ksteps+1][2].set(rmax*cosEnd,rmax*sin 433 pols[ksteps+1][2].set(rmax*cosEnd,rmax*sinEnd,zmin); 430 pols[ksteps+1][3].set(rmax*cosEnd,rmax*sin 434 pols[ksteps+1][3].set(rmax*cosEnd,rmax*sinEnd,zmax); 431 435 432 // set envelope and calculate extent 436 // set envelope and calculate extent 433 std::vector<const G4ThreeVectorList *> pol 437 std::vector<const G4ThreeVectorList *> polygons; 434 polygons.resize(ksteps+2); 438 polygons.resize(ksteps+2); 435 for (G4int k=0; k<ksteps+2; ++k) polygons[ 439 for (G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k]; 436 G4BoundingEnvelope benv(bmin,bmax,polygons 440 G4BoundingEnvelope benv(bmin,bmax,polygons); 437 exist = benv.CalculateExtent(pAxis,pVoxelL 441 exist = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax); 438 } 442 } 439 return exist; 443 return exist; 440 } 444 } 441 445 442 ////////////////////////////////////////////// 446 /////////////////////////////////////////////////////////////////////////// 443 // 447 // 444 // Return real Z coordinate of point on Cutted 448 // Return real Z coordinate of point on Cutted +/- fDZ plane 445 449 446 G4double G4UCutTubs::GetCutZ(const G4ThreeVect 450 G4double G4UCutTubs::GetCutZ(const G4ThreeVector& p) const 447 { 451 { 448 G4double newz = p.z(); // p.z() should be e 452 G4double newz = p.z(); // p.z() should be either +fDz or -fDz 449 G4ThreeVector fLowNorm = GetLowNorm(); 453 G4ThreeVector fLowNorm = GetLowNorm(); 450 G4ThreeVector fHighNorm = GetHighNorm(); 454 G4ThreeVector fHighNorm = GetHighNorm(); 451 455 452 if (p.z()<0) 456 if (p.z()<0) 453 { 457 { 454 if(fLowNorm.z()!=0.) 458 if(fLowNorm.z()!=0.) 455 { 459 { 456 newz = -GetZHalfLength() 460 newz = -GetZHalfLength() 457 - (p.x()*fLowNorm.x()+p.y()*fLowNo 461 - (p.x()*fLowNorm.x()+p.y()*fLowNorm.y())/fLowNorm.z(); 458 } 462 } 459 } 463 } 460 else 464 else 461 { 465 { 462 if(fHighNorm.z()!=0.) 466 if(fHighNorm.z()!=0.) 463 { 467 { 464 newz = GetZHalfLength() 468 newz = GetZHalfLength() 465 - (p.x()*fHighNorm.x()+p.y()*fHigh 469 - (p.x()*fHighNorm.x()+p.y()*fHighNorm.y())/fHighNorm.z(); 466 } 470 } 467 } 471 } 468 return newz; 472 return newz; 469 } 473 } 470 474 471 ////////////////////////////////////////////// 475 ////////////////////////////////////////////////////////////////////////// 472 // 476 // 473 // Create polyhedron for visualization 477 // Create polyhedron for visualization 474 // 478 // 475 G4Polyhedron* G4UCutTubs::CreatePolyhedron() c 479 G4Polyhedron* G4UCutTubs::CreatePolyhedron() const 476 { 480 { 477 typedef G4double G4double3[3]; 481 typedef G4double G4double3[3]; 478 typedef G4int G4int4[4]; 482 typedef G4int G4int4[4]; 479 483 480 auto ph = new G4Polyhedron; << 484 G4Polyhedron *ph = new G4Polyhedron; 481 G4Polyhedron *ph1 = new G4PolyhedronTubs(Get 485 G4Polyhedron *ph1 = new G4PolyhedronTubs(GetInnerRadius(), 482 Get 486 GetOuterRadius(), 483 Get 487 GetZHalfLength(), 484 Get 488 GetStartPhiAngle(), 485 Get 489 GetDeltaPhiAngle()); 486 G4int nn=ph1->GetNoVertices(); 490 G4int nn=ph1->GetNoVertices(); 487 G4int nf=ph1->GetNoFacets(); 491 G4int nf=ph1->GetNoFacets(); 488 auto xyz = new G4double3[nn]; // number of << 492 G4double3* xyz = new G4double3[nn]; // number of nodes 489 auto faces = new G4int4[nf] ; // number of << 493 G4int4* faces = new G4int4[nf] ; // number of faces 490 G4double fDz = GetZHalfLength(); 494 G4double fDz = GetZHalfLength(); 491 495 492 for(G4int i=0; i<nn; ++i) << 496 for(G4int i=0;i<nn;++i) 493 { 497 { 494 xyz[i][0]=ph1->GetVertex(i+1).x(); 498 xyz[i][0]=ph1->GetVertex(i+1).x(); 495 xyz[i][1]=ph1->GetVertex(i+1).y(); 499 xyz[i][1]=ph1->GetVertex(i+1).y(); 496 G4double tmpZ=ph1->GetVertex(i+1).z(); 500 G4double tmpZ=ph1->GetVertex(i+1).z(); 497 if (tmpZ>=fDz-kCarTolerance) << 501 if(tmpZ>=fDz-kCarTolerance) 498 { 502 { 499 xyz[i][2]=GetCutZ(G4ThreeVector(xyz[i][0 503 xyz[i][2]=GetCutZ(G4ThreeVector(xyz[i][0],xyz[i][1],fDz)); 500 } 504 } 501 else if(tmpZ<=-fDz+kCarTolerance) 505 else if(tmpZ<=-fDz+kCarTolerance) 502 { 506 { 503 xyz[i][2]=GetCutZ(G4ThreeVector(xyz[i][0 507 xyz[i][2]=GetCutZ(G4ThreeVector(xyz[i][0],xyz[i][1],-fDz)); 504 } 508 } 505 else 509 else 506 { 510 { 507 xyz[i][2]=tmpZ; 511 xyz[i][2]=tmpZ; 508 } 512 } 509 } 513 } 510 G4int iNodes[4]; 514 G4int iNodes[4]; 511 G4int* iEdge=nullptr; << 515 G4int *iEdge=0; 512 G4int n; 516 G4int n; 513 for(G4int i=0; i<nf; ++i) << 517 for(G4int i=0;i<nf;++i) 514 { 518 { 515 ph1->GetFacet(i+1,n,iNodes,iEdge); 519 ph1->GetFacet(i+1,n,iNodes,iEdge); 516 for(G4int k=0; k<n; ++k) << 520 for(G4int k=0;k<n;++k) 517 { 521 { 518 faces[i][k]=iNodes[k]; 522 faces[i][k]=iNodes[k]; 519 } 523 } 520 for(G4int k=n; k<4; ++k) << 524 for(G4int k=n;k<4;++k) 521 { 525 { 522 faces[i][k]=0; 526 faces[i][k]=0; 523 } 527 } 524 } 528 } 525 ph->createPolyhedron(nn,nf,xyz,faces); 529 ph->createPolyhedron(nn,nf,xyz,faces); 526 530 527 delete [] xyz; 531 delete [] xyz; 528 delete [] faces; 532 delete [] faces; 529 delete ph1; 533 delete ph1; 530 534 531 return ph; 535 return ph; 532 } 536 } 533 537 534 #endif // G4GEOM_USE_USOLIDS 538 #endif // G4GEOM_USE_USOLIDS 535 539