81     fLowerEndcap(0), fUpperEndcap(0), fSide0(0),
 
   82     fSide90(0), fSide180(0), fSide270(0),
 
   83     fSurfaceArea(0.), fpPolyhedron(0)
 
  103   fDxDown = ( fDx1 > fDx2 ? fDx1 : fDx2 ) ;
 
  104   fDxUp   = ( fDx3 > fDx4 ? fDx3 : fDx4 ) ;
 
  105   fDx     = ( fDxUp > fDxDown ? fDxUp : fDxDown ) ;
 
  106   fDy     = ( fDy1 > fDy2 ? fDy1 : fDy2 ) ;
 
  110   if ( fDx1 != fDx2 && fDx3 != fDx4 )
 
  112     pDytmp = fDy1 * ( fDx3 - fDx4 ) / ( fDx1 - fDx2 ) ;
 
  115       std::ostringstream message;
 
  116       message << 
"Not planar surface in untwisted Trapezoid: " 
  118               << 
"fDy2 is " << fDy2 << 
" but should be " 
  120       G4Exception(
"G4VTwistedFaceted::G4VTwistedFaceted()", 
"GeomSolids0002",
 
  126   if ( fDx1 == fDx2 && fDx3 == fDx4 )
 
  133   if ( (  fDx1 == fDx2 && fDx3 != fDx4 ) || ( fDx1 != fDx2 && fDx3 == fDx4 ) )
 
  135     std::ostringstream message;
 
  136     message << 
"Not planar surface in untwisted Trapezoid: " 
  138             << 
"One endcap is rectangular, the other is a trapezoid." << 
G4endl 
  139             << 
"For planarity reasons they have to be rectangles or trapezoids " 
  141     G4Exception(
"G4VTwistedFaceted::G4VTwistedFaceted()", 
"GeomSolids0002",
 
  147   fPhiTwist = PhiTwist ;
 
  152   fTAlph = std::tan(fAlph) ;
 
  159   fdeltaX = 2 * fDz * std::tan(fTheta) * std::cos(fPhi)  ;
 
  163   fdeltaY = 2 * fDz * std::tan(fTheta) * std::sin(fPhi)  ;
 
  172          && ( std::fabs(fPhiTwist) > 2*kAngTolerance )
 
  173          && ( std::fabs(fPhiTwist) < 
pi/2 )
 
  174          && ( std::fabs(fAlph) < 
pi/2 )
 
  175          && ( fTheta < pi/2 && fTheta >= 0 ) )
 
  178     std::ostringstream message;
 
  179     message << 
"Invalid dimensions. Too small, or twist angle too big: " 
  181             << 
"fDx 1-4 = " << fDx1/
cm << 
", " << fDx2/
cm << 
", " 
  182             << fDx3/
cm << 
", " << fDx4/
cm << 
" cm" << 
G4endl  
  183             << 
"fDy 1-2 = " << fDy1/
cm << 
", " << fDy2/
cm << 
", " 
  185             << 
"fDz = " << fDz/
cm << 
" cm" << 
G4endl  
  186             << 
" twistangle " << fPhiTwist/
deg << 
" deg" << 
G4endl  
  187             << 
" phi,theta = " << fPhi/
deg << 
", "  << fTheta/
deg << 
" deg";
 
  192   fCubicVolume = 2 * fDz * ( ( fDx1 + fDx2 ) * fDy1 + ( fDx3 + fDx4 ) * fDy2 );
 
  200   : 
G4VSolid(a), fTheta(0.), fPhi(0.), fDy1(0.), fDx1(0.), fDx2(0.),
 
  201     fDy2(0.), fDx3(0.), fDx4(0.), fDz(0.), fDx(0.), fDy(0.), fAlph(0.),
 
  202     fTAlph(0.), fdeltaX(0.), fdeltaY(0.), fPhiTwist(0.),
 
  203     fLowerEndcap(0), fUpperEndcap(0), fSide0(0), fSide90(0), fSide180(0),
 
  204     fSide270(0), fCubicVolume(0.), fSurfaceArea(0.), fpPolyhedron(0)
 
  213   if (fLowerEndcap) 
delete fLowerEndcap ;
 
  214   if (fUpperEndcap) 
delete fUpperEndcap ;
 
  216   if (fSide0)       
delete fSide0 ;
 
  217   if (fSide90)      
delete fSide90 ;
 
  218   if (fSide180)     
delete fSide180 ;
 
  219   if (fSide270)     
delete fSide270 ;
 
  220   if (fpPolyhedron) 
delete fpPolyhedron;
 
  227   : 
G4VSolid(rhs), fTheta(rhs.fTheta), fPhi(rhs.fPhi),
 
  228     fDy1(rhs.fDy1), fDx1(rhs.fDx1), fDx2(rhs.fDx2), fDy2(rhs.fDy2),
 
  229     fDx3(rhs.fDx3), fDx4(rhs.fDx4), fDz(rhs.fDz), fDx(rhs.fDx), fDy(rhs.fDy),
 
  230     fAlph(rhs.fAlph), fTAlph(rhs.fTAlph), fdeltaX(rhs.fdeltaX),
 
  231     fdeltaY(rhs.fdeltaY), fPhiTwist(rhs.fPhiTwist), fLowerEndcap(0),
 
  232     fUpperEndcap(0), fSide0(0), fSide90(0), fSide180(0), fSide270(0),
 
  233     fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
 
  235     fLastInside(rhs.fLastInside), fLastNormal(rhs.fLastNormal),
 
  236     fLastDistanceToIn(rhs.fLastDistanceToIn),
 
  237     fLastDistanceToOut(rhs.fLastDistanceToOut),
 
  238     fLastDistanceToInWithV(rhs.fLastDistanceToInWithV),
 
  239     fLastDistanceToOutWithV(rhs.fLastDistanceToOutWithV)
 
  252    if (
this == &rhs)  { 
return *
this; }
 
  260    fTheta = rhs.fTheta; fPhi = rhs.fPhi;
 
  261    fDy1= rhs.fDy1; fDx1= rhs.fDx1; fDx2= rhs.fDx2; fDy2= rhs.fDy2;
 
  262    fDx3= rhs.fDx3; fDx4= rhs.fDx4; fDz= rhs.fDz; fDx= rhs.fDx; fDy= rhs.fDy;
 
  263    fAlph= rhs.fAlph; fTAlph= rhs.fTAlph; fdeltaX= rhs.fdeltaX;
 
  264    fdeltaY= rhs.fdeltaY; fPhiTwist= rhs.fPhiTwist; fLowerEndcap= 0;
 
  265    fUpperEndcap= 0; fSide0= 0; fSide90= 0; fSide180= 0; fSide270= 0;
 
  266    fCubicVolume= rhs.fCubicVolume; fSurfaceArea= rhs.fSurfaceArea;
 
  268    fLastInside= rhs.fLastInside; fLastNormal= rhs.fLastNormal;
 
  269    fLastDistanceToIn= rhs.fLastDistanceToIn;
 
  270    fLastDistanceToOut= rhs.fLastDistanceToOut;
 
  271    fLastDistanceToInWithV= rhs.fLastDistanceToInWithV;
 
  272    fLastDistanceToOutWithV= rhs.fLastDistanceToOutWithV;
 
  286   G4Exception(
"G4VTwistedFaceted::ComputeDimensions()",
 
  288               "G4VTwistedFaceted does not support Parameterisation.");
 
  301   G4double maxRad = std::sqrt( fDx*fDx + fDy*fDy);
 
  314       xMin    = xoffset - maxRad ;
 
  315       xMax    = xoffset + maxRad ;
 
  334       yMin    = yoffset - maxRad ;
 
  335       yMax    = yoffset + maxRad ;
 
  354       zMin    = zoffset - fDz ;
 
  355       zMax    = zoffset + fDz ;
 
  397       G4bool existsAfterClip = false ;
 
  410       if (pVoxelLimit.
IsLimited(pAxis) == 
false) 
 
  412           if ( pMin != kInfinity || pMax != -kInfinity ) 
 
  414               existsAfterClip = true ;
 
  429       if ( pMin != kInfinity || pMax != -kInfinity )
 
  431           existsAfterClip = true ;
 
  467           existsAfterClip = true ;
 
  473       return existsAfterClip;
 
  487     vertices->reserve(8);
 
  489     G4double maxRad = std::sqrt( fDx*fDx + fDy*fDy);
 
  512     G4Exception(
"G4VTwistedFaceted::CreateRotatedVertices()",
 
  514                 "Error in allocation of vertices. Out of memory !");
 
  527    if (fLastInside.p == p) {
 
  528      return fLastInside.inside;
 
  531       tmpin     = 
const_cast<EInside*
>(&(fLastInside.inside));
 
  532       tmpp->
set(p.
x(), p.
y(), p.
z());
 
  537    G4double phi = p.
z()/(2*fDz) * fPhiTwist ;  
 
  541    G4double px  = p.
x() + fdeltaX * ( -phi/fPhiTwist) ;  
 
  542    G4double py  = p.
y() + fdeltaY * ( -phi/fPhiTwist) ;
 
  545    G4double posx = px * cphi - py * sphi   ;  
 
  546    G4double posy = px * sphi + py * cphi   ;
 
  569    G4cout << 
"phi,theta = " << fPhi << 
" , " << fTheta << 
G4endl ;
 
  612   return fLastInside.inside;
 
  628    if (fLastNormal.p == p)
 
  630      return fLastNormal.vec;
 
  636    tmpp->
set(p.
x(), p.
y(), p.
z());
 
  642    surfaces[0] = fSide0 ;
 
  643    surfaces[1] = fSide90 ;
 
  644    surfaces[2] = fSide180 ;
 
  645    surfaces[3] = fSide270 ;
 
  646    surfaces[4] = fLowerEndcap;
 
  647    surfaces[5] = fUpperEndcap;
 
  656       if (tmpdistance < distance)
 
  658          distance = tmpdistance;
 
  664    tmpsurface[0] = surfaces[besti];
 
  665    *tmpnormal = tmpsurface[0]->
GetNormal(bestxx, 
true);
 
  667    return fLastNormal.vec;
 
  690    if (fLastDistanceToInWithV.p == p && fLastDistanceToInWithV.vec == v)
 
  692       return fLastDistanceToIn.value;
 
  696       tmpp    = 
const_cast<G4ThreeVector*
>(&(fLastDistanceToInWithV.p));
 
  697       tmpv    = 
const_cast<G4ThreeVector*
>(&(fLastDistanceToInWithV.vec));
 
  698       tmpdist = 
const_cast<G4double*
>(&(fLastDistanceToInWithV.value));
 
  699       tmpp->
set(p.
x(), p.
y(), p.
z());
 
  700       tmpv->
set(v.
x(), v.
y(), v.
z());
 
  721        return fLastDistanceToInWithV.value;
 
  735    surfaces[0] = fSide0;
 
  736    surfaces[1] = fSide90 ;
 
  737    surfaces[2] = fSide180 ;
 
  738    surfaces[3] = fSide270 ;
 
  739    surfaces[4] = fLowerEndcap;
 
  740    surfaces[5] = fUpperEndcap;
 
  745    for (i=0; i < 6 ; i++)
 
  752       G4cout << 
"Solid DistanceToIn : distance = " << tmpdistance << 
G4endl ; 
 
  755       if (tmpdistance < distance)
 
  757          distance = tmpdistance;
 
  768    return fLastDistanceToInWithV.value;
 
  785    if (fLastDistanceToIn.p == p)
 
  787       return fLastDistanceToIn.value;
 
  792       tmpdist = 
const_cast<G4double*
>(&(fLastDistanceToIn.value));
 
  793       tmpp->
set(p.
x(), p.
y(), p.
z());
 
  811          return fLastDistanceToIn.value;
 
  824          surfaces[0] = fSide0;
 
  825          surfaces[1] = fSide90 ;
 
  826          surfaces[2] = fSide180 ;
 
  827          surfaces[3] = fSide270 ;
 
  828          surfaces[4] = fLowerEndcap;
 
  829          surfaces[5] = fUpperEndcap;
 
  837             if (tmpdistance < distance)
 
  839                distance = tmpdistance;
 
  844          return fLastDistanceToIn.value;
 
  849          G4Exception(
"G4VTwistedFaceted::DistanceToIn(p)", 
"GeomSolids0003",
 
  881    if (fLastDistanceToOutWithV.p == p && fLastDistanceToOutWithV.vec == v  )
 
  883       return fLastDistanceToOutWithV.value;
 
  887       tmpp    = 
const_cast<G4ThreeVector*
>(&(fLastDistanceToOutWithV.p));
 
  888       tmpv    = 
const_cast<G4ThreeVector*
>(&(fLastDistanceToOutWithV.vec));
 
  889       tmpdist = 
const_cast<G4double*
>(&(fLastDistanceToOutWithV.value));
 
  890       tmpp->
set(p.
x(), p.
y(), p.
z());
 
  891       tmpv->
set(v.
x(), v.
y(), v.
z());
 
  914                *norm = (blockedsurface->
GetNormal(p, 
true));
 
  919             return fLastDistanceToOutWithV.value;
 
  931    surfaces[0] = fSide0;
 
  932    surfaces[1] = fSide90 ;
 
  933    surfaces[2] = fSide180 ;
 
  934    surfaces[3] = fSide270 ;
 
  935    surfaces[4] = fLowerEndcap;
 
  936    surfaces[5] = fUpperEndcap;
 
  942    for (i=0; i< 6 ; i++) {
 
  944       if (tmpdistance < distance)
 
  946          distance = tmpdistance;
 
  956          *norm = (surfaces[besti]->
GetNormal(p, 
true));
 
  963    return fLastDistanceToOutWithV.value;
 
  980    if (fLastDistanceToOut.p == p)
 
  982       return fLastDistanceToOut.value;
 
  987       tmpdist = 
const_cast<G4double*
>(&(fLastDistanceToOut.value));
 
  988       tmpp->
set(p.
x(), p.
y(), p.
z());
 
 1010         G4cout.precision(oldprc) ;
 
 1011         G4Exception(
"G4VTwistedFaceted::DistanceToOut(p)", 
"GeomSolids1002",
 
 1019         retval = fLastDistanceToOut.value;
 
 1033         surfaces[0] = fSide0;
 
 1034         surfaces[1] = fSide90 ;
 
 1035         surfaces[2] = fSide180 ;
 
 1036         surfaces[3] = fSide270 ;
 
 1037         surfaces[4] = fLowerEndcap;
 
 1038         surfaces[5] = fUpperEndcap;
 
 1043         for (i=0; i< 6; i++)
 
 1046           if (tmpdistance < distance)
 
 1048             distance = tmpdistance;
 
 1052         *tmpdist = distance;
 
 1054         retval = fLastDistanceToOut.value;
 
 1060         G4Exception(
"G4VTwistedFaceted::DistanceToOut(p)", 
"GeomSolids0003",
 
 1078   G4int oldprc = os.precision(16);
 
 1079   os << 
"-----------------------------------------------------------\n" 
 1080      << 
"    *** Dump for solid - " << 
GetName() << 
" ***\n" 
 1081      << 
"    ===================================================\n" 
 1082      << 
" Solid type: G4VTwistedFaceted\n" 
 1083      << 
" Parameters: \n" 
 1084      << 
"  polar angle theta = "   <<  fTheta/
degree      << 
" deg" << 
G4endl 
 1085      << 
"  azimuthal angle phi = "  << fPhi/
degree        << 
" deg" << 
G4endl   
 1086      << 
"  tilt angle  alpha = "   << fAlph/
degree        << 
" deg" << 
G4endl   
 1087      << 
"  TWIST angle = "         << fPhiTwist/
degree    << 
" deg" << 
G4endl   
 1088      << 
"  Half length along y (lower endcap) = "         << fDy1/
cm << 
" cm" 
 1090      << 
"  Half length along x (lower endcap, bottom) = " << fDx1/
cm << 
" cm" 
 1092      << 
"  Half length along x (lower endcap, top) = "    << fDx2/
cm << 
" cm" 
 1094      << 
"  Half length along y (upper endcap) = "         << fDy2/
cm << 
" cm" 
 1096      << 
"  Half length along x (upper endcap, bottom) = " << fDx3/
cm << 
" cm" 
 1098      << 
"  Half length along x (upper endcap, top) = "    << fDx4/
cm << 
" cm" 
 1100      << 
"-----------------------------------------------------------\n";
 
 1101   os.precision(oldprc);
 
 1120   G4double maxRad = std::sqrt( fDx*fDx + fDy*fDy);
 
 1133   G4double maxRad = std::sqrt( fDx*fDx + fDy*fDy);
 
 1143 void G4VTwistedFaceted::CreateSurfaces() 
 
 1148   if ( fDx1 == fDx2 && fDx3 == fDx4 )    
 
 1150     fSide0   = 
new G4TwistBoxSide(
"0deg",   fPhiTwist, fDz, fTheta, fPhi,
 
 1151                                         fDy1, fDx1, fDx1, fDy2, fDx3, fDx3, fAlph, 0.*
deg);
 
 1153                                         fDy1, fDx1, fDx1, fDy2, fDx3, fDx3, fAlph, 180.*
deg);
 
 1158                       fPhi, fDy1, fDx1, fDx2, fDy2, fDx3, fDx4, fAlph, 0.*
deg);
 
 1160                  fPhi+
pi, fDy1, fDx2, fDx1, fDy2, fDx4, fDx3, fAlph, 180.*
deg);
 
 1166                       fPhi, fDy1, fDx1, fDx2, fDy2, fDx3, fDx4, fAlph, 0.*
deg);
 
 1168                  fPhi+
pi, fDy1, fDx2, fDx1, fDy2, fDx4, fDx3, fAlph, 180.*
deg);
 
 1173                                     fDz, fAlph, fPhi, fTheta,  1 );
 
 1175                                     fDz, fAlph, fPhi, fTheta, -1 );
 
 1179   fSide0->
