34 #if !(defined(G4GEOM_USE_UELLIPTICALTUBE) && defined(G4GEOM_USE_SYS_USOLIDS))
55 using namespace CLHEP;
65 :
G4VSolid(name), fDx(Dx), fDy(Dy), fDz(Dz)
76 :
G4VSolid(a), halfTolerance(0.), fDx(0.), fDy(0.), fDz(0.),
77 fRsph(0.), fDDx(0.), fDDy(0.), fSx(0.), fSy(0.), fR(0.),
78 fQ1(0.), fQ2(0.), fScratch(0.)
96 :
G4VSolid(rhs), halfTolerance(rhs.halfTolerance),
97 fDx(rhs.fDx), fDy(rhs.fDy), fDz(rhs.fDz),
98 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
99 fRsph(rhs.fRsph), fDDx(rhs.fDDx), fDDy(rhs.fDDy),
100 fSx(rhs.fSx), fSy(rhs.fSy), fR(rhs.fR),
101 fQ1(rhs.fQ1), fQ2(rhs.fQ2), fScratch(rhs.fScratch)
113 if (
this == &rhs) {
return *
this; }
154 if (
fDx < dmin ||
fDy < dmin ||
fDz < dmin)
157 message <<
"Invalid (too small or negative) dimensions for Solid: "
161 <<
"\n Dz = " <<
fDz;
162 G4Exception(
"G4EllipticalTube::CheckParameters()",
"GeomSolids0002",
212 return bbox.
CalculateExtent(pAxis,pVoxelLimit, pTransform, pMin, pMax);
216 return exist = (pMin <
pMax) ?
true :
false;
225 const G4int NSTEPS = 24;
228 G4double sinHalf = std::sin(0.5*ang);
229 G4double cosHalf = std::cos(0.5*ang);
230 G4double sinStep = 2.*sinHalf*cosHalf;
231 G4double cosStep = 1. - 2.*sinHalf*sinHalf;
240 baseA[
k].set(sx*cosCur,sy*sinCur,-dz);
241 baseB[
k].set(sx*cosCur,sy*sinCur, dz);
244 sinCur = sinCur*cosStep + cosCur*sinStep;
245 cosCur = cosCur*cosStep - sinTmp*sinStep;
248 std::vector<const G4ThreeVectorList *> polygons(2);
249 polygons[0] = &baseA;
250 polygons[1] = &baseB;
252 exist = benv.
CalculateExtent(pAxis, pVoxelLimit, pTransform, pMin, pMax);
296 norm.
setZ(p.
z() < 0 ? -1. : 1.);
301 if (nsurf == 1)
return norm;
302 else if (nsurf > 1)
return norm.
unit();
309 G4int oldprc = message.precision(16);
310 message <<
"Point p is not on surface (!?) of solid: "
312 message <<
"Position:\n";
313 message <<
" p.x() = " << p.
x()/
mm <<
" mm\n";
314 message <<
" p.y() = " << p.
y()/
mm <<
" mm\n";
315 message <<
" p.z() = " << p.
z()/
mm <<
" mm";
317 G4Exception(
"G4EllipticalTube::SurfaceNormal(p)",
"GeomSolids1002",
338 if (distR > distZ && (x * x + y * y) > 0)
370 offset = (1. - 1.e-08) * pcur.
mag() - 2. *
fRsph;
396 G4bool parallelToZ = (A < DBL_EPSILON || std::abs(vz) >= 1.);
414 G4double tmp = -B - std::copysign(std::sqrt(D), B);
445 G4double distR = std::sqrt(x * x + y * y) -
fR;
449 return (dist < 0) ? 0 : dist;
474 n->
set(0, 0, (pz < 0) ? -1. : 1.);
508 G4int oldprc = message.precision(16);
509 message <<
"Point p is outside (!?) of solid: "
511 message <<
"Position: " << p <<
G4endl;;
512 message <<
"Direction: " <<
v;
514 G4Exception(
"G4EllipticalTube::DistanceToOut(p,v)",
"GeomSolids1002",
536 G4bool parallelToZ = (A < DBL_EPSILON || std::abs(vz) >= 1.);
542 n->
set(0, 0, (vz < 0) ? -1. : 1.);
557 G4double tmp = -B - std::copysign(std::sqrt(D), B);
572 n->
set(0, 0, (pnew.
z() < 0) ? -1. : 1.);
591 G4int oldprc = message.precision(16);
592 message <<
"Point p is outside (!?) of solid: " <<
GetName() <<
"\n"
594 <<
" p.x() = " << p.
x()/
mm <<
" mm\n"
595 <<
" p.y() = " << p.
y()/
mm <<
" mm\n"
596 <<
" p.z() = " << p.
z()/
mm <<
" mm";
597 message.precision(oldprc) ;
598 G4Exception(
"G4ElliptocalTube::DistanceToOut(p)",
"GeomSolids1002",
609 G4double distR =
fR - std::sqrt(x * x + y * y);
613 return (dist < 0) ? 0 : dist;
622 return G4String(
"G4EllipticalTube");
657 if (cached_Dx !=
fDx || cached_Dy !=
fDy || cached_Dz !=
fDz)
686 G4int oldprc = os.precision(16);
687 os <<
"-----------------------------------------------------------\n"
688 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
689 <<
" ===================================================\n"
690 <<
" Solid type: G4EllipticalTube\n"
692 <<
" length Z: " <<
fDz/
mm <<
" mm \n"
693 <<
" lateral surface equation: \n"
694 <<
" (X / " <<
fDx <<
")^2 + (Y / " <<
fDy <<
")^2 = 1 \n"
695 <<
"-----------------------------------------------------------\n";
696 os.precision(oldprc);
715 if (select > sbase) k = 1;
716 if (select > 2. * sbase) k = 2;
799 #endif // !defined(G4GEOM_USE_UELLIPTICALTUBE) || !defined(G4GEOM_USE_SYS_USOLIDS)