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