70using CLHEP::perMillion;
86 for (
G4int k=0; k<4; k++) {
87 ostr <<
" " << facet.edge[k].v <<
"/" << facet.edge[k].f;
94 ostr <<
"Nvertices=" << ph.
nvert <<
", Nfacets=" << ph.
nface << std::endl;
96 for (i=1; i<=ph.
nvert; i++) {
97 ostr <<
"xyz(" << i <<
")="
98 << ph.
pV[i].
x() <<
' ' << ph.
pV[i].
y() <<
' ' << ph.
pV[i].
z()
101 for (i=1; i<=ph.
nface; i++) {
102 ostr <<
"face(" << i <<
")=" << ph.
pF[i] << std::endl;
114: nvert(0), nface(0), pV(0), pF(0)
128: nvert(0), nface(0), pV(nullptr), pF(nullptr)
199 for (i=0; i<4; i++) {
200 if (iNode == std::abs(pF[iFace].edge[i].v))
break;
204 <<
"HepPolyhedron::FindNeighbour: face " << iFace
205 <<
" has no node " << iNode
211 if (pF[iFace].edge[i].v == 0) i = 2;
213 return (pF[iFace].edge[i].v > 0) ? 0 : pF[iFace].edge[i].f;
227 G4int k = iFace, iOrder = 1, n = 1;
230 k = FindNeighbour(k, iNode, iOrder);
231 if (k == iFace)
break;
234 normal += GetUnitNormal(k);
236 if (iOrder < 0)
break;
241 return normal.
unit();
267 const G4int nMin = 3;
270 <<
"HepPolyhedron::SetNumberOfRotationSteps: attempt to set the\n"
271 <<
"number of steps per circle < " << nMin <<
"; forced to " << nMin
306 if (
pV != 0)
delete []
pV;
307 if (
pF != 0)
delete []
pF;
308 if (Nvert > 0 && Nface > 0) {
328 enum {DUMMY, BOTTOM, LEFT, BACK, RIGHT, FRONT, TOP};
330 pF[1] =
G4Facet(1,LEFT, 4,BACK, 3,RIGHT, 2,FRONT);
331 pF[2] =
G4Facet(5,TOP, 8,BACK, 4,BOTTOM, 1,FRONT);
332 pF[3] =
G4Facet(8,TOP, 7,RIGHT, 3,BOTTOM, 4,LEFT);
333 pF[4] =
G4Facet(7,TOP, 6,FRONT, 2,BOTTOM, 3,BACK);
334 pF[5] =
G4Facet(6,TOP, 5,LEFT, 1,BOTTOM, 2,RIGHT);
335 pF[6] =
G4Facet(5,FRONT, 6,RIGHT, 7,BACK, 8,LEFT);
360 if (r1 == 0. && r2 == 0)
return;
365 G4int ii1 = ifWholeCircle ? i1 : i1+nds;
366 G4int ii2 = ifWholeCircle ? i2 : i2+nds;
367 G4int vv = ifWholeCircle ? vEdge : 1;
371 pF[kface++] =
G4Facet(i1,0, v2*i2,0, (i2+1),0);
372 }
else if (r2 == 0.) {
373 pF[kface++] =
G4Facet(i1,0, i2,0, v1*(i1+1),0);
375 pF[kface++] =
G4Facet(i1,0, v2*i2,0, (i2+1),0, v1*(i1+1),0);
379 pF[kface++] =
G4Facet(vv*i1,0, v2*i2,0, vEdge*(i2+1),0);
380 for (i2++,i=1; i<nds-1; i2++,i++) {
381 pF[kface++] =
G4Facet(vEdge*i1,0, v2*i2,0, vEdge*(i2+1),0);
383 pF[kface++] =
G4Facet(vEdge*i1,0, v2*i2,0, vv*ii2,0);
384 }
else if (r2 == 0.) {
385 pF[kface++] =
G4Facet(vv*i1,0, vEdge*i2,0, v1*(i1+1),0);
386 for (i1++,i=1; i<nds-1; i1++,i++) {
387 pF[kface++] =
G4Facet(vEdge*i1,0, vEdge*i2,0, v1*(i1+1),0);
389 pF[kface++] =
G4Facet(vEdge*i1,0, vv*i2,0, v1*ii1,0);
391 pF[kface++] =
G4Facet(vv*i1,0, v2*i2,0, vEdge*(i2+1),0,v1*(i1+1),0);
392 for (i1++,i2++,i=1; i<nds-1; i1++,i2++,i++) {
393 pF[kface++] =
G4Facet(vEdge*i1,0, v2*i2,0, vEdge*(i2+1),0,v1*(i1+1),0);
395 pF[kface++] =
G4Facet(vEdge*i1,0, v2*i2,0, vv*ii2,0, v1*ii1,0);
420 G4int k1, k2, k3, k4;
422 if (std::abs((
G4double)(dphi-pi)) < perMillion) {
423 for (
G4int i=0; i<4; i++) {
426 if (r[k1] == 0. && r[k2] == 0.) vv[i] = -1;
430 if (ii[1] == ii[2]) {
434 pF[kface++] =
G4Facet(vv[0]*k1,0, vv[2]*k2,0, vv[3]*k3,0);
435 if (r[ii[0]] != 0.) k1 += nds;
436 if (r[ii[2]] != 0.) k2 += nds;
437 if (r[ii[3]] != 0.) k3 += nds;
438 pF[kface++] =
G4Facet(vv[2]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
439 }
else if (kk[ii[0]] == kk[ii[1]]) {
443 pF[kface++] =
G4Facet(vv[1]*k1,0, vv[2]*k2,0, vv[3]*k3,0);
444 if (r[ii[0]] != 0.) k1 += nds;
445 if (r[ii[2]] != 0.) k2 += nds;
446 if (r[ii[3]] != 0.) k3 += nds;
447 pF[kface++] =
G4Facet(vv[2]*k3,0, vv[1]*k2,0, vv[3]*k1,0);
448 }
else if (kk[ii[2]] == kk[ii[3]]) {
452 pF[kface++] =
G4Facet(vv[0]*k1,0, vv[1]*k2,0, vv[3]*k3,0);
453 if (r[ii[0]] != 0.) k1 += nds;
454 if (r[ii[1]] != 0.) k2 += nds;
455 if (r[ii[2]] != 0.) k3 += nds;
456 pF[kface++] =
G4Facet(vv[1]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
462 pF[kface++] =
G4Facet(vv[0]*k1,0, vv[1]*k2,0, vv[2]*k3,0, vv[3]*k4,0);
463 if (r[ii[0]] != 0.) k1 += nds;
464 if (r[ii[1]] != 0.) k2 += nds;
465 if (r[ii[2]] != 0.) k3 += nds;
466 if (r[ii[3]] != 0.) k4 += nds;
467 pF[kface++] =
G4Facet(vv[2]*k4,0, vv[1]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
497 static const G4double wholeCircle = twopi;
501 G4bool ifWholeCircle = (std::abs(dphi-wholeCircle) < perMillion) ?
true :
false;
502 G4double delPhi = ifWholeCircle ? wholeCircle : dphi;
503 G4int nSphi = (nstep > 0) ?
505 if (nSphi == 0) nSphi = 1;
506 G4int nVphi = ifWholeCircle ? nSphi : nSphi+1;
507 G4bool ifClosed = np1 > 0 ? false :
true;
511 G4int absNp1 = std::abs(np1);
512 G4int absNp2 = std::abs(np2);
514 G4int i1end = absNp1-1;
515 G4int i2beg = absNp1;
516 G4int i2end = absNp1+absNp2-1;
519 for(i=i1beg; i<=i2end; i++) {
524 for (i=i1beg; i<=i1end; i++) {
525 j += (r[i] == 0.) ? 1 : nVphi;
531 if (r[i2beg] != r[i1beg] || z[i2beg] != z[i1beg]) {
532 j += (r[i2beg] == 0.) ? 1 : nVphi;
536 for(i=i2beg+1; i<i2end; i++) {
537 j += (r[i] == 0.) ? 1 : nVphi;
540 if (r[i2end] != r[i1end] || z[i2end] != z[i1end]) {
541 if (absNp2 > 1) j += (r[i2end] == 0.) ? 1 : nVphi;
547 k = ifClosed ? absNp1*nSphi : (absNp1-1)*nSphi;
550 for(i=i2beg; i<i2end; i++) {
551 if (r[i] > 0. || r[i+1] > 0.) k += nSphi;
555 if (r[i2end] > 0. || r[i2beg] > 0.) k += nSphi;
560 if (ifSide1 && (r[i1beg] > 0. || r[i2beg] > 0.)) k += nSphi;
561 if (ifSide2 && (r[i1end] > 0. || r[i2end] > 0.)) k += nSphi;
564 if (!ifWholeCircle) {
565 k += ifClosed ? 2*absNp1 : 2*(absNp1-1);
575 kk =
new G4int[absNp1+absNp2];
578 for(i=i1beg; i<=i1end; i++) {
581 {
pV[k++] =
G4Point3D(0, 0, z[i]); }
else { k += nVphi; }
588 {
pV[k++] =
G4Point3D(0, 0, z[i]); }
else { k += nVphi; }
593 for(i=i2beg+1; i<i2end; i++) {
596 {
pV[k++] =
G4Point3D(0, 0, z[i]); }
else { k += nVphi; }
611 for(j=0; j<nVphi; j++) {
612 cosPhi = std::cos(phi+j*delPhi/nSphi);
613 sinPhi = std::sin(phi+j*delPhi/nSphi);
614 for(i=i1beg; i<=i2end; i++) {
616 pV[kk[i]+j] =
G4Point3D(r[i]*cosPhi,r[i]*sinPhi,z[i]);
625 v2 = ifClosed ? nodeVis : 1;
626 for(i=i1beg; i<i1end; i++) {
628 if (!ifClosed && i == i1end-1) {
631 v2 = (r[i] == r[i+1] && r[i+1] == r[i+2]) ? -1 : nodeVis;
633 RotateEdge(kk[i], kk[i+1], r[i], r[i+1], v1, v2,
634 edgeVis, ifWholeCircle, nSphi, k);
637 RotateEdge(kk[i1end], kk[i1beg], r[i1end],r[i1beg], nodeVis, nodeVis,
638 edgeVis, ifWholeCircle, nSphi, k);
644 v2 = ifClosed ? nodeVis : 1;
645 for(i=i2beg; i<i2end; i++) {
647 if (!ifClosed && i==i2end-1) {
650 v2 = (r[i] == r[i+1] && r[i+1] == r[i+2]) ? -1 : nodeVis;
652 RotateEdge(kk[i+1], kk[i], r[i+1], r[i], v2, v1,
653 edgeVis, ifWholeCircle, nSphi, k);
656 RotateEdge(kk[i2beg], kk[i2end], r[i2beg], r[i2end], nodeVis, nodeVis,
657 edgeVis, ifWholeCircle, nSphi, k);
665 RotateEdge(kk[i2beg], kk[i1beg], r[i2beg], r[i1beg], 1, 1,
666 -1, ifWholeCircle, nSphi, k);
669 RotateEdge(kk[i1end], kk[i2end], r[i1end], r[i2end], 1, 1,
670 -1, ifWholeCircle, nSphi, k);
676 if (!ifWholeCircle) {
681 for (i=i1beg; i<=i1end; i++) {
683 ii[3] = (i == i1end) ? i1beg : i+1;
684 ii[1] = (absNp2 == 1) ? i2beg : ii[0]+absNp1;
685 ii[2] = (absNp2 == 1) ? i2beg : ii[3]+absNp1;
693 for (i=i1beg; i<i1end; i++) {
696 ii[1] = (absNp2 == 1) ? i2beg : ii[0]+absNp1;
697 ii[2] = (absNp2 == 1) ? i2beg : ii[3]+absNp1;
698 vv[0] = (i == i1beg) ? 1 : -1;
700 vv[2] = (i == i1end-1) ? 1 : -1;
711 <<
"Polyhedron::RotateAroundZ: number of generated faces ("
712 << k-1 <<
") is not equal to the number of allocated faces ("
728 if (
nface <= 0)
return;
730 struct edgeListMember {
731 edgeListMember *next;
735 } *edgeList, *freeList, **headList;
740 edgeList =
new edgeListMember[2*
nface];
741 headList =
new edgeListMember*[
nvert];
744 for (i=0; i<
nvert; i++) {
748 for (i=0; i<2*
nface-1; i++) {
749 edgeList[i].next = &edgeList[i+1];
751 edgeList[2*
nface-1].next = 0;
755 G4int iface, iedge, nedge, i1, i2, k1, k2;
756 edgeListMember *prev, *cur;
758 for(iface=1; iface<=
nface; iface++) {
759 nedge = (
pF[iface].edge[3].v == 0) ? 3 : 4;
760 for (iedge=0; iedge<nedge; iedge++) {
762 i2 = (iedge < nedge-1) ? iedge+1 : 0;
763 i1 = std::abs(
pF[iface].edge[i1].v);
764 i2 = std::abs(
pF[iface].edge[i2].v);
765 k1 = (i1 < i2) ? i1 : i2;
766 k2 = (i1 > i2) ? i1 : i2;
771 headList[k1] = freeList;
774 <<
"Polyhedron::SetReferences: bad link "
778 freeList = freeList->next;
788 headList[k1] = cur->next;
789 cur->next = freeList;
791 pF[iface].edge[iedge].f = cur->iface;
792 pF[cur->iface].edge[cur->iedge].f = iface;
793 i1 = (
pF[iface].edge[iedge].v < 0) ? -1 : 1;
794 i2 = (
pF[cur->iface].edge[cur->iedge].v < 0) ? -1 : 1;
797 <<
"Polyhedron::SetReferences: different edge visibility "
798 << iface <<
"/" << iedge <<
"/"
799 <<
pF[iface].edge[iedge].v <<
" and "
800 << cur->iface <<
"/" << cur->iedge <<
"/"
801 <<
pF[cur->iface].edge[cur->iedge].v
812 prev->next = freeList;
815 <<
"Polyhedron::SetReferences: bad link "
819 freeList = freeList->next;
829 prev->next = cur->next;
830 cur->next = freeList;
832 pF[iface].edge[iedge].f = cur->iface;
833 pF[cur->iface].edge[cur->iedge].f = iface;
834 i1 = (
pF[iface].edge[iedge].v < 0) ? -1 : 1;
835 i2 = (
pF[cur->iface].edge[cur->iedge].v < 0) ? -1 : 1;
838 <<
"Polyhedron::SetReferences: different edge visibility "
839 << iface <<
"/" << iedge <<
"/"
840 <<
pF[iface].edge[iedge].v <<
" and "
841 << cur->iface <<
"/" << cur->iedge <<
"/"
842 <<
pF[cur->iface].edge[cur->iedge].v
853 for (i=0; i<
nvert; i++) {
854 if (headList[i] != 0) {
856 <<
"Polyhedron::SetReferences: List " << i <<
" is not empty"
877 if (
nface <= 0)
return;
878 G4int i, k, nnode, v[4],f[4];
879 for (i=1; i<=
nface; i++) {
880 nnode = (
pF[i].edge[3].v == 0) ? 3 : 4;
881 for (k=0; k<nnode; k++) {
882 v[k] = (k+1 == nnode) ?
pF[i].edge[0].v :
pF[i].edge[k+1].v;
883 if (v[k] *
pF[i].edge[k].v < 0) v[k] = -v[k];
884 f[k] =
pF[i].edge[k].f;
886 for (k=0; k<nnode; k++) {
887 pF[i].edge[nnode-1-k].v = v[k];
888 pF[i].edge[nnode-1-k].f = f[k];
930 G4int vIndex = pF[iFace].edge[iQVertex].v;
932 edgeFlag = (vIndex > 0) ? 1 : 0;
933 index = std::abs(vIndex);
935 if (iQVertex >= 3 || pF[iFace].edge[iQVertex+1].v == 0) {
937 if (++iFace > nface) iFace = 1;
955 if (index <= 0 || index > nvert) {
957 <<
"HepPolyhedron::GetVertex: irrelevant index " << index
978 G4bool rep = GetNextVertexIndex(index, edgeFlag);
999 if (nface == 0)
return false;
1001 G4int k = pF[iFace].edge[iNode].v;
1002 if (k > 0) { edgeFlag = 1; }
else { edgeFlag = -1; k = -k; }
1004 normal = FindNodeNormal(iFace,k);
1005 if (iNode >= 3 || pF[iFace].edge[iNode+1].v == 0) {
1007 if (++iFace > nface) iFace = 1;
1031 G4int k1, k2, kflag, kface1, kface2;
1033 if (iFace == 1 && iQVertex == 0) {
1034 k2 = pF[nface].edge[0].v;
1035 k1 = pF[nface].edge[3].v;
1036 if (k1 == 0) k1 = pF[nface].edge[2].v;
1037 if (std::abs(k1) > std::abs(k2)) iOrder = -1;
1041 k1 = pF[iFace].edge[iQVertex].v;
1045 kface2 = pF[iFace].edge[iQVertex].f;
1046 if (iQVertex >= 3 || pF[iFace].edge[iQVertex+1].v == 0) {
1048 k2 = std::abs(pF[iFace].edge[iQVertex].v);
1052 k2 = std::abs(pF[iFace].edge[iQVertex].v);
1054 }
while (iOrder*k1 > iOrder*k2);
1056 i1 = k1; i2 = k2; edgeFlag = (kflag > 0) ? 1 : 0;
1057 iface1 = kface1; iface2 = kface2;
1059 if (iFace > nface) {
1060 iFace = 1; iOrder = 1;
1079 G4int kface1, kface2;
1080 return GetNextEdgeIndices(i1, i2, edgeFlag, kface1, kface2);
1086 G4int &edgeFlag)
const
1098 G4bool rep = GetNextEdgeIndices(i1,i2,edgeFlag);
1119 G4bool rep = GetNextEdgeIndices(i1,i2,edgeFlag,iface1,iface2);
1136 if (iFace < 1 || iFace > nface) {
1138 <<
"HepPolyhedron::GetFacet: irrelevant index " << iFace
1143 for (i=0; i<4; i++) {
1144 k = pF[iFace].edge[i].v;
1146 if (iFaces != 0) iFaces[i] = pF[iFace].edge[i].f;
1149 if (edgeFlags != 0) edgeFlags[i] = 1;
1152 if (edgeFlags != 0) edgeFlags[i] = -1;
1171 GetFacet(index, n, iNodes, edgeFlags);
1173 for (
G4int i=0; i<n; i++) {
1174 nodes[i] = pV[iNodes[i]];
1175 if (normals != 0) normals[i] = FindNodeNormal(index,iNodes[i]);
1195 if (edgeFlags == 0) {
1196 GetFacet(iFace, n, nodes);
1197 }
else if (normals == 0) {
1198 GetFacet(iFace, n, nodes, edgeFlags);
1200 GetFacet(iFace, n, nodes, edgeFlags, normals);
1203 if (++iFace > nface) {
1221 if (iFace < 1 || iFace > nface) {
1223 <<
"HepPolyhedron::GetNormal: irrelevant index " << iFace
1228 G4int i0 = std::abs(pF[iFace].edge[0].v);
1229 G4int i1 = std::abs(pF[iFace].edge[1].v);
1230 G4int i2 = std::abs(pF[iFace].edge[2].v);
1231 G4int i3 = std::abs(pF[iFace].edge[3].v);
1232 if (i3 == 0) i3 = i0;
1233 return (pV[i2] - pV[i0]).cross(pV[i3] - pV[i1]);
1246 if (iFace < 1 || iFace > nface) {
1248 <<
"HepPolyhedron::GetUnitNormal: irrelevant index " << iFace
1253 G4int i0 = std::abs(pF[iFace].edge[0].v);
1254 G4int i1 = std::abs(pF[iFace].edge[1].v);
1255 G4int i2 = std::abs(pF[iFace].edge[2].v);
1256 G4int i3 = std::abs(pF[iFace].edge[3].v);
1257 if (i3 == 0) i3 = i0;
1258 return ((pV[i2] - pV[i0]).cross(pV[i3] - pV[i1])).unit();
1273 normal = GetNormal(iFace);
1274 if (++iFace > nface) {
1293 G4bool rep = GetNextNormal(normal);
1294 normal = normal.unit();
1310 G4int i0 = std::abs(
pF[iFace].edge[0].v);
1311 G4int i1 = std::abs(
pF[iFace].edge[1].v);
1312 G4int i2 = std::abs(
pF[iFace].edge[2].v);
1313 G4int i3 = std::abs(
pF[iFace].edge[3].v);
1314 if (i3 == 0) i3 = i0;
1315 srf += ((
pV[i2] -
pV[i0]).cross(
pV[i3] -
pV[i1])).mag();
1332 G4int i0 = std::abs(
pF[iFace].edge[0].v);
1333 G4int i1 = std::abs(
pF[iFace].edge[1].v);
1334 G4int i2 = std::abs(
pF[iFace].edge[2].v);
1335 G4int i3 = std::abs(
pF[iFace].edge[3].v);
1339 pt = (
pV[i0]+
pV[i1]+
pV[i2]) * (1./3.);
1341 pt = (
pV[i0]+
pV[i1]+
pV[i2]+
pV[i3]) * 0.25;
1343 v += ((
pV[i2] -
pV[i0]).cross(
pV[i3] -
pV[i1])).dot(pt);
1383 enum {DUMMY, BOTTOM,
1384 LEFT_BOTTOM, LEFT_FRONT, LEFT_TOP, LEFT_BACK,
1385 BACK_BOTTOM, BACK_LEFT, BACK_TOP, BACK_RIGHT,
1386 RIGHT_BOTTOM, RIGHT_BACK, RIGHT_TOP, RIGHT_FRONT,
1387 FRONT_BOTTOM, FRONT_RIGHT, FRONT_TOP, FRONT_LEFT,
1390 pF[ 1]=
G4Facet(1,LEFT_BOTTOM, 4,BACK_BOTTOM, 3,RIGHT_BOTTOM, 2,FRONT_BOTTOM);
1392 pF[ 2]=
G4Facet(4,BOTTOM, -1,LEFT_FRONT, -12,LEFT_BACK, 0,0);
1393 pF[ 3]=
G4Facet(1,FRONT_LEFT, -5,LEFT_TOP, -12,LEFT_BOTTOM, 0,0);
1394 pF[ 4]=
G4Facet(5,TOP, -8,LEFT_BACK, -12,LEFT_FRONT, 0,0);
1395 pF[ 5]=
G4Facet(8,BACK_LEFT, -4,LEFT_BOTTOM, -12,LEFT_TOP, 0,0);
1397 pF[ 6]=
G4Facet(3,BOTTOM, -4,BACK_LEFT, -11,BACK_RIGHT, 0,0);
1398 pF[ 7]=
G4Facet(4,LEFT_BACK, -8,BACK_TOP, -11,BACK_BOTTOM, 0,0);
1399 pF[ 8]=
G4Facet(8,TOP, -7,BACK_RIGHT, -11,BACK_LEFT, 0,0);
1400 pF[ 9]=
G4Facet(7,RIGHT_BACK, -3,BACK_BOTTOM, -11,BACK_TOP, 0,0);
1402 pF[10]=
G4Facet(2,BOTTOM, -3,RIGHT_BACK, -10,RIGHT_FRONT, 0,0);
1403 pF[11]=
G4Facet(3,BACK_RIGHT, -7,RIGHT_TOP, -10,RIGHT_BOTTOM, 0,0);
1404 pF[12]=
G4Facet(7,TOP, -6,RIGHT_FRONT, -10,RIGHT_BACK, 0,0);
1405 pF[13]=
G4Facet(6,FRONT_RIGHT,-2,RIGHT_BOTTOM,-10,RIGHT_TOP, 0,0);
1407 pF[14]=
G4Facet(1,BOTTOM, -2,FRONT_RIGHT, -9,FRONT_LEFT, 0,0);
1408 pF[15]=
G4Facet(2,RIGHT_FRONT,-6,FRONT_TOP, -9,FRONT_BOTTOM, 0,0);
1409 pF[16]=
G4Facet(6,TOP, -5,FRONT_LEFT, -9,FRONT_RIGHT, 0,0);
1410 pF[17]=
G4Facet(5,LEFT_FRONT, -1,FRONT_BOTTOM, -9,FRONT_TOP, 0,0);
1412 pF[18]=
G4Facet(5,FRONT_TOP, 6,RIGHT_TOP, 7,BACK_TOP, 8,LEFT_TOP);
1420 const G4int faces[][4])
1436 if (
nvert == 0)
return 1;
1438 for (
G4int i=0; i<Nnodes; i++) {
1439 pV[i+1] =
G4Point3D(xyz[i][0], xyz[i][1], xyz[i][2]);
1441 for (
G4int k=0; k<Nfaces; k++) {
1442 pF[k+1] =
G4Facet(faces[k][0],0,faces[k][1],0,faces[k][2],0,faces[k][3],0);
1527 G4double DzTthetaCphi = Dz*std::tan(Theta)*std::cos(Phi);
1528 G4double DzTthetaSphi = Dz*std::tan(Theta)*std::sin(Phi);
1529 G4double Dy1Talp1 = Dy1*std::tan(Alp1);
1530 G4double Dy2Talp2 = Dy2*std::tan(Alp2);
1534 pV[1] =
G4Point3D(-DzTthetaCphi-Dy1Talp1-Dx1,-DzTthetaSphi-Dy1,-Dz);
1535 pV[2] =
G4Point3D(-DzTthetaCphi-Dy1Talp1+Dx1,-DzTthetaSphi-Dy1,-Dz);
1536 pV[3] =
G4Point3D(-DzTthetaCphi+Dy1Talp1+Dx2,-DzTthetaSphi+Dy1,-Dz);
1537 pV[4] =
G4Point3D(-DzTthetaCphi+Dy1Talp1-Dx2,-DzTthetaSphi+Dy1,-Dz);
1538 pV[5] =
G4Point3D( DzTthetaCphi-Dy2Talp2-Dx3, DzTthetaSphi-Dy2, Dz);
1539 pV[6] =
G4Point3D( DzTthetaCphi-Dy2Talp2+Dx3, DzTthetaSphi-Dy2, Dz);
1540 pV[7] =
G4Point3D( DzTthetaCphi+Dy2Talp2+Dx4, DzTthetaSphi+Dy2, Dz);
1541 pV[8] =
G4Point3D( DzTthetaCphi+Dy2Talp2-Dx4, DzTthetaSphi+Dy2, Dz);
1551 :
HepPolyhedronTrap(Dz, Theta, Phi, Dy, Dx, Dx,
Alpha, Dy, Dx, Dx,
Alpha) {}
1575 static const G4double wholeCircle=twopi;
1580 if (r1 < 0. || r2 <= 0.) k = 1;
1582 if (dz <= 0.) k += 2;
1588 phi2 = sPhi; phi1 = phi2 + dPhi;
1592 phi1 = sPhi; phi2 = phi1 + wholeCircle;
1596 phi1 = sPhi; phi2 = phi1 + dPhi;
1600 if (std::abs(dphi-wholeCircle) < perMillion) dphi = wholeCircle;
1601 if (dphi > wholeCircle) k += 4;
1604 std::cerr <<
"HepPolyhedronParaboloid: error in input parameters";
1605 if ((k & 1) != 0) std::cerr <<
" (radiuses)";
1606 if ((k & 2) != 0) std::cerr <<
" (half-length)";
1607 if ((k & 4) != 0) std::cerr <<
" (angles)";
1608 std::cerr << std::endl;
1609 std::cerr <<
" r1=" << r1;
1610 std::cerr <<
" r2=" << r2;
1611 std::cerr <<
" dz=" << dz <<
" sPhi=" << sPhi <<
" dPhi=" << dPhi
1620 G4double k1 = (r2*r2 - r1*r1) / 2 / dz;
1628 for(
G4int i = 1; i < n - 1; i++)
1630 rr[i] = rr[i-1] - dl;
1631 zz[i] = (rr[i]*rr[i] - k2) / k1;
1680 static const G4double wholeCircle = twopi;
1685 if (r1 < 0. || r2 < 0. || r1 >= r2) k = 1;
1686 if (halfZ <= 0.) k += 2;
1687 if (sqrtan1 < 0.|| sqrtan2 < 0.) k += 4;
1691 std::cerr <<
"HepPolyhedronHype: error in input parameters";
1692 if ((k & 1) != 0) std::cerr <<
" (radiuses)";
1693 if ((k & 2) != 0) std::cerr <<
" (half-length)";
1694 if ((k & 4) != 0) std::cerr <<
" (angles)";
1695 std::cerr << std::endl;
1696 std::cerr <<
" r1=" << r1 <<
" r2=" << r2;
1697 std::cerr <<
" halfZ=" << halfZ <<
" sqrTan1=" << sqrtan1
1698 <<
" sqrTan2=" << sqrtan2
1706 G4int nz1 = (sqrtan1 == 0.) ? 2 :
ns + 1;
1707 G4int nz2 = (sqrtan2 == 0.) ? 2 :
ns + 1;
1713 for(
G4int i = 0; i < nz2; ++i)
1715 zz[i] = halfZ - dz2*i;
1716 rr[i] = std::sqrt(sqrtan2*zz[i]*zz[i] + r2*r2);
1721 for(
G4int i = 0; i < nz1; ++i)
1724 zz[j] = halfZ - dz1*i;
1725 rr[j] = std::sqrt(sqrtan1*zz[j]*zz[j] + r1*r1);
1730 RotateAroundZ(0, 0., wholeCircle, nz2, nz1, zz, rr, -1, -1);
1761 static const G4double wholeCircle=twopi;
1766 if (Rmn1 < 0. || Rmx1 < 0. || Rmn2 < 0. || Rmx2 < 0.) k = 1;
1767 if (Rmn1 > Rmx1 || Rmn2 > Rmx2) k = 1;
1768 if (Rmn1 == Rmx1 && Rmn2 == Rmx2) k = 1;
1770 if (Dz <= 0.) k += 2;
1774 phi2 = Phi1; phi1 = phi2 - Dphi;
1775 }
else if (Dphi == 0.) {
1776 phi1 = Phi1; phi2 = phi1 + wholeCircle;
1778 phi1 = Phi1; phi2 = phi1 + Dphi;
1781 if (std::abs(dphi-wholeCircle) < perMillion) dphi = wholeCircle;
1782 if (dphi > wholeCircle) k += 4;
1785 std::cerr <<
"HepPolyhedronCone(s)/Tube(s): error in input parameters";
1786 if ((k & 1) != 0) std::cerr <<
" (radiuses)";
1787 if ((k & 2) != 0) std::cerr <<
" (half-length)";
1788 if ((k & 4) != 0) std::cerr <<
" (angles)";
1789 std::cerr << std::endl;
1790 std::cerr <<
" Rmn1=" << Rmn1 <<
" Rmx1=" << Rmx1;
1791 std::cerr <<
" Rmn2=" << Rmn2 <<
" Rmx2=" << Rmx2;
1792 std::cerr <<
" Dz=" << Dz <<
" Phi1=" << Phi1 <<
" Dphi=" << Dphi
1863 if (dphi <= 0. || dphi > twopi) {
1865 <<
"HepPolyhedronPgon/Pcon: wrong delta phi = " << dphi
1872 <<
"HepPolyhedronPgon/Pcon: number of z-planes less than two = " << nz
1879 <<
"HepPolyhedronPgon/Pcon: error in number of phi-steps =" << npdv
1885 for (i=0; i<nz; i++) {
1886 if (rmin[i] < 0. || rmax[i] < 0. || rmin[i] > rmax[i]) {
1888 <<
"HepPolyhedronPgon: error in radiuses rmin[" << i <<
"]="
1889 << rmin[i] <<
" rmax[" << i <<
"]=" << rmax[i]
1901 if (z[0] > z[nz-1]) {
1902 for (i=0; i<nz; i++) {
1909 for (i=0; i<nz; i++) {
1911 rr[i] = rmax[nz-i-1];
1912 zz[i+nz] = z[nz-i-1];
1913 rr[i+nz] = rmin[nz-i-1];
1919 RotateAroundZ(npdv, phi, dphi, nz, nz, zz, rr, -1, (npdv == 0) ? -1 : 1);
1957 if (dphi <= 0. || dphi > twopi) {
1959 <<
"HepPolyhedronSphere: wrong delta phi = " << dphi
1964 if (the < 0. || the > pi) {
1966 <<
"HepPolyhedronSphere: wrong theta = " << the
1971 if (dthe <= 0. || dthe > pi) {
1973 <<
"HepPolyhedronSphere: wrong delta theta = " << dthe
1978 if (the+dthe > pi) {
1980 <<
"HepPolyhedronSphere: wrong theta + delta theta = "
1981 << the <<
" " << dthe
1986 if (rmin < 0. || rmin >= rmax) {
1988 <<
"HepPolyhedronSphere: error in radiuses"
1989 <<
" rmin=" << rmin <<
" rmax=" << rmax
1998 if (np1 <= 1) np1 = 2;
2007 for (
G4int i=0; i<np1; i++) {
2008 cosa = std::cos(the+i*a);
2009 sina = std::sin(the+i*a);
2013 zz[i+np1] = rmin*cosa;
2014 rr[i+np1] = rmin*sina;
2055 if (dphi <= 0. || dphi > twopi) {
2057 <<
"HepPolyhedronTorus: wrong delta phi = " << dphi
2062 if (rmin < 0. || rmin >= rmax || rmax >= rtor) {
2064 <<
"HepPolyhedronTorus: error in radiuses"
2065 <<
" rmin=" << rmin <<
" rmax=" << rmax <<
" rtorus=" << rtor
2082 for (
G4int i=0; i<np1; i++) {
2083 cosa = std::cos(i*a);
2084 sina = std::sin(i*a);
2086 rr[i] = rtor+rmax*sina;
2088 zz[i+np1] = rmin*cosa;
2089 rr[i+np1] = rtor+rmin*sina;
2126 pV[1].
set(p0[0], p0[1], p0[2]);
2127 pV[2].
set(p1[0], p1[1], p1[2]);
2128 pV[3].
set(p2[0], p2[1], p2[2]);
2129 pV[4].
set(p3[0], p3[1], p3[2]);
2135 if (v1.
cross(v2).dot(v3) < 0.)
2137 pV[3].
set(p3[0], p3[1], p3[2]);
2138 pV[4].
set(p2[0], p2[1], p2[2]);
2169 if (zCut1 >= cz || zCut2 <= -cz || zCut1 > zCut2) {
2170 std::cerr <<
"HepPolyhedronEllipsoid: wrong zCut1 = " << zCut1
2171 <<
" zCut2 = " << zCut2
2172 <<
" for given cz = " << cz << std::endl;
2176 std::cerr <<
"HepPolyhedronEllipsoid: bad z semi-axis: cz = " << cz
2191 sthe= std::acos(zCut2/cz);
2200 dthe= std::acos(zCut1/cz)-sthe;
2208 G4int np1 =
G4int(dthe*nds/pi) + 2 + cutflag;
2215 G4Exception(
"HepPolyhedronEllipsoid::HepPolyhedronEllipsoid",
2228 for (
G4int i=0; i<np1-cutflag; i++) {
2229 cosa = std::cos(sthe+i*a);
2230 sina = std::sin(sthe+i*a);
2243 std::cerr <<
"Logic error in HepPolyhedronEllipsoid, memory corrupted!"
2248 std::cerr <<
"Warning: logic error in HepPolyhedronEllipsoid."
2268 p->
setX( p->
x() * ax/cz );
2269 p->
setY( p->
y() * by/cz );
2296 if ( (ax <= 0.) || (ay <= 0.) || (h <= 0.) || (zTopCut <= 0.) ) { k = 1; }
2299 std::cerr <<
"HepPolyhedronCone: error in input parameters";
2300 std::cerr << std::endl;
2306 zTopCut = (h >= zTopCut ? zTopCut : h);
2315 rr[0] = (h-zTopCut);
2316 rr[1] = (h+zTopCut);
2332 p->
setX( p->
x() * ax );
2333 p->
setY( p->
y() * ay );
2365 G4double maxAng = (
A == 0.) ? 0. : std::acosh(1. + H/
A);
2366 G4double delAng = maxAng/(np1 - 1);
2374 for (
G4int iz = 1; iz < np1 - 1; ++iz)
2377 zz[iz] =
A*std::cosh(ang) -
A;
2378 rr[iz] =
B*std::sinh(ang);
2412#include "BooleanProcessor.src"
2426 return processor.execute(OP_UNION, *
this, p,ierr);
2441 return processor.execute(OP_INTERSECTION, *
this, p,ierr);
2456 return processor.execute(OP_SUBTRACTION, *
this, p,ierr);
2464#include "HepPolyhedronProcessor.src"
double B(double temperature)
double A(double temperature)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
HepGeom::Normal3D< G4double > G4Normal3D
HepGeom::Point3D< G4double > G4Point3D
HepGeom::Vector3D< G4double > G4Vector3D
std::ostream & operator<<(std::ostream &ostr, const G4Facet &facet)
const G4double spatialTolerance
#define DEFAULT_NUMBER_OF_STEPS
BasicVector3D< T > cross(const BasicVector3D< T > &v) const
BasicVector3D< T > unit() const
void set(T x1, T y1, T z1)
virtual ~HepPolyhedronBox()
HepPolyhedronBox(G4double Dx, G4double Dy, G4double Dz)
virtual ~HepPolyhedronCone()
HepPolyhedronCone(G4double Rmn1, G4double Rmx1, G4double Rmn2, G4double Rmx2, G4double Dz)
virtual ~HepPolyhedronCons()
HepPolyhedronCons(G4double Rmn1, G4double Rmx1, G4double Rmn2, G4double Rmx2, G4double Dz, G4double Phi1, G4double Dphi)
virtual ~HepPolyhedronEllipsoid()
HepPolyhedronEllipsoid(G4double dx, G4double dy, G4double dz, G4double zcut1, G4double zcut2)
virtual ~HepPolyhedronEllipticalCone()
HepPolyhedronEllipticalCone(G4double dx, G4double dy, G4double z, G4double zcut1)
HepPolyhedronHype(G4double r1, G4double r2, G4double tan1, G4double tan2, G4double halfZ)
virtual ~HepPolyhedronHype()
virtual ~HepPolyhedronHyperbolicMirror()
HepPolyhedronHyperbolicMirror(G4double a, G4double h, G4double r)
virtual ~HepPolyhedronPara()
HepPolyhedronPara(G4double Dx, G4double Dy, G4double Dz, G4double Alpha, G4double Theta, G4double Phi)
virtual ~HepPolyhedronParaboloid()
HepPolyhedronParaboloid(G4double r1, G4double r2, G4double dz, G4double Phi1, G4double Dphi)
virtual ~HepPolyhedronPcon()
HepPolyhedronPcon(G4double phi, G4double dphi, G4int nz, const G4double *z, const G4double *rmin, const G4double *rmax)
virtual ~HepPolyhedronPgon()
HepPolyhedronPgon(G4double phi, G4double dphi, G4int npdv, G4int nz, const G4double *z, const G4double *rmin, const G4double *rmax)
virtual ~HepPolyhedronSphere()
HepPolyhedronSphere(G4double rmin, G4double rmax, G4double phi, G4double dphi, G4double the, G4double dthe)
virtual ~HepPolyhedronTet()
HepPolyhedronTet(const G4double p0[3], const G4double p1[3], const G4double p2[3], const G4double p3[3])
HepPolyhedronTorus(G4double rmin, G4double rmax, G4double rtor, G4double phi, G4double dphi)
virtual ~HepPolyhedronTorus()
HepPolyhedronTrap(G4double Dz, G4double Theta, G4double Phi, G4double Dy1, G4double Dx1, G4double Dx2, G4double Alp1, G4double Dy2, G4double Dx3, G4double Dx4, G4double Alp2)
virtual ~HepPolyhedronTrap()
HepPolyhedronTrd1(G4double Dx1, G4double Dx2, G4double Dy, G4double Dz)
virtual ~HepPolyhedronTrd1()
virtual ~HepPolyhedronTrd2()
HepPolyhedronTrd2(G4double Dx1, G4double Dx2, G4double Dy1, G4double Dy2, G4double Dz)
virtual ~HepPolyhedronTube()
HepPolyhedronTube(G4double Rmin, G4double Rmax, G4double Dz)
HepPolyhedronTubs(G4double Rmin, G4double Rmax, G4double Dz, G4double Phi1, G4double Dphi)
virtual ~HepPolyhedronTubs()
static void SetNumberOfRotationSteps(G4int n)
void RotateAroundZ(G4int nstep, G4double phi, G4double dphi, G4int np1, G4int np2, const G4double *z, G4double *r, G4int nodeVis, G4int edgeVis)
G4bool GetNextEdgeIndices(G4int &i1, G4int &i2, G4int &edgeFlag, G4int &iface1, G4int &iface2) const
G4Normal3D GetUnitNormal(G4int iFace) const
void GetFacet(G4int iFace, G4int &n, G4int *iNodes, G4int *edgeFlags=0, G4int *iFaces=0) const
G4int createTwistedTrap(G4double Dz, const G4double xy1[][2], const G4double xy2[][2])
G4bool GetNextNormal(G4Normal3D &normal) const
HepPolyhedron & operator=(const HepPolyhedron &from)
G4Normal3D FindNodeNormal(G4int iFace, G4int iNode) const
static G4int GetNumberOfRotationSteps()
G4Normal3D GetNormal(G4int iFace) const
G4int FindNeighbour(G4int iFace, G4int iNode, G4int iOrder) const
G4Point3D GetVertex(G4int index) const
G4double GetSurfaceArea() const
HepPolyhedron subtract(const HepPolyhedron &p) const
G4bool GetNextVertex(G4Point3D &vertex, G4int &edgeFlag) const
G4double GetVolume() const
HepPolyhedron intersect(const HepPolyhedron &p) const
HepPolyhedron & Transform(const G4Transform3D &t)
G4int createPolyhedron(G4int Nnodes, G4int Nfaces, const G4double xyz[][3], const G4int faces[][4])
void AllocateMemory(G4int Nvert, G4int Nface)
G4bool GetNextUnitNormal(G4Normal3D &normal) const
static void ResetNumberOfRotationSteps()
void RotateEdge(G4int k1, G4int k2, G4double r1, G4double r2, G4int v1, G4int v2, G4int vEdge, G4bool ifWholeCircle, G4int ns, G4int &kface)
G4bool GetNextFacet(G4int &n, G4Point3D *nodes, G4int *edgeFlags=0, G4Normal3D *normals=0) const
static G4ThreadLocal G4int fNumberOfRotationSteps
G4bool GetNextVertexIndex(G4int &index, G4int &edgeFlag) const
HepPolyhedron add(const HepPolyhedron &p) const
G4bool GetNextEdge(G4Point3D &p1, G4Point3D &p2, G4int &edgeFlag) const
void SetSideFacets(G4int ii[4], G4int vv[4], G4int *kk, G4double *r, G4double dphi, G4int ns, G4int &kface)