29 std::vector<UVector2> polygon,
30 std::vector<ZSection> zsections)
36 fGeometryType(
"UExtrudedSolid")
47 std::vector<UVector2> polygon,
double dz,
56 fGeometryType(
"UExtrudedSolid")
61 Initialise(polygon, dz, off1, scale1, off2, scale2);
68 fTriangles(), fIsConvex(false), fGeometryType(
"UExtrudedSolid")
78 fPolygon(rhs.fPolygon), fZSections(rhs.fZSections),
79 fTriangles(rhs.fTriangles), fIsConvex(rhs.fIsConvex),
80 fGeometryType(rhs.fGeometryType), fKScales(rhs.fKScales),
81 fScale0s(rhs.fScale0s), fKOffsets(rhs.fKOffsets), fOffset0s(rhs.fOffset0s)
128 std::vector<ZSection>& zsections)
130 fNv = polygon.size();
131 fNz = zsections.size();
136 std::ostringstream message;
137 message <<
"Number of polygon vertices < 3 - " <<
GetName().c_str();
144 std::ostringstream message;
145 message <<
"Number of z-sides < 2 - " <<
GetName().c_str();
150 for (
int i = 0; i <
fNz - 1; ++i)
152 if (zsections[i].fZ > zsections[i + 1].fZ)
154 std::ostringstream message;
155 message <<
"Z-sections have to be ordered by z value (z0 < z1 < z2...) - "
162 std::ostringstream message;
163 message <<
"Z-sections with the same z position are not supported - "
174 for (
int i = 0; i <
fNv; ++i)
178 area += 0.5 * (polygon[i].x * polygon[j].y - polygon[j].x * polygon[i].y);
186 for (
int i = 0; i <
fNv; ++i)
196 "Polygon vertices defined anti-clockwise, reverting polygon");
197 for (
int i = 0; i <
fNv; ++i)
199 fPolygon.push_back(polygon[fNv - i - 1]);
206 for (
int i = 0; i <
fNz; ++i)
215 std::ostringstream message;
216 message <<
"Making facets failed - " <<
GetName().c_str();
232 fNv = polygon.size();
238 std::ostringstream message;
239 message <<
"Number of polygon vertices < 3 - " <<
GetName().c_str();
248 for (
int i = 0; i <
fNv; ++i)
255 area += 0.5 * (polygon[i].x * polygon[j].y
256 - polygon[j].x * polygon[i].y);
264 for (
int i = 0; i <
fNv; ++i)
274 "Polygon vertices defined anti-clockwise, reverting polygon");
275 for (
int i = 0; i <
fNv; ++i)
277 fPolygon.push_back(polygon[fNv - i - 1]);
289 std::ostringstream message;
290 message <<
"Making facets failed - " <<
GetName().c_str();
320 double kscale = (scale2 - scale1) / (z2 - z1);
321 double scale0 = scale2 - kscale * (z2 - z1) / 2.0;
322 UVector2 koff = (off2 - off1) / (z2 - z1);
323 UVector2 off0 = off2 - koff * (z2 - z1) / 2.0;
372 return (p2 - poffset) / pscale;
386 double slope = ((l2.
y - l1.
y) / (l2.
x - l1.
x));
387 double predy = l1.
y + slope * (p.
x - l1.
x);
388 double dy = p.
y - predy;
398 bool squareComp = (dy * dy < (1 + slope * slope) * tol * tol);
430 return ((p1.
x - l1.
x) * (l2.
y - l1.
y)
431 - (l2.
x - l1.
x) * (p1.
y - l1.
y))
432 * ((p2.
x - l1.
x) * (l2.
y - l1.
y)
433 - (l2.
x - l1.
x) * (p2.
y - l1.
y)) > 0;
446 if ((p.
x < a.
x && p.
x < b.
x && p.
x < c.
x) ||
447 (p.
x > a.
x && p.
x > b.
x && p.
x > c.
x) ||
448 (p.
y < a.
y && p.
y < b.
y && p.
y < c.
y) ||
449 (p.
y > a.
y && p.
y > b.
y && p.
y > c.
y))
return false;
461 return inside || onEdge;
474 double result = (std::atan2(t1.
y, t1.
x) - std::atan2(t2.
y, t2.
x));
489 std::vector<UVector3> vertices;
497 = (vertices[1] - vertices[0]).Cross(vertices[2] - vertices[1]);
504 vertices[1] = vertices[2];
520 std::vector<UVector3> vertices;
528 = (vertices[1] - vertices[0]).Cross(vertices[2] - vertices[1]);
535 vertices[1] = vertices[2];
549 typedef std::pair < UVector2, int > Vertex;
553 std::vector< Vertex > verticesToBeDone;
554 for (
int i = 0; i <
fNv; ++i)
556 verticesToBeDone.push_back(Vertex(
fPolygon[i], i));
558 std::vector< Vertex > ears;
560 std::vector< Vertex >::iterator
c1 = verticesToBeDone.begin();
561 std::vector< Vertex >::iterator
c2 = c1 + 1;
562 std::vector< Vertex >::iterator
c3 = c1 + 2;
563 while (verticesToBeDone.size() > 2)
567 double angle =
GetAngle(c2->first, c3->first, c1->first);
577 if (c3 == verticesToBeDone.end())
579 c3 = verticesToBeDone.begin();
582 angle =
GetAngle(c2->first, c3->first, c1->first);
590 "Triangularisation has failed.");
596 std::vector< Vertex >::iterator it;
597 for (it = verticesToBeDone.begin(); it != verticesToBeDone.end(); ++it)
601 if (it == c1 || it == c2 || it == c3)
606 if (
IsPointInside(c1->first, c2->first, c3->first, it->first))
615 if (c3 == verticesToBeDone.end())
617 c3 = verticesToBeDone.begin();
639 std::vector<int> triangle(3);
640 triangle[0] = c1->second;
641 triangle[1] = c2->second;
642 triangle[2] = c3->second;
647 verticesToBeDone.erase(c2);
648 c1 = verticesToBeDone.begin();
682 std::vector<int> triangle(3);
707 std::vector<int> triangle1(3);
713 std::vector<int> triangle2(3);
732 for (
int i = 0; i <
fNv; ++i)
734 int j = (i + 1) % fNv;
756 for (
int i = 0; i <
fNv; ++i)
758 int j = (i + 1) % fNv;
759 int k = (i + 2) % fNv;
761 UVector2 v2 = fPolygon[k] - fPolygon[j];
762 double dphi = v2.
phi() - v1.
phi();
819 for (
int i = 0; i <
fNv; ++i)
821 int j = (i + 1) % fNv;
830 std::vector< std::vector<int> >::const_iterator it =
fTriangles.begin();
841 while ((inside ==
false) && (it !=
fTriangles.end()));
889 int oldprc = os.precision(16);
890 os <<
"-----------------------------------------------------------\n"
891 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
892 <<
" ===================================================\n"
897 os <<
" Convex polygon; list of vertices:" << std::endl;
901 os <<
" Concave polygon; list of vertices:" << std::endl;
904 for (
int i = 0; i <
fNv; ++i)
906 os << std::setw(5) <<
"#" << i
907 <<
" vx = " <<
fPolygon[i].x <<
" mm"
908 <<
" vy = " <<
fPolygon[i].y <<
" mm" << std::endl;
911 os <<
" Sections:" << std::endl;
935 os.precision(oldprc);
double GetMaxZExtent() const
double GetMinYExtent() const
static c2_factory< G4double > c2
void Initialise(std::vector< UVector2 > &polygon, std::vector< ZSection > &zsections)
std::ostream & StreamInfo(std::ostream &os) const
std::vector< double > fKScales
virtual ~UExtrudedSolid()
bool IsPointInside(UVector2 a, UVector2 b, UVector2 c, UVector2 p) const
UTessellatedSolid & operator=(const UTessellatedSolid &s)
double GetMinXExtent() const
double SafetyFromInside(const UVector3 &aPoint, bool aAccurate=false) const
double GetMaxYExtent() const
UVector2 ProjectPoint(const UVector3 &point) const
const std::string & GetName() const
static double fgTolerance
std::vector< std::vector< int > > fTriangles
bool IsSameLineSegment(UVector2 p, UVector2 l1, UVector2 l2) const
VUFacet * MakeUpFacet(int ind1, int ind2, int ind3) const
bool AddFacet(VUFacet *aFacet)
std::vector< UVector2 > fKOffsets
std::vector< double > fScale0s
UGeometryType fGeometryType
EnumInside Inside(const UVector3 &aPoint) const
std::vector< UVector2 > fPolygon
double GetMaxXExtent() const
bool AddGeneralPolygonFacets()
double GetAngle(UVector2 p0, UVector2 pa, UVector2 pb) const
std::vector< ZSection > fZSections
std::vector< UVector2 > fOffset0s
VUFacet * MakeDownFacet(int ind1, int ind2, int ind3) const
UVector2 GetVertex(int index) const
double GetMinZExtent() const
virtual double SafetyFromInside(const UVector3 &p, bool aAccurate=false) const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
bool IsSameSide(UVector2 p1, UVector2 p2, UVector2 l1, UVector2 l2) const
UExtrudedSolid & operator=(const UExtrudedSolid &rhs)
void SetSolidClosed(const bool t)
void Exception(const char *originOfException, const char *exceptionCode, ExceptionSeverity severity, int level, const char *description)
bool IsSameLine(UVector2 p, UVector2 l1, UVector2 l2) const
void ComputeProjectionParameters()
virtual double DistanceToOut(const UVector3 &p, const UVector3 &v, UVector3 &aNormalVector, bool &aConvex, double aPstep=UUtils::kInfinity) const
double DistanceToOut(const UVector3 &aPoint, const UVector3 &aDirection, UVector3 &aNormalVector, bool &aConvex, double aPstep=UUtils::kInfinity) const