63const G4int G4GenericTrap::fgkNofVertices = 8;
64const G4double G4GenericTrap::fgkTolerance = 1E-3;
69 const std::vector<G4TwoVector>& vertices )
87 G4String errorDescription =
"InvalidSetup in \" ";
88 errorDescription += name;
89 errorDescription +=
"\"";
93 if (
G4int(vertices.size()) != fgkNofVertices )
95 G4Exception(
"G4GenericTrap::G4GenericTrap()",
"GeomSolids0002",
103 G4Exception(
"G4GenericTrap::G4GenericTrap()",
"GeomSolids0002",
109 if(CheckOrder(vertices))
111 for (
G4int i=0; i<fgkNofVertices; ++i) {fVertices.push_back(vertices[i]);}
115 for (
G4int i=0; i <4; ++i) {fVertices.push_back(vertices[3-i]);}
116 for (
G4int i=0; i <4; ++i) {fVertices.push_back(vertices[7-i]);}
121 for (
G4int j=0; j < 2; j++)
123 for (
G4int i=1; i<4; ++i)
126 length = (fVertices[k]-fVertices[k-1]).mag();
129 std::ostringstream message;
130 message <<
"Length segment is too small." <<
G4endl
131 <<
"Distance between " << fVertices[k-1] <<
" and "
132 << fVertices[k] <<
" is only " << length <<
" mm !";
133 G4Exception(
"G4GenericTrap::G4GenericTrap()",
"GeomSolids1001",
134 JustWarning, message,
"Vertices will be collapsed.");
135 fVertices[k]=fVertices[k-1];
142 for(
G4int i=0; i<4; i++) { fTwist[i]=0.; }
143 fIsTwisted = ComputeIsTwisted();
153 if ( !fIsTwisted ) { fTessellatedSolid = CreateTessellatedSolid(); }
165 fTessellatedSolid(0),
175 for (
size_t i=0; i<4; ++i) { fTwist[i]=0.; }
183 delete fTessellatedSolid;
190 fpPolyhedron(0), fDz(rhs.fDz), fVertices(rhs.fVertices),
191 fIsTwisted(rhs.fIsTwisted), fTessellatedSolid(0),
192 fMinBBoxVector(rhs.fMinBBoxVector), fMaxBBoxVector(rhs.fMaxBBoxVector),
193 fVisSubdivisions(rhs.fVisSubdivisions),
194 fSurfaceArea(rhs.fSurfaceArea), fCubicVolume(rhs.fCubicVolume)
196 for (
size_t i=0; i<4; ++i) { fTwist[i] = rhs.fTwist[i]; }
198 if (rhs.fTessellatedSolid && !fIsTwisted )
199 { fTessellatedSolid = CreateTessellatedSolid(); }
209 if (
this == &rhs) {
return *
this; }
217 fpPolyhedron = 0; fDz = rhs.fDz; fVertices = rhs.fVertices;
218 fIsTwisted = rhs.fIsTwisted; fTessellatedSolid = 0;
219 fMinBBoxVector = rhs.fMinBBoxVector; fMaxBBoxVector = rhs.fMaxBBoxVector;
220 fVisSubdivisions = rhs.fVisSubdivisions;
221 fSurfaceArea = rhs.fSurfaceArea; fCubicVolume = rhs.fCubicVolume;
223 for (
size_t i=0; i<4; ++i) { fTwist[i] = rhs.fTwist[i]; }
225 if (rhs.fTessellatedSolid && !fIsTwisted )
226 {
delete fTessellatedSolid; fTessellatedSolid = CreateTessellatedSolid(); }
236 const std::vector<G4TwoVector>& poly)
const
243 for (
G4int i = 0; i < 4; i++)
247 cross = (p.
x()-poly[i].x())*(poly[j].y()-poly[i].y())-
248 (p.
y()-poly[i].y())*(poly[j].x()-poly[i].x());
250 len2=(poly[i]-poly[j]).mag2();
253 if(cross*cross<=len2*halfCarTolerance*halfCarTolerance)
257 if ( poly[i].y() > poly[j].y() ) { k=i; l=j; }
260 if ( poly[k].x() != poly[l].x() )
262 test = (p.
x()-poly[l].x())/(poly[k].x()-poly[l].x())
263 * (poly[k].y()-poly[l].y())+poly[l].y();
272 if( (test>=(poly[l].y()-halfCarTolerance))
273 && (test<=(poly[k].y()+halfCarTolerance)) )
282 else if (cross<0.) {
return kOutside; }
294 if ( (std::fabs(p.
x()-poly[0].x())+std::fabs(p.
y()-poly[0].y())) > halfCarTolerance )
309 if ( fTessellatedSolid )
311 return fTessellatedSolid->
Inside(p);
317 std::vector<G4TwoVector> xy;
319 if (std::fabs(p.
z()) <= fDz+halfCarTolerance)
324 for (
G4int i=0; i<4; i++)
326 xy.push_back(fVertices[i+4]+cf*( fVertices[i]-fVertices[i+4]));
329 innew=InsidePolygone(p,xy);
333 if(std::fabs(p.
z()) > fDz-halfCarTolerance) { innew=
kSurface; }
347 if ( fTessellatedSolid )
356 p0, p1, p2, r1, r2, r3, r4;
357 G4int noSurfaces = 0;
361 distz = fDz-std::fabs(p.
z());
362 if (distz < halfCarTolerance)
378 std:: vector<G4TwoVector> vertices;
380 for (
G4int i=0; i<4; i++)
382 vertices.push_back(fVertices[i+4]+cf*(fVertices[i]-fVertices[i+4]));
387 for (
G4int q=0; q<4; q++)
398 p2=
G4ThreeVector(vertices[(q+1)%4].x(),vertices[(q+1)%4].y(),p.
z());
406 p2=
G4ThreeVector(fVertices[(q+1)%4].x(),fVertices[(q+1)%4].y(),-fDz);
410 p2=
G4ThreeVector(fVertices[(q+1)%4+4].x(),fVertices[(q+1)%4+4].y(),fDz);
413 lnorm = (p1-p0).cross(p2-p0);
414 lnorm = lnorm.
unit();
415 if(zPlusSide) { lnorm=-lnorm; }
424 G4double proj=(p-p0).dot(p2-p0)/normP;
425 if(proj<0) { proj=0; }
426 if(proj>normP) { proj=normP; }
432 r1=r1+proj*(r2-r1)/normP;
433 r3=r3+proj*(r4-r3)/normP;
440 distxy=std::fabs((p0-p).dot(lnorm));
441 if ( distxy<halfCarTolerance )
447 sumnorm=sumnorm+lnorm;
461 if ( noSurfaces == 0 )
463 G4Exception(
"G4GenericTrap::SurfaceNormal(p)",
"GeomSolids1002",
468 else if ( noSurfaces == 1 ) { sumnorm = sumnorm; }
469 else { sumnorm = sumnorm.unit(); }
477 const G4int ipl )
const
482 if ( fTessellatedSolid )
499 u=fVertices[i+4]+cf*(fVertices[i]-fVertices[i+4]);
500 v=fVertices[j+4]+cf*(fVertices[j]-fVertices[j+4]);
506 if (std::fabs(distz)<halfCarTolerance)
508 p1=
G4ThreeVector(fVertices[i].x(),fVertices[i].y(),-fDz);distz=-1;}
519 if ( std::fabs(p.
z()+fDz) > halfCarTolerance )
528 lnorm=-(p1-p0).cross(p2-p0);
529 if (distz>-halfCarTolerance) { lnorm=-lnorm.
unit(); }
530 else { lnorm=lnorm.
unit(); }
539 G4double proj=(p-p0).dot(p2-p0)/normP;
540 if (proj<0) { proj=0; }
541 if (proj>normP) { proj=normP; }
547 r1=r1+proj*(r2-r1)/normP;
548 r3=r3+proj*(r4-r3)/normP;
562 const G4int ipl)
const
575 xa=fVertices[ipl].x();
576 ya=fVertices[ipl].y();
577 xb=fVertices[ipl+4].x();
578 yb=fVertices[ipl+4].y();
581 xd=fVertices[4+j].x();
582 yd=fVertices[4+j].y();
599 G4double a = (dtx*v.
y()-dty*v.
x()+(tx1*ty2-tx2*ty1)*v.
z())*v.
z();
600 G4double b = dxs*v.
y()-dys*v.
x()+(dtx*p.
y()-dty*p.
x()+ty2*xs1-ty1*xs2
601 + tx1*ys2-tx2*ys1)*v.
z();
602 G4double c=dxs*p.
y()-dys*p.
x()+xs1*ys2-xs2*ys1;
613 if (q>-halfCarTolerance)
615 if (q<halfCarTolerance)
617 if (NormalToPlane(p,ipl).
dot(v)<=0)
620 {
return kInfinity; }
626 if (std::fabs(zi)<fDz)
634 zi = (xp-x1)*(xp-x2)+(yp-y1)*(yp-y2);
635 if (zi<=halfCarTolerance) {
return q; }
643 if (a>0) { q=0.5*(-b-std::sqrt(d))/a; }
644 else { q=0.5*(-b+std::sqrt(d))/a; }
648 if (q>-halfCarTolerance)
650 if(q<halfCarTolerance)
652 if (NormalToPlane(p,ipl).
dot(v)<=0)
658 if (a>0) { q=0.5*(-b+std::sqrt(d))/a; }
659 else { q=0.5*(-b-std::sqrt(d))/a; }
660 if (q<=halfCarTolerance) {
return kInfinity; }
666 if (std::fabs(zi)<fDz)
674 zi = (xp-x1)*(xp-x2)+(yp-y1)*(yp-y2);
675 if (zi<=halfCarTolerance) {
return q; }
678 if (a>0) { q=0.5*(-b+std::sqrt(d))/a; }
679 else { q=0.5*(-b-std::sqrt(d))/a; }
683 if (q>-halfCarTolerance)
685 if(q<halfCarTolerance)
687 if (NormalToPlane(p,ipl).
dot(v)<=0)
693 if (a>0) { q=0.5*(-b-std::sqrt(d))/a; }
694 else { q=0.5*(-b+std::sqrt(d))/a; }
695 if (q<=halfCarTolerance) {
return kInfinity; }
701 if (std::fabs(zi)<fDz)
709 zi = (xp-x1)*(xp-x2)+(yp-y1)*(yp-y2);
710 if (zi<=halfCarTolerance) {
return q; }
723 if ( fTessellatedSolid )
739 dist[i]=DistToPlane(p, v, i);
745 if (std::fabs(p.
z())>fDz-halfCarTolerance)
752 dist[4] = (fDz-p.
z())/v.
z();
756 dist[4] = (-fDz-p.
z())/v.
z();
758 if (dist[4]<-halfCarTolerance)
764 if(dist[4]<halfCarTolerance)
768 if (n.dot(v)<0) { dist[4]=0.; }
769 else { dist[4]=kInfinity; }
779 if (dist[i] < distmin) { distmin = dist[i]; }
782 if (distmin<halfCarTolerance) { distmin=0.; }
794 if ( fTessellatedSolid )
801 if(safz<0) { safz=0; }
807 for (iseg=0; iseg<4; iseg++)
809 safxy = SafetyToFace(p,iseg);
810 if (safxy>safe) { safe=safxy; }
827 p1=
G4ThreeVector(fVertices[iseg].x(),fVertices[iseg].y(),-fDz);
829 norm=NormalToPlane(p,iseg);
830 safe = (p-p1).dot(norm);
853 if ( (std::fabs(xa-xc)+std::fabs(ya-yc)) < halfCarTolerance )
855 xc=fVertices[j+4].x();
856 yc=fVertices[j+4].y();
862 if ( (std::fabs(xb-xc)+std::fabs(yb-yc)) < halfCarTolerance )
869 G4double c=(xb-xa)*(yc-ya)-(xc-xa)*(yb-ya);
875 t=-(a*p.
x()+b*p.
y()+c*p.
z()+d)/t;
877 if ( (t<halfCarTolerance) && (t>-halfCarTolerance) )
902 if ( fTessellatedSolid )
904 return fTessellatedSolid->
DistanceToOut(p, v, calcNorm, validNorm, n);
911 G4bool lateral_cross =
false;
912 ESide side = kUndefined;
914 if (calcNorm) { *validNorm=
true; }
918 distmin=(-fDz-p.
z())/v.
z();
925 distmin = (fDz-p.
z())/v.
z();
928 else { distmin = kInfinity; }
935 for (
G4int ipl=0; ipl<4; ipl++)
938 xa=fVertices[ipl].x();
939 ya=fVertices[ipl].y();
940 xb=fVertices[ipl+4].x();
941 yb=fVertices[ipl+4].y();
944 xd=fVertices[4+j].x();
945 yd=fVertices[4+j].y();
947 if ( ((std::fabs(xb-xd)+std::fabs(yb-yd))<halfCarTolerance)
948 || ((std::fabs(xa-xc)+std::fabs(ya-yc))<halfCarTolerance) )
950 G4double q=DistToTriangle(p,v,ipl) ;
951 if ( (q>=0) && (q<distmin) )
972 G4double a = (dtx*v.
y()-dty*v.
x()+(tx1*ty2-tx2*ty1)*v.
z())*v.
z();
973 G4double b = dxs*v.
y()-dys*v.
x()+(dtx*p.
y()-dty*p.
x()+ty2*xs1-ty1*xs2
974 + tx1*ys2-tx2*ys1)*v.
z();
975 G4double c=dxs*p.
y()-dys*p.
x()+xs1*ys2-xs2*ys1;
985 if ((q > -halfCarTolerance) && (q < distmin))
987 if (q < halfCarTolerance)
989 if (NormalToPlane(p,ipl).
dot(v)<0.) {
continue; }
1000 if (a > 0) { q=0.5*(-b-std::sqrt(d))/a; }
1001 else { q=0.5*(-b+std::sqrt(d))/a; }
1005 if (q > -halfCarTolerance )
1009 if(q < halfCarTolerance)
1011 if (NormalToPlane(p,ipl).
dot(v)<0.)
1013 if (a > 0) { q=0.5*(-b+std::sqrt(d))/a; }
1014 else { q=0.5*(-b-std::sqrt(d))/a; }
1015 if (( q > halfCarTolerance) && (q < distmin))
1018 lateral_cross =
true;
1025 lateral_cross =
true;
1031 if (a > 0) { q=0.5*(-b+std::sqrt(d))/a; }
1032 else { q=0.5*(-b-std::sqrt(d))/a; }
1036 if ((q > -halfCarTolerance) && (q < distmin))
1038 if (q < halfCarTolerance)
1040 if (NormalToPlane(p,ipl).
dot(v)<0.)
1042 if (a > 0) { q=0.5*(-b-std::sqrt(d))/a; }
1043 else { q=0.5*(-b+std::sqrt(d))/a; }
1044 if ( ( q > halfCarTolerance) && (q < distmin) )
1047 lateral_cross =
true;
1054 lateral_cross =
true;
1068 if (v.z()>0.) { i=4; }
1069 std::vector<G4TwoVector> xy;
1070 for (
G4int j=0; j<4; j++) { xy.push_back(fVertices[i+j]); }
1074 if (InsidePolygone(pt,xy)==
kOutside)
1085 if(v.z()>0) {side=kPZ;}
1096 *n=NormalToPlane(pt,0);
1099 *n=NormalToPlane(pt,1);
1102 *n=NormalToPlane(pt,2);
1105 *n=NormalToPlane(pt,3);
1115 std::ostringstream message;
1116 G4int oldprc = message.precision(16);
1117 message <<
"Undefined side for valid surface normal to solid." <<
G4endl
1119 <<
" p.x() = " << p.
x()/mm <<
" mm" <<
G4endl
1120 <<
" p.y() = " << p.
y()/mm <<
" mm" <<
G4endl
1121 <<
" p.z() = " << p.
z()/mm <<
" mm" <<
G4endl
1122 <<
"Direction:" <<
G4endl
1123 <<
" v.x() = " << v.
x() <<
G4endl
1124 <<
" v.y() = " << v.
y() <<
G4endl
1125 <<
" v.z() = " << v.
z() <<
G4endl
1126 <<
"Proposed distance :" <<
G4endl
1127 <<
" distmin = " << distmin/mm <<
" mm";
1128 message.precision(oldprc);
1129 G4Exception(
"G4GenericTrap::DistanceToOut(p,v,..)",
1135 if (distmin<halfCarTolerance) { distmin=0.; }
1146 if ( fTessellatedSolid )
1153 if (safz<0) { safz = 0; }
1158 for (
G4int iseg=0; iseg<4; iseg++)
1160 safxy = std::fabs(SafetyToFace(p,iseg));
1161 if (safxy < safe) { safe = safxy; }
1175 if ( fTessellatedSolid )
1178 pTransform, pMin, pMax);
1187 Dx = 0.5*(maxVec.
x()- minVec.
x());
1188 Dy = 0.5*(maxVec.
y()- minVec.
y());
1295 G4bool existsAfterClip=
false;
1303 vertices=CreateRotatedVertices(pTransform);
1308 if ( (pMin!=kInfinity) || (pMax!=-kInfinity) )
1310 existsAfterClip=
true;
1331 existsAfterClip=
true;
1337 return existsAfterClip;
1360 vertices->reserve(8);
1381 G4Exception(
"G4GenericTrap::CreateRotatedVertices()",
"FatalError",
1405 G4int oldprc = os.precision(16);
1406 os <<
"-----------------------------------------------------------\n"
1407 <<
" *** Dump for solid - " <<
GetName() <<
" *** \n"
1408 <<
" =================================================== \n"
1410 <<
" half length Z: " << fDz/mm <<
" mm \n"
1411 <<
" list of vertices:\n";
1413 for (
G4int i=0; i<fgkNofVertices; ++i )
1415 os << std::setw(5) <<
"#" << i
1416 <<
" vx = " << fVertices[i].x()/mm <<
" mm"
1417 <<
" vy = " << fVertices[i].y()/mm <<
" mm" <<
G4endl;
1419 os.precision(oldprc);
1430 if ( fTessellatedSolid )
1438 G4double rand,area,chose,cf,lambda0,lambda1,alfa,beta,zp;
1441 std::vector<G4ThreeVector> vertices;
1442 for (
G4int i=0; i<4;i++)
1444 vertices.push_back(
G4ThreeVector(fVertices[i].x(),fVertices[i].y(),-fDz));
1446 for (
G4int i=4; i<8;i++)
1448 vertices.push_back(
G4ThreeVector(fVertices[i].x(),fVertices[i].y(),fDz));
1453 G4double Surface0=GetFaceSurfaceArea(vertices[0],vertices[1],
1454 vertices[2],vertices[3]);
1455 G4double Surface1=GetFaceSurfaceArea(vertices[0],vertices[1],
1456 vertices[5],vertices[4]);
1457 G4double Surface2=GetFaceSurfaceArea(vertices[3],vertices[0],
1458 vertices[4],vertices[7]);
1459 G4double Surface3=GetFaceSurfaceArea(vertices[2],vertices[3],
1460 vertices[7],vertices[6]);
1461 G4double Surface4=GetFaceSurfaceArea(vertices[2],vertices[1],
1462 vertices[5],vertices[6]);
1463 G4double Surface5=GetFaceSurfaceArea(vertices[4],vertices[5],
1464 vertices[6],vertices[7]);
1466 area = Surface0+Surface1+Surface2+Surface3+Surface4+Surface5;
1469 if ( ( chose < Surface0)
1470 || ( chose > (Surface0+Surface1+Surface2+Surface3+Surface4)) )
1474 if(chose < Surface0)
1477 u = fVertices[ipl]; v = fVertices[j];
1478 w = fVertices[(ipl+3)%4];
1483 u = fVertices[ipl+4]; v = fVertices[j+4];
1484 w = fVertices[(ipl+3)%4+4];
1489 lambda0=alfa-lambda1;
1492 v = u+lambda0*v+lambda1*w;
1496 if (chose < Surface0+Surface1) { ipl=0; }
1497 else if (chose < Surface0+Surface1+Surface2) { ipl=1; }
1498 else if (chose < Surface0+Surface1+Surface2+Surface3) { ipl=2; }
1502 cf = 0.5*(fDz-zp)/fDz;
1503 u = fVertices[ipl+4]+cf*( fVertices[ipl]-fVertices[ipl+4]);
1504 v = fVertices[j+4]+cf*(fVertices[j]-fVertices[j+4]);
1516 if(fCubicVolume != 0.) {;}
1518 return fCubicVolume;
1525 if(fSurfaceArea != 0.) {;}
1528 std::vector<G4ThreeVector> vertices;
1529 for (
G4int i=0; i<4;i++)
1531 vertices.push_back(
G4ThreeVector(fVertices[i].x(),fVertices[i].y(),-fDz));
1533 for (
G4int i=4; i<8;i++)
1535 vertices.push_back(
G4ThreeVector(fVertices[i].x(),fVertices[i].y(),fDz));
1540 G4double fSurface0=GetFaceSurfaceArea(vertices[0],vertices[1],
1541 vertices[2],vertices[3]);
1542 G4double fSurface1=GetFaceSurfaceArea(vertices[0],vertices[1],
1543 vertices[5],vertices[4]);
1544 G4double fSurface2=GetFaceSurfaceArea(vertices[3],vertices[0],
1545 vertices[4],vertices[7]);
1546 G4double fSurface3=GetFaceSurfaceArea(vertices[2],vertices[3],
1547 vertices[7],vertices[6]);
1548 G4double fSurface4=GetFaceSurfaceArea(vertices[2],vertices[1],
1549 vertices[5],vertices[6]);
1550 G4double fSurface5=GetFaceSurfaceArea(vertices[4],vertices[5],
1551 vertices[6],vertices[7]);
1557 fSurfaceArea = fSurface0+fSurface1+fSurface2
1558 + fSurface3+fSurface4+fSurface5;
1565 return fSurfaceArea;
1586 aOne = 0.5*Area.
mag();
1589 aTwo = 0.5*Area.
mag();
1596G4bool G4GenericTrap::ComputeIsTwisted()
1603 G4int nv = fgkNofVertices/2;
1605 for (
G4int i=0; i<4; i++ )
1607 dx1 = fVertices[(i+1)%nv].x()-fVertices[i].x();
1608 dy1 = fVertices[(i+1)%nv].y()-fVertices[i].y();
1609 if ( (dx1 == 0) && (dy1 == 0) ) {
continue; }
1611 dx2 = fVertices[nv+(i+1)%nv].x()-fVertices[nv+i].x();
1612 dy2 = fVertices[nv+(i+1)%nv].y()-fVertices[nv+i].y();
1614 if ( dx2 == 0 && dy2 == 0 ) {
continue; }
1615 G4double twist_angle = std::fabs(dy1*dx2 - dx1*dy2);
1616 if ( twist_angle < fgkTolerance ) {
continue; }
1618 SetTwistAngle(i,twist_angle);
1622 twist_angle = std::acos( (dx1*dx2 + dy1*dy2)
1623 / (std::sqrt(dx1*dx1+dy1*dy1)
1624 * std::sqrt(dx2*dx2+dy2*dy2)) );
1628 std::ostringstream message;
1629 message <<
"Twisted Angle is bigger than 90 degrees - " <<
GetName()
1631 <<
" Potential problem of malformed Solid !" <<
G4endl
1632 <<
" TwistANGLE = " << twist_angle
1633 <<
"*rad for lateral plane N= " << i;
1634 G4Exception(
"G4GenericTrap::ComputeIsTwisted()",
"GeomSolids1002",
1644G4bool G4GenericTrap::CheckOrder(
const std::vector<G4TwoVector>& vertices)
const
1649 G4bool clockwise_order=
true;
1654 for (
G4int i=0; i<4; i++)
1657 sum1 += vertices[i].x()*vertices[j].y() - vertices[j].x()*vertices[i].y();
1658 sum2 += vertices[i+4].x()*vertices[j+4].y()
1659 - vertices[j+4].x()*vertices[i+4].y();
1661 if (sum1*sum2 < -fgkTolerance)
1663 std::ostringstream message;
1664 message <<
"Lower/upper faces defined with opposite clockwise - "
1666 G4Exception(
"G4GenericTrap::CheckOrder()",
"GeomSolids0002",
1670 if ((sum1 > 0.)||(sum2 > 0.))
1672 std::ostringstream message;
1673 message <<
"Vertices must be defined in clockwise XY planes - "
1675 G4Exception(
"G4GenericTrap::CheckOrder()",
"GeomSolids1001",
1677 clockwise_order =
false;
1682 G4bool illegal_cross =
false;
1683 illegal_cross = IsSegCrossingZ(vertices[0],vertices[4],
1684 vertices[1],vertices[5]);
1688 illegal_cross = IsSegCrossingZ(vertices[2],vertices[6],
1689 vertices[3],vertices[7]);
1694 illegal_cross = IsSegCrossing(vertices[0],vertices[1],
1695 vertices[2],vertices[3]);
1699 illegal_cross = IsSegCrossing(vertices[0],vertices[3],
1700 vertices[1],vertices[2]);
1704 illegal_cross = IsSegCrossing(vertices[4],vertices[5],
1705 vertices[6],vertices[7]);
1709 illegal_cross = IsSegCrossing(vertices[4],vertices[7],
1710 vertices[5],vertices[6]);
1715 std::ostringstream message;
1716 message <<
"Malformed polygone with opposite sides - " <<
GetName();
1717 G4Exception(
"G4GenericTrap::CheckOrderAndSetup()",
1720 return clockwise_order;
1725void G4GenericTrap::ReorderVertices(std::vector<G4ThreeVector>& vertices)
const
1729 std::vector<G4ThreeVector> oldVertices(vertices);
1731 for (
G4int i=0; i <
G4int(oldVertices.size()); ++i )
1733 vertices[i] = oldVertices[oldVertices.size()-1-i];
1747 G4double dx1,dx2,xm=0.,ym=0.,a1=0.,a2=0.,b1=0.,b2=0.;
1751 if( std::fabs(dx1) < fgkTolerance ) { stand1 =
true; }
1752 if( std::fabs(dx2) < fgkTolerance ) { stand2 =
true; }
1755 a1 = (b.
x()*a.
y()-a.
x()*b.
y())/dx1;
1760 a2 = (d.
x()*c.
y()-c.
x()*d.
y())/dx2;
1763 if (stand1 && stand2)
1767 if (std::fabs(a.
x()-c.
x())<fgkTolerance)
1771 if ( ((c.
y()-a.
y())*(c.
y()-b.
y())<-fgkTolerance)
1772 || ((d.
y()-a.
y())*(d.
y()-b.
y())<-fgkTolerance)
1773 || ((a.
y()-c.
y())*(a.
y()-d.
y())<-fgkTolerance)
1774 || ((b.
y()-c.
y())*(b.
y()-d.
y())<-fgkTolerance) ) {
return true; }
1797 if (std::fabs(b1-b2) < fgkTolerance)
1801 if (std::fabs(c.
y()-(a1+b1*c.
x())) > fgkTolerance) {
return false; }
1805 if ( ((c.
x()-a.
x())*(c.
x()-b.
x())<-fgkTolerance)
1806 || ((d.
x()-a.
x())*(d.
x()-b.
x())<-fgkTolerance)
1807 || ((a.
x()-c.
x())*(a.
x()-d.
x())<-fgkTolerance)
1808 || ((b.
x()-c.
x())*(b.
x()-d.
x())<-fgkTolerance) ) {
return true; }
1812 xm = (a1-a2)/(b2-b1);
1813 ym = (a1*b2-a2*b1)/(b2-b1);
1819 G4double check = (xm-a.
x())*(xm-b.
x())+(ym-a.
y())*(ym-b.
y());
1820 if (check > -fgkTolerance) {
return false; }
1821 check = (xm-c.
x())*(xm-d.
x())+(ym-c.
y())*(ym-d.
y());
1822 if (check > -fgkTolerance) {
return false; }
1855 (std::fabs((p4-p3).y()) <
kCarTolerance ) ) {
return false; }
1859 det = dv.
x()*v1.
y()*v2.
z()+dv.
y()*v1.
z()*v2.
x()
1860 - dv.
x()*v1.
z()*v2.
y()-dv.
y()*v1.
x()*v2.
z();
1864 temp1 = v1.
cross(v2);
1865 temp2 = (p2-p1).cross(v2);
1866 if (temp1.
dot(temp2) < 0) {
return false; }
1870 q = ((dv).cross(v2)).mag()/q;
1880G4GenericTrap::MakeDownFacet(
const std::vector<G4ThreeVector>& fromVertices,
1887 if ( (fromVertices[ind1] == fromVertices[ind2]) ||
1888 (fromVertices[ind2] == fromVertices[ind3]) ||
1889 (fromVertices[ind1] == fromVertices[ind3]) ) {
return 0; }
1891 std::vector<G4ThreeVector> vertices;
1892 vertices.push_back(fromVertices[ind1]);
1893 vertices.push_back(fromVertices[ind2]);
1894 vertices.push_back(fromVertices[ind3]);
1898 G4ThreeVector cross=(vertices[1]-vertices[0]).cross(vertices[2]-vertices[1]);
1900 if ( cross.
z() > 0.0 )
1904 std::ostringstream message;
1905 message <<
"Vertices in wrong order - " <<
GetName();
1906 G4Exception(
"G4GenericTrap::MakeDownFacet",
"GeomSolids0002",
1916G4GenericTrap::MakeUpFacet(
const std::vector<G4ThreeVector>& fromVertices,
1924 if ( (fromVertices[ind1] == fromVertices[ind2]) ||
1925 (fromVertices[ind2] == fromVertices[ind3]) ||
1926 (fromVertices[ind1] == fromVertices[ind3]) ) {
return 0; }
1928 std::vector<G4ThreeVector> vertices;
1929 vertices.push_back(fromVertices[ind1]);
1930 vertices.push_back(fromVertices[ind2]);
1931 vertices.push_back(fromVertices[ind3]);
1935 G4ThreeVector cross=(vertices[1]-vertices[0]).cross(vertices[2]-vertices[1]);
1937 if ( cross.
z() < 0.0 )
1941 std::ostringstream message;
1942 message <<
"Vertices in wrong order - " <<
GetName();
1943 G4Exception(
"G4GenericTrap::MakeUpFacet",
"GeomSolids0002",
1953G4GenericTrap::MakeSideFacet(
const G4ThreeVector& downVertex0,
1961 if ( (downVertex0 == downVertex1) && (upVertex0 == upVertex1) )
1966 if ( downVertex0 == downVertex1 )
1971 if ( upVertex0 == upVertex1 )
1986 G4int nv = fgkNofVertices/2;
1987 std::vector<G4ThreeVector> downVertices;
1988 for (
G4int i=0; i<nv; i++ )
1991 fVertices[i].y(), -fDz));
1994 std::vector<G4ThreeVector> upVertices;
1995 for (
G4int i=nv; i<2*nv; i++ )
1998 fVertices[i].y(), fDz));
2004 = (downVertices[1]-downVertices[0]).cross(downVertices[2]-downVertices[1]);
2006 = (upVertices[1]-upVertices[0]).cross(upVertices[2]-upVertices[1]);
2007 if ( (cross.
z() > 0.0) || (cross1.
z() > 0.0) )
2009 ReorderVertices(downVertices);
2010 ReorderVertices(upVertices);
2016 facet = MakeDownFacet(downVertices, 0, 1, 2);
2017 if (facet) { tessellatedSolid->
AddFacet( facet ); }
2018 facet = MakeDownFacet(downVertices, 0, 2, 3);
2019 if (facet) { tessellatedSolid->
AddFacet( facet ); }
2020 facet = MakeUpFacet(upVertices, 0, 2, 1);
2021 if (facet) { tessellatedSolid->
AddFacet( facet ); }
2022 facet = MakeUpFacet(upVertices, 0, 3, 2);
2023 if (facet) { tessellatedSolid->
AddFacet( facet ); }
2027 for (
G4int i = 0; i < nv; ++i )
2029 G4int j = (i+1) % nv;
2030 facet = MakeSideFacet(downVertices[j], downVertices[i],
2031 upVertices[i], upVertices[j]);
2033 if ( facet ) { tessellatedSolid->
AddFacet( facet ); }
2038 return tessellatedSolid;
2043void G4GenericTrap::ComputeBBox()
2048 minX = maxX = fVertices[0].x();
2049 minY = maxY = fVertices[0].y();
2051 for (
G4int i=1; i< fgkNofVertices; i++)
2053 if (minX>fVertices[i].x()) { minX=fVertices[i].x(); }
2054 if (maxX<fVertices[i].x()) { maxX=fVertices[i].x(); }
2055 if (minY>fVertices[i].y()) { minY=fVertices[i].y(); }
2056 if (maxY<fVertices[i].y()) { maxY=fVertices[i].y(); }
2068 if ( fTessellatedSolid )
2090 if ( fTessellatedSolid )
2106 if ( fTessellatedSolid )
2115 Dx = 0.5*(maxVec.
x()- minVec.
x());
2116 Dy = 0.5*(maxVec.
y()- minVec.
y());
2127 if ( fTessellatedSolid )
2137 size_t nVertices, nFacets;
2139 G4int subdivisions=0;
2162 Dx = 0.5*(maxVec.
x()- minVec.
y());
2163 Dy = 0.5*(maxVec.
y()- minVec.
y());
2164 if (Dy > Dx) { Dx=Dy; }
2166 subdivisions=8*
G4int(maxTwist/(Dx*Dx*Dx)*fDz);
2167 if (subdivisions<4) { subdivisions=4; }
2168 if (subdivisions>30) { subdivisions=30; }
2171 G4int sub4=4*subdivisions;
2172 nVertices = 8+subdivisions*4;
2173 nFacets = 6+subdivisions*4;
2182 fVertices[i].y(),-fDz));
2184 for( i=0;i<subdivisions;i++)
2186 for(
G4int j=0;j<4;j++)
2188 G4TwoVector u=fVertices[j]+cf*(i+1)*( fVertices[j+4]-fVertices[j]);
2195 fVertices[i].y(),fDz));
2201 for (i=0;i<subdivisions+1;i++)
2204 polyhedron->
AddFacet(5+is,8+is,4+is,1+is);
2205 polyhedron->
AddFacet(8+is,7+is,3+is,4+is);
2206 polyhedron->
AddFacet(7+is,6+is,2+is,3+is);
2207 polyhedron->
AddFacet(6+is,5+is,1+is,2+is);
2209 polyhedron->
AddFacet(5+sub4,6+sub4,7+sub4,8+sub4);
2222 if ( fTessellatedSolid )
2233 Dx = 0.5*(maxVec.
x()- minVec.
y());
2234 Dy = 0.5*(maxVec.
y()- minVec.
y());
CLHEP::Hep3Vector G4ThreeVector
std::vector< G4ThreeVector > G4ThreeVectorList
Hep3Vector cross(const Hep3Vector &) const
double dot(const Hep3Vector &) const
G4Polyhedron * CreatePolyhedron() const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4GenericTrap & operator=(const G4GenericTrap &rhs)
G4double GetCubicVolume()
G4double GetSurfaceArea()
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const
G4ThreeVector GetPointOnSurface() const
G4double GetTwistAngle(G4int index) const
G4Polyhedron * GetPolyhedron() const
std::ostream & StreamInfo(std::ostream &os) const
G4VisExtent GetExtent() const
G4NURBS * CreateNURBS() const
EInside Inside(const G4ThreeVector &p) const
G4GeometryType GetEntityType() const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
G4int GetVisSubdivisions() const
void DescribeYourselfTo(G4VGraphicsScene &scene) const
G4GenericTrap(const G4String &name, G4double halfZ, const std::vector< G4TwoVector > &vertices)
G4Polyhedron * fpPolyhedron
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
void AddVertex(const G4ThreeVector v)
void AddFacet(const G4int iv1, const G4int iv2, const G4int iv3, const G4int iv4=0)
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
virtual G4Polyhedron * GetPolyhedron() const
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4bool AddFacet(G4VFacet *aFacet)
virtual G4double DistanceToOut(const G4ThreeVector &p) const
virtual G4NURBS * CreateNURBS() const
virtual void DescribeYourselfTo(G4VGraphicsScene &scene) const
void SetSolidClosed(const G4bool t)
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
virtual G4VisExtent GetExtent() const
virtual G4Polyhedron * CreatePolyhedron() const
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
virtual EInside Inside(const G4ThreeVector &p) const
virtual G4ThreeVector GetPointOnSurface() const
virtual void AddSolid(const G4Box &)=0
void ClipBetweenSections(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
G4VSolid & operator=(const G4VSolid &rhs)
virtual G4double GetCubicVolume()
void ClipCrossSection(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
virtual G4double GetSurfaceArea()
G4double GetMinExtent(const EAxis pAxis) const
G4bool IsYLimited() const
G4double GetMinZExtent() const
G4bool IsXLimited() const
G4double GetMaxExtent(const EAxis pAxis) const
G4double GetMaxYExtent() const
G4double GetMaxZExtent() const
G4double GetMinYExtent() const
G4double GetMinXExtent() const
G4bool IsZLimited() const
G4double GetMaxXExtent() const
static G4int GetNumberOfRotationSteps()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)