46 #if !defined(G4GEOM_USE_UEXTRUDEDSOLID)
67 const std::vector<G4TwoVector>& polygon,
68 const std::vector<ZSection>& zsections)
71 fNz(zsections.size()),
73 fGeometryType(
"G4ExtrudedSolid"),
83 message <<
"Number of vertices in polygon < 3 - " << pName;
84 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
91 message <<
"Number of z-sides < 2 - " << pName;
92 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
98 if ( zsections[i].fZ > zsections[i+1].fZ )
101 message <<
"Z-sections have to be ordered by z value (z0 < z1 < z2...) - "
103 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
109 message <<
"Z-sections with the same z position are not supported - "
111 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0001",
122 std::vector<G4int> removedVertices;
125 if (removedVertices.size() != 0)
127 G4int nremoved = removedVertices.size();
129 message <<
"The following "<< nremoved
130 <<
" vertices have been removed from polygon in " << pName
131 <<
"\nas collinear or coincident with other vertices: "
132 << removedVertices[0];
133 for (
G4int i=1; i<nremoved; ++i) message <<
", " << removedVertices[i];
134 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids1001",
142 message <<
"Number of vertices in polygon after removal < 3 - " << pName;
143 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
167 message <<
"Making facets failed - " << pName;
168 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0003",
190 const std::vector<G4TwoVector>& polygon,
197 fGeometryType(
"G4ExtrudedSolid")
206 message <<
"Number of vertices in polygon < 3 - " << pName;
207 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
217 std::vector<G4int> removedVertices;
220 if (removedVertices.size() != 0)
222 G4int nremoved = removedVertices.size();
224 message <<
"The following "<< nremoved
225 <<
" vertices have been removed from polygon in " << pName
226 <<
"\nas collinear or coincident with other vertices: "
227 << removedVertices[0];
228 for (
G4int i=1; i<nremoved; ++i) message <<
", " << removedVertices[i];
229 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids1001",
237 message <<
"Number of vertices in polygon after removal < 3 - " << pName;
238 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
263 message <<
"Making facets failed - " << pName;
264 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0003",
273 if ((scale1 == 1) && (scale2 == 1)
285 fGeometryType(
"G4ExtrudedSolid")
295 fPolygon(rhs.fPolygon), fZSections(rhs.fZSections),
296 fTriangles(rhs.fTriangles), fIsConvex(rhs.fIsConvex),
297 fGeometryType(rhs.fGeometryType),
298 fSolidType(rhs.fSolidType), fPlanes(rhs.fPlanes),
299 fLines(rhs.fLines), fLengths(rhs.fLengths),
300 fKScales(rhs.fKScales), fScale0s(rhs.fScale0s),
301 fKOffsets(rhs.fKOffsets), fOffset0s(rhs.fOffset0s)
311 if (
this == &rhs) {
return *
this; }
359 G4double kscale = (scale2 - scale1)/(z2 - z1);
360 G4double scale0 = scale2 - kscale*(z2 -
z1)/2.0;
379 for (
G4int i=0,
k=Nv-1; i<Nv;
k=i++)
393 for (
G4int i=0,
k=Nv-1; i<Nv;
k=i++)
450 return (p2 - poffset)/pscale;
461 if ( l1.
x() == l2.
x() )
476 G4bool squareComp = (dy*dy < (1+slope*slope)
512 return ( (p1.
x() - l1.
x()) * (l2.
y() - l1.
y())
513 - (l2.
x() - l1.
x()) * (p1.
y() - l1.
y()) )
514 * ( (p2.
x() - l1.
x()) * (l2.
y() - l1.
y())
515 - (l2.
x() - l1.
x()) * (p2.
y() - l1.
y()) ) > 0;
530 if ( ( p.
x() < a.
x() && p.
x() < b.
x() && p.
x() < c.
x() ) ||
531 ( p.
x() > a.
x() && p.
x() > b.
x() && p.
x() > c.
x() ) ||
532 ( p.
y() < a.
y() && p.
y() < b.
y() && p.
y() < c.
y() ) ||
533 ( p.
y() > a.
y() && p.
y() > b.
y() && p.
y() > c.
y() ) )
return false;
545 return inside || onEdge;
560 G4double result = (std::atan2(t1.
y(), t1.
x()) - std::atan2(t2.
y(), t2.
x()));
562 if ( result < 0 ) result += 2*
pi;
575 std::vector<G4ThreeVector> vertices;
583 = (vertices[1]-vertices[0]).
cross(vertices[2]-vertices[1]);
585 if ( cross.
z() > 0.0 )
593 vertices[1] = vertices[2];
609 std::vector<G4ThreeVector> vertices;
617 = (vertices[1]-vertices[0]).
cross(vertices[2]-vertices[1]);
619 if ( cross.
z() < 0.0 )
627 vertices[1] = vertices[2];
641 typedef std::pair < G4TwoVector, G4int > Vertex;
643 static const G4double kAngTolerance =
648 std::vector< Vertex > verticesToBeDone;
651 verticesToBeDone.push_back(Vertex(
fPolygon[i], i));
653 std::vector< Vertex > ears;
655 std::vector< Vertex >::iterator
c1 = verticesToBeDone.begin();
656 std::vector< Vertex >::iterator
c2 = c1+1;
657 std::vector< Vertex >::iterator c3 = c1+2;
658 while ( verticesToBeDone.size()>2 )
675 while ( angle >= (
pi-kAngTolerance) )
684 if ( c3 == verticesToBeDone.end() ) { c3 = verticesToBeDone.begin(); }
690 angle =
GetAngle(c2->first, c3->first, c1->first);
697 G4Exception(
"G4ExtrudedSolid::AddGeneralPolygonFacets",
699 "Triangularisation has failed.");
705 for (
auto it=verticesToBeDone.cbegin();
it!=verticesToBeDone.cend(); ++
it )
709 if (
it == c1 ||
it == c2 ||
it == c3 ) {
continue; }
721 if ( c3 == verticesToBeDone.end() ) { c3 = verticesToBeDone.begin(); }
737 if ( ! result ) {
return false; }
740 if ( ! result ) {
return false; }
742 std::vector<G4int> triangle(3);
743 triangle[0] = c1->second;
744 triangle[1] = c2->second;
745 triangle[2] = c3->second;
750 verticesToBeDone.erase(c2);
751 c1 = verticesToBeDone.begin();
773 if ( ! good ) {
return false; }
779 if ( ! good ) {
return false; }
781 std::vector<G4int> triangle(3);
793 if ( ! good ) {
return false; }
800 if ( ! good ) {
return false; }
802 std::vector<G4int> triangle1(3);
808 std::vector<G4int> triangle2(3);
817 if ( ! good ) {
return false; }
822 for (
G4int iz = 0; iz <
fNz-1; ++iz )
826 G4int j = (i+1) % fNv;
830 if ( ! good ) {
return false; }
867 for (
G4int i=0; i<np; ++i)
870 if (dd > dist) { dist = dd; }
920 G4int j = (i+1) % fNv;
937 fPolygon[(*
it)[2]], pscaled) ) { inside =
true; }
939 }
while ( (inside ==
false) && (
it !=
fTriangles.cend()) );
1011 if (ix*ix + iy*iy > sqrCarToleranceHalf)
continue;
1017 if (kx*kx + ky*ky > sqrCarToleranceHalf)
continue;
1022 if (dd*dd > sqrCarToleranceHalf)
continue;
1042 else if (nsurf != 0)
1052 G4int oldprc = message.precision(16);
1053 message <<
"Point p is not on surface (!?) of solid: "
1055 message <<
"Position:\n";
1056 message <<
" p.x() = " << p.
x()/
mm <<
" mm\n";
1057 message <<
" p.y() = " << p.
y()/
mm <<
" mm\n";
1058 message <<
" p.z() = " << p.
z()/
mm <<
" mm";
1059 G4cout.precision(oldprc) ;
1060 G4Exception(
"G4TesselatedSolid::SurfaceNormal(p)",
"GeomSolids1002",
1096 if (tmp < dd) { dd =
tmp; iside = i; }
1103 if (tmp < dd) { dd =
tmp; iside = i; }
1109 if (tmp < dd) { dd =
tmp; iside = i; }
1122 if (
std::max(dz0,dz1) > 0) iregion = 1;
1125 if (!in) iregion += 2;
1133 if (ddz0 <= ddz1 && ddz0 <= dd)
return G4ThreeVector(0, 0,-1);
1134 if (ddz1 <= ddz0 && ddz1 <= dd)
return G4ThreeVector(0, 0, 1);
1148 if (dzmax*dzmax > dd)
return G4ThreeVector(0,0,(dz0 > dz1) ? -1 : 1);
1176 G4double ddz = (invz < 0) ? dz : -dz;
1183 G4double txmin = tzmin, txmax = tzmax;
1184 for (
G4int i=0; i<np; ++i)
1192 if (txmin < tmp) { txmin =
tmp; }
1197 if (txmax > tmp) { txmax =
tmp; }
1203 G4double tmin = txmin, tmax = txmax;
1227 for (
G4int i=0; i<np; ++i)
1230 if (dd > dist) dist = dd;
1232 return (dist > 0) ? dist : 0.;
1240 return (distz > 0) ? distz : 0;
1246 if (distz > 0) dd += distz*distz;
1247 return std::sqrt(dd);
1264 G4bool getnorm = calcNorm;
1265 if (getnorm) *validNorm =
true;
1271 if (getnorm) n->
set(0,0,-1);
1276 if (getnorm) n->
set(0,0,1);
1291 G4int iside = (vz < 0) ? -4 : -2;
1296 for (
G4int i=0; i<np; ++i)
1308 if (tmax > tmp) { tmax =
tmp; iside = i; }
1317 { n->
set(0, 0, iside + 3); }
1333 if (validNorm) { *validNorm =
fIsConvex; }
1348 for (
G4int i=0; i<np; ++i)
1351 if (dd > dist) dist = dd;
1353 return (dist < 0) ? -dist : 0.;
1359 if (distz >= 0 || (!in))
return 0;
1380 if (x < xmin0) xmin0 =
x;
1381 if (x > xmax0) xmax0 =
x;
1383 if (y < ymin0) ymin0 =
y;
1384 if (y > ymax0) ymax0 =
y;
1391 for (
G4int i=0; i<nsect; ++i)
1397 xmin =
std::min(xmin,xmin0*scale+dx);
1398 xmax =
std::max(xmax,xmax0*scale+dx);
1399 ymin =
std::min(ymin,ymin0*scale+dy);
1400 ymax =
std::max(ymax,ymax0*scale+dy);
1406 pMin.
set(xmin,ymin,zmin);
1407 pMax.
set(xmax,ymax,zmax);
1411 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
1414 message <<
"Bad bounding box (min >= max) for solid: "
1416 <<
"\npMin = " << pMin
1417 <<
"\npMax = " <<
pMax;
1440 #ifdef G4BBOX_EXTENT
1445 return exist = (pMin <
pMax) ?
true :
false;
1460 message <<
"Triangulation of the base polygon has failed for solid: "
1462 <<
"\nExtent has been calculated using boundary box";
1470 std::vector<const G4ThreeVectorList *> polygons;
1471 polygons.resize(nsect);
1477 G4int ntria = triangles.size()/3;
1478 for (
G4int i=0; i<ntria; ++i)
1490 G4ThreeVectorList::iterator iter = ptr->begin();
1507 if (!benv.
CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax))
continue;
1508 if (emin < pMin) pMin =
emin;
1509 if (emax > pMax) pMax =
emax;
1510 if (eminlim > pMin && emaxlim < pMax)
break;
1513 for (
G4int k=0;
k<nsect; ++
k) {
delete polygons[
k]; polygons[
k]=0;}
1514 return (pMin < pMax);
1521 G4int oldprc = os.precision(16);
1522 os <<
"-----------------------------------------------------------\n"
1523 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
1524 <<
" ===================================================\n"
1528 { os <<
" Convex polygon; list of vertices:" <<
G4endl; }
1530 { os <<
" Concave polygon; list of vertices:" <<
G4endl; }
1534 os << std::setw(5) <<
"#" << i
1539 os <<
" Sections:" <<
G4endl;
1564 os.precision(oldprc);