63 #include "HepPolyhedron.h"
85 std::ostream &
operator<<(std::ostream & ostr,
const G4Facet & facet) {
86 for (
G4int k=0; k<4; k++) {
87 ostr <<
" " << facet.edge[k].v <<
"/" << facet.edge[k].f;
92 std::ostream &
operator<<(std::ostream & ostr,
const HepPolyhedron & ph) {
94 ostr <<
"Nverteces=" << 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;
107 HepPolyhedron::HepPolyhedron(
const HepPolyhedron &from)
114 : nvert(0), nface(0), pV(0), pF(0)
116 AllocateMemory(from.nvert, from.nface);
117 for (
G4int i=1; i<=nvert; i++) pV[i] = from.pV[i];
118 for (
G4int k=1; k<=nface; k++) pF[k] = from.pF[k];
121 HepPolyhedron & HepPolyhedron::operator=(
const HepPolyhedron &from)
132 AllocateMemory(from.nvert, from.nface);
133 for (
G4int i=1; i<=nvert; i++) pV[i] = from.pV[i];
134 for (
G4int k=1; k<=nface; k++) pF[k] = from.pF[k];
140 HepPolyhedron::FindNeighbour(
G4int iFace,
G4int iNode,
G4int iOrder)
const
151 for (i=0; i<4; i++) {
152 if (iNode == std::abs(pF[iFace].edge[i].v))
break;
156 <<
"HepPolyhedron::FindNeighbour: face " << iFace
157 <<
" has no node " << iNode
163 if (pF[iFace].edge[i].v == 0) i = 2;
165 return (pF[iFace].edge[i].v > 0) ? 0 : pF[iFace].edge[i].f;
179 G4int k = iFace, iOrder = 1,
n = 1;
182 k = FindNeighbour(k, iNode, iOrder);
183 if (k == iFace)
break;
186 normal += GetUnitNormal(k);
188 if (iOrder < 0)
break;
193 return normal.unit();
196 G4int HepPolyhedron::GetNumberOfRotationSteps()
206 return fNumberOfRotationSteps;
209 void HepPolyhedron::SetNumberOfRotationSteps(
G4int n)
219 const G4int nMin = 3;
222 <<
"HepPolyhedron::SetNumberOfRotationSteps: attempt to set the\n"
223 <<
"number of steps per circle < " << nMin <<
"; forced to " << nMin
225 fNumberOfRotationSteps = nMin;
227 fNumberOfRotationSteps =
n;
231 void HepPolyhedron::ResetNumberOfRotationSteps()
241 fNumberOfRotationSteps = DEFAULT_NUMBER_OF_STEPS;
244 void HepPolyhedron::AllocateMemory(
G4int Nvert,
G4int Nface)
257 if (nvert == Nvert && nface == Nface)
return;
258 if (pV != 0)
delete [] pV;
259 if (pF != 0)
delete [] pF;
260 if (Nvert > 0 && Nface > 0) {
264 pF =
new G4Facet[nface+1];
266 nvert = 0; nface = 0; pV = 0; pF = 0;
270 void HepPolyhedron::CreatePrism()
280 enum {DUMMY, BOTTOM, LEFT, BACK, RIGHT, FRONT, TOP};
282 pF[1] = G4Facet(1,LEFT, 4,BACK, 3,RIGHT, 2,FRONT);
283 pF[2] = G4Facet(5,TOP, 8,BACK, 4,BOTTOM, 1,FRONT);
284 pF[3] = G4Facet(8,TOP, 7,RIGHT, 3,BOTTOM, 4,LEFT);
285 pF[4] = G4Facet(7,TOP, 6,FRONT, 2,BOTTOM, 3,BACK);
286 pF[5] = G4Facet(6,TOP, 5,LEFT, 1,BOTTOM, 2,RIGHT);
287 pF[6] = G4Facet(5,FRONT, 6,RIGHT, 7,BACK, 8,LEFT);
312 if (r1 == 0. && r2 == 0)
return;
317 G4int ii1 = ifWholeCircle ? i1 : i1+nds;
318 G4int ii2 = ifWholeCircle ? i2 : i2+nds;
319 G4int vv = ifWholeCircle ? vEdge : 1;
323 pF[kface++] = G4Facet(i1,0, v2*i2,0, (i2+1),0);
324 }
else if (r2 == 0.) {
325 pF[kface++] = G4Facet(i1,0, i2,0, v1*(i1+1),0);
327 pF[kface++] = G4Facet(i1,0, v2*i2,0, (i2+1),0, v1*(i1+1),0);
331 pF[kface++] = G4Facet(vv*i1,0, v2*i2,0, vEdge*(i2+1),0);
332 for (i2++,i=1; i<nds-1; i2++,i++) {
333 pF[kface++] = G4Facet(vEdge*i1,0, v2*i2,0, vEdge*(i2+1),0);
335 pF[kface++] = G4Facet(vEdge*i1,0, v2*i2,0, vv*ii2,0);
336 }
else if (r2 == 0.) {
337 pF[kface++] = G4Facet(vv*i1,0, vEdge*i2,0, v1*(i1+1),0);
338 for (i1++,i=1; i<nds-1; i1++,i++) {
339 pF[kface++] = G4Facet(vEdge*i1,0, vEdge*i2,0, v1*(i1+1),0);
341 pF[kface++] = G4Facet(vEdge*i1,0, vv*i2,0, v1*ii1,0);
343 pF[kface++] = G4Facet(vv*i1,0, v2*i2,0, vEdge*(i2+1),0,v1*(i1+1),0);
344 for (i1++,i2++,i=1; i<nds-1; i1++,i2++,i++) {
345 pF[kface++] = G4Facet(vEdge*i1,0, v2*i2,0, vEdge*(i2+1),0,v1*(i1+1),0);
347 pF[kface++] = G4Facet(vEdge*i1,0, v2*i2,0, vv*ii2,0, v1*ii1,0);
352 void HepPolyhedron::SetSideFacets(
G4int ii[4],
G4int vv[4],
372 G4int k1, k2, k3, k4;
375 for (
G4int i=0; i<4; i++) {
377 k2 = (i == 3) ? ii[0] : ii[i+1];
378 if (r[k1] == 0. && r[k2] == 0.) vv[i] = -1;
382 if (ii[1] == ii[2]) {
386 pF[kface++] = G4Facet(vv[0]*k1,0, vv[2]*k2,0, vv[3]*k3,0);
387 if (r[ii[0]] != 0.) k1 += nds;
388 if (r[ii[2]] != 0.) k2 += nds;
389 if (r[ii[3]] != 0.) k3 += nds;
390 pF[kface++] = G4Facet(vv[2]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
391 }
else if (kk[ii[0]] == kk[ii[1]]) {
395 pF[kface++] = G4Facet(vv[1]*k1,0, vv[2]*k2,0, vv[3]*k3,0);
396 if (r[ii[0]] != 0.) k1 += nds;
397 if (r[ii[2]] != 0.) k2 += nds;
398 if (r[ii[3]] != 0.) k3 += nds;
399 pF[kface++] = G4Facet(vv[2]*k3,0, vv[1]*k2,0, vv[3]*k1,0);
400 }
else if (kk[ii[2]] == kk[ii[3]]) {
404 pF[kface++] = G4Facet(vv[0]*k1,0, vv[1]*k2,0, vv[3]*k3,0);
405 if (r[ii[0]] != 0.) k1 += nds;
406 if (r[ii[1]] != 0.) k2 += nds;
407 if (r[ii[2]] != 0.) k3 += nds;
408 pF[kface++] = G4Facet(vv[1]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
414 pF[kface++] = G4Facet(vv[0]*k1,0, vv[1]*k2,0, vv[2]*k3,0, vv[3]*k4,0);
415 if (r[ii[0]] != 0.) k1 += nds;
416 if (r[ii[1]] != 0.) k2 += nds;
417 if (r[ii[2]] != 0.) k3 += nds;
418 if (r[ii[3]] != 0.) k4 += nds;
419 pF[kface++] = G4Facet(vv[2]*k4,0, vv[1]*k3,0, vv[0]*k2,0, vv[3]*k1,0);
449 static const G4double wholeCircle = twopi;
453 G4bool ifWholeCircle = (std::abs(dphi-wholeCircle) <
perMillion) ?
true :
false;
454 G4double delPhi = ifWholeCircle ? wholeCircle : dphi;
455 G4int nSphi = (nstep > 0) ?
456 nstep :
G4int(delPhi*GetNumberOfRotationSteps()/wholeCircle+.5);
457 if (nSphi == 0) nSphi = 1;
458 G4int nVphi = ifWholeCircle ? nSphi : nSphi+1;
459 G4bool ifClosed = np1 > 0 ?
false :
true;
463 G4int absNp1 = std::abs(np1);
464 G4int absNp2 = std::abs(np2);
466 G4int i1end = absNp1-1;
467 G4int i2beg = absNp1;
468 G4int i2end = absNp1+absNp2-1;
471 for(i=i1beg; i<=i2end; i++) {
476 for (i=i1beg; i<=i1end; i++) {
477 j += (r[i] == 0.) ? 1 : nVphi;
483 if (r[i2beg] != r[i1beg] || z[i2beg] != z[i1beg]) {
484 j += (r[i2beg] == 0.) ? 1 : nVphi;
488 for(i=i2beg+1; i<i2end; i++) {
489 j += (r[i] == 0.) ? 1 : nVphi;
492 if (r[i2end] != r[i1end] || z[i2end] != z[i1end]) {
493 if (absNp2 > 1) j += (r[i2end] == 0.) ? 1 : nVphi;
499 k = ifClosed ? absNp1*nSphi : (absNp1-1)*nSphi;
502 for(i=i2beg; i<i2end; i++) {
503 if (r[i] > 0. || r[i+1] > 0.) k += nSphi;
507 if (r[i2end] > 0. || r[i2beg] > 0.) k += nSphi;
512 if (ifSide1 && (r[i1beg] > 0. || r[i2beg] > 0.)) k += nSphi;
513 if (ifSide2 && (r[i1end] > 0. || r[i2end] > 0.)) k += nSphi;
516 if (!ifWholeCircle) {
517 k += ifClosed ? 2*absNp1 : 2*(absNp1-1);
522 AllocateMemory(j, k);
527 kk =
new G4int[absNp1+absNp2];
530 for(i=i1beg; i<=i1end; i++) {
533 { pV[k++] =
G4Point3D(0, 0, z[i]); }
else { k += nVphi; }
540 { pV[k++] =
G4Point3D(0, 0, z[i]); }
else { k += nVphi; }
545 for(i=i2beg+1; i<i2end; i++) {
548 { pV[k++] =
G4Point3D(0, 0, z[i]); }
else { k += nVphi; }
555 if (r[i] == 0.) pV[k] =
G4Point3D(0, 0, z[i]);
563 for(j=0; j<nVphi; j++) {
564 cosPhi = std::cos(phi+j*delPhi/nSphi);
565 sinPhi = std::sin(phi+j*delPhi/nSphi);
566 for(i=i1beg; i<=i2end; i++) {
568 pV[kk[i]+j] =
G4Point3D(r[i]*cosPhi,r[i]*sinPhi,z[i]);
577 v2 = ifClosed ? nodeVis : 1;
578 for(i=i1beg; i<i1end; i++) {
580 if (!ifClosed && i == i1end-1) {
583 v2 = (r[i] == r[i+1] && r[i+1] == r[i+2]) ? -1 : nodeVis;
585 RotateEdge(kk[i], kk[i+1], r[i], r[i+1], v1, v2,
586 edgeVis, ifWholeCircle, nSphi, k);
589 RotateEdge(kk[i1end], kk[i1beg], r[i1end],r[i1beg], nodeVis, nodeVis,
590 edgeVis, ifWholeCircle, nSphi, k);
596 v2 = ifClosed ? nodeVis : 1;
597 for(i=i2beg; i<i2end; i++) {
599 if (!ifClosed && i==i2end-1) {
602 v2 = (r[i] == r[i+1] && r[i+1] == r[i+2]) ? -1 : nodeVis;
604 RotateEdge(kk[i+1], kk[i], r[i+1], r[i], v2, v1,
605 edgeVis, ifWholeCircle, nSphi, k);
608 RotateEdge(kk[i2beg], kk[i2end], r[i2beg], r[i2end], nodeVis, nodeVis,
609 edgeVis, ifWholeCircle, nSphi, k);
617 RotateEdge(kk[i2beg], kk[i1beg], r[i2beg], r[i1beg], 1, 1,
618 -1, ifWholeCircle, nSphi, k);
621 RotateEdge(kk[i1end], kk[i2end], r[i1end], r[i2end], 1, 1,
622 -1, ifWholeCircle, nSphi, k);
628 if (!ifWholeCircle) {
633 for (i=i1beg; i<=i1end; i++) {
635 ii[3] = (i == i1end) ? i1beg : i+1;
636 ii[1] = (absNp2 == 1) ? i2beg : ii[0]+absNp1;
637 ii[2] = (absNp2 == 1) ? i2beg : ii[3]+absNp1;
642 SetSideFacets(ii, vv, kk, r, dphi, nSphi, k);
645 for (i=i1beg; i<i1end; i++) {
648 ii[1] = (absNp2 == 1) ? i2beg : ii[0]+absNp1;
649 ii[2] = (absNp2 == 1) ? i2beg : ii[3]+absNp1;
650 vv[0] = (i == i1beg) ? 1 : -1;
652 vv[2] = (i == i1end-1) ? 1 : -1;
654 SetSideFacets(ii, vv, kk, r, dphi, nSphi, k);
663 <<
"Polyhedron::RotateAroundZ: number of generated faces ("
664 << k-1 <<
") is not equal to the number of allocated faces ("
670 void HepPolyhedron::SetReferences()
680 if (nface <= 0)
return;
682 struct edgeListMember {
683 edgeListMember *next;
687 } *edgeList, *freeList, **headList;
692 edgeList =
new edgeListMember[2*nface];
693 headList =
new edgeListMember*[nvert];
696 for (i=0; i<nvert; i++) {
700 for (i=0; i<2*nface-1; i++) {
701 edgeList[i].next = &edgeList[i+1];
703 edgeList[2*nface-1].next = 0;
707 G4int iface, iedge, nedge, i1, i2, k1, k2;
708 edgeListMember *prev, *cur;
710 for(iface=1; iface<=nface; iface++) {
711 nedge = (pF[iface].edge[3].v == 0) ? 3 : 4;
712 for (iedge=0; iedge<nedge; iedge++) {
714 i2 = (iedge < nedge-1) ? iedge+1 : 0;
715 i1 = std::abs(pF[iface].edge[i1].v);
716 i2 = std::abs(pF[iface].edge[i2].v);
717 k1 = (i1 < i2) ? i1 : i2;
718 k2 = (i1 > i2) ? i1 : i2;
723 headList[k1] = freeList;
726 <<
"Polyhedron::SetReferences: bad link "
730 freeList = freeList->next;
740 headList[k1] = cur->next;
741 cur->next = freeList;
743 pF[iface].edge[iedge].f = cur->iface;
744 pF[cur->iface].edge[cur->iedge].f = iface;
745 i1 = (pF[iface].edge[iedge].v < 0) ? -1 : 1;
746 i2 = (pF[cur->iface].edge[cur->iedge].v < 0) ? -1 : 1;
749 <<
"Polyhedron::SetReferences: different edge visibility "
750 << iface <<
"/" << iedge <<
"/"
751 << pF[iface].edge[iedge].v <<
" and "
752 << cur->iface <<
"/" << cur->iedge <<
"/"
753 << pF[cur->iface].edge[cur->iedge].v
764 prev->next = freeList;
767 <<
"Polyhedron::SetReferences: bad link "
771 freeList = freeList->next;
781 prev->next = cur->next;
782 cur->next = freeList;
784 pF[iface].edge[iedge].f = cur->iface;
785 pF[cur->iface].edge[cur->iedge].f = iface;
786 i1 = (pF[iface].edge[iedge].v < 0) ? -1 : 1;
787 i2 = (pF[cur->iface].edge[cur->iedge].v < 0) ? -1 : 1;
790 <<
"Polyhedron::SetReferences: different edge visibility "
791 << iface <<
"/" << iedge <<
"/"
792 << pF[iface].edge[iedge].v <<
" and "
793 << cur->iface <<
"/" << cur->iedge <<
"/"
794 << pF[cur->iface].edge[cur->iedge].v
805 for (i=0; i<nvert; i++) {
806 if (headList[i] != 0) {
808 <<
"Polyhedron::SetReferences: List " << i <<
" is not empty"
819 void HepPolyhedron::InvertFacets()
829 if (nface <= 0)
return;
830 G4int i, k, nnode, v[4],f[4];
831 for (i=1; i<=nface; i++) {
832 nnode = (pF[i].edge[3].v == 0) ? 3 : 4;
833 for (k=0; k<nnode; k++) {
834 v[k] = (k+1 == nnode) ? pF[i].edge[0].v : pF[i].edge[k+1].v;
835 if (v[k] * pF[i].edge[k].v < 0) v[k] = -v[k];
836 f[k] = pF[i].edge[k].f;
838 for (k=0; k<nnode; k++) {
839 pF[i].edge[nnode-1-k].v = v[k];
840 pF[i].edge[nnode-1-k].f = f[k];
845 HepPolyhedron & HepPolyhedron::Transform(
const G4Transform3D &t)
856 for (
G4int i=1; i<=nvert; i++) { pV[i] = t * pV[i]; }
865 if ((x.cross(y))*z < 0) InvertFacets();
870 G4bool HepPolyhedron::GetNextVertexIndex(
G4int &index,
G4int &edgeFlag)
const
882 G4int vIndex = pF[iFace].edge[iQVertex].v;
884 edgeFlag = (vIndex > 0) ? 1 : 0;
885 index = std::abs(vIndex);
887 if (iQVertex >= 3 || pF[iFace].edge[iQVertex+1].v == 0) {
889 if (++iFace > nface) iFace = 1;
907 if (index <= 0 || index > nvert) {
909 <<
"HepPolyhedron::GetVertex: irrelevant index " << index
917 HepPolyhedron::GetNextVertex(
G4Point3D &vertex,
G4int &edgeFlag)
const
930 G4bool rep = GetNextVertexIndex(index, edgeFlag);
951 if (nface == 0)
return false;
953 G4int k = pF[iFace].edge[iNode].v;
954 if (k > 0) { edgeFlag = 1; }
else { edgeFlag = -1; k = -k; }
956 normal = FindNodeNormal(iFace,k);
957 if (iNode >= 3 || pF[iFace].edge[iNode+1].v == 0) {
959 if (++iFace > nface) iFace = 1;
983 G4int k1, k2, kflag, kface1, kface2;
985 if (iFace == 1 && iQVertex == 0) {
986 k2 = pF[nface].edge[0].v;
987 k1 = pF[nface].edge[3].v;
988 if (k1 == 0) k1 = pF[nface].edge[2].v;
989 if (std::abs(k1) > std::abs(k2)) iOrder = -1;
993 k1 = pF[iFace].edge[iQVertex].v;
997 kface2 = pF[iFace].edge[iQVertex].f;
998 if (iQVertex >= 3 || pF[iFace].edge[iQVertex+1].v == 0) {
1000 k2 = std::abs(pF[iFace].edge[iQVertex].v);
1004 k2 = std::abs(pF[iFace].edge[iQVertex].v);
1006 }
while (iOrder*k1 > iOrder*k2);
1008 i1 = k1; i2 = k2; edgeFlag = (kflag > 0) ? 1 : 0;
1009 iface1 = kface1; iface2 = kface2;
1011 if (iFace > nface) {
1012 iFace = 1; iOrder = 1;
1020 HepPolyhedron::GetNextEdgeIndeces(
G4int &i1,
G4int &i2,
G4int &edgeFlag)
const
1031 G4int kface1, kface2;
1032 return GetNextEdgeIndeces(i1, i2, edgeFlag, kface1, kface2);
1036 HepPolyhedron::GetNextEdge(
G4Point3D &p1,
1038 G4int &edgeFlag)
const
1050 G4bool rep = GetNextEdgeIndeces(i1,i2,edgeFlag);
1071 G4bool rep = GetNextEdgeIndeces(i1,i2,edgeFlag,iface1,iface2);
1088 if (iFace < 1 || iFace > nface) {
1090 <<
"HepPolyhedron::GetFacet: irrelevant index " << iFace
1095 for (i=0; i<4; i++) {
1096 k = pF[iFace].edge[i].v;
1098 if (iFaces != 0) iFaces[i] = pF[iFace].edge[i].f;
1101 if (edgeFlags != 0) edgeFlags[i] = 1;
1104 if (edgeFlags != 0) edgeFlags[i] = -1;
1123 GetFacet(index, n, iNodes, edgeFlags);
1125 for (
G4int i=0; i<
n; i++) {
1126 nodes[i] = pV[iNodes[i]];
1127 if (normals != 0) normals[i] = FindNodeNormal(index,iNodes[i]);
1147 if (edgeFlags == 0) {
1148 GetFacet(iFace, n, nodes);
1149 }
else if (normals == 0) {
1150 GetFacet(iFace, n, nodes, edgeFlags);
1152 GetFacet(iFace, n, nodes, edgeFlags, normals);
1155 if (++iFace > nface) {
1173 if (iFace < 1 || iFace > nface) {
1175 <<
"HepPolyhedron::GetNormal: irrelevant index " << iFace
1180 G4int i0 = std::abs(pF[iFace].edge[0].v);
1181 G4int i1 = std::abs(pF[iFace].edge[1].v);
1182 G4int i2 = std::abs(pF[iFace].edge[2].v);
1183 G4int i3 = std::abs(pF[iFace].edge[3].v);
1184 if (i3 == 0) i3 = i0;
1185 return (pV[i2] - pV[i0]).cross(pV[i3] - pV[i1]);
1198 if (iFace < 1 || iFace > nface) {
1200 <<
"HepPolyhedron::GetUnitNormal: irrelevant index " << iFace
1205 G4int i0 = std::abs(pF[iFace].edge[0].v);
1206 G4int i1 = std::abs(pF[iFace].edge[1].v);
1207 G4int i2 = std::abs(pF[iFace].edge[2].v);
1208 G4int i3 = std::abs(pF[iFace].edge[3].v);
1209 if (i3 == 0) i3 = i0;
1210 return ((pV[i2] - pV[i0]).cross(pV[i3] - pV[i1])).unit();
1225 normal = GetNormal(iFace);
1226 if (++iFace > nface) {
1245 G4bool rep = GetNextNormal(normal);
1246 normal = normal.unit();
1250 G4double HepPolyhedron::GetSurfaceArea() const
1261 for (
G4int iFace=1; iFace<=nface; iFace++) {
1262 G4int i0 = std::abs(pF[iFace].edge[0].v);
1263 G4int i1 = std::abs(pF[iFace].edge[1].v);
1264 G4int i2 = std::abs(pF[iFace].edge[2].v);
1265 G4int i3 = std::abs(pF[iFace].edge[3].v);
1266 if (i3 == 0) i3 = i0;
1267 srf += ((pV[i2] - pV[i0]).cross(pV[i3] - pV[i1])).mag();
1272 G4double HepPolyhedron::GetVolume() const
1283 for (
G4int iFace=1; iFace<=nface; iFace++) {
1284 G4int i0 = std::abs(pF[iFace].edge[0].v);
1285 G4int i1 = std::abs(pF[iFace].edge[1].v);
1286 G4int i2 = std::abs(pF[iFace].edge[2].v);
1287 G4int i3 = std::abs(pF[iFace].edge[3].v);
1291 pt = (pV[i0]+pV[i1]+pV[i2]) * (1./3.);
1293 pt = (pV[i0]+pV[i1]+pV[i2]+pV[i3]) * 0.25;
1295 v += ((pV[i2] - pV[i0]).cross(pV[i3] - pV[i1])).dot(pt);
1301 HepPolyhedron::createTwistedTrap(
G4double Dz,
1318 AllocateMemory(12,18);
1320 pV[ 1] =
G4Point3D(xy1[0][0],xy1[0][1],-Dz);
1321 pV[ 2] =
G4Point3D(xy1[1][0],xy1[1][1],-Dz);
1322 pV[ 3] =
G4Point3D(xy1[2][0],xy1[2][1],-Dz);
1323 pV[ 4] =
G4Point3D(xy1[3][0],xy1[3][1],-Dz);
1325 pV[ 5] =
G4Point3D(xy2[0][0],xy2[0][1], Dz);
1326 pV[ 6] =
G4Point3D(xy2[1][0],xy2[1][1], Dz);
1327 pV[ 7] =
G4Point3D(xy2[2][0],xy2[2][1], Dz);
1328 pV[ 8] =
G4Point3D(xy2[3][0],xy2[3][1], Dz);
1330 pV[ 9] = (pV[1]+pV[2]+pV[5]+pV[6])/4.;
1331 pV[10] = (pV[2]+pV[3]+pV[6]+pV[7])/4.;
1332 pV[11] = (pV[3]+pV[4]+pV[7]+pV[8])/4.;
1333 pV[12] = (pV[4]+pV[1]+pV[8]+pV[5])/4.;
1335 enum {DUMMY, BOTTOM,
1336 LEFT_BOTTOM, LEFT_FRONT, LEFT_TOP, LEFT_BACK,
1337 BACK_BOTTOM, BACK_LEFT, BACK_TOP, BACK_RIGHT,
1338 RIGHT_BOTTOM, RIGHT_BACK, RIGHT_TOP, RIGHT_FRONT,
1339 FRONT_BOTTOM, FRONT_RIGHT, FRONT_TOP, FRONT_LEFT,
1342 pF[ 1]=G4Facet(1,LEFT_BOTTOM, 4,BACK_BOTTOM, 3,RIGHT_BOTTOM, 2,FRONT_BOTTOM);
1344 pF[ 2]=G4Facet(4,BOTTOM, -1,LEFT_FRONT, -12,LEFT_BACK, 0,0);
1345 pF[ 3]=G4Facet(1,FRONT_LEFT, -5,LEFT_TOP, -12,LEFT_BOTTOM, 0,0);
1346 pF[ 4]=G4Facet(5,TOP, -8,LEFT_BACK, -12,LEFT_FRONT, 0,0);
1347 pF[ 5]=G4Facet(8,BACK_LEFT, -4,LEFT_BOTTOM, -12,LEFT_TOP, 0,0);
1349 pF[ 6]=G4Facet(3,BOTTOM, -4,BACK_LEFT, -11,BACK_RIGHT, 0,0);
1350 pF[ 7]=G4Facet(4,LEFT_BACK, -8,BACK_TOP, -11,BACK_BOTTOM, 0,0);
1351 pF[ 8]=G4Facet(8,TOP, -7,BACK_RIGHT, -11,BACK_LEFT, 0,0);
1352 pF[ 9]=G4Facet(7,RIGHT_BACK, -3,BACK_BOTTOM, -11,BACK_TOP, 0,0);
1354 pF[10]=G4Facet(2,BOTTOM, -3,RIGHT_BACK, -10,RIGHT_FRONT, 0,0);
1355 pF[11]=G4Facet(3,BACK_RIGHT, -7,RIGHT_TOP, -10,RIGHT_BOTTOM, 0,0);
1356 pF[12]=G4Facet(7,TOP, -6,RIGHT_FRONT, -10,RIGHT_BACK, 0,0);
1357 pF[13]=G4Facet(6,FRONT_RIGHT,-2,RIGHT_BOTTOM,-10,RIGHT_TOP, 0,0);
1359 pF[14]=G4Facet(1,BOTTOM, -2,FRONT_RIGHT, -9,FRONT_LEFT, 0,0);
1360 pF[15]=G4Facet(2,RIGHT_FRONT,-6,FRONT_TOP, -9,FRONT_BOTTOM, 0,0);
1361 pF[16]=G4Facet(6,TOP, -5,FRONT_LEFT, -9,FRONT_RIGHT, 0,0);
1362 pF[17]=G4Facet(5,LEFT_FRONT, -1,FRONT_BOTTOM, -9,FRONT_TOP, 0,0);
1364 pF[18]=G4Facet(5,FRONT_TOP, 6,RIGHT_TOP, 7,BACK_TOP, 8,LEFT_TOP);
1370 HepPolyhedron::createPolyhedron(
G4int Nnodes,
G4int Nfaces,
1372 const G4int faces[][4])
1387 AllocateMemory(Nnodes, Nfaces);
1388 if (nvert == 0)
return 1;
1390 for (
G4int i=0; i<Nnodes; i++) {
1391 pV[i+1] =
G4Point3D(xyz[i][0], xyz[i][1], xyz[i][2]);
1393 for (
G4int k=0; k<Nfaces; k++) {
1394 pF[k+1] = G4Facet(faces[k][0],0,faces[k][1],0,faces[k][2],0,faces[k][3],0);
1418 AllocateMemory(8,6);
1432 HepPolyhedronTrd2::~HepPolyhedronTrd2() {}
1436 : HepPolyhedronTrd2(Dx1, Dx2, Dy, Dy, Dz) {}
1438 HepPolyhedronTrd1::~HepPolyhedronTrd1() {}
1441 : HepPolyhedronTrd2(Dx, Dx, Dy, Dy, Dz) {}
1443 HepPolyhedronBox::~HepPolyhedronBox() {}
1445 HepPolyhedronTrap::HepPolyhedronTrap(
G4double Dz,
1479 G4double DzTthetaCphi = Dz*std::tan(Theta)*std::cos(Phi);
1480 G4double DzTthetaSphi = Dz*std::tan(Theta)*std::sin(Phi);
1481 G4double Dy1Talp1 = Dy1*std::tan(Alp1);
1482 G4double Dy2Talp2 = Dy2*std::tan(Alp2);
1484 AllocateMemory(8,6);
1486 pV[1] =
G4Point3D(-DzTthetaCphi-Dy1Talp1-Dx1,-DzTthetaSphi-Dy1,-Dz);
1487 pV[2] =
G4Point3D(-DzTthetaCphi-Dy1Talp1+Dx1,-DzTthetaSphi-Dy1,-Dz);
1488 pV[3] =
G4Point3D(-DzTthetaCphi+Dy1Talp1+Dx2,-DzTthetaSphi+Dy1,-Dz);
1489 pV[4] =
G4Point3D(-DzTthetaCphi+Dy1Talp1-Dx2,-DzTthetaSphi+Dy1,-Dz);
1490 pV[5] =
G4Point3D( DzTthetaCphi-Dy2Talp2-Dx3, DzTthetaSphi-Dy2, Dz);
1491 pV[6] =
G4Point3D( DzTthetaCphi-Dy2Talp2+Dx3, DzTthetaSphi-Dy2, Dz);
1492 pV[7] =
G4Point3D( DzTthetaCphi+Dy2Talp2+Dx4, DzTthetaSphi+Dy2, Dz);
1493 pV[8] =
G4Point3D( DzTthetaCphi+Dy2Talp2-Dx4, DzTthetaSphi+Dy2, Dz);
1498 HepPolyhedronTrap::~HepPolyhedronTrap() {}
1503 : HepPolyhedronTrap(Dz, Theta, Phi, Dy, Dx, Dx, Alpha, Dy, Dx, Dx, Alpha) {}
1505 HepPolyhedronPara::~HepPolyhedronPara() {}
1507 HepPolyhedronParaboloid::HepPolyhedronParaboloid(
G4double r1,
1527 static const G4double wholeCircle=twopi;
1532 if (r1 < 0. || r2 <= 0.) k = 1;
1534 if (dz <= 0.) k += 2;
1540 phi2 = sPhi; phi1 = phi2 + dPhi;
1544 phi1 = sPhi; phi2 = phi1 + wholeCircle;
1548 phi1 = sPhi; phi2 = phi1 + dPhi;
1552 if (std::abs(dphi-wholeCircle) <
perMillion) dphi = wholeCircle;
1553 if (dphi > wholeCircle) k += 4;
1556 std::cerr <<
"HepPolyhedronParaboloid: error in input parameters";
1557 if ((k & 1) != 0) std::cerr <<
" (radiuses)";
1558 if ((k & 2) != 0) std::cerr <<
" (half-length)";
1559 if ((k & 4) != 0) std::cerr <<
" (angles)";
1560 std::cerr << std::endl;
1561 std::cerr <<
" r1=" << r1;
1562 std::cerr <<
" r2=" << r2;
1563 std::cerr <<
" dz=" << dz <<
" sPhi=" << sPhi <<
" dPhi=" << dPhi
1570 G4int n = GetNumberOfRotationSteps();
1572 G4double k1 = (r2*r2 - r1*r1) / 2 / dz;
1580 for(
G4int i = 1; i < n - 1; i++)
1582 rr[i] = rr[i-1] - dl;
1583 zz[i] = (rr[i]*rr[i] - k2) / k1;
1602 RotateAroundZ(0, phi1, dphi, n, 2, zz, rr, -1, -1);
1609 HepPolyhedronParaboloid::~HepPolyhedronParaboloid() {}
1611 HepPolyhedronHype::HepPolyhedronHype(
G4double r1,
1631 static const G4double wholeCircle=twopi;
1636 if (r2 < 0. || r1 < 0. ) k = 1;
1637 if (r1 > r2 ) k = 1;
1638 if (r1 == r2) k = 1;
1640 if (halfZ <= 0.) k += 2;
1642 if (sqrtan1<0.||sqrtan2<0.) k += 4;
1646 std::cerr <<
"HepPolyhedronHype: error in input parameters";
1647 if ((k & 1) != 0) std::cerr <<
" (radiuses)";
1648 if ((k & 2) != 0) std::cerr <<
" (half-length)";
1649 if ((k & 4) != 0) std::cerr <<
" (angles)";
1650 std::cerr << std::endl;
1651 std::cerr <<
" r1=" << r1 <<
" r2=" << r2;
1652 std::cerr <<
" halfZ=" << halfZ <<
" sqrTan1=" << sqrtan1
1653 <<
" sqrTan2=" << sqrtan2
1660 G4int n = GetNumberOfRotationSteps();
1668 rr[0] = std::sqrt(sqrtan2*halfZ*halfZ+k2);
1670 for(
G4int i = 1; i < n-1; i++)
1672 zz[i] = zz[i-1] - dz;
1673 rr[i] =std::sqrt(sqrtan2*zz[i]*zz[i]+k2);
1680 rr[
n] = std::sqrt(sqrtan1*halfZ*halfZ+k1);
1682 for(
G4int i = n+1; i < n+
n; i++)
1684 zz[i] = zz[i-1] - dz;
1685 rr[i] =std::sqrt(sqrtan1*zz[i]*zz[i]+k1);
1692 RotateAroundZ(0, 0., wholeCircle, n, n, zz, rr, -1, -1);
1699 HepPolyhedronHype::~HepPolyhedronHype() {}
1701 HepPolyhedronCons::HepPolyhedronCons(
G4double Rmn1,
1723 static const G4double wholeCircle=twopi;
1728 if (Rmn1 < 0. || Rmx1 < 0. || Rmn2 < 0. || Rmx2 < 0.) k = 1;
1729 if (Rmn1 > Rmx1 || Rmn2 > Rmx2) k = 1;
1730 if (Rmn1 == Rmx1 && Rmn2 == Rmx2) k = 1;
1732 if (Dz <= 0.) k += 2;
1736 phi2 = Phi1; phi1 = phi2 - Dphi;
1737 }
else if (Dphi == 0.) {
1738 phi1 = Phi1; phi2 = phi1 + wholeCircle;
1740 phi1 = Phi1; phi2 = phi1 + Dphi;
1743 if (std::abs(dphi-wholeCircle) <
perMillion) dphi = wholeCircle;
1744 if (dphi > wholeCircle) k += 4;
1747 std::cerr <<
"HepPolyhedronCone(s)/Tube(s): error in input parameters";
1748 if ((k & 1) != 0) std::cerr <<
" (radiuses)";
1749 if ((k & 2) != 0) std::cerr <<
" (half-length)";
1750 if ((k & 4) != 0) std::cerr <<
" (angles)";
1751 std::cerr << std::endl;
1752 std::cerr <<
" Rmn1=" << Rmn1 <<
" Rmx1=" << Rmx1;
1753 std::cerr <<
" Rmn2=" << Rmn2 <<
" Rmx2=" << Rmx2;
1754 std::cerr <<
" Dz=" << Dz <<
" Phi1=" << Phi1 <<
" Dphi=" << Dphi
1773 RotateAroundZ(0, phi1, dphi, 2, 2, zz, rr, -1, -1);
1777 HepPolyhedronCons::~HepPolyhedronCons() {}
1782 HepPolyhedronCons(Rmn1, Rmx1, Rmn2, Rmx2, Dz, 0*
deg, 360*
deg) {}
1784 HepPolyhedronCone::~HepPolyhedronCone() {}
1789 : HepPolyhedronCons(Rmin, Rmax, Rmin, Rmax, Dz, Phi1, Dphi) {}
1791 HepPolyhedronTubs::~HepPolyhedronTubs() {}
1795 : HepPolyhedronCons(Rmin, Rmax, Rmin, Rmax, Dz, 0*
deg, 360*
deg) {}
1797 HepPolyhedronTube::~HepPolyhedronTube () {}
1799 HepPolyhedronPgon::HepPolyhedronPgon(
G4double phi,
1825 if (dphi <= 0. || dphi > twopi) {
1827 <<
"HepPolyhedronPgon/Pcon: wrong delta phi = " << dphi
1834 <<
"HepPolyhedronPgon/Pcon: number of z-planes less than two = " << nz
1841 <<
"HepPolyhedronPgon/Pcon: error in number of phi-steps =" << npdv
1847 for (i=0; i<nz; i++) {
1848 if (rmin[i] < 0. || rmax[i] < 0. || rmin[i] > rmax[i]) {
1850 <<
"HepPolyhedronPgon: error in radiuses rmin[" << i <<
"]="
1851 << rmin[i] <<
" rmax[" << i <<
"]=" << rmax[i]
1863 if (z[0] > z[nz-1]) {
1864 for (i=0; i<nz; i++) {
1871 for (i=0; i<nz; i++) {
1873 rr[i] = rmax[nz-i-1];
1874 zz[i+nz] = z[nz-i-1];
1875 rr[i+nz] = rmin[nz-i-1];
1881 RotateAroundZ(npdv, phi, dphi, nz, nz, zz, rr, -1, (npdv == 0) ? -1 : 1);
1888 HepPolyhedronPgon::~HepPolyhedronPgon() {}
1894 : HepPolyhedronPgon(phi, dphi, 0, nz, z, rmin, rmax) {}
1896 HepPolyhedronPcon::~HepPolyhedronPcon() {}
1919 if (dphi <= 0. || dphi > twopi) {
1921 <<
"HepPolyhedronSphere: wrong delta phi = " << dphi
1926 if (the < 0. || the >
pi) {
1928 <<
"HepPolyhedronSphere: wrong theta = " << the
1933 if (dthe <= 0. || dthe > pi) {
1935 <<
"HepPolyhedronSphere: wrong delta theta = " << dthe
1940 if (the+dthe > pi) {
1942 <<
"HepPolyhedronSphere: wrong theta + delta theta = "
1943 << the <<
" " << dthe
1948 if (rmin < 0. || rmin >= rmax) {
1950 <<
"HepPolyhedronSphere: error in radiuses"
1951 <<
" rmin=" << rmin <<
" rmax=" << rmax
1958 G4int nds = (GetNumberOfRotationSteps() + 1) / 2;
1960 if (np1 <= 1) np1 = 2;
1969 for (
G4int i=0; i<np1; i++) {
1970 cosa = std::cos(the+i*a);
1971 sina = std::sin(the+i*a);
1975 zz[i+np1] = rmin*cosa;
1976 rr[i+np1] = rmin*sina;
1986 RotateAroundZ(0, phi, dphi, np1, np2, zz, rr, -1, -1);
1993 HepPolyhedronSphere::~HepPolyhedronSphere() {}
1995 HepPolyhedronTorus::HepPolyhedronTorus(
G4double rmin,
2017 if (dphi <= 0. || dphi > twopi) {
2019 <<
"HepPolyhedronTorus: wrong delta phi = " << dphi
2024 if (rmin < 0. || rmin >= rmax || rmax >= rtor) {
2026 <<
"HepPolyhedronTorus: error in radiuses"
2027 <<
" rmin=" << rmin <<
" rmax=" << rmax <<
" rtorus=" << rtor
2034 G4int np1 = GetNumberOfRotationSteps();
2043 for (
G4int i=0; i<np1; i++) {
2044 cosa = std::cos(i*a);
2045 sina = std::sin(i*a);
2047 rr[i] = rtor+rmax*sina;
2049 zz[i+np1] = rmin*cosa;
2050 rr[i+np1] = rtor+rmin*sina;
2061 RotateAroundZ(0, phi, dphi, -np1, -np2, zz, rr, -1,-1);
2068 HepPolyhedronTorus::~HepPolyhedronTorus() {}
2090 if (zCut1 >= cz || zCut2 <= -cz || zCut1 > zCut2) {
2091 std::cerr <<
"HepPolyhedronEllipsoid: wrong zCut1 = " << zCut1
2092 <<
" zCut2 = " << zCut2
2093 <<
" for given cz = " << cz << std::endl;
2097 std::cerr <<
"HepPolyhedronEllipsoid: bad z semi-axis: cz = " << cz
2112 sthe= std::acos(zCut2/cz);
2121 dthe= std::acos(zCut1/cz)-sthe;
2128 G4int nds = (GetNumberOfRotationSteps() + 1) / 2;
2129 G4int np1 =
G4int(dthe*nds/pi) + 2 + cutflag;
2136 G4Exception(
"HepPolyhedronEllipsoid::HepPolyhedronEllipsoid",
2149 for (
G4int i=0; i<np1-cutflag; i++) {
2150 cosa = std::cos(sthe+i*a);
2151 sina = std::sin(sthe+i*a);
2164 std::cerr <<
"Logic error in HepPolyhedronEllipsoid, memory corrupted!"
2169 std::cerr <<
"Warning: logic error in HepPolyhedronEllipsoid."
2179 RotateAroundZ(0, 0.0, twopi, np1, 1, zz, rr, -1, 1);
2188 for (
G4int i=0; i<nvert; i++, p++) {
2189 p->setX( p->x() * ax/cz );
2190 p->setY( p->y() * by/cz );
2195 HepPolyhedronEllipsoid::~HepPolyhedronEllipsoid() {}
2197 HepPolyhedronEllipticalCone::HepPolyhedronEllipticalCone(
G4double ax,
2217 if ( (ax <= 0.) || (ay <= 0.) || (h <= 0.) || (zTopCut <= 0.) ) { k = 1; }
2220 std::cerr <<
"HepPolyhedronCone: error in input parameters";
2221 std::cerr << std::endl;
2227 zTopCut = (h >= zTopCut ? zTopCut : h);
2236 rr[0] = (h-zTopCut);
2237 rr[1] = (h+zTopCut);
2243 RotateAroundZ(0, 0., twopi, 2, 2, zz, rr, -1, -1);
2252 for (
G4int i=0; i<nvert; i++, p++) {
2253 p->setX( p->x() * ax );
2254 p->setY( p->y() * ay );
2259 HepPolyhedronEllipticalCone::~HepPolyhedronEllipticalCone() {}
2271 #include "BooleanProcessor.src"
2273 HepPolyhedron HepPolyhedron::add(
const HepPolyhedron & p)
const
2285 return processor.execute(OP_UNION, *
this, p,ierr);
2288 HepPolyhedron HepPolyhedron::intersect(
const HepPolyhedron & p)
const
2300 return processor.execute(OP_INTERSECTION, *
this, p,ierr);
2303 HepPolyhedron HepPolyhedron::subtract(
const HepPolyhedron & p)
const
2315 return processor.execute(OP_SUBTRACTION, *
this, p,ierr);
2323 #include "HepPolyhedronProcessor.src"
const G4double spatialTolerance
HepGeom::Point3D< G4double > G4Point3D
HepGeom::Vector3D< G4double > G4Vector3D
static double normal(HepRandomEngine *eptr)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
std::ostream & operator<<(std::ostream &ostr, const G4Facet &facet)
static const double perMillion
HepGeom::Normal3D< G4double > G4Normal3D