SetNeighbours(  fSide270 , fLowerEndcap , fSide90  , fUpperEndcap );
 
 1180   fSide90->
SetNeighbours( fSide0   , fLowerEndcap , fSide180 , fUpperEndcap );
 
 1181   fSide180->
SetNeighbours(fSide90  , fLowerEndcap , fSide270 , fUpperEndcap );
 
 1182   fSide270->
SetNeighbours(fSide180 , fLowerEndcap , fSide0   , fUpperEndcap );
 
 1183   fUpperEndcap->
SetNeighbours( fSide180, fSide270 , fSide0 , fSide90  );
 
 1184   fLowerEndcap->
SetNeighbours( fSide180, fSide270 , fSide0 , fSide90  );
 
 1194   return G4String(
"G4VTwistedFaceted");
 
 1203   if (!fpPolyhedron ||
 
 1207       delete fpPolyhedron;
 
 1211   return fpPolyhedron;
 
 1225   if ( z == fDz ) z -= 0.1*fDz ;
 
 1226   if ( z == -fDz ) z += 0.1*fDz ;
 
 1228   G4double phi = z/(2*fDz)*fPhiTwist ;
 
 1230   return G4ThreeVector(fdeltaX * phi/fPhiTwist, fdeltaY * phi/fPhiTwist, z ) ;
 
 1240   G4double  phi = G4RandFlat::shoot(-fPhiTwist/2.,fPhiTwist/2.);
 
 1265   G4double chose = G4RandFlat::shoot(0.,a1 + a2 + a3 + a4 + a5 + a6) ;
 
 1272     u = G4RandFlat::shoot(umin,umax) ;
 
 1277   else if( (chose >= a1) && (chose < a1 + a2 ) )
 
 1283     u = G4RandFlat::shoot(umin,umax) ;
 
 1288   else if( (chose >= a1 + a2 ) && (chose < a1 + a2 + a3 ) )
 
 1293     u = G4RandFlat::shoot(umin,umax) ;
 
 1298   else if( (chose >= a1 + a2 + a3  ) && (chose < a1 + a2 + a3 + a4  ) )
 
 1303     u = G4RandFlat::shoot(umin,umax) ;
 
 1308   else if( (chose >= a1 + a2 + a3 + a4  ) && (chose < a1 + a2 + a3 + a4 + a5 ) )
 
 1311     y = G4RandFlat::shoot(-fDy1,fDy1) ;
 
 1314     u = G4RandFlat::shoot(umin,umax) ;
 
 1320     y = G4RandFlat::shoot(-fDy2,fDy2) ;
 
 1323     u = G4RandFlat::shoot(umin,umax) ;
 
 1341   const G4int nnodes = 4*(k-1)*(n-2) + 2*k*k ;
 
 1342   const G4int nfaces = 4*(k-1)*(n-1) + 2*(k-1)*(k-1) ;
 
 1346   typedef G4int G4int4[4];
 
 1347   G4double3* xyz = 
new G4double3[nnodes];  
 
 1348   G4int4*  faces = 
new G4int4[nfaces] ;    
 
 1350   fLowerEndcap->
GetFacets(k,k,xyz,faces,0) ;
 
 1351   fUpperEndcap->
GetFacets(k,k,xyz,faces,1) ;