00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062   
00063 #include "HepPolyhedron.h"
00064 #include "G4PhysicalConstants.hh"
00065 #include "G4Vector3D.hh"
00066 
00067 #include <cstdlib>  
00068 #include <cmath>
00069 
00070 using CLHEP::perMillion;
00071 using CLHEP::deg;
00072 using CLHEP::pi;
00073 using CLHEP::twopi;
00074 using CLHEP::nm;
00075 const G4double spatialTolerance = 0.01*nm;
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 std::ostream & operator<<(std::ostream & ostr, const G4Facet & facet) {
00086   for (G4int k=0; k<4; k++) {
00087     ostr << " " << facet.edge[k].v << "/" << facet.edge[k].f;
00088   }
00089   return ostr;
00090 }
00091 
00092 std::ostream & operator<<(std::ostream & ostr, const HepPolyhedron & ph) {
00093   ostr << std::endl;
00094   ostr << "Nverteces=" << ph.nvert << ", Nfacets=" << ph.nface << std::endl;
00095   G4int i;
00096   for (i=1; i<=ph.nvert; i++) {
00097      ostr << "xyz(" << i << ")="
00098           << ph.pV[i].x() << ' ' << ph.pV[i].y() << ' ' << ph.pV[i].z()
00099           << std::endl;
00100   }
00101   for (i=1; i<=ph.nface; i++) {
00102     ostr << "face(" << i << ")=" << ph.pF[i] << std::endl;
00103   }
00104   return ostr;
00105 }
00106 
00107 HepPolyhedron::HepPolyhedron(const HepPolyhedron &from)
00108 
00109 
00110 
00111 
00112 
00113 
00114 : nvert(0), nface(0), pV(0), pF(0)
00115 {
00116   AllocateMemory(from.nvert, from.nface);
00117   for (G4int i=1; i<=nvert; i++) pV[i] = from.pV[i];
00118   for (G4int k=1; k<=nface; k++) pF[k] = from.pF[k];
00119 }
00120 
00121 HepPolyhedron & HepPolyhedron::operator=(const HepPolyhedron &from)
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 {
00131   if (this != &from) {
00132     AllocateMemory(from.nvert, from.nface);
00133     for (G4int i=1; i<=nvert; i++) pV[i] = from.pV[i];
00134     for (G4int k=1; k<=nface; k++) pF[k] = from.pF[k];
00135   }
00136   return *this;
00137 }
00138 
00139 G4int
00140 HepPolyhedron::FindNeighbour(G4int iFace, G4int iNode, G4int iOrder) const
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 {
00150   G4int i;
00151   for (i=0; i<4; i++) {
00152     if (iNode == std::abs(pF[iFace].edge[i].v)) break;
00153   }
00154   if (i == 4) {
00155     std::cerr
00156       << "HepPolyhedron::FindNeighbour: face " << iFace
00157       << " has no node " << iNode
00158       << std::endl; 
00159     return 0;
00160   }
00161   if (iOrder < 0) {
00162     if ( --i < 0) i = 3;
00163     if (pF[iFace].edge[i].v == 0) i = 2;
00164   }
00165   return (pF[iFace].edge[i].v > 0) ? 0 : pF[iFace].edge[i].f;
00166 }
00167 
00168 G4Normal3D HepPolyhedron::FindNodeNormal(G4int iFace, G4int iNode) const
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 {
00178   G4Normal3D   normal = GetUnitNormal(iFace);
00179   G4int          k = iFace, iOrder = 1, n = 1;
00180 
00181   for(;;) {
00182     k = FindNeighbour(k, iNode, iOrder);
00183     if (k == iFace) break; 
00184     if (k > 0) {
00185       n++;
00186       normal += GetUnitNormal(k);
00187     }else{
00188       if (iOrder < 0) break;
00189       k = iFace;
00190       iOrder = -iOrder;
00191     }
00192   }
00193   return normal.unit();
00194 }
00195 
00196 G4int HepPolyhedron::GetNumberOfRotationSteps()
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 {
00206   return fNumberOfRotationSteps;
00207 }
00208 
00209 void HepPolyhedron::SetNumberOfRotationSteps(G4int n)
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 
00218 {
00219   const G4int nMin = 3;
00220   if (n < nMin) {
00221     std::cerr 
00222       << "HepPolyhedron::SetNumberOfRotationSteps: attempt to set the\n"
00223       << "number of steps per circle < " << nMin << "; forced to " << nMin
00224       << std::endl;
00225     fNumberOfRotationSteps = nMin;
00226   }else{
00227     fNumberOfRotationSteps = n;
00228   }    
00229 }
00230 
00231 void HepPolyhedron::ResetNumberOfRotationSteps()
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 {
00241   fNumberOfRotationSteps = DEFAULT_NUMBER_OF_STEPS;
00242 }
00243 
00244 void HepPolyhedron::AllocateMemory(G4int Nvert, G4int Nface)
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254 
00255 
00256 {
00257   if (nvert == Nvert && nface == Nface) return;
00258   if (pV != 0) delete [] pV;
00259   if (pF != 0) delete [] pF;
00260   if (Nvert > 0 && Nface > 0) {
00261     nvert = Nvert;
00262     nface = Nface;
00263     pV    = new G4Point3D[nvert+1];
00264     pF    = new G4Facet[nface+1];
00265   }else{
00266     nvert = 0; nface = 0; pV = 0; pF = 0;
00267   }
00268 }
00269 
00270 void HepPolyhedron::CreatePrism()
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279 {
00280   enum {DUMMY, BOTTOM, LEFT, BACK, RIGHT, FRONT, TOP};
00281 
00282   pF[1] = G4Facet(1,LEFT,  4,BACK,  3,RIGHT,  2,FRONT);
00283   pF[2] = G4Facet(5,TOP,   8,BACK,  4,BOTTOM, 1,FRONT);
00284   pF[3] = G4Facet(8,TOP,   7,RIGHT, 3,BOTTOM, 4,LEFT);
00285   pF[4] = G4Facet(7,TOP,   6,FRONT, 2,BOTTOM, 3,BACK);
00286   pF[5] = G4Facet(6,TOP,   5,LEFT,  1,BOTTOM, 2,RIGHT);
00287   pF[6] = G4Facet(5,FRONT, 6,RIGHT, 7,BACK,   8,LEFT);
00288 }
00289 
00290 void HepPolyhedron::RotateEdge(G4int k1, G4int k2, G4double r1, G4double r2,
00291                               G4int v1, G4int v2, G4int vEdge,
00292                               G4bool ifWholeCircle, G4int nds, G4int &kface)
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 {
00312   if (r1 == 0. && r2 == 0) return;
00313 
00314   G4int i;
00315   G4int i1  = k1;
00316   G4int i2  = k2;
00317   G4int ii1 = ifWholeCircle ? i1 : i1+nds;
00318   G4int ii2 = ifWholeCircle ? i2 : i2+nds;
00319   G4int vv  = ifWholeCircle ? vEdge : 1;
00320 
00321   if (nds == 1) {
00322     if (r1 == 0.) {
00323       pF[kface++]   = G4Facet(i1,0,    v2*i2,0, (i2+1),0);
00324     }else if (r2 == 0.) {
00325       pF[kface++]   = G4Facet(i1,0,    i2,0,    v1*(i1+1),0);
00326     }else{
00327       pF[kface++]   = G4Facet(i1,0,    v2*i2,0, (i2+1),0, v1*(i1+1),0);
00328     }
00329   }else{
00330     if (r1 == 0.) {
00331       pF[kface++]   = G4Facet(vv*i1,0,    v2*i2,0, vEdge*(i2+1),0);
00332       for (i2++,i=1; i<nds-1; i2++,i++) {
00333         pF[kface++] = G4Facet(vEdge*i1,0, v2*i2,0, vEdge*(i2+1),0);
00334       }
00335       pF[kface++]   = G4Facet(vEdge*i1,0, v2*i2,0, vv*ii2,0);
00336     }else if (r2 == 0.) {
00337       pF[kface++]   = G4Facet(vv*i1,0,    vEdge*i2,0, v1*(i1+1),0);
00338       for (i1++,i=1; i<nds-1; i1++,i++) {
00339         pF[kface++] = G4Facet(vEdge*i1,0, vEdge*i2,0, v1*(i1+1),0);
00340       }
00341       pF[kface++]   = G4Facet(vEdge*i1,0, vv*i2,0,    v1*ii1,0);
00342     }else{
00343       pF[kface++]   = G4Facet(vv*i1,0,    v2*i2,0, vEdge*(i2+1),0,v1*(i1+1),0);
00344       for (i1++,i2++,i=1; i<nds-1; i1++,i2++,i++) {
00345         pF[kface++] = G4Facet(vEdge*i1,0, v2*i2,0, vEdge*(i2+1),0,v1*(i1+1),0);
00346       }  
00347       pF[kface++]   = G4Facet(vEdge*i1,0, v2*i2,0, vv*ii2,0,      v1*ii1,0);
00348     }
00349   }
00350 }
00351 
00352 void HepPolyhedron::SetSideFacets(G4int ii[4], G4int vv[4],
00353                                  G4int *kk, G4double *r,
00354                                  G4double dphi, G4int nds, G4int &kface)
00355 
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 
00370 
00371 {
00372   G4int k1, k2, k3, k4;
00373   
00374   if (std::abs((G4double)(dphi-pi)) < perMillion) {          
00375     for (G4int i=0; i<4; i++) {
00376       k1 = ii[i];
00377       k2 = (i == 3) ? ii[0] : ii[i+1];
00378       if (r[k1] == 0. && r[k2] == 0.) vv[i] = -1;      
00379     }
00380   }
00381 
00382   if (ii[1] == ii[2]) {
00383     k1 = kk[ii[0]];
00384     k2 = kk[ii[2]];
00385     k3 = kk[ii[3]];
00386     pF[kface++] = G4Facet(vv[0]*k1,0, vv[2]*k2,0, vv[3]*k3,0);
00387     if (r[ii[0]] != 0.) k1 += nds;
00388     if (r[ii[2]] != 0.) k2 += nds;
00389     if (r[ii[3]] != 0.) k3 += nds;
00390     pF[kface++] = G4Facet(vv[2]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
00391   }else if (kk[ii[0]] == kk[ii[1]]) {
00392     k1 = kk[ii[0]];
00393     k2 = kk[ii[2]];
00394     k3 = kk[ii[3]];
00395     pF[kface++] = G4Facet(vv[1]*k1,0, vv[2]*k2,0, vv[3]*k3,0);
00396     if (r[ii[0]] != 0.) k1 += nds;
00397     if (r[ii[2]] != 0.) k2 += nds;
00398     if (r[ii[3]] != 0.) k3 += nds;
00399     pF[kface++] = G4Facet(vv[2]*k3,0, vv[1]*k2,0, vv[3]*k1,0);
00400   }else if (kk[ii[2]] == kk[ii[3]]) {
00401     k1 = kk[ii[0]];
00402     k2 = kk[ii[1]];
00403     k3 = kk[ii[2]];
00404     pF[kface++] = G4Facet(vv[0]*k1,0, vv[1]*k2,0, vv[3]*k3,0);
00405     if (r[ii[0]] != 0.) k1 += nds;
00406     if (r[ii[1]] != 0.) k2 += nds;
00407     if (r[ii[2]] != 0.) k3 += nds;
00408     pF[kface++] = G4Facet(vv[1]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
00409   }else{
00410     k1 = kk[ii[0]];
00411     k2 = kk[ii[1]];
00412     k3 = kk[ii[2]];
00413     k4 = kk[ii[3]];
00414     pF[kface++] = G4Facet(vv[0]*k1,0, vv[1]*k2,0, vv[2]*k3,0, vv[3]*k4,0);
00415     if (r[ii[0]] != 0.) k1 += nds;
00416     if (r[ii[1]] != 0.) k2 += nds;
00417     if (r[ii[2]] != 0.) k3 += nds;
00418     if (r[ii[3]] != 0.) k4 += nds;
00419     pF[kface++] = G4Facet(vv[2]*k4,0, vv[1]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
00420   }
00421 }
00422 
00423 void HepPolyhedron::RotateAroundZ(G4int nstep, G4double phi, G4double dphi,
00424                                  G4int np1, G4int np2,
00425                                  const G4double *z, G4double *r,
00426                                  G4int nodeVis, G4int edgeVis)
00427 
00428 
00429 
00430 
00431 
00432 
00433 
00434 
00435 
00436 
00437 
00438 
00439 
00440 
00441 
00442 
00443 
00444 
00445 
00446 
00447 
00448 {
00449   static const G4double wholeCircle = twopi;
00450     
00451   
00452 
00453   G4bool ifWholeCircle = (std::abs(dphi-wholeCircle) < perMillion) ? true : false;
00454   G4double   delPhi  = ifWholeCircle ? wholeCircle : dphi;  
00455   G4int        nSphi    = (nstep > 0) ?
00456     nstep : G4int(delPhi*GetNumberOfRotationSteps()/wholeCircle+.5);
00457   if (nSphi == 0) nSphi = 1;
00458   G4int        nVphi    = ifWholeCircle ? nSphi : nSphi+1;
00459   G4bool ifClosed = np1 > 0 ? false : true;
00460   
00461   
00462 
00463   G4int absNp1 = std::abs(np1);
00464   G4int absNp2 = std::abs(np2);
00465   G4int i1beg = 0;
00466   G4int i1end = absNp1-1;
00467   G4int i2beg = absNp1;
00468   G4int i2end = absNp1+absNp2-1; 
00469   G4int i, j, k;
00470 
00471   for(i=i1beg; i<=i2end; i++) {
00472     if (std::abs(r[i]) < spatialTolerance) r[i] = 0.;
00473   }
00474 
00475   j = 0;                                                
00476   for (i=i1beg; i<=i1end; i++) {
00477     j += (r[i] == 0.) ? 1 : nVphi;
00478   }
00479 
00480   G4bool ifSide1 = false;                           
00481   G4bool ifSide2 = false;
00482 
00483   if (r[i2beg] != r[i1beg] || z[i2beg] != z[i1beg]) {
00484     j += (r[i2beg] == 0.) ? 1 : nVphi;
00485     ifSide1 = true;
00486   }
00487 
00488   for(i=i2beg+1; i<i2end; i++) {
00489     j += (r[i] == 0.) ? 1 : nVphi;
00490   }
00491   
00492   if (r[i2end] != r[i1end] || z[i2end] != z[i1end]) {
00493     if (absNp2 > 1) j += (r[i2end] == 0.) ? 1 : nVphi;
00494     ifSide2 = true;
00495   }
00496 
00497   
00498 
00499   k = ifClosed ? absNp1*nSphi : (absNp1-1)*nSphi;       
00500 
00501   if (absNp2 > 1) {                                     
00502     for(i=i2beg; i<i2end; i++) {
00503       if (r[i] > 0. || r[i+1] > 0.)       k += nSphi;
00504     }
00505 
00506     if (ifClosed) {
00507       if (r[i2end] > 0. || r[i2beg] > 0.) k += nSphi;
00508     }
00509   }
00510 
00511   if (!ifClosed) {                                      
00512     if (ifSide1 && (r[i1beg] > 0. || r[i2beg] > 0.)) k += nSphi;
00513     if (ifSide2 && (r[i1end] > 0. || r[i2end] > 0.)) k += nSphi;
00514   }
00515 
00516   if (!ifWholeCircle) {                                 
00517     k += ifClosed ? 2*absNp1 : 2*(absNp1-1);
00518   }
00519 
00520   
00521 
00522   AllocateMemory(j, k);
00523 
00524   
00525 
00526   G4int *kk;
00527   kk = new G4int[absNp1+absNp2];
00528 
00529   k = 1;
00530   for(i=i1beg; i<=i1end; i++) {
00531     kk[i] = k;
00532     if (r[i] == 0.)
00533     { pV[k++] = G4Point3D(0, 0, z[i]); } else { k += nVphi; }
00534   }
00535 
00536   i = i2beg;
00537   if (ifSide1) {
00538     kk[i] = k;
00539     if (r[i] == 0.)
00540     { pV[k++] = G4Point3D(0, 0, z[i]); } else { k += nVphi; }
00541   }else{
00542     kk[i] = kk[i1beg];
00543   }
00544 
00545   for(i=i2beg+1; i<i2end; i++) {
00546     kk[i] = k;
00547     if (r[i] == 0.)
00548     { pV[k++] = G4Point3D(0, 0, z[i]); } else { k += nVphi; }
00549   }
00550 
00551   if (absNp2 > 1) {
00552     i = i2end;
00553     if (ifSide2) {
00554       kk[i] = k;
00555       if (r[i] == 0.) pV[k] = G4Point3D(0, 0, z[i]);
00556     }else{
00557       kk[i] = kk[i1end];
00558     }
00559   }
00560 
00561   G4double cosPhi, sinPhi;
00562 
00563   for(j=0; j<nVphi; j++) {
00564     cosPhi = std::cos(phi+j*delPhi/nSphi);
00565     sinPhi = std::sin(phi+j*delPhi/nSphi);
00566     for(i=i1beg; i<=i2end; i++) {
00567       if (r[i] != 0.)
00568         pV[kk[i]+j] = G4Point3D(r[i]*cosPhi,r[i]*sinPhi,z[i]);
00569     }
00570   }
00571 
00572   
00573 
00574   G4int v1,v2;
00575 
00576   k = 1;
00577   v2 = ifClosed ? nodeVis : 1;
00578   for(i=i1beg; i<i1end; i++) {
00579     v1 = v2;
00580     if (!ifClosed && i == i1end-1) {
00581       v2 = 1;
00582     }else{
00583       v2 = (r[i] == r[i+1] && r[i+1] == r[i+2]) ? -1 : nodeVis;
00584     }
00585     RotateEdge(kk[i], kk[i+1], r[i], r[i+1], v1, v2,
00586                edgeVis, ifWholeCircle, nSphi, k);
00587   }
00588   if (ifClosed) {
00589     RotateEdge(kk[i1end], kk[i1beg], r[i1end],r[i1beg], nodeVis, nodeVis,
00590                edgeVis, ifWholeCircle, nSphi, k);
00591   }
00592 
00593   
00594 
00595   if (absNp2 > 1) {
00596     v2 = ifClosed ? nodeVis : 1;
00597     for(i=i2beg; i<i2end; i++) {
00598       v1 = v2;
00599       if (!ifClosed && i==i2end-1) {
00600         v2 = 1;
00601       }else{
00602         v2 = (r[i] == r[i+1] && r[i+1] == r[i+2]) ? -1 :  nodeVis;
00603       }
00604       RotateEdge(kk[i+1], kk[i], r[i+1], r[i], v2, v1,
00605                  edgeVis, ifWholeCircle, nSphi, k);
00606     }
00607     if (ifClosed) {
00608       RotateEdge(kk[i2beg], kk[i2end], r[i2beg], r[i2end], nodeVis, nodeVis,
00609                  edgeVis, ifWholeCircle, nSphi, k);
00610     }
00611   }
00612 
00613   
00614 
00615   if (!ifClosed) {
00616     if (ifSide1) {
00617       RotateEdge(kk[i2beg], kk[i1beg], r[i2beg], r[i1beg], 1, 1,
00618                  -1, ifWholeCircle, nSphi, k);
00619     }
00620     if (ifSide2) {
00621       RotateEdge(kk[i1end], kk[i2end], r[i1end], r[i2end], 1, 1,
00622                  -1, ifWholeCircle, nSphi, k);
00623     }
00624   }
00625 
00626   
00627 
00628   if (!ifWholeCircle) {
00629 
00630     G4int  ii[4], vv[4];
00631 
00632     if (ifClosed) {
00633       for (i=i1beg; i<=i1end; i++) {
00634         ii[0] = i;
00635         ii[3] = (i == i1end) ? i1beg : i+1;
00636         ii[1] = (absNp2 == 1) ? i2beg : ii[0]+absNp1;
00637         ii[2] = (absNp2 == 1) ? i2beg : ii[3]+absNp1;
00638         vv[0] = -1;
00639         vv[1] = 1;
00640         vv[2] = -1;
00641         vv[3] = 1;
00642         SetSideFacets(ii, vv, kk, r, dphi, nSphi, k);
00643       }
00644     }else{
00645       for (i=i1beg; i<i1end; i++) {
00646         ii[0] = i;
00647         ii[3] = i+1;
00648         ii[1] = (absNp2 == 1) ? i2beg : ii[0]+absNp1;
00649         ii[2] = (absNp2 == 1) ? i2beg : ii[3]+absNp1;
00650         vv[0] = (i == i1beg)   ? 1 : -1;
00651         vv[1] = 1;
00652         vv[2] = (i == i1end-1) ? 1 : -1;
00653         vv[3] = 1;
00654         SetSideFacets(ii, vv, kk, r, dphi, nSphi, k);
00655       }
00656     }      
00657   }
00658 
00659   delete [] kk;
00660 
00661   if (k-1 != nface) {
00662     std::cerr
00663       << "Polyhedron::RotateAroundZ: number of generated faces ("
00664       << k-1 << ") is not equal to the number of allocated faces ("
00665       << nface << ")"
00666       << std::endl;
00667   }
00668 }
00669 
00670 void HepPolyhedron::SetReferences()
00671 
00672 
00673 
00674 
00675 
00676 
00677 
00678 
00679 {
00680   if (nface <= 0) return;
00681 
00682   struct edgeListMember {
00683     edgeListMember *next;
00684     G4int v2;
00685     G4int iface;
00686     G4int iedge;
00687   } *edgeList, *freeList, **headList;
00688 
00689   
00690   
00691 
00692   edgeList = new edgeListMember[2*nface];
00693   headList = new edgeListMember*[nvert];
00694   
00695   G4int i;
00696   for (i=0; i<nvert; i++) {
00697     headList[i] = 0;
00698   }
00699   freeList = edgeList;
00700   for (i=0; i<2*nface-1; i++) {
00701     edgeList[i].next = &edgeList[i+1];
00702   }
00703   edgeList[2*nface-1].next = 0;
00704 
00705   
00706 
00707   G4int iface, iedge, nedge, i1, i2, k1, k2;
00708   edgeListMember *prev, *cur;
00709   
00710   for(iface=1; iface<=nface; iface++) {
00711     nedge = (pF[iface].edge[3].v == 0) ? 3 : 4;
00712     for (iedge=0; iedge<nedge; iedge++) {
00713       i1 = iedge;
00714       i2 = (iedge < nedge-1) ? iedge+1 : 0;
00715       i1 = std::abs(pF[iface].edge[i1].v);
00716       i2 = std::abs(pF[iface].edge[i2].v);
00717       k1 = (i1 < i2) ? i1 : i2;          
00718       k2 = (i1 > i2) ? i1 : i2;          
00719       
00720       
00721       cur = headList[k1];
00722       if (cur == 0) {
00723         headList[k1] = freeList;
00724         freeList = freeList->next;
00725         cur = headList[k1];
00726         cur->next = 0;
00727         cur->v2 = k2;
00728         cur->iface = iface;
00729         cur->iedge = iedge;
00730         continue;
00731       }
00732 
00733       if (cur->v2 == k2) {
00734         headList[k1] = cur->next;
00735         cur->next = freeList;
00736         freeList = cur;      
00737         pF[iface].edge[iedge].f = cur->iface;
00738         pF[cur->iface].edge[cur->iedge].f = iface;
00739         i1 = (pF[iface].edge[iedge].v < 0) ? -1 : 1;
00740         i2 = (pF[cur->iface].edge[cur->iedge].v < 0) ? -1 : 1;
00741         if (i1 != i2) {
00742           std::cerr
00743             << "Polyhedron::SetReferences: different edge visibility "
00744             << iface << "/" << iedge << "/"
00745             << pF[iface].edge[iedge].v << " and "
00746             << cur->iface << "/" << cur->iedge << "/"
00747             << pF[cur->iface].edge[cur->iedge].v
00748             << std::endl;
00749         }
00750         continue;
00751       }
00752 
00753       
00754       for (;;) {
00755         prev = cur;
00756         cur = prev->next;
00757         if (cur == 0) {
00758           prev->next = freeList;
00759           freeList = freeList->next;
00760           cur = prev->next;
00761           cur->next = 0;
00762           cur->v2 = k2;
00763           cur->iface = iface;
00764           cur->iedge = iedge;
00765           break;
00766         }
00767 
00768         if (cur->v2 == k2) {
00769           prev->next = cur->next;
00770           cur->next = freeList;
00771           freeList = cur;      
00772           pF[iface].edge[iedge].f = cur->iface;
00773           pF[cur->iface].edge[cur->iedge].f = iface;
00774           i1 = (pF[iface].edge[iedge].v < 0) ? -1 : 1;
00775           i2 = (pF[cur->iface].edge[cur->iedge].v < 0) ? -1 : 1;
00776             if (i1 != i2) {
00777               std::cerr
00778                 << "Polyhedron::SetReferences: different edge visibility "
00779                 << iface << "/" << iedge << "/"
00780                 << pF[iface].edge[iedge].v << " and "
00781                 << cur->iface << "/" << cur->iedge << "/"
00782                 << pF[cur->iface].edge[cur->iedge].v
00783                 << std::endl;
00784             }
00785           break;
00786         }
00787       }
00788     }
00789   }
00790 
00791   
00792 
00793   for (i=0; i<nvert; i++) {
00794     if (headList[i] != 0) {
00795       std::cerr
00796         << "Polyhedron::SetReferences: List " << i << " is not empty"
00797         << std::endl;
00798     }
00799   }
00800 
00801   
00802 
00803   delete [] edgeList;
00804   delete [] headList;
00805 }
00806 
00807 void HepPolyhedron::InvertFacets()
00808 
00809 
00810 
00811 
00812 
00813 
00814 
00815 
00816 {
00817   if (nface <= 0) return;
00818   G4int i, k, nnode, v[4],f[4];
00819   for (i=1; i<=nface; i++) {
00820     nnode =  (pF[i].edge[3].v == 0) ? 3 : 4;
00821     for (k=0; k<nnode; k++) {
00822       v[k] = (k+1 == nnode) ? pF[i].edge[0].v : pF[i].edge[k+1].v;
00823       if (v[k] * pF[i].edge[k].v < 0) v[k] = -v[k];
00824       f[k] = pF[i].edge[k].f;
00825     }
00826     for (k=0; k<nnode; k++) {
00827       pF[i].edge[nnode-1-k].v = v[k];
00828       pF[i].edge[nnode-1-k].f = f[k];
00829     }
00830   }
00831 }
00832 
00833 HepPolyhedron & HepPolyhedron::Transform(const G4Transform3D &t)
00834 
00835 
00836 
00837 
00838 
00839 
00840 
00841 
00842 {
00843   if (nvert > 0) {
00844     for (G4int i=1; i<=nvert; i++) { pV[i] = t * pV[i]; }
00845 
00846     
00847     
00848 
00849     G4Vector3D d = t * G4Vector3D(0,0,0);
00850     G4Vector3D x = t * G4Vector3D(1,0,0) - d;
00851     G4Vector3D y = t * G4Vector3D(0,1,0) - d;
00852     G4Vector3D z = t * G4Vector3D(0,0,1) - d;
00853     if ((x.cross(y))*z < 0) InvertFacets();
00854   }
00855   return *this;
00856 }
00857 
00858 G4bool HepPolyhedron::GetNextVertexIndex(G4int &index, G4int &edgeFlag) const
00859 
00860 
00861 
00862 
00863 
00864 
00865 
00866 
00867 {
00868   static G4int iFace = 1;
00869   static G4int iQVertex = 0;
00870   G4int vIndex = pF[iFace].edge[iQVertex].v;
00871 
00872   edgeFlag = (vIndex > 0) ? 1 : 0;
00873   index = std::abs(vIndex);
00874 
00875   if (iQVertex >= 3 || pF[iFace].edge[iQVertex+1].v == 0) {
00876     iQVertex = 0;
00877     if (++iFace > nface) iFace = 1;
00878     return false;  
00879   }else{
00880     ++iQVertex;
00881     return true;  
00882   }
00883 }
00884 
00885 G4Point3D HepPolyhedron::GetVertex(G4int index) const
00886 
00887 
00888 
00889 
00890 
00891 
00892 
00893 
00894 {
00895   if (index <= 0 || index > nvert) {
00896     std::cerr
00897       << "HepPolyhedron::GetVertex: irrelevant index " << index
00898       << std::endl;
00899     return G4Point3D();
00900   }
00901   return pV[index];
00902 }
00903 
00904 G4bool
00905 HepPolyhedron::GetNextVertex(G4Point3D &vertex, G4int &edgeFlag) const
00906 
00907 
00908 
00909 
00910 
00911 
00912 
00913 
00914 
00915 
00916 {
00917   G4int index;
00918   G4bool rep = GetNextVertexIndex(index, edgeFlag);
00919   vertex = pV[index];
00920   return rep;
00921 }
00922 
00923 G4bool HepPolyhedron::GetNextVertex(G4Point3D &vertex, G4int &edgeFlag,
00924                                   G4Normal3D &normal) const
00925 
00926 
00927 
00928 
00929 
00930 
00931 
00932 
00933 
00934 
00935 {
00936   static G4int iFace = 1;
00937   static G4int iNode = 0;
00938 
00939   if (nface == 0) return false;  
00940 
00941   G4int k = pF[iFace].edge[iNode].v;
00942   if (k > 0) { edgeFlag = 1; } else { edgeFlag = -1; k = -k; }
00943   vertex = pV[k];
00944   normal = FindNodeNormal(iFace,k);
00945   if (iNode >= 3 || pF[iFace].edge[iNode+1].v == 0) {
00946     iNode = 0;
00947     if (++iFace > nface) iFace = 1;
00948     return false;                
00949   }else{
00950     ++iNode;
00951     return true;                 
00952   }
00953 }
00954 
00955 G4bool HepPolyhedron::GetNextEdgeIndeces(G4int &i1, G4int &i2, G4int &edgeFlag,
00956                                        G4int &iface1, G4int &iface2) const
00957 
00958 
00959 
00960 
00961 
00962 
00963 
00964 
00965 
00966 
00967 {
00968   static G4int iFace    = 1;
00969   static G4int iQVertex = 0;
00970   static G4int iOrder   = 1;
00971   G4int  k1, k2, kflag, kface1, kface2;
00972 
00973   if (iFace == 1 && iQVertex == 0) {
00974     k2 = pF[nface].edge[0].v;
00975     k1 = pF[nface].edge[3].v;
00976     if (k1 == 0) k1 = pF[nface].edge[2].v;
00977     if (std::abs(k1) > std::abs(k2)) iOrder = -1;
00978   }
00979 
00980   do {
00981     k1     = pF[iFace].edge[iQVertex].v;
00982     kflag  = k1;
00983     k1     = std::abs(k1);
00984     kface1 = iFace; 
00985     kface2 = pF[iFace].edge[iQVertex].f;
00986     if (iQVertex >= 3 || pF[iFace].edge[iQVertex+1].v == 0) {
00987       iQVertex = 0;
00988       k2 = std::abs(pF[iFace].edge[iQVertex].v);
00989       iFace++;
00990     }else{
00991       iQVertex++;
00992       k2 = std::abs(pF[iFace].edge[iQVertex].v);
00993     }
00994   } while (iOrder*k1 > iOrder*k2);
00995 
00996   i1 = k1; i2 = k2; edgeFlag = (kflag > 0) ? 1 : 0;
00997   iface1 = kface1; iface2 = kface2; 
00998 
00999   if (iFace > nface) {
01000     iFace  = 1; iOrder = 1;
01001     return false;
01002   }else{
01003     return true;
01004   }
01005 }
01006 
01007 G4bool
01008 HepPolyhedron::GetNextEdgeIndeces(G4int &i1, G4int &i2, G4int &edgeFlag) const
01009 
01010 
01011 
01012 
01013 
01014 
01015 
01016 
01017 
01018 {
01019   G4int kface1, kface2;
01020   return GetNextEdgeIndeces(i1, i2, edgeFlag, kface1, kface2);
01021 }
01022 
01023 G4bool
01024 HepPolyhedron::GetNextEdge(G4Point3D &p1,
01025                            G4Point3D &p2,
01026                            G4int &edgeFlag) const
01027 
01028 
01029 
01030 
01031 
01032 
01033 
01034 
01035 
01036 {
01037   G4int i1,i2;
01038   G4bool rep = GetNextEdgeIndeces(i1,i2,edgeFlag);
01039   p1 = pV[i1];
01040   p2 = pV[i2];
01041   return rep;
01042 }
01043 
01044 G4bool
01045 HepPolyhedron::GetNextEdge(G4Point3D &p1, G4Point3D &p2,
01046                           G4int &edgeFlag, G4int &iface1, G4int &iface2) const
01047 
01048 
01049 
01050 
01051 
01052 
01053 
01054 
01055 
01056 
01057 {
01058   G4int i1,i2;
01059   G4bool rep = GetNextEdgeIndeces(i1,i2,edgeFlag,iface1,iface2);
01060   p1 = pV[i1];
01061   p2 = pV[i2];
01062   return rep;
01063 }
01064 
01065 void HepPolyhedron::GetFacet(G4int iFace, G4int &n, G4int *iNodes,
01066                             G4int *edgeFlags, G4int *iFaces) const
01067 
01068 
01069 
01070 
01071 
01072 
01073 
01074 
01075 {
01076   if (iFace < 1 || iFace > nface) {
01077     std::cerr 
01078       << "HepPolyhedron::GetFacet: irrelevant index " << iFace
01079       << std::endl;
01080     n = 0;
01081   }else{
01082     G4int i, k;
01083     for (i=0; i<4; i++) { 
01084       k = pF[iFace].edge[i].v;
01085       if (k == 0) break;
01086       if (iFaces != 0) iFaces[i] = pF[iFace].edge[i].f;
01087       if (k > 0) { 
01088         iNodes[i] = k;
01089         if (edgeFlags != 0) edgeFlags[i] = 1;
01090       }else{
01091         iNodes[i] = -k;
01092         if (edgeFlags != 0) edgeFlags[i] = -1;
01093       }
01094     }
01095     n = i;
01096   }
01097 }
01098 
01099 void HepPolyhedron::GetFacet(G4int index, G4int &n, G4Point3D *nodes,
01100                              G4int *edgeFlags, G4Normal3D *normals) const
01101 
01102 
01103 
01104 
01105 
01106 
01107 
01108 
01109 {
01110   G4int iNodes[4];
01111   GetFacet(index, n, iNodes, edgeFlags);
01112   if (n != 0) {
01113     for (G4int i=0; i<n; i++) {
01114       nodes[i] = pV[iNodes[i]];
01115       if (normals != 0) normals[i] = FindNodeNormal(index,iNodes[i]);
01116     }
01117   }
01118 }
01119 
01120 G4bool
01121 HepPolyhedron::GetNextFacet(G4int &n, G4Point3D *nodes,
01122                            G4int *edgeFlags, G4Normal3D *normals) const
01123 
01124 
01125 
01126 
01127 
01128 
01129 
01130 
01131 
01132 {
01133   static G4int iFace = 1;
01134 
01135   if (edgeFlags == 0) {
01136     GetFacet(iFace, n, nodes);
01137   }else if (normals == 0) {
01138     GetFacet(iFace, n, nodes, edgeFlags);
01139   }else{
01140     GetFacet(iFace, n, nodes, edgeFlags, normals);
01141   }
01142 
01143   if (++iFace > nface) {
01144     iFace  = 1;
01145     return false;
01146   }else{
01147     return true;
01148   }
01149 }
01150 
01151 G4Normal3D HepPolyhedron::GetNormal(G4int iFace) const
01152 
01153 
01154 
01155 
01156 
01157 
01158 
01159 
01160 {
01161   if (iFace < 1 || iFace > nface) {
01162     std::cerr 
01163       << "HepPolyhedron::GetNormal: irrelevant index " << iFace 
01164       << std::endl;
01165     return G4Normal3D();
01166   }
01167 
01168   G4int i0  = std::abs(pF[iFace].edge[0].v);
01169   G4int i1  = std::abs(pF[iFace].edge[1].v);
01170   G4int i2  = std::abs(pF[iFace].edge[2].v);
01171   G4int i3  = std::abs(pF[iFace].edge[3].v);
01172   if (i3 == 0) i3 = i0;
01173   return (pV[i2] - pV[i0]).cross(pV[i3] - pV[i1]);
01174 }
01175 
01176 G4Normal3D HepPolyhedron::GetUnitNormal(G4int iFace) const
01177 
01178 
01179 
01180 
01181 
01182 
01183 
01184 
01185 {
01186   if (iFace < 1 || iFace > nface) {
01187     std::cerr 
01188       << "HepPolyhedron::GetUnitNormal: irrelevant index " << iFace
01189       << std::endl;
01190     return G4Normal3D();
01191   }
01192 
01193   G4int i0  = std::abs(pF[iFace].edge[0].v);
01194   G4int i1  = std::abs(pF[iFace].edge[1].v);
01195   G4int i2  = std::abs(pF[iFace].edge[2].v);
01196   G4int i3  = std::abs(pF[iFace].edge[3].v);
01197   if (i3 == 0) i3 = i0;
01198   return ((pV[i2] - pV[i0]).cross(pV[i3] - pV[i1])).unit();
01199 }
01200 
01201 G4bool HepPolyhedron::GetNextNormal(G4Normal3D &normal) const
01202 
01203 
01204 
01205 
01206 
01207 
01208 
01209 
01210 
01211 {
01212   static G4int iFace = 1;
01213   normal = GetNormal(iFace);
01214   if (++iFace > nface) {
01215     iFace = 1;
01216     return false;
01217   }else{
01218     return true;
01219   }
01220 }
01221 
01222 G4bool HepPolyhedron::GetNextUnitNormal(G4Normal3D &normal) const
01223 
01224 
01225 
01226 
01227 
01228 
01229 
01230 
01231 
01232 {
01233   G4bool rep = GetNextNormal(normal);
01234   normal = normal.unit();
01235   return rep;
01236 }
01237 
01238 G4double HepPolyhedron::GetSurfaceArea() const
01239 
01240 
01241 
01242 
01243 
01244 
01245 
01246 
01247 {
01248   G4double srf = 0.;
01249   for (G4int iFace=1; iFace<=nface; iFace++) {
01250     G4int i0 = std::abs(pF[iFace].edge[0].v);
01251     G4int i1 = std::abs(pF[iFace].edge[1].v);
01252     G4int i2 = std::abs(pF[iFace].edge[2].v);
01253     G4int i3 = std::abs(pF[iFace].edge[3].v);
01254     if (i3 == 0) i3 = i0;
01255     srf += ((pV[i2] - pV[i0]).cross(pV[i3] - pV[i1])).mag();
01256   }
01257   return srf/2.;
01258 }
01259 
01260 G4double HepPolyhedron::GetVolume() const
01261 
01262 
01263 
01264 
01265 
01266 
01267 
01268 
01269 {
01270   G4double v = 0.;
01271   for (G4int iFace=1; iFace<=nface; iFace++) {
01272     G4int i0 = std::abs(pF[iFace].edge[0].v);
01273     G4int i1 = std::abs(pF[iFace].edge[1].v);
01274     G4int i2 = std::abs(pF[iFace].edge[2].v);
01275     G4int i3 = std::abs(pF[iFace].edge[3].v);
01276     G4Point3D pt;
01277     if (i3 == 0) {
01278       i3 = i0;
01279       pt = (pV[i0]+pV[i1]+pV[i2]) * (1./3.);
01280     }else{
01281       pt = (pV[i0]+pV[i1]+pV[i2]+pV[i3]) * 0.25;
01282     }
01283     v += ((pV[i2] - pV[i0]).cross(pV[i3] - pV[i1])).dot(pt);
01284   }
01285   return v/6.;
01286 }
01287 
01288 G4int
01289 HepPolyhedron::createTwistedTrap(G4double Dz,
01290                                  const G4double xy1[][2],
01291                                  const G4double xy2[][2])
01292 
01293 
01294 
01295 
01296 
01297 
01298 
01299 
01300 
01301 
01302 
01303 
01304 
01305 {
01306   AllocateMemory(12,18);
01307 
01308   pV[ 1] = G4Point3D(xy1[0][0],xy1[0][1],-Dz);
01309   pV[ 2] = G4Point3D(xy1[1][0],xy1[1][1],-Dz);
01310   pV[ 3] = G4Point3D(xy1[2][0],xy1[2][1],-Dz);
01311   pV[ 4] = G4Point3D(xy1[3][0],xy1[3][1],-Dz);
01312 
01313   pV[ 5] = G4Point3D(xy2[0][0],xy2[0][1], Dz);
01314   pV[ 6] = G4Point3D(xy2[1][0],xy2[1][1], Dz);
01315   pV[ 7] = G4Point3D(xy2[2][0],xy2[2][1], Dz);
01316   pV[ 8] = G4Point3D(xy2[3][0],xy2[3][1], Dz);
01317 
01318   pV[ 9] = (pV[1]+pV[2]+pV[5]+pV[6])/4.;
01319   pV[10] = (pV[2]+pV[3]+pV[6]+pV[7])/4.;
01320   pV[11] = (pV[3]+pV[4]+pV[7]+pV[8])/4.;
01321   pV[12] = (pV[4]+pV[1]+pV[8]+pV[5])/4.;
01322 
01323   enum {DUMMY, BOTTOM,
01324         LEFT_BOTTOM,  LEFT_FRONT,   LEFT_TOP,  LEFT_BACK,
01325         BACK_BOTTOM,  BACK_LEFT,    BACK_TOP,  BACK_RIGHT,
01326         RIGHT_BOTTOM, RIGHT_BACK,   RIGHT_TOP, RIGHT_FRONT,
01327         FRONT_BOTTOM, FRONT_RIGHT,  FRONT_TOP, FRONT_LEFT,
01328         TOP};
01329 
01330   pF[ 1]=G4Facet(1,LEFT_BOTTOM, 4,BACK_BOTTOM, 3,RIGHT_BOTTOM, 2,FRONT_BOTTOM);
01331 
01332   pF[ 2]=G4Facet(4,BOTTOM,     -1,LEFT_FRONT,  -12,LEFT_BACK,    0,0);
01333   pF[ 3]=G4Facet(1,FRONT_LEFT, -5,LEFT_TOP,    -12,LEFT_BOTTOM,  0,0);
01334   pF[ 4]=G4Facet(5,TOP,        -8,LEFT_BACK,   -12,LEFT_FRONT,   0,0);
01335   pF[ 5]=G4Facet(8,BACK_LEFT,  -4,LEFT_BOTTOM, -12,LEFT_TOP,     0,0);
01336 
01337   pF[ 6]=G4Facet(3,BOTTOM,     -4,BACK_LEFT,   -11,BACK_RIGHT,   0,0);
01338   pF[ 7]=G4Facet(4,LEFT_BACK,  -8,BACK_TOP,    -11,BACK_BOTTOM,  0,0);
01339   pF[ 8]=G4Facet(8,TOP,        -7,BACK_RIGHT,  -11,BACK_LEFT,    0,0);
01340   pF[ 9]=G4Facet(7,RIGHT_BACK, -3,BACK_BOTTOM, -11,BACK_TOP,     0,0);
01341 
01342   pF[10]=G4Facet(2,BOTTOM,     -3,RIGHT_BACK,  -10,RIGHT_FRONT,  0,0);
01343   pF[11]=G4Facet(3,BACK_RIGHT, -7,RIGHT_TOP,   -10,RIGHT_BOTTOM, 0,0);
01344   pF[12]=G4Facet(7,TOP,        -6,RIGHT_FRONT, -10,RIGHT_BACK,   0,0);
01345   pF[13]=G4Facet(6,FRONT_RIGHT,-2,RIGHT_BOTTOM,-10,RIGHT_TOP,    0,0);
01346 
01347   pF[14]=G4Facet(1,BOTTOM,     -2,FRONT_RIGHT,  -9,FRONT_LEFT,   0,0);
01348   pF[15]=G4Facet(2,RIGHT_FRONT,-6,FRONT_TOP,    -9,FRONT_BOTTOM, 0,0);
01349   pF[16]=G4Facet(6,TOP,        -5,FRONT_LEFT,   -9,FRONT_RIGHT,  0,0);
01350   pF[17]=G4Facet(5,LEFT_FRONT, -1,FRONT_BOTTOM, -9,FRONT_TOP,    0,0);
01351  
01352   pF[18]=G4Facet(5,FRONT_TOP, 6,RIGHT_TOP, 7,BACK_TOP, 8,LEFT_TOP);
01353 
01354   return 0;
01355 }
01356 
01357 G4int
01358 HepPolyhedron::createPolyhedron(G4int Nnodes, G4int Nfaces,
01359                                 const G4double xyz[][3],
01360                                 const G4int  faces[][4])
01361 
01362 
01363 
01364 
01365 
01366 
01367 
01368 
01369 
01370 
01371 
01372 
01373 
01374 {
01375   AllocateMemory(Nnodes, Nfaces);
01376   if (nvert == 0) return 1;
01377 
01378   for (G4int i=0; i<Nnodes; i++) {
01379     pV[i+1] = G4Point3D(xyz[i][0], xyz[i][1], xyz[i][2]);
01380   }
01381   for (G4int k=0; k<Nfaces; k++) {
01382     pF[k+1] = G4Facet(faces[k][0],0,faces[k][1],0,faces[k][2],0,faces[k][3],0);
01383   }
01384   SetReferences();
01385   return 0;
01386 }
01387 
01388 HepPolyhedronTrd2::HepPolyhedronTrd2(G4double Dx1, G4double Dx2,
01389                                      G4double Dy1, G4double Dy2,
01390                                      G4double Dz)
01391 
01392 
01393 
01394 
01395 
01396 
01397 
01398 
01399 
01400 
01401 
01402 
01403 
01404 
01405 {
01406   AllocateMemory(8,6);
01407 
01408   pV[1] = G4Point3D(-Dx1,-Dy1,-Dz);
01409   pV[2] = G4Point3D( Dx1,-Dy1,-Dz);
01410   pV[3] = G4Point3D( Dx1, Dy1,-Dz);
01411   pV[4] = G4Point3D(-Dx1, Dy1,-Dz);
01412   pV[5] = G4Point3D(-Dx2,-Dy2, Dz);
01413   pV[6] = G4Point3D( Dx2,-Dy2, Dz);
01414   pV[7] = G4Point3D( Dx2, Dy2, Dz);
01415   pV[8] = G4Point3D(-Dx2, Dy2, Dz);
01416 
01417   CreatePrism();
01418 }
01419 
01420 HepPolyhedronTrd2::~HepPolyhedronTrd2() {}
01421 
01422 HepPolyhedronTrd1::HepPolyhedronTrd1(G4double Dx1, G4double Dx2,
01423                                      G4double Dy, G4double Dz)
01424   : HepPolyhedronTrd2(Dx1, Dx2, Dy, Dy, Dz) {}
01425 
01426 HepPolyhedronTrd1::~HepPolyhedronTrd1() {}
01427 
01428 HepPolyhedronBox::HepPolyhedronBox(G4double Dx, G4double Dy, G4double Dz)
01429   : HepPolyhedronTrd2(Dx, Dx, Dy, Dy, Dz) {}
01430 
01431 HepPolyhedronBox::~HepPolyhedronBox() {}
01432 
01433 HepPolyhedronTrap::HepPolyhedronTrap(G4double Dz,
01434                                      G4double Theta,
01435                                      G4double Phi,
01436                                      G4double Dy1,
01437                                      G4double Dx1,
01438                                      G4double Dx2,
01439                                      G4double Alp1,
01440                                      G4double Dy2,
01441                                      G4double Dx3,
01442                                      G4double Dx4,
01443                                      G4double Alp2)
01444 
01445 
01446 
01447 
01448 
01449 
01450 
01451 
01452 
01453 
01454 
01455 
01456 
01457 
01458 
01459 
01460 
01461 
01462 
01463 
01464 
01465 
01466 {
01467   G4double DzTthetaCphi = Dz*std::tan(Theta)*std::cos(Phi);
01468   G4double DzTthetaSphi = Dz*std::tan(Theta)*std::sin(Phi);
01469   G4double Dy1Talp1 = Dy1*std::tan(Alp1);
01470   G4double Dy2Talp2 = Dy2*std::tan(Alp2);
01471   
01472   AllocateMemory(8,6);
01473 
01474   pV[1] = G4Point3D(-DzTthetaCphi-Dy1Talp1-Dx1,-DzTthetaSphi-Dy1,-Dz);
01475   pV[2] = G4Point3D(-DzTthetaCphi-Dy1Talp1+Dx1,-DzTthetaSphi-Dy1,-Dz);
01476   pV[3] = G4Point3D(-DzTthetaCphi+Dy1Talp1+Dx2,-DzTthetaSphi+Dy1,-Dz);
01477   pV[4] = G4Point3D(-DzTthetaCphi+Dy1Talp1-Dx2,-DzTthetaSphi+Dy1,-Dz);
01478   pV[5] = G4Point3D( DzTthetaCphi-Dy2Talp2-Dx3, DzTthetaSphi-Dy2, Dz);
01479   pV[6] = G4Point3D( DzTthetaCphi-Dy2Talp2+Dx3, DzTthetaSphi-Dy2, Dz);
01480   pV[7] = G4Point3D( DzTthetaCphi+Dy2Talp2+Dx4, DzTthetaSphi+Dy2, Dz);
01481   pV[8] = G4Point3D( DzTthetaCphi+Dy2Talp2-Dx4, DzTthetaSphi+Dy2, Dz);
01482 
01483   CreatePrism();
01484 }
01485 
01486 HepPolyhedronTrap::~HepPolyhedronTrap() {}
01487 
01488 HepPolyhedronPara::HepPolyhedronPara(G4double Dx, G4double Dy, G4double Dz,
01489                                      G4double Alpha, G4double Theta,
01490                                      G4double Phi)
01491   : HepPolyhedronTrap(Dz, Theta, Phi, Dy, Dx, Dx, Alpha, Dy, Dx, Dx, Alpha) {}
01492 
01493 HepPolyhedronPara::~HepPolyhedronPara() {}
01494 
01495 HepPolyhedronParaboloid::HepPolyhedronParaboloid(G4double r1,
01496                                                  G4double r2,
01497                                                  G4double dz,
01498                                                  G4double sPhi,
01499                                                  G4double dPhi) 
01500 
01501 
01502 
01503 
01504 
01505 
01506 
01507 
01508 
01509 
01510 
01511 
01512 
01513 
01514 {
01515   static const G4double wholeCircle=twopi;
01516 
01517   
01518 
01519   G4int k = 0;
01520   if (r1 < 0. || r2 <= 0.)        k = 1;
01521 
01522   if (dz <= 0.) k += 2;
01523 
01524   G4double phi1, phi2, dphi;
01525 
01526   if(dPhi < 0.)
01527   {
01528     phi2 = sPhi; phi1 = phi2 + dPhi;
01529   }
01530   else if(dPhi == 0.) 
01531   {
01532     phi1 = sPhi; phi2 = phi1 + wholeCircle;
01533   }
01534   else
01535   {
01536     phi1 = sPhi; phi2 = phi1 + dPhi;
01537   }
01538   dphi  = phi2 - phi1;
01539 
01540   if (std::abs(dphi-wholeCircle) < perMillion) dphi = wholeCircle;
01541   if (dphi > wholeCircle) k += 4; 
01542 
01543   if (k != 0) {
01544     std::cerr << "HepPolyhedronParaboloid: error in input parameters";
01545     if ((k & 1) != 0) std::cerr << " (radiuses)";
01546     if ((k & 2) != 0) std::cerr << " (half-length)";
01547     if ((k & 4) != 0) std::cerr << " (angles)";
01548     std::cerr << std::endl;
01549     std::cerr << " r1=" << r1;
01550     std::cerr << " r2=" << r2;
01551     std::cerr << " dz=" << dz << " sPhi=" << sPhi << " dPhi=" << dPhi
01552               << std::endl;
01553     return;
01554   }
01555   
01556   
01557 
01558   G4int n = GetNumberOfRotationSteps();
01559   G4double dl = (r2 - r1) / n;
01560   G4double k1 = (r2*r2 - r1*r1) / 2 / dz;
01561   G4double k2 = (r2*r2 + r1*r1) / 2;
01562 
01563   G4double *zz = new G4double[n + 2], *rr = new G4double[n + 2];
01564 
01565   zz[0] = dz;
01566   rr[0] = r2;
01567 
01568   for(G4int i = 1; i < n - 1; i++)
01569   {
01570     rr[i] = rr[i-1] - dl;
01571     zz[i] = (rr[i]*rr[i] - k2) / k1;
01572     if(rr[i] < 0)
01573     {
01574       rr[i] = 0;
01575       zz[i] = 0;
01576     }
01577   }
01578 
01579   zz[n-1] = -dz;
01580   rr[n-1] = r1;
01581 
01582   zz[n] = dz;
01583   rr[n] = 0;
01584 
01585   zz[n+1] = -dz;
01586   rr[n+1] = 0;
01587 
01588   
01589 
01590   RotateAroundZ(0, phi1, dphi, n, 2, zz, rr, -1, -1); 
01591   SetReferences();
01592 
01593   delete [] zz;
01594   delete [] rr;
01595 }
01596 
01597 HepPolyhedronParaboloid::~HepPolyhedronParaboloid() {}
01598 
01599 HepPolyhedronHype::HepPolyhedronHype(G4double r1,
01600                                      G4double r2,
01601                                      G4double sqrtan1,
01602                                      G4double sqrtan2,
01603                                      G4double halfZ) 
01604 
01605 
01606 
01607 
01608 
01609 
01610 
01611 
01612 
01613 
01614 
01615 
01616 
01617 
01618 {
01619   static const G4double wholeCircle=twopi;
01620 
01621   
01622 
01623   G4int k = 0;
01624   if (r2 < 0. || r1 < 0. )        k = 1;
01625   if (r1 > r2 )                   k = 1;
01626   if (r1 == r2)                   k = 1;
01627 
01628   if (halfZ <= 0.) k += 2;
01629  
01630   if (sqrtan1<0.||sqrtan2<0.) k += 4;  
01631  
01632   if (k != 0)
01633   {
01634     std::cerr << "HepPolyhedronHype: error in input parameters";
01635     if ((k & 1) != 0) std::cerr << " (radiuses)";
01636     if ((k & 2) != 0) std::cerr << " (half-length)";
01637     if ((k & 4) != 0) std::cerr << " (angles)";
01638     std::cerr << std::endl;
01639     std::cerr << " r1=" << r1 << " r2=" << r2;
01640     std::cerr << " halfZ=" << halfZ << " sqrTan1=" << sqrtan1
01641               << " sqrTan2=" << sqrtan2
01642               << std::endl;
01643     return;
01644   }
01645   
01646   
01647 
01648   G4int n = GetNumberOfRotationSteps();
01649   G4double dz = 2.*halfZ / n;
01650   G4double k1 = r1*r1;
01651   G4double k2 = r2*r2;
01652 
01653   G4double *zz = new G4double[n+n+1], *rr = new G4double[n+n+1];
01654 
01655   zz[0] = halfZ;
01656   rr[0] = std::sqrt(sqrtan2*halfZ*halfZ+k2);
01657 
01658   for(G4int i = 1; i < n-1; i++)
01659   {
01660     zz[i] = zz[i-1] - dz;
01661     rr[i] =std::sqrt(sqrtan2*zz[i]*zz[i]+k2);
01662   }
01663 
01664   zz[n-1] = -halfZ;
01665   rr[n-1] = rr[0];
01666 
01667   zz[n] = halfZ;
01668   rr[n] =  std::sqrt(sqrtan1*halfZ*halfZ+k1);
01669 
01670   for(G4int i = n+1; i < n+n; i++)
01671   {
01672     zz[i] = zz[i-1] - dz;
01673     rr[i] =std::sqrt(sqrtan1*zz[i]*zz[i]+k1);
01674   }
01675   zz[n+n] = -halfZ;
01676   rr[n+n] = rr[n];
01677 
01678   
01679 
01680   RotateAroundZ(0, 0., wholeCircle, n, n, zz, rr, -1, -1); 
01681   SetReferences();
01682 
01683   delete [] zz;
01684   delete [] rr;
01685 }
01686 
01687 HepPolyhedronHype::~HepPolyhedronHype() {}
01688 
01689 HepPolyhedronCons::HepPolyhedronCons(G4double Rmn1,
01690                                      G4double Rmx1,
01691                                      G4double Rmn2,
01692                                      G4double Rmx2, 
01693                                      G4double Dz,
01694                                      G4double Phi1,
01695                                      G4double Dphi) 
01696 
01697 
01698 
01699 
01700 
01701 
01702 
01703 
01704 
01705 
01706 
01707 
01708 
01709 
01710 {
01711   static const G4double wholeCircle=twopi;
01712 
01713   
01714 
01715   G4int k = 0;
01716   if (Rmn1 < 0. || Rmx1 < 0. || Rmn2 < 0. || Rmx2 < 0.)        k = 1;
01717   if (Rmn1 > Rmx1 || Rmn2 > Rmx2)                              k = 1;
01718   if (Rmn1 == Rmx1 && Rmn2 == Rmx2)                            k = 1;
01719 
01720   if (Dz <= 0.) k += 2;
01721  
01722   G4double phi1, phi2, dphi;
01723   if (Dphi < 0.) {
01724     phi2 = Phi1; phi1 = phi2 - Dphi;
01725   }else if (Dphi == 0.) {
01726     phi1 = Phi1; phi2 = phi1 + wholeCircle;
01727   }else{
01728     phi1 = Phi1; phi2 = phi1 + Dphi;
01729   }
01730   dphi  = phi2 - phi1;
01731   if (std::abs(dphi-wholeCircle) < perMillion) dphi = wholeCircle;
01732   if (dphi > wholeCircle) k += 4; 
01733 
01734   if (k != 0) {
01735     std::cerr << "HepPolyhedronCone(s)/Tube(s): error in input parameters";
01736     if ((k & 1) != 0) std::cerr << " (radiuses)";
01737     if ((k & 2) != 0) std::cerr << " (half-length)";
01738     if ((k & 4) != 0) std::cerr << " (angles)";
01739     std::cerr << std::endl;
01740     std::cerr << " Rmn1=" << Rmn1 << " Rmx1=" << Rmx1;
01741     std::cerr << " Rmn2=" << Rmn2 << " Rmx2=" << Rmx2;
01742     std::cerr << " Dz=" << Dz << " Phi1=" << Phi1 << " Dphi=" << Dphi
01743               << std::endl;
01744     return;
01745   }
01746   
01747   
01748 
01749   G4double zz[4], rr[4];
01750   zz[0] =  Dz; 
01751   zz[1] = -Dz; 
01752   zz[2] =  Dz; 
01753   zz[3] = -Dz; 
01754   rr[0] =  Rmx2;
01755   rr[1] =  Rmx1;
01756   rr[2] =  Rmn2;
01757   rr[3] =  Rmn1;
01758 
01759   
01760 
01761   RotateAroundZ(0, phi1, dphi, 2, 2, zz, rr, -1, -1); 
01762   SetReferences();
01763 }
01764 
01765 HepPolyhedronCons::~HepPolyhedronCons() {}
01766 
01767 HepPolyhedronCone::HepPolyhedronCone(G4double Rmn1, G4double Rmx1, 
01768                                      G4double Rmn2, G4double Rmx2,
01769                                      G4double Dz) :
01770   HepPolyhedronCons(Rmn1, Rmx1, Rmn2, Rmx2, Dz, 0*deg, 360*deg) {}
01771 
01772 HepPolyhedronCone::~HepPolyhedronCone() {}
01773 
01774 HepPolyhedronTubs::HepPolyhedronTubs(G4double Rmin, G4double Rmax,
01775                                      G4double Dz, 
01776                                      G4double Phi1, G4double Dphi)
01777   :   HepPolyhedronCons(Rmin, Rmax, Rmin, Rmax, Dz, Phi1, Dphi) {}
01778 
01779 HepPolyhedronTubs::~HepPolyhedronTubs() {}
01780 
01781 HepPolyhedronTube::HepPolyhedronTube (G4double Rmin, G4double Rmax,
01782                                       G4double Dz)
01783   : HepPolyhedronCons(Rmin, Rmax, Rmin, Rmax, Dz, 0*deg, 360*deg) {}
01784 
01785 HepPolyhedronTube::~HepPolyhedronTube () {}
01786 
01787 HepPolyhedronPgon::HepPolyhedronPgon(G4double phi,
01788                                      G4double dphi,
01789                                      G4int    npdv,
01790                                      G4int    nz,
01791                                      const G4double *z,
01792                                      const G4double *rmin,
01793                                      const G4double *rmax)
01794 
01795 
01796 
01797 
01798 
01799 
01800 
01801 
01802 
01803 
01804 
01805 
01806 
01807 
01808 
01809 
01810 {
01811   
01812 
01813   if (dphi <= 0. || dphi > twopi) {
01814     std::cerr
01815       << "HepPolyhedronPgon/Pcon: wrong delta phi = " << dphi
01816       << std::endl;
01817     return;
01818   }    
01819     
01820   if (nz < 2) {
01821     std::cerr
01822       << "HepPolyhedronPgon/Pcon: number of z-planes less than two = " << nz
01823       << std::endl;
01824     return;
01825   }
01826 
01827   if (npdv < 0) {
01828     std::cerr
01829       << "HepPolyhedronPgon/Pcon: error in number of phi-steps =" << npdv
01830       << std::endl;
01831     return;
01832   }
01833 
01834   G4int i;
01835   for (i=0; i<nz; i++) {
01836     if (rmin[i] < 0. || rmax[i] < 0. || rmin[i] > rmax[i]) {
01837       std::cerr
01838         << "HepPolyhedronPgon: error in radiuses rmin[" << i << "]="
01839         << rmin[i] << " rmax[" << i << "]=" << rmax[i]
01840         << std::endl;
01841       return;
01842     }
01843   }
01844 
01845   
01846 
01847   G4double *zz, *rr;
01848   zz = new G4double[2*nz];
01849   rr = new G4double[2*nz];
01850 
01851   if (z[0] > z[nz-1]) {
01852     for (i=0; i<nz; i++) {
01853       zz[i]    = z[i];
01854       rr[i]    = rmax[i];
01855       zz[i+nz] = z[i];
01856       rr[i+nz] = rmin[i];
01857     }
01858   }else{
01859     for (i=0; i<nz; i++) {
01860       zz[i]    = z[nz-i-1];
01861       rr[i]    = rmax[nz-i-1];
01862       zz[i+nz] = z[nz-i-1];
01863       rr[i+nz] = rmin[nz-i-1];
01864     }
01865   }
01866 
01867   
01868 
01869   RotateAroundZ(npdv, phi, dphi, nz, nz, zz, rr, -1, (npdv == 0) ? -1 : 1); 
01870   SetReferences();
01871   
01872   delete [] zz;
01873   delete [] rr;
01874 }
01875 
01876 HepPolyhedronPgon::~HepPolyhedronPgon() {}
01877 
01878 HepPolyhedronPcon::HepPolyhedronPcon(G4double phi, G4double dphi, G4int nz,
01879                                      const G4double *z,
01880                                      const G4double *rmin,
01881                                      const G4double *rmax)
01882   : HepPolyhedronPgon(phi, dphi, 0, nz, z, rmin, rmax) {}
01883 
01884 HepPolyhedronPcon::~HepPolyhedronPcon() {}
01885 
01886 HepPolyhedronSphere::HepPolyhedronSphere(G4double rmin, G4double rmax,
01887                                          G4double phi, G4double dphi,
01888                                          G4double the, G4double dthe)
01889 
01890 
01891 
01892 
01893 
01894 
01895 
01896 
01897 
01898 
01899 
01900 
01901 
01902 
01903 
01904 {
01905   
01906 
01907   if (dphi <= 0. || dphi > twopi) {
01908     std::cerr
01909       << "HepPolyhedronSphere: wrong delta phi = " << dphi
01910       << std::endl;
01911     return;
01912   }    
01913 
01914   if (the < 0. || the > pi) {
01915     std::cerr
01916       << "HepPolyhedronSphere: wrong theta = " << the
01917       << std::endl;
01918     return;
01919   }    
01920   
01921   if (dthe <= 0. || dthe > pi) {
01922     std::cerr
01923       << "HepPolyhedronSphere: wrong delta theta = " << dthe
01924       << std::endl;
01925     return;
01926   }    
01927 
01928   if (the+dthe > pi) {
01929     std::cerr
01930       << "HepPolyhedronSphere: wrong theta + delta theta = "
01931       << the << " " << dthe
01932       << std::endl;
01933     return;
01934   }    
01935   
01936   if (rmin < 0. || rmin >= rmax) {
01937     std::cerr
01938       << "HepPolyhedronSphere: error in radiuses"
01939       << " rmin=" << rmin << " rmax=" << rmax
01940       << std::endl;
01941     return;
01942   }
01943 
01944   
01945 
01946   G4int nds = (GetNumberOfRotationSteps() + 1) / 2;
01947   G4int np1 = G4int(dthe*nds/pi+.5) + 1;
01948   if (np1 <= 1) np1 = 2;
01949   G4int np2 = rmin < spatialTolerance ? 1 : np1;
01950 
01951   G4double *zz, *rr;
01952   zz = new G4double[np1+np2];
01953   rr = new G4double[np1+np2];
01954 
01955   G4double a = dthe/(np1-1);
01956   G4double cosa, sina;
01957   for (G4int i=0; i<np1; i++) {
01958     cosa  = std::cos(the+i*a);
01959     sina  = std::sin(the+i*a);
01960     zz[i] = rmax*cosa;
01961     rr[i] = rmax*sina;
01962     if (np2 > 1) {
01963       zz[i+np1] = rmin*cosa;
01964       rr[i+np1] = rmin*sina;
01965     }
01966   }
01967   if (np2 == 1) {
01968     zz[np1] = 0.;
01969     rr[np1] = 0.;
01970   }
01971 
01972   
01973 
01974   RotateAroundZ(0, phi, dphi, np1, np2, zz, rr, -1, -1); 
01975   SetReferences();
01976   
01977   delete [] zz;
01978   delete [] rr;
01979 }
01980 
01981 HepPolyhedronSphere::~HepPolyhedronSphere() {}
01982 
01983 HepPolyhedronTorus::HepPolyhedronTorus(G4double rmin,
01984                                        G4double rmax,
01985                                        G4double rtor,
01986                                        G4double phi,
01987                                        G4double dphi)
01988 
01989 
01990 
01991 
01992 
01993 
01994 
01995 
01996 
01997 
01998 
01999 
02000 
02001 
02002 {
02003   
02004 
02005   if (dphi <= 0. || dphi > twopi) {
02006     std::cerr
02007       << "HepPolyhedronTorus: wrong delta phi = " << dphi
02008       << std::endl;
02009     return;
02010   }
02011 
02012   if (rmin < 0. || rmin >= rmax || rmax >= rtor) {
02013     std::cerr
02014       << "HepPolyhedronTorus: error in radiuses"
02015       << " rmin=" << rmin << " rmax=" << rmax << " rtorus=" << rtor
02016       << std::endl;
02017     return;
02018   }
02019 
02020   
02021 
02022   G4int np1 = GetNumberOfRotationSteps();
02023   G4int np2 = rmin < spatialTolerance ? 1 : np1;
02024 
02025   G4double *zz, *rr;
02026   zz = new G4double[np1+np2];
02027   rr = new G4double[np1+np2];
02028 
02029   G4double a = twopi/np1;
02030   G4double cosa, sina;
02031   for (G4int i=0; i<np1; i++) {
02032     cosa  = std::cos(i*a);
02033     sina  = std::sin(i*a);
02034     zz[i] = rmax*cosa;
02035     rr[i] = rtor+rmax*sina;
02036     if (np2 > 1) {
02037       zz[i+np1] = rmin*cosa;
02038       rr[i+np1] = rtor+rmin*sina;
02039     }
02040   }
02041   if (np2 == 1) {
02042     zz[np1] = 0.;
02043     rr[np1] = rtor;
02044     np2 = -1;
02045   }
02046 
02047   
02048 
02049   RotateAroundZ(0, phi, dphi, -np1, -np2, zz, rr, -1,-1); 
02050   SetReferences();
02051   
02052   delete [] zz;
02053   delete [] rr;
02054 }
02055 
02056 HepPolyhedronTorus::~HepPolyhedronTorus() {}
02057 
02058 HepPolyhedronEllipsoid::HepPolyhedronEllipsoid(G4double ax, G4double by,
02059                                                G4double cz, G4double zCut1,
02060                                                G4double zCut2)
02061 
02062 
02063 
02064 
02065 
02066 
02067 
02068 
02069 
02070 
02071 
02072 
02073 
02074 
02075 {
02076   
02077 
02078   if (zCut1 >= cz || zCut2 <= -cz || zCut1 > zCut2) {
02079     std::cerr << "HepPolyhedronEllipsoid: wrong zCut1 = " << zCut1
02080            << " zCut2 = " << zCut2
02081            << " for given cz = " << cz << std::endl;
02082     return;
02083   }
02084   if (cz <= 0.0) {
02085     std::cerr << "HepPolyhedronEllipsoid: bad z semi-axis: cz = " << cz
02086       << std::endl;
02087     return;
02088   }
02089 
02090   G4double dthe;
02091   G4double sthe;
02092   G4int cutflag;
02093   cutflag= 0;
02094   if (zCut2 >= cz)
02095     {
02096       sthe= 0.0;
02097     }
02098   else
02099     {
02100       sthe= std::acos(zCut2/cz);
02101       cutflag++;
02102     }
02103   if (zCut1 <= -cz)
02104     {
02105       dthe= pi - sthe;
02106     }
02107   else
02108     {
02109       dthe= std::acos(zCut1/cz)-sthe;
02110       cutflag++;
02111     }
02112 
02113   
02114   
02115 
02116   G4int nds = (GetNumberOfRotationSteps() + 1) / 2;
02117   G4int np1 = G4int(dthe*nds/pi) + 2 + cutflag;
02118 
02119   G4double *zz, *rr;
02120   zz = new G4double[np1+1];
02121   rr = new G4double[np1+1];
02122   if (!zz || !rr)
02123     {
02124       G4Exception("HepPolyhedronEllipsoid::HepPolyhedronEllipsoid",
02125                   "greps1002", FatalException, "Out of memory");
02126     }
02127 
02128   G4double a = dthe/(np1-cutflag-1);
02129   G4double cosa, sina;
02130   G4int j=0;
02131   if (sthe > 0.0)
02132     {
02133       zz[j]= zCut2;
02134       rr[j]= 0.;
02135       j++;
02136     }
02137   for (G4int i=0; i<np1-cutflag; i++) {
02138     cosa  = std::cos(sthe+i*a);
02139     sina  = std::sin(sthe+i*a);
02140     zz[j] = cz*cosa;
02141     rr[j] = cz*sina;
02142     j++;
02143   }
02144   if (j < np1)
02145     {
02146       zz[j]= zCut1;
02147       rr[j]= 0.;
02148       j++;
02149     }
02150   if (j > np1)
02151     {
02152       std::cerr << "Logic error in HepPolyhedronEllipsoid, memory corrupted!"
02153                 << std::endl;
02154     }
02155   if (j < np1)
02156     {
02157       std::cerr << "Warning: logic error in HepPolyhedronEllipsoid."
02158                 << std::endl;
02159       np1= j;
02160     }
02161   zz[j] = 0.;
02162   rr[j] = 0.;
02163 
02164   
02165   
02166 
02167   RotateAroundZ(0, 0.0, twopi, np1, 1, zz, rr, -1, 1); 
02168   SetReferences();
02169 
02170   delete [] zz;
02171   delete [] rr;
02172 
02173   
02174   {
02175     G4Point3D * p= pV;
02176     for (G4int i=0; i<nvert; i++, p++) {
02177       p->setX( p->x() * ax/cz );
02178       p->setY( p->y() * by/cz );
02179     }
02180   }
02181 }
02182 
02183 HepPolyhedronEllipsoid::~HepPolyhedronEllipsoid() {}
02184 
02185 HepPolyhedronEllipticalCone::HepPolyhedronEllipticalCone(G4double ax,
02186                                                          G4double ay,
02187                                                          G4double h,
02188                                                          G4double zTopCut) 
02189 
02190 
02191 
02192 
02193 
02194 
02195 
02196 
02197 
02198 
02199 
02200 
02201 {
02202   
02203 
02204   G4int k = 0;
02205   if ( (ax <= 0.) || (ay <= 0.) || (h <= 0.) || (zTopCut <= 0.) ) { k = 1; }
02206 
02207   if (k != 0) {
02208     std::cerr << "HepPolyhedronCone: error in input parameters";
02209     std::cerr << std::endl;
02210     return;
02211   }
02212   
02213   
02214 
02215   zTopCut = (h >= zTopCut ? zTopCut : h);
02216 
02217   G4double *zz, *rr;
02218   zz = new G4double[4];
02219   rr = new G4double[4];
02220   zz[0] =   zTopCut; 
02221   zz[1] =  -zTopCut; 
02222   zz[2] =   zTopCut; 
02223   zz[3] =  -zTopCut; 
02224   rr[0] =  (h-zTopCut);
02225   rr[1] =  (h+zTopCut);
02226   rr[2] =  0.;
02227   rr[3] =  0.;
02228 
02229   
02230 
02231   RotateAroundZ(0, 0., twopi, 2, 2, zz, rr, -1, -1); 
02232   SetReferences();
02233 
02234   delete [] zz;
02235   delete [] rr;
02236 
02237   
02238  {
02239    G4Point3D * p= pV;
02240    for (G4int i=0; i<nvert; i++, p++) {
02241      p->setX( p->x() * ax );
02242      p->setY( p->y() * ay );
02243    }
02244  }
02245 }
02246 
02247 HepPolyhedronEllipticalCone::~HepPolyhedronEllipticalCone() {}
02248 
02249 G4int HepPolyhedron::fNumberOfRotationSteps = DEFAULT_NUMBER_OF_STEPS;
02250 
02251 
02252 
02253 
02254 
02255 
02256 
02257 
02258 
02259 #include "BooleanProcessor.src"
02260 
02261 HepPolyhedron HepPolyhedron::add(const HepPolyhedron & p) const 
02262 
02263 
02264 
02265 
02266 
02267 
02268 
02269 
02270 {
02271   G4int ierr;
02272   BooleanProcessor processor;
02273   return processor.execute(OP_UNION, *this, p,ierr);
02274 }
02275 
02276 HepPolyhedron HepPolyhedron::intersect(const HepPolyhedron & p) const 
02277 
02278 
02279 
02280 
02281 
02282 
02283 
02284 
02285 {
02286   G4int ierr;
02287   BooleanProcessor processor;
02288   return processor.execute(OP_INTERSECTION, *this, p,ierr);
02289 }
02290 
02291 HepPolyhedron HepPolyhedron::subtract(const HepPolyhedron & p) const 
02292 
02293 
02294 
02295 
02296 
02297 
02298 
02299 
02300 {
02301   G4int ierr;
02302   BooleanProcessor processor;
02303   return processor.execute(OP_SUBTRACTION, *this, p,ierr);
02304 }
02305 
02306 
02307 
02308 
02309 #undef INTERSECTION
02310 
02311 #include "HepPolyhedronProcessor.src"
02312