35 #if !defined(G4GEOM_USE_UGENERICTRAP)
66 const std::vector<G4TwoVector>& vertices )
67 :
G4VSolid(name), fDz(halfZ), fVertices(),
74 G4String errorDescription =
"InvalidSetup in \" ";
75 errorDescription +=
name;
76 errorDescription +=
"\"";
84 G4Exception(
"G4GenericTrap::G4GenericTrap()",
"GeomSolids0002",
92 G4Exception(
"G4GenericTrap::G4GenericTrap()",
"GeomSolids0002",
104 for (
auto i=0; i <4; ++i) {
fVertices.push_back(vertices[3-i]);}
105 for (
auto i=0; i <4; ++i) {
fVertices.push_back(vertices[7-i]);}
110 for (
auto j=0; j<2; ++j)
112 for (
auto i=1; i<4; ++i)
119 message <<
"Length segment is too small." <<
G4endl
120 <<
"Distance between " <<
fVertices[k-1] <<
" and "
121 <<
fVertices[
k] <<
" is only " << length <<
" mm !";
122 G4Exception(
"G4GenericTrap::G4GenericTrap()",
"GeomSolids1001",
123 JustWarning, message,
"Vertices will be collapsed.");
131 for(
auto i=0; i<4; ++i) {
fTwist[i]=0.; }
149 :
G4VSolid(a), halfCarTolerance(0.), fDz(0.), fVertices(),
167 halfCarTolerance(rhs.halfCarTolerance),
168 fDz(rhs.fDz), fVertices(rhs.fVertices),
169 fIsTwisted(rhs.fIsTwisted),
170 fMinBBoxVector(rhs.fMinBBoxVector), fMaxBBoxVector(rhs.fMaxBBoxVector),
171 fVisSubdivisions(rhs.fVisSubdivisions),
172 fSurfaceArea(rhs.fSurfaceArea), fCubicVolume(rhs.fCubicVolume)
187 if (
this == &rhs) {
return *
this; }
217 const std::vector<G4TwoVector>&
poly)
const
223 for (
G4int i=0; i<4; ++i)
227 cross = (p.
x()-poly[i].x())*(poly[j].
y()-poly[i].y())-
228 (p.
y()-poly[i].y())*(poly[j].
x()-poly[i].x());
230 len2=(poly[i]-poly[j]).mag2();
242 if (poly[j].
x() > poly[i].x())
251 if ( p.
x() > poly[iMax].x()+halfCarTolerance
257 if (poly[j].
y() > poly[i].y())
267 if ( p.
y() > poly[iMax].y()+halfCarTolerance
273 if ( poly[iMax].
x() != poly[iMin].x() )
275 test = (p.
x()-poly[iMin].x())/(poly[iMax].
x()-poly[iMin].x())
276 * (poly[iMax].
y()-poly[iMin].y())+poly[iMin].
y();
285 if( (test>=(poly[iMin].
y()-halfCarTolerance))
286 && (test<=(poly[iMax].
y()+halfCarTolerance)) )
295 else if (cross<0.) {
return kOutside; }
307 if ( (std::fabs(p.
x()-poly[0].x())
330 std::vector<G4TwoVector> xy;
337 for (
auto i=0; i<4; ++i)
367 p0, p1, p2,
r1,
r2, r3, r4;
368 G4int noSurfaces = 0;
372 distz =
fDz-std::fabs(p.
z());
389 std:: vector<G4TwoVector> vertices;
391 for (
auto i=0; i<4; ++i)
398 for (
G4int q=0; q<4; ++q)
424 lnorm = (p1-p0).
cross(p2-p0);
425 lnorm = lnorm.
unit();
426 if(zPlusSide) { lnorm=-lnorm; }
436 if(proj<0) { proj=0; }
437 if(proj>normP) { proj=normP; }
443 r1=r1+proj*(r2-
r1)/normP;
444 r3=r3+proj*(r4-r3)/normP;
451 distxy=std::fabs((p0-p).dot(lnorm));
458 sumnorm=sumnorm+lnorm;
472 if ( noSurfaces == 0 )
475 G4Exception(
"G4GenericTrap::SurfaceNormal(p)",
"GeomSolids1002",
481 else if ( noSurfaces == 1 ) { ; }
482 else { sumnorm = sumnorm.unit(); }
490 const G4int ipl )
const
542 lnorm=-(p1-p0).
cross(p2-p0);
544 else { lnorm=lnorm.
unit(); }
554 if (proj<0) { proj=0; }
555 if (proj>normP) { proj=normP; }
561 r1=r1+proj*(r2-
r1)/normP;
562 r3=r3+proj*(r4-r3)/normP;
576 const G4int ipl)
const
612 G4double a = (dtx*v.
y()-dty*v.
x()+(tx1*ty2-tx2*ty1)*v.
z())*v.
z();
613 G4double b = dxs*v.
y()-dys*v.
x()+(dtx*p.
y()-dty*p.
x()+ty2*xs1-ty1*xs2
614 + tx1*ys2-tx2*ys1)*v.
z();
639 if (std::fabs(zi)<
fDz)
647 zi = (xp-
x1)*(xp-x2)+(yp-
y1)*(yp-y2);
656 if (a>0) { q=0.5*(-b-std::sqrt(d))/a; }
657 else { q=0.5*(-b+std::sqrt(d))/a; }
671 if (a>0) { q=0.5*(-b+std::sqrt(d))/a; }
672 else { q=0.5*(-b-std::sqrt(d))/a; }
679 if (std::fabs(zi)<
fDz)
687 zi = (xp-
x1)*(xp-x2)+(yp-
y1)*(yp-y2);
691 if (a>0) { q=0.5*(-b+std::sqrt(d))/a; }
692 else { q=0.5*(-b-std::sqrt(d))/a; }
706 if (a>0) { q=0.5*(-b-std::sqrt(d))/a; }
707 else { q=0.5*(-b+std::sqrt(d))/a; }
714 if (std::fabs(zi)<
fDz)
722 zi = (xp-
x1)*(xp-x2)+(yp-
y1)*(yp-y2);
763 dist[4] = (
fDz-p.
z())/v.
z();
767 dist[4] = (-
fDz-p.
z())/v.
z();
779 if (n.
dot(v)<0) { dist[4]=0.; }
790 if (dist[i] < distmin) { distmin = dist[i]; }
812 if(safz<0) { safz=0; }
818 for (iseg=0; iseg<4; ++iseg)
821 if (safxy>safe) { safe=safxy; }
841 safe = (p-p1).dot(norm);
878 G4double c=(xb-xa)*(yc-ya)-(xc-xa)*(yb-ya);
884 t=-(a*p.
x()+b*p.
y()+c*p.
z()+
d)/t;
918 G4bool lateral_cross =
false;
921 if (calcNorm) { *validNorm =
true; }
925 distmin=(-
fDz-p.
z())/v.
z();
932 distmin = (
fDz-p.
z())/v.
z();
942 for (
G4int ipl=0; ipl<4; ++ipl)
958 if ( (q>=0) && (q<distmin) )
979 G4double a = (dtx*v.
y()-dty*v.
x()+(tx1*ty2-tx2*ty1)*v.
z())*v.
z();
980 G4double b = dxs*v.
y()-dys*v.
x()+(dtx*p.
y()-dty*p.
x()+ty2*xs1-ty1*xs2
981 + tx1*ys2-tx2*ys1)*v.
z();
1007 if (a > 0) { q=0.5*(-b-std::sqrt(d))/a; }
1008 else { q=0.5*(-b+std::sqrt(d))/a; }
1020 if (a > 0) { q=0.5*(-b+std::sqrt(d))/a; }
1021 else { q=0.5*(-b-std::sqrt(d))/a; }
1025 lateral_cross =
true;
1032 lateral_cross =
true;
1038 if (a > 0) { q=0.5*(-b+std::sqrt(d))/a; }
1039 else { q=0.5*(-b-std::sqrt(d))/a; }
1049 if (a > 0) { q=0.5*(-b-std::sqrt(d))/a; }
1050 else { q=0.5*(-b+std::sqrt(d))/a; }
1054 lateral_cross =
true;
1061 lateral_cross =
true;
1075 if (v.z()>0.) { i=4; }
1076 std::vector<G4TwoVector> xy;
1092 if(v.z()>0) {side=
kPZ;}
1123 G4int oldprc = message.precision(16);
1124 message <<
"Undefined side for valid surface normal to solid." <<
G4endl
1126 <<
" p.x() = " << p.
x()/
mm <<
" mm" <<
G4endl
1127 <<
" p.y() = " << p.
y()/
mm <<
" mm" <<
G4endl
1128 <<
" p.z() = " << p.
z()/
mm <<
" mm" <<
G4endl
1129 <<
"Direction:" <<
G4endl
1130 <<
" v.x() = " << v.
x() <<
G4endl
1131 <<
" v.y() = " << v.
y() <<
G4endl
1132 <<
" v.z() = " << v.
z() <<
G4endl
1133 <<
"Proposed distance :" <<
G4endl
1134 <<
" distmin = " << distmin/
mm <<
" mm";
1135 message.precision(oldprc);
1136 G4Exception(
"G4GenericTrap::DistanceToOut(p,v,..)",
1160 if (safz<0) { safz = 0; }
1165 for (
G4int iseg=0; iseg<4; ++iseg)
1168 if (safxy < safe) { safe = safxy; }
1184 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
1187 message <<
"Bad bounding box (min >= max) for solid: "
1189 <<
"\npMin = " << pMin
1190 <<
"\npMax = " <<
pMax;
1191 G4Exception(
"G4GenericTrap::BoundingLimits()",
"GeomMgt0001",
1212 #ifdef G4BBOX_EXTENT
1217 return exist = (pMin <
pMax) ?
true :
false;
1229 for (
G4int i=0; i<4; ++i)
1233 baseA[2*i].set(va.
x(),va.
y(),-
dz);
1234 baseB[2*i].set(vb.
x(),vb.
y(),
dz);
1236 for (
G4int i=0; i<4; ++i)
1244 baseA[k1+1] = (znorm < 0.0) ? baseA[
k2] : baseA[
k1];
1245 baseB[k1+1] = (znorm < 0.0) ? baseB[
k1] : baseB[
k2];
1248 std::vector<const G4ThreeVectorList *> polygons(2);
1249 polygons[0] = &baseA;
1250 polygons[1] = &baseB;
1275 G4int oldprc = os.precision(16);
1276 os <<
"-----------------------------------------------------------\n"
1277 <<
" *** Dump for solid - " <<
GetName() <<
" *** \n"
1278 <<
" =================================================== \n"
1280 <<
" half length Z: " <<
fDz/
mm <<
" mm \n"
1281 <<
" list of vertices:\n";
1285 os << std::setw(5) <<
"#" << i
1289 os.precision(oldprc);
1308 G4double rand,area,chose,cf,lambda0,lambda1,alfa,beta,zp;
1311 std::vector<G4ThreeVector> vertices;
1312 for (
auto i=0; i<4; ++i)
1316 for (
auto i=4; i<8; ++i)
1324 vertices[2],vertices[3]);
1326 vertices[5],vertices[4]);
1328 vertices[4],vertices[7]);
1330 vertices[7],vertices[6]);
1332 vertices[5],vertices[6]);
1334 vertices[6],vertices[7]);
1336 area = Surface0+Surface1+Surface2+Surface3+Surface4+Surface5;
1339 if ( ( chose < Surface0)
1340 || ( chose > (Surface0+Surface1+Surface2+Surface3+Surface4)) )
1344 if(chose < Surface0)
1359 lambda0=alfa-lambda1;
1362 v = u+lambda0*v+lambda1*
w;
1366 if (chose < Surface0+Surface1) { ipl=0; }
1367 else if (chose < Surface0+Surface1+Surface2) { ipl=1; }
1368 else if (chose < Surface0+Surface1+Surface2+Surface3) { ipl=2; }
1372 cf = 0.5*(fDz-zp)/fDz;
1458 return (((p2-p0).
cross(p3-p1)).mag()) / 2.;
1470 return (((p2-p0).
cross(p3-p1)).dot(p0)) / 6.;
1484 for (
G4int i=0; i<4; ++i )
1488 if ( (dx1 == 0) && (dy1 == 0) ) {
continue; }
1493 if ( dx2 == 0 && dy2 == 0 ) {
continue; }
1494 G4double twist_angle = std::fabs(dy1*dx2 - dx1*dy2);
1501 twist_angle = std::acos( (dx1*dx2 + dy1*dy2)
1502 / (std::sqrt(dx1*dx1+dy1*dy1)
1503 * std::sqrt(dx2*dx2+dy2*dy2)) );
1508 message <<
"Twisted Angle is bigger than 90 degrees - " <<
GetName()
1510 <<
" Potential problem of malformed Solid !" <<
G4endl
1511 <<
" TwistANGLE = " << twist_angle
1512 <<
"*rad for lateral plane N= " << i;
1513 G4Exception(
"G4GenericTrap::ComputeIsTwisted()",
"GeomSolids1002",
1528 G4bool clockwise_order=
true;
1533 for (
G4int i=0; i<4; ++i)
1536 sum1 += vertices[i].x()*vertices[j].y() - vertices[j].x()*vertices[i].y();
1537 sum2 += vertices[i+4].x()*vertices[j+4].y()
1538 - vertices[j+4].x()*vertices[i+4].y();
1543 message <<
"Lower/upper faces defined with opposite clockwise - "
1545 G4Exception(
"G4GenericTrap::CheckOrder()",
"GeomSolids0002",
1549 if ((sum1 > 0.)||(sum2 > 0.))
1552 message <<
"Vertices must be defined in clockwise XY planes - "
1554 G4Exception(
"G4GenericTrap::CheckOrder()",
"GeomSolids1001",
1556 clockwise_order =
false;
1561 G4bool illegal_cross =
false;
1563 vertices[1],vertices[5]);
1568 vertices[3],vertices[7]);
1574 vertices[2],vertices[3]);
1579 vertices[1],vertices[2]);
1584 vertices[6],vertices[7]);
1589 vertices[5],vertices[6]);
1595 message <<
"Malformed polygone with opposite sides - " <<
GetName();
1596 G4Exception(
"G4GenericTrap::CheckOrderAndSetup()",
1599 return clockwise_order;
1608 std::vector<G4ThreeVector> oldVertices(vertices);
1610 for (
size_t i=0; i<oldVertices.size(); ++i )
1612 vertices[i] = oldVertices[oldVertices.size()-1-i];
1626 G4double dx1,dx2,xm=0.,ym=0.,a1=0.,a2=0.,b1=0.,b2=0.;
1634 a1 = (b.
x()*a.
y()-a.
x()*b.
y())/dx1;
1639 a2 = (d.
x()*c.
y()-c.
x()*d.
y())/dx2;
1642 if (stand1 && stand2)
1680 if (std::fabs(c.
y()-(a1+b1*c.
x())) >
fgkTolerance) {
return false; }
1691 xm = (a1-a2)/(b2-b1);
1692 ym = (a1*b2-a2*b1)/(b2-b1);
1698 G4double check = (xm-a.
x())*(xm-b.
x())+(ym-a.
y())*(ym-b.
y());
1700 check = (xm-c.
x())*(xm-d.
x())+(ym-c.
y())*(ym-d.
y());
1738 det = dv.
x()*v1.
y()*v2.
z()+dv.
y()*v1.
z()*v2.
x()
1739 - dv.
x()*v1.
z()*v2.
y()-dv.
y()*v1.
x()*v2.
z();
1743 temp1 = v1.
cross(v2);
1744 temp2 = (p2-p1).
cross(v2);
1745 if (temp1.
dot(temp2) < 0) {
return false; }
1749 q = ((dv).
cross(v2)).mag()/q;
1766 if ( (fromVertices[ind1] == fromVertices[ind2]) ||
1767 (fromVertices[ind2] == fromVertices[ind3]) ||
1768 (fromVertices[ind1] == fromVertices[ind3]) ) {
return 0; }
1770 std::vector<G4ThreeVector> vertices;
1771 vertices.push_back(fromVertices[ind1]);
1772 vertices.push_back(fromVertices[ind2]);
1773 vertices.push_back(fromVertices[ind3]);
1779 if ( cross.
z() > 0.0 )
1784 message <<
"Vertices in wrong order - " <<
GetName();
1785 G4Exception(
"G4GenericTrap::MakeDownFacet",
"GeomSolids0002",
1803 if ( (fromVertices[ind1] == fromVertices[ind2]) ||
1804 (fromVertices[ind2] == fromVertices[ind3]) ||
1805 (fromVertices[ind1] == fromVertices[ind3]) ) {
return nullptr; }
1807 std::vector<G4ThreeVector> vertices;
1808 vertices.push_back(fromVertices[ind1]);
1809 vertices.push_back(fromVertices[ind2]);
1810 vertices.push_back(fromVertices[ind3]);
1816 if ( cross.
z() < 0.0 )
1821 message <<
"Vertices in wrong order - " <<
GetName();
1822 G4Exception(
"G4GenericTrap::MakeUpFacet",
"GeomSolids0002",
1840 if ( (downVertex0 == downVertex1) && (upVertex0 == upVertex1) )
1845 if ( downVertex0 == downVertex1 )
1850 if ( upVertex0 == upVertex1 )
1866 std::vector<G4ThreeVector> downVertices;
1867 for (
G4int i=0; i<nv; ++i )
1873 std::vector<G4ThreeVector> upVertices;
1874 for (
G4int i=nv; i<2*nv; ++i )
1883 = (downVertices[1]-downVertices[0]).
cross(downVertices[2]-downVertices[1]);
1885 = (upVertices[1]-upVertices[0]).
cross(upVertices[2]-upVertices[1]);
1886 if ( (cross.
z() > 0.0) || (cross1.
z() > 0.0) )
1896 if (facet) { tessellatedSolid->
AddFacet( facet ); }
1898 if (facet) { tessellatedSolid->
AddFacet( facet ); }
1900 if (facet) { tessellatedSolid->
AddFacet( facet ); }
1902 if (facet) { tessellatedSolid->
AddFacet( facet ); }
1906 for (
G4int i = 0; i < nv; ++i )
1908 G4int j = (i+1) % nv;
1910 upVertices[i], upVertices[j]);
1912 if ( facet ) { tessellatedSolid->
AddFacet( facet ); }
1917 return tessellatedSolid;
1998 minVec.
y(), maxVec.
y(),
1999 minVec.
z(), maxVec.
z());
2018 size_t nVertices, nFacets;
2020 G4int subdivisions=0;
2043 Dx = 0.5*(maxVec.
x()- minVec.
y());
2044 Dy = 0.5*(maxVec.
y()- minVec.
y());
2045 if (Dy > Dx) { Dx=
Dy; }
2047 subdivisions=8*
G4int(maxTwist/(Dx*Dx*Dx)*
fDz);
2048 if (subdivisions<4) { subdivisions=4; }
2049 if (subdivisions>30) { subdivisions=30; }
2052 G4int sub4=4*subdivisions;
2053 nVertices = 8+subdivisions*4;
2054 nFacets = 6+subdivisions*4;
2065 for( i=0; i<subdivisions; ++i)
2067 for(
G4int j=0;j<4;j++)
2082 for (i=0; i<subdivisions+1; ++i)
2085 polyhedron->
AddFacet(5+is,8+is,4+is,1+is);
2086 polyhedron->
AddFacet(8+is,7+is,3+is,4+is);
2087 polyhedron->
AddFacet(7+is,6+is,2+is,3+is);
2088 polyhedron->
AddFacet(6+is,5+is,1+is,2+is);
2090 polyhedron->
AddFacet(5+sub4,6+sub4,7+sub4,8+sub4);