40 #if !defined(G4GEOM_USE_UEXTRUDEDSOLID)
56 std::vector<G4TwoVector> polygon,
57 std::vector<ZSection> zsections)
60 fNz(zsections.size()),
65 fGeometryType(
"G4ExtrudedSolid")
74 std::ostringstream message;
75 message <<
"Number of polygon vertices < 3 - " << pName;
76 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
82 std::ostringstream message;
83 message <<
"Number of z-sides < 2 - " << pName;
84 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
90 if ( zsections[i].fZ > zsections[i+1].fZ )
92 std::ostringstream message;
93 message <<
"Z-sections have to be ordered by z value (z0 < z1 < z2...) - "
95 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
98 if ( std::fabs( zsections[i+1].fZ - zsections[i].fZ ) <
kCarTolerance * 0.5 )
100 std::ostringstream message;
101 message <<
"Z-sections with the same z position are not supported - "
103 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0001",
114 if ( j == fNv ) j = 0;
115 area += 0.5 * ( polygon[i].x()*polygon[j].y() - polygon[j].x()*polygon[i].y());
141 std::ostringstream message;
142 message <<
"Making facets failed - " << pName;
143 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0003",
155 std::vector<G4TwoVector> polygon,
166 fGeometryType(
"G4ExtrudedSolid")
175 std::ostringstream message;
176 message <<
"Number of polygon vertices < 3 - " << pName;
177 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
188 if ( j == fNv ) { j = 0; }
189 area += 0.5 * ( polygon[i].x()*polygon[j].y()
190 - polygon[j].x()*polygon[i].y());
217 std::ostringstream message;
218 message <<
"Making facets failed - " << pName;
219 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0003",
231 fTriangles(), fIsConvex(false), fGeometryType(
"G4ExtrudedSolid")
241 fPolygon(rhs.fPolygon), fZSections(rhs.fZSections),
242 fTriangles(rhs.fTriangles), fIsConvex(rhs.fIsConvex),
243 fGeometryType(rhs.fGeometryType), fKScales(rhs.fKScales),
244 fScale0s(rhs.fScale0s), fKOffsets(rhs.fKOffsets), fOffset0s(rhs.fOffset0s)
255 if (
this == &rhs) {
return *
this; }
301 G4double kscale = (scale2 - scale1)/(z2 - z1);
302 G4double scale0 = scale2 - kscale*(z2 - z1)/2.0;
354 return (p2 - poffset)/pscale;
364 if ( l1.x() == l2.x() )
368 G4double slope= ((l2.y() - l1.y())/(l2.x() - l1.x()));
369 G4double predy= l1.y() + slope *(p.x() - l1.x());
380 G4bool squareComp= (dy*dy < (1+slope*slope) * tol * tol);
412 return ( (p1.x() - l1.x()) * (l2.y() - l1.y())
413 - (l2.x() - l1.x()) * (p1.y() - l1.y()) )
414 * ( (p2.x() - l1.x()) * (l2.y() - l1.y())
415 - (l2.x() - l1.x()) * (p2.y() - l1.y()) ) > 0;
428 if ( ( p.x() < a.x() && p.x() < b.x() && p.x() < c.x() ) ||
429 ( p.x() > a.x() && p.x() > b.x() && p.x() > c.x() ) ||
430 ( p.y() < a.y() && p.y() < b.y() && p.y() < c.y() ) ||
431 ( p.y() > a.y() && p.y() > b.y() && p.y() > c.y() ) )
return false;
443 return inside || onEdge;
456 G4double result = (std::atan2(t1.y(), t1.x()) - std::atan2(t2.y(), t2.x()));
458 if ( result < 0 ) result += 2*
pi;
471 std::vector<G4ThreeVector> vertices;
479 = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[1]);
481 if ( cross.z() > 0.0 )
489 vertices[1] = vertices[2];
505 std::vector<G4ThreeVector> vertices;
513 = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[1]);
515 if ( cross.z() < 0.0 )
523 vertices[1] = vertices[2];
537 typedef std::pair < G4TwoVector, G4int > Vertex;
541 std::vector< Vertex > verticesToBeDone;
544 verticesToBeDone.push_back(Vertex(
fPolygon[i], i));
546 std::vector< Vertex > ears;
548 std::vector< Vertex >::iterator
c1 = verticesToBeDone.begin();
549 std::vector< Vertex >::iterator
c2 = c1+1;
550 std::vector< Vertex >::iterator
c3 = c1+2;
551 while ( verticesToBeDone.size()>2 )
573 if ( c3 == verticesToBeDone.end() ) { c3 = verticesToBeDone.begin(); }
579 angle =
GetAngle(c2->first, c3->first, c1->first);
584 if ( counter > fNv) {
585 G4Exception(
"G4ExtrudedSolid::AddGeneralPolygonFacets",
587 "Triangularisation has failed.");
593 std::vector< Vertex >::iterator it;
594 for ( it=verticesToBeDone.begin(); it != verticesToBeDone.end(); ++it )
598 if ( it == c1 || it == c2 || it == c3 ) {
continue; }
600 if (
IsPointInside(c1->first, c2->first, c3->first, it->first) )
610 if ( c3 == verticesToBeDone.end() ) { c3 = verticesToBeDone.begin(); }
626 if ( ! result ) {
return false; }
629 if ( ! result ) {
return false; }
631 std::vector<G4int> triangle(3);
632 triangle[0] = c1->second;
633 triangle[1] = c2->second;
634 triangle[2] = c3->second;
639 verticesToBeDone.erase(c2);
640 c1 = verticesToBeDone.begin();
662 if ( ! good ) {
return false; }
666 if ( ! good ) {
return false; }
668 std::vector<G4int> triangle(3);
680 if ( ! good ) {
return false; }
685 if ( ! good ) {
return false; }
687 std::vector<G4int> triangle1(3);
693 std::vector<G4int> triangle2(3);
702 if ( ! good ) {
return false; }
711 G4int j = (i+1) % fNv;
715 if ( ! good ) {
return false; }
732 G4int j = ( i + 1 ) % fNv;
733 G4int k = ( i + 2 ) % fNv;
736 G4double dphi = v2.phi() - v1.phi();
737 if ( dphi < 0. ) { dphi += 2.*
pi; }
739 if ( dphi >=
pi ) {
return false; }
790 G4int j = (i+1) % fNv;
802 std::vector< std::vector<G4int> >::const_iterator it =
fTriangles.begin();
807 fPolygon[(*it)[2]], pscaled) ) { inside =
true; }
809 }
while ( (inside ==
false) && (it !=
fTriangles.end()) );
847 if (validNorm) { *validNorm =
fIsConvex; }
866 G4int oldprc = os.precision(16);
867 os <<
"-----------------------------------------------------------\n"
868 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
869 <<
" ===================================================\n"
873 { os <<
" Convex polygon; list of vertices:" <<
G4endl; }
875 { os <<
" Concave polygon; list of vertices:" <<
G4endl; }
879 os << std::setw(5) <<
"#" << i
884 os <<
" Sections:" <<
G4endl;
908 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