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 )
568 while ( angle >=
pi )
577 if ( c3 == verticesToBeDone.end() ) { c3 = verticesToBeDone.begin(); }
583 angle =
GetAngle(c2->first, c3->first, c1->first);
588 if ( counter > fNv) {
589 G4Exception(
"G4ExtrudedSolid::AddGeneralPolygonFacets",
591 "Triangularisation has failed.");
597 std::vector< Vertex >::iterator it;
598 for ( it=verticesToBeDone.begin(); it != verticesToBeDone.end(); ++it )
602 if ( it == c1 || it == c2 || it == c3 ) {
continue; }
604 if (
IsPointInside(c1->first, c2->first, c3->first, it->first) )
614 if ( c3 == verticesToBeDone.end() ) { c3 = verticesToBeDone.begin(); }
630 if ( ! result ) {
return false; }
633 if ( ! result ) {
return false; }
635 std::vector<G4int> triangle(3);
636 triangle[0] = c1->second;
637 triangle[1] = c2->second;
638 triangle[2] = c3->second;
643 verticesToBeDone.erase(c2);
644 c1 = verticesToBeDone.begin();
666 if ( ! good ) {
return false; }
670 if ( ! good ) {
return false; }
672 std::vector<G4int> triangle(3);
684 if ( ! good ) {
return false; }
689 if ( ! good ) {
return false; }
691 std::vector<G4int> triangle1(3);
697 std::vector<G4int> triangle2(3);
706 if ( ! good ) {
return false; }
715 G4int j = (i+1) % fNv;
719 if ( ! good ) {
return false; }
736 G4int j = ( i + 1 ) % fNv;
737 G4int k = ( i + 2 ) % fNv;
740 G4double dphi = v2.phi() - v1.phi();
741 if ( dphi < 0. ) { dphi += 2.*
pi; }
743 if ( dphi >=
pi ) {
return false; }
794 G4int j = (i+1) % fNv;
806 std::vector< std::vector<G4int> >::const_iterator it =
fTriangles.begin();
811 fPolygon[(*it)[2]], pscaled) ) { inside =
true; }
813 }
while ( (inside ==
false) && (it !=
fTriangles.end()) );
851 if (validNorm) { *validNorm =
fIsConvex; }
870 G4int oldprc = os.precision(16);
871 os <<
"-----------------------------------------------------------\n"
872 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
873 <<
" ===================================================\n"
877 { os <<
" Convex polygon; list of vertices:" <<
G4endl; }
879 { os <<
" Concave polygon; list of vertices:" <<
G4endl; }
883 os << std::setw(5) <<
"#" << i
888 os <<
" Sections:" <<
G4endl;
912 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