53 std::vector<G4TwoVector> polygon,
54 std::vector<ZSection> zsections)
57 fNz(zsections.size()),
62 fGeometryType(
"G4ExtrudedSolid")
71 std::ostringstream message;
72 message <<
"Number of polygon vertices < 3 - " << pName;
73 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
79 std::ostringstream message;
80 message <<
"Number of z-sides < 2 - " << pName;
81 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
87 if ( zsections[i].fZ > zsections[i+1].fZ )
89 std::ostringstream message;
90 message <<
"Z-sections have to be ordered by z value (z0 < z1 < z2...) - "
92 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
95 if ( std::fabs( zsections[i+1].fZ - zsections[i].fZ ) <
kCarTolerance * 0.5 )
97 std::ostringstream message;
98 message <<
"Z-sections with the same z position are not supported - "
100 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0001",
111 if ( j == fNv ) j = 0;
112 area += 0.5 * ( polygon[i].x()*polygon[j].y() - polygon[j].x()*polygon[i].y());
138 std::ostringstream message;
139 message <<
"Making facets failed - " << pName;
140 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0003",
152 std::vector<G4TwoVector> polygon,
163 fGeometryType(
"G4ExtrudedSolid")
172 std::ostringstream message;
173 message <<
"Number of polygon vertices < 3 - " << pName;
174 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
185 if ( j == fNv ) { j = 0; }
186 area += 0.5 * ( polygon[i].x()*polygon[j].y()
187 - polygon[j].x()*polygon[i].y());
214 std::ostringstream message;
215 message <<
"Making facets failed - " << pName;
216 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0003",
228 fTriangles(), fIsConvex(false), fGeometryType(
"G4ExtrudedSolid")
238 fPolygon(rhs.fPolygon), fZSections(rhs.fZSections),
239 fTriangles(rhs.fTriangles), fIsConvex(rhs.fIsConvex),
240 fGeometryType(rhs.fGeometryType), fKScales(rhs.fKScales),
241 fScale0s(rhs.fScale0s), fKOffsets(rhs.fKOffsets), fOffset0s(rhs.fOffset0s)
252 if (
this == &rhs) {
return *
this; }
298 G4double kscale = (scale2 - scale1)/(z2 - z1);
299 G4double scale0 = scale2 - kscale*(z2 - z1)/2.0;
351 return (p2 - poffset)/pscale;
361 if ( l1.x() == l2.x() )
365 G4double slope= ((l2.y() - l1.y())/(l2.x() - l1.x()));
366 G4double predy= l1.y() + slope *(p.x() - l1.x());
377 G4bool squareComp= (dy*dy < (1+slope*slope) * tol * tol);
409 return ( (p1.x() - l1.x()) * (l2.y() - l1.y())
410 - (l2.x() - l1.x()) * (p1.y() - l1.y()) )
411 * ( (p2.x() - l1.x()) * (l2.y() - l1.y())
412 - (l2.x() - l1.x()) * (p2.y() - l1.y()) ) > 0;
425 if ( ( p.x() < a.x() && p.x() < b.x() && p.x() < c.x() ) ||
426 ( p.x() > a.x() && p.x() > b.x() && p.x() > c.x() ) ||
427 ( p.y() < a.y() && p.y() < b.y() && p.y() < c.y() ) ||
428 ( p.y() > a.y() && p.y() > b.y() && p.y() > c.y() ) )
return false;
440 return inside || onEdge;
453 G4double result = (std::atan2(t1.y(), t1.x()) - std::atan2(t2.y(), t2.x()));
455 if ( result < 0 ) result += 2*
pi;
468 std::vector<G4ThreeVector> vertices;
476 = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[1]);
478 if ( cross.z() > 0.0 )
486 vertices[1] = vertices[2];
502 std::vector<G4ThreeVector> vertices;
510 = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[1]);
512 if ( cross.z() < 0.0 )
520 vertices[1] = vertices[2];
534 typedef std::pair < G4TwoVector, G4int > Vertex;
538 std::vector< Vertex > verticesToBeDone;
541 verticesToBeDone.push_back(Vertex(
fPolygon[i], i));
543 std::vector< Vertex > ears;
545 std::vector< Vertex >::iterator
c1 = verticesToBeDone.begin();
546 std::vector< Vertex >::iterator
c2 = c1+1;
547 std::vector< Vertex >::iterator
c3 = c1+2;
548 while ( verticesToBeDone.size()>2 )
570 if ( c3 == verticesToBeDone.end() ) { c3 = verticesToBeDone.begin(); }
576 angle =
GetAngle(c2->first, c3->first, c1->first);
581 if ( counter > fNv) {
582 G4Exception(
"G4ExtrudedSolid::AddGeneralPolygonFacets",
584 "Triangularisation has failed.");
590 std::vector< Vertex >::iterator it;
591 for ( it=verticesToBeDone.begin(); it != verticesToBeDone.end(); ++it )
595 if ( it == c1 || it == c2 || it == c3 ) {
continue; }
597 if (
IsPointInside(c1->first, c2->first, c3->first, it->first) )
607 if ( c3 == verticesToBeDone.end() ) { c3 = verticesToBeDone.begin(); }
623 if ( ! result ) {
return false; }
626 if ( ! result ) {
return false; }
628 std::vector<G4int> triangle(3);
629 triangle[0] = c1->second;
630 triangle[1] = c2->second;
631 triangle[2] = c3->second;
636 verticesToBeDone.erase(c2);
637 c1 = verticesToBeDone.begin();
659 if ( ! good ) {
return false; }
663 if ( ! good ) {
return false; }
665 std::vector<G4int> triangle(3);
677 if ( ! good ) {
return false; }
682 if ( ! good ) {
return false; }
684 std::vector<G4int> triangle1(3);
690 std::vector<G4int> triangle2(3);
699 if ( ! good ) {
return false; }
708 G4int j = (i+1) % fNv;
712 if ( ! good ) {
return false; }
729 G4int j = ( i + 1 ) % fNv;
730 G4int k = ( i + 2 ) % fNv;
733 G4double dphi = v2.phi() - v1.phi();
734 if ( dphi < 0. ) { dphi += 2.*
pi; }
736 if ( dphi >=
pi ) {
return false; }
787 G4int j = (i+1) % fNv;
799 std::vector< std::vector<G4int> >::const_iterator it =
fTriangles.begin();
804 fPolygon[(*it)[2]], pscaled) ) { inside =
true; }
806 }
while ( (inside ==
false) && (it !=
fTriangles.end()) );
844 if (validNorm) { *validNorm =
fIsConvex; }
863 G4int oldprc = os.precision(16);
864 os <<
"-----------------------------------------------------------\n"
865 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
866 <<
" ===================================================\n"
870 { os <<
" Convex polygon; list of vertices:" <<
G4endl; }
872 { os <<
" Concave polygon; list of vertices:" <<
G4endl; }
876 os << std::setw(5) <<
"#" << i
881 os <<
" Sections:" <<
G4endl;
905 os.precision(oldprc);
static c2_factory< G4double > c2
G4bool IsPointInside(G4TwoVector a, G4TwoVector b, G4TwoVector c, G4TwoVector p) const
G4GeometryType GetEntityType() const
void SetSolidClosed(const G4bool t)
CLHEP::Hep3Vector G4ThreeVector
std::vector< G4TwoVector > fOffset0s
std::vector< G4double > fScale0s
G4ExtrudedSolid(const G4String &pName, std::vector< G4TwoVector > polygon, std::vector< ZSection > zsections)
G4double GetMaxXExtent() const
std::vector< ZSection > fZSections
G4double GetMinXExtent() const
virtual ~G4ExtrudedSolid()
EInside Inside(const G4ThreeVector &p) const
G4double GetMaxZExtent() const
G4TwoVector ProjectPoint(const G4ThreeVector &point) const
G4bool AddGeneralPolygonFacets()
G4TwoVector GetVertex(G4int index) const
G4bool IsSameLine(G4TwoVector p, G4TwoVector l1, G4TwoVector l2) const
G4double GetAngle(G4TwoVector p0, G4TwoVector pa, G4TwoVector pb) const
G4double GetMinZExtent() const
void ComputeProjectionParameters()
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const
virtual G4double DistanceToOut(const G4ThreeVector &p) const
G4bool AddFacet(G4VFacet *aFacet)
std::vector< G4double > fKScales
std::ostream & StreamInfo(std::ostream &os) const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
G4bool IsSameLineSegment(G4TwoVector p, G4TwoVector l1, G4TwoVector l2) const
std::vector< G4TwoVector > fKOffsets
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4bool IsSameSide(G4TwoVector p1, G4TwoVector p2, G4TwoVector l1, G4TwoVector l2) const
CLHEP::Hep2Vector G4TwoVector
G4VFacet * MakeUpFacet(G4int ind1, G4int ind2, G4int ind3) const
G4GeometryType fGeometryType
G4double GetMaxYExtent() const
G4ExtrudedSolid & operator=(const G4ExtrudedSolid &rhs)
G4VFacet * MakeDownFacet(G4int ind1, G4int ind2, G4int ind3) const
G4double GetMinYExtent() const
std::vector< std::vector< G4int > > fTriangles
G4TessellatedSolid & operator=(const G4TessellatedSolid &right)
std::vector< G4TwoVector > fPolygon