40 #if !defined(G4GEOM_USE_UEXTRUDEDSOLID) 57 std::vector<G4TwoVector> polygon,
58 std::vector<ZSection> zsections)
61 fNz(zsections.size()),
66 fGeometryType(
"G4ExtrudedSolid")
75 std::ostringstream message;
76 message <<
"Number of polygon vertices < 3 - " << pName;
77 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
83 std::ostringstream message;
84 message <<
"Number of z-sides < 2 - " << pName;
85 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
91 if ( zsections[i].fZ > zsections[i+1].fZ )
93 std::ostringstream message;
94 message <<
"Z-sections have to be ordered by z value (z0 < z1 < z2...) - " 96 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
101 std::ostringstream message;
102 message <<
"Z-sections with the same z position are not supported - " 104 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0001",
115 if ( j == fNv ) j = 0;
116 area += 0.5 * ( polygon[i].x()*polygon[j].y() - polygon[j].x()*polygon[i].y());
142 std::ostringstream message;
143 message <<
"Making facets failed - " << pName;
144 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0003",
156 std::vector<G4TwoVector> polygon,
176 std::ostringstream message;
177 message <<
"Number of polygon vertices < 3 - " << pName;
178 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0002",
189 if ( j == fNv ) { j = 0; }
190 area += 0.5 * ( polygon[i].x()*polygon[j].y()
191 - polygon[j].x()*polygon[i].y());
218 std::ostringstream message;
219 message <<
"Making facets failed - " << pName;
220 G4Exception(
"G4ExtrudedSolid::G4ExtrudedSolid()",
"GeomSolids0003",
256 if (
this == &rhs) {
return *
this; }
302 G4double kscale = (scale2 - scale1)/(z2 - z1);
303 G4double scale0 = scale2 - kscale*(z2 - z1)/2.0;
356 return (p2 - poffset)/pscale;
366 if ( l1.
x() == l2.
x() )
381 G4bool squareComp= (dy*dy < (1+slope*slope)
414 return ( (p1.
x() - l1.
x()) * (l2.
y() - l1.
y())
415 - (l2.
x() - l1.
x()) * (p1.
y() - l1.
y()) )
416 * ( (p2.
x() - l1.
x()) * (l2.
y() - l1.
y())
417 - (l2.
x() - l1.
x()) * (p2.
y() - l1.
y()) ) > 0;
430 if ( ( p.
x() < a.
x() && p.
x() < b.
x() && p.
x() < c.
x() ) ||
431 ( p.
x() > a.
x() && p.
x() > b.
x() && p.
x() > c.
x() ) ||
432 ( p.
y() < a.
y() && p.
y() < b.
y() && p.
y() < c.
y() ) ||
433 ( p.
y() > a.
y() && p.
y() > b.
y() && p.
y() > c.
y() ) )
return false;
445 return inside || onEdge;
458 G4double result = (std::atan2(t1.
y(), t1.
x()) - std::atan2(t2.
y(), t2.
x()));
460 if ( result < 0 ) result += 2*
pi;
473 std::vector<G4ThreeVector> vertices;
481 = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[1]);
483 if ( cross.
z() > 0.0 )
491 vertices[1] = vertices[2];
507 std::vector<G4ThreeVector> vertices;
515 = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[1]);
517 if ( cross.
z() < 0.0 )
525 vertices[1] = vertices[2];
539 typedef std::pair < G4TwoVector, G4int > Vertex;
541 static const G4double kAngTolerance =
546 std::vector< Vertex > verticesToBeDone;
549 verticesToBeDone.push_back(Vertex(
fPolygon[i], i));
551 std::vector< Vertex > ears;
553 std::vector< Vertex >::iterator
c1 = verticesToBeDone.begin();
554 std::vector< Vertex >::iterator
c2 = c1+1;
555 std::vector< Vertex >::iterator
c3 = c1+2;
556 while ( verticesToBeDone.size()>2 )
573 while ( angle >= (
pi-kAngTolerance) )
582 if ( c3 == verticesToBeDone.end() ) { c3 = verticesToBeDone.begin(); }
588 angle =
GetAngle(c2->first, c3->first, c1->first);
593 if ( counter > fNv) {
594 G4Exception(
"G4ExtrudedSolid::AddGeneralPolygonFacets",
596 "Triangularisation has failed.");
602 std::vector< Vertex >::iterator it;
603 for ( it=verticesToBeDone.begin(); it != verticesToBeDone.end(); ++it )
607 if ( it == c1 || it == c2 || it == c3 ) {
continue; }
609 if (
IsPointInside(c1->first, c2->first, c3->first, it->first) )
619 if ( c3 == verticesToBeDone.end() ) { c3 = verticesToBeDone.begin(); }
635 if ( ! result ) {
return false; }
638 if ( ! result ) {
return false; }
640 std::vector<G4int> triangle(3);
641 triangle[0] = c1->second;
642 triangle[1] = c2->second;
643 triangle[2] = c3->second;
648 verticesToBeDone.erase(c2);
649 c1 = verticesToBeDone.begin();
671 if ( ! good ) {
return false; }
675 if ( ! good ) {
return false; }
677 std::vector<G4int> triangle(3);
689 if ( ! good ) {
return false; }
694 if ( ! good ) {
return false; }
696 std::vector<G4int> triangle1(3);
702 std::vector<G4int> triangle2(3);
711 if ( ! good ) {
return false; }
720 G4int j = (i+1) % fNv;
724 if ( ! good ) {
return false; }
741 G4int j = ( i + 1 ) % fNv;
742 G4int k = ( i + 2 ) % fNv;
746 if ( dphi < 0. ) { dphi += 2.*
pi; }
748 if ( dphi >=
pi ) {
return false; }
799 G4int j = (i+1) % fNv;
811 std::vector< std::vector<G4int> >::const_iterator it =
fTriangles.begin();
816 fPolygon[(*it)[2]], pscaled) ) { inside =
true; }
818 }
while ( (inside ==
false) && (it !=
fTriangles.end()) );
856 if (validNorm) { *validNorm =
fIsConvex; }
875 G4int oldprc = os.precision(16);
876 os <<
"-----------------------------------------------------------\n" 877 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n" 878 <<
" ===================================================\n" 882 { os <<
" Convex polygon; list of vertices:" <<
G4endl; }
884 { os <<
" Concave polygon; list of vertices:" <<
G4endl; }
888 os << std::setw(5) <<
"#" << i
893 os <<
" Sections:" <<
G4endl;
917 os.precision(oldprc);
G4double GetMinYExtent() const
G4double GetMinXExtent() const
void SetSolidClosed(const G4bool t)
G4VFacet * MakeUpFacet(G4int ind1, G4int ind2, G4int ind3) const
G4bool IsSameLine(G4TwoVector p, G4TwoVector l1, G4TwoVector l2) const
CLHEP::Hep3Vector G4ThreeVector
virtual G4double DistanceToOut(const G4ThreeVector &p) const
std::vector< G4TwoVector > fOffset0s
std::vector< G4double > fScale0s
G4double GetMaxZExtent() const
G4ExtrudedSolid(const G4String &pName, std::vector< G4TwoVector > polygon, std::vector< ZSection > zsections)
G4double GetMaxYExtent() const
std::vector< ZSection > fZSections
static G4double angle[DIM]
G4GeometryType GetEntityType() const
virtual ~G4ExtrudedSolid()
G4bool AddGeneralPolygonFacets()
G4double kCarToleranceHalf
G4TwoVector ProjectPoint(const G4ThreeVector &point) const
G4double GetAngle(G4TwoVector p0, G4TwoVector pa, G4TwoVector pb) const
std::ostream & StreamInfo(std::ostream &os) const
void ComputeProjectionParameters()
G4double GetMaxXExtent() const
G4double GetMinZExtent() const
G4bool IsSameSide(G4TwoVector p1, G4TwoVector p2, G4TwoVector l1, G4TwoVector l2) const
G4bool AddFacet(G4VFacet *aFacet)
G4bool IsPointInside(G4TwoVector a, G4TwoVector b, G4TwoVector c, G4TwoVector p) const
G4double GetAngularTolerance() const
std::vector< G4double > fKScales
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
EInside Inside(const G4ThreeVector &p) const
G4VFacet * MakeDownFacet(G4int ind1, G4int ind2, G4int ind3) const
std::vector< G4TwoVector > fKOffsets
G4TwoVector GetVertex(G4int index) const
G4GeometryType fGeometryType
G4ExtrudedSolid & operator=(const G4ExtrudedSolid &rhs)
static G4GeometryTolerance * GetInstance()
std::vector< std::vector< G4int > > fTriangles
G4TessellatedSolid & operator=(const G4TessellatedSolid &right)
G4bool IsSameLineSegment(G4TwoVector p, G4TwoVector l1, G4TwoVector l2) const
std::vector< G4TwoVector > fPolygon