55 using namespace CLHEP;
 
   64   : 
G4VSolid( name ), fCubicVolume(0.), fSurfaceArea(0.), fpPolyhedron(0)
 
   77   : 
G4VSolid(a), dx(0.), dy(0.), dz(0.),
 
   78     fCubicVolume(0.), fSurfaceArea(0.), fpPolyhedron(0)
 
   96   : 
G4VSolid(rhs), dx(rhs.dx), dy(rhs.dy), dz(rhs.dz),
 
   97     fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
 
  110    if (
this == &rhs)  { 
return *
this; }
 
  119    fCubicVolume = rhs.fCubicVolume; fSurfaceArea = rhs.fSurfaceArea;
 
  155   G4double rFudge = 1.0/std::cos(0.5*sigPhi);
 
  167            cosPhi = std::cos(phi),
 
  168            sinPhi = std::sin(phi);
 
  170                 v1( dxFudge*cosPhi, dyFudge*sinPhi, -
dz ),
 
  177     if (numPhi == 1) phi = 0;  
 
  178     cosPhi = std::cos(phi), 
 
  179     sinPhi = std::sin(phi);
 
  207       phiPoly.
SetNormal( (v1-v0).cross(w0-v0).unit() );
 
  217   } 
while( --numPhi > 0 );
 
  299   if (  (distZ  < halfTol ) && ( distR1 <= 1 ) )
 
  304   if( (distR1 <= 1 ) && ( distR2 >= 1 ) )
 
  310   if ( noSurfaces == 0 )
 
  313     G4Exception(
"G4EllipticalTube::SurfaceNormal(p)", 
"GeomSolids1002",
 
  316     norm = ApproxSurfaceNormal(p);
 
  318   else if ( noSurfaces == 1 )  { norm = sumnorm; }
 
  319   else                         { norm = sumnorm.
unit(); }
 
  329 G4EllipticalTube::ApproxSurfaceNormal( 
const G4ThreeVector& 
p )
 const 
  342   if (distZ*distZ < distR2)
 
  389       if (sigz < 0) 
return kInfinity;
 
  395       if (
CheckXY(p.
x(),p.
y(),-halfTol) <= 1.0) 
return kInfinity;
 
  408                yi = p.
y() + q*v.
y();
 
  418         return (sigz < -halfTol) ? q : 0;
 
  420       else if (xi*dy*dy*v.
x() + yi*
dx*
dx*v.
y() >= 0)
 
  440       if (sigz > 0) 
return kInfinity;
 
  441       if (
CheckXY(p.
x(),p.
y(),-halfTol) <= 1.0) 
return kInfinity;
 
  447                yi = p.
y() + q*v.
y();
 
  451         return (sigz > -halfTol) ? q : 0;
 
  453       else if (xi*dy*dy*v.
x() + yi*
dx*
dx*v.
y() >= 0)
 
  466   if (n==0) 
return kInfinity;
 
  471   if (std::fabs(p.
z()) < 
dz+halfTol) {
 
  472     if (
CheckXY( p.
x(), p.
y(), halfTol ) < 1.0)
 
  477       if (p.
x()*dy*dy*v.
x() + p.
y()*
dx*
dx*v.
y() < 0) 
return 0;
 
  486   if (q[0] < 0) 
return kInfinity;
 
  496     if (zi < -
dz) 
return kInfinity;
 
  500     if (zi > +
dz) 
return kInfinity;
 
  529   if (
CheckXY( p.
x(), p.
y(), +halfTol ) < 1.0)
 
  535     if (p.
z() < -
dz-halfTol) 
 
  537     else if (p.
z() > 
dz+halfTol)
 
  557   G4double tnorm = std::sqrt( tx*tx + ty*ty );
 
  562   G4double distR = ( (p.
x()-xe)*ty - (p.
y()-ye)*tx )/tnorm;
 
  572     return std::sqrt( (p.
z()+
dz)*(p.
z()+
dz) + distR*distR );
 
  574     return std::sqrt( (p.
z()-
dz)*(p.
z()-
dz) + distR*distR );
 
  599   if (calcNorm)  { *validNorm = 
true; }
 
  613     sBest = -(p.
z()+
dz)/v.
z();
 
  618     if (p.
z() < -
dz+halfTol)
 
  620       if (calcNorm)  { *norm = normHere; }
 
  643     if (p.
z() > +
dz-halfTol)
 
  645       if (calcNorm)  { *norm = normHere; }
 
  652     if (q < sBest) { sBest = q; nBest = normHere; }
 
  663     if (sBest == kInfinity)
 
  666       std::ostringstream message;
 
  667       G4int oldprc = message.precision(16) ;
 
  668       message << 
"Point p is outside !?" << 
G4endl 
  670               << 
"   p.x() = "   << p.
x()/
mm << 
" mm" << 
G4endl 
  671               << 
"   p.y() = "   << p.
y()/
mm << 
" mm" << 
G4endl 
  672               << 
"   p.z() = "   << p.
z()/
mm << 
" mm" << 
G4endl 
  674               << 
"   v.x() = "   << v.
x() << 
G4endl 
  675               << 
"   v.y() = "   << v.
y() << 
G4endl 
  676               << 
"   v.z() = "   << v.
z() << 
G4endl 
  677               << 
"Proposed distance :" << 
G4endl 
  678               << 
"   snxt = "    << sBest/
mm << 
" mm";
 
  679       message.precision(oldprc) ;
 
  680       G4Exception( 
"G4EllipticalTube::DistanceToOut(p,v,...)",
 
  683     if (calcNorm)  { *norm = nBest; }
 
  686   else if (q[n-1] > sBest)
 
  688     if (calcNorm)  { *norm = nBest; }
 
  705   if (
CheckXY( p.
x(), p.
y(), -halfTol ) > 1.0)
 
  710     if (p.
x()*dy*dy*v.
x() + p.
y()*
dx*
dx*v.
y() > 0) 
return 0;
 
  740   if (sBest < halfTol) 
return 0;
 
  747   if (radical < +
DBL_MIN) 
return 0;
 
  750   if (p.
x() < 0) xi = -xi;
 
  755   radical = 1.0 - p.
x()*p.
x()/
dx/
dx;
 
  756   if (radical < +
DBL_MIN) 
return 0;
 
  758   G4double yi = dy*std::sqrt( radical );
 
  759   if (p.
y() < 0) yi = -yi;
 
  768   G4double normi = std::sqrt( xdi*xdi + ydi*ydi );
 
  769   if (normi < halfTol) 
return 0;
 
  773   G4double q = 0.5*(xdi*(p.
y()-yi) - ydi*(p.
x()-xi));
 
  774   if (xi*yi < 0) q = -q;
 
  776   if (q < sBest) sBest = q;
 
  781   return sBest < halfTol ? 0 : sBest;
 
  825   if (radical < -
DBL_MIN) 
return 0;    
 
  836   radical = std::sqrt(radical);
 
  838   G4double q = -0.5*( b + (b < 0 ? -radical : +radical) );
 
  841   if (sa < sb) { ss[0] = sa; ss[1] = sb; } 
else { ss[0] = sb; ss[1] = sa; }
 
  851   return G4String(
"G4EllipticalTube");
 
  869   if(fCubicVolume != 0.) {;}
 
  879   if(fSurfaceArea != 0.) {;}
 
  889   G4int oldprc = os.precision(16);
 
  890   os << 
"-----------------------------------------------------------\n" 
  891      << 
"    *** Dump for solid - " << 
GetName() << 
" ***\n" 
  892      << 
"    ===================================================\n" 
  893      << 
" Solid type: G4EllipticalTube\n" 
  895      << 
"    length Z: " << 
dz/
mm << 
" mm \n" 
  896      << 
"    surface equation in X and Y: \n" 
  897      << 
"       (X / " << 
dx << 
")^2 + (Y / " << dy << 
")^2 = 1 \n" 
  898      << 
"-----------------------------------------------------------\n";
 
  899   os.precision(oldprc);
 
  913   G4double xRand, yRand, zRand, phi, cosphi, sinphi, zArea, cArea,
p, chose;
 
  915   phi    = RandFlat::shoot(0., 2.*
pi);
 
  916   cosphi = std::cos(phi);
 
  917   sinphi = std::sin(phi);
 
  926   p = 2.*
pi*std::sqrt(0.5*(
dx*
dx+dy*dy));
 
  933   zRand = RandFlat::shoot(
dz, -1.*
dz);
 
  935   chose = RandFlat::shoot(0.,2.*zArea+cArea);
 
  937   if( (chose>=0) && (chose < cArea) )
 
  941   else if( (chose >= cArea) && (chose < cArea + zArea) )
 
  943     xRand = RandFlat::shoot(-1.*
dx,
dx);
 
  944     yRand = std::sqrt(1.-
sqr(xRand/
dx));
 
  945     yRand = RandFlat::shoot(-1.*yRand, yRand);
 
  950     xRand = RandFlat::shoot(-1.*
dx,
dx);
 
  951     yRand = std::sqrt(1.-
sqr(xRand/
dx));
 
  952     yRand = RandFlat::shoot(-1.*yRand, yRand);