Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4GeomTools Class Reference

G4GeomTools is a collecting utilities which can be helpful for a wide range of geometry-related tasks. More...

#include <G4GeomTools.hh>

Static Public Member Functions

static G4double TriangleArea (G4double Ax, G4double Ay, G4double Bx, G4double By, G4double Cx, G4double Cy)
static G4double TriangleArea (const G4TwoVector &A, const G4TwoVector &B, const G4TwoVector &C)
static G4double QuadArea (const G4TwoVector &A, const G4TwoVector &B, const G4TwoVector &C, const G4TwoVector &D)
static G4double PolygonArea (const G4TwoVectorList &polygon)
static G4bool PointInTriangle (G4double Px, G4double Py, G4double Ax, G4double Ay, G4double Bx, G4double By, G4double Cx, G4double Cy)
static G4bool PointInTriangle (const G4TwoVector &P, const G4TwoVector &A, const G4TwoVector &B, const G4TwoVector &C)
static G4bool PointInPolygon (const G4TwoVector &P, const G4TwoVectorList &Polygon)
static G4bool IsConvex (const G4TwoVectorList &polygon)
static G4bool TriangulatePolygon (const G4TwoVectorList &polygon, std::vector< G4int > &result)
static G4bool TriangulatePolygon (const G4TwoVectorList &polygon, G4TwoVectorList &result)
static void RemoveRedundantVertices (G4TwoVectorList &polygon, std::vector< G4int > &iout, G4double tolerance=0.0)
static G4bool DiskExtent (G4double rmin, G4double rmax, G4double startPhi, G4double delPhi, G4TwoVector &pmin, G4TwoVector &pmax)
static void DiskExtent (G4double rmin, G4double rmax, G4double sinPhiStart, G4double cosPhiStart, G4double sinPhiEnd, G4double cosPhiEnd, G4TwoVector &pmin, G4TwoVector &pmax)
static G4double EllipsePerimeter (G4double a, G4double b)
static G4double EllipticConeLateralArea (G4double a, G4double b, G4double h)
static G4ThreeVector TriangleAreaNormal (const G4ThreeVector &A, const G4ThreeVector &B, const G4ThreeVector &C)
static G4ThreeVector QuadAreaNormal (const G4ThreeVector &A, const G4ThreeVector &B, const G4ThreeVector &C, const G4ThreeVector &D)
static G4ThreeVector PolygonAreaNormal (const G4ThreeVectorList &polygon)
static G4double DistancePointSegment (const G4ThreeVector &P, const G4ThreeVector &A, const G4ThreeVector &B)
static G4ThreeVector ClosestPointOnSegment (const G4ThreeVector &P, const G4ThreeVector &A, const G4ThreeVector &B)
static G4ThreeVector ClosestPointOnTriangle (const G4ThreeVector &P, const G4ThreeVector &A, const G4ThreeVector &B, const G4ThreeVector &C)
static G4bool SphereExtent (G4double rmin, G4double rmax, G4double startTheta, G4double delTheta, G4double startPhi, G4double delPhi, G4ThreeVector &pmin, G4ThreeVector &pmax)
static G4double HypeStereo (G4double r0, G4double r, G4double h)
static void TwistedTubeBoundingTrap (G4double twistAng, G4double endInnerRad, G4double endOuterRad, G4double dPhi, G4TwoVectorList &vertices)
static G4double HyperboloidSurfaceArea (G4double dphi, G4double r0, G4double tanstereo, G4double zmin, G4double zmax)

Detailed Description

G4GeomTools is a collecting utilities which can be helpful for a wide range of geometry-related tasks.

Definition at line 50 of file G4GeomTools.hh.

Member Function Documentation

◆ ClosestPointOnSegment()

G4ThreeVector G4GeomTools::ClosestPointOnSegment ( const G4ThreeVector & P,
const G4ThreeVector & A,
const G4ThreeVector & B )
static

Finds a point on a 3D line segment AB closest to point 'P'.

Definition at line 667 of file G4GeomTools.cc.

670{
671 G4ThreeVector AP = P - A;
672 G4ThreeVector AB = B - A;
673
674 G4double u = AP.dot(AB);
675 if (u <= 0) { return A; } // closest point is A
676
677 G4double len2 = AB.mag2();
678 if (u >= len2) { return B; } // closest point is B
679
680 G4double t = u/len2;
681 return A + t*AB; // closest point on segment
682}
G4double B(G4double temperature)
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition G4Types.hh:83
const G4double A[17]
double mag2() const
double dot(const Hep3Vector &) const

◆ ClosestPointOnTriangle()

G4ThreeVector G4GeomTools::ClosestPointOnTriangle ( const G4ThreeVector & P,
const G4ThreeVector & A,
const G4ThreeVector & B,
const G4ThreeVector & C )
static

Finds a point on a 3D triangle ABC closest to point 'P'.

Definition at line 696 of file G4GeomTools.cc.

700{
701 G4ThreeVector diff = A - P;
702 G4ThreeVector edge0 = B - A;
703 G4ThreeVector edge1 = C - A;
704
705 G4double a = edge0.mag2();
706 G4double b = edge0.dot(edge1);
707 G4double c = edge1.mag2();
708 G4double d = diff.dot(edge0);
709 G4double e = diff.dot(edge1);
710
711 G4double det = a*c - b*b;
712 G4double t0 = b*e - c*d;
713 G4double t1 = b*d - a*e;
714
715 /*
716 ^ t1
717 \ 2 |
718 \ |
719 \ | regions
720 \|
721 C
722 |\
723 3 | \ 1
724 | \
725 | 0 \
726 | \
727 ---- A --- B ----> t0
728 | \
729 4 | 5 \ 6
730 | \
731 */
732
733 G4int region = -1;
734 if (t0+t1 <= det)
735 {
736 region = (t0 < 0) ? ((t1 < 0) ? 4 : 3) : ((t1 < 0) ? 5 : 0);
737 }
738 else
739 {
740 region = (t0 < 0) ? 2 : ((t1 < 0) ? 6 : 1);
741 }
742
743 switch (region)
744 {
745 case 0: // interior of triangle
746 {
747 G4double invDet = 1./det;
748 return A + (t0*invDet)*edge0 + (t1*invDet)*edge1;
749 }
750 case 1: // edge BC
751 {
752 G4double numer = c + e - b - d;
753 if (numer <= 0) { return C; }
754 G4double denom = a - 2*b + c;
755 return (numer >= denom) ? B : C + (numer/denom)*(edge0-edge1);
756 }
757 case 2: // edge AC or BC
758 {
759 G4double tmp0 = b + d;
760 G4double tmp1 = c + e;
761 if (tmp1 > tmp0)
762 {
763 G4double numer = tmp1 - tmp0;
764 G4double denom = a - 2*b + c;
765 return (numer >= denom) ? B : C + (numer/denom)*(edge0-edge1);
766 }
767 // same: (e >= 0) ? A : ((-e >= c) ? C : A + (-e/c)*edge1)
768 return (tmp1 <= 0) ? C : (( e >= 0) ? A : A + (-e/c)*edge1);
769 }
770 case 3: // edge AC
771 return (e >= 0) ? A : ((-e >= c) ? C : A + (-e/c)*edge1);
772
773 case 4: // edge AB or AC
774 if (d < 0) { return (-d >= a) ? B : A + (-d/a)*edge0; }
775 return (e >= 0) ? A : ((-e >= c) ? C : A + (-e/c)*edge1);
776
777 case 5: // edge AB
778 return (d >= 0) ? A : ((-d >= a) ? B : A + (-d/a)*edge0);
779
780 case 6: // edge AB or BC
781 {
782 G4double tmp0 = b + e;
783 G4double tmp1 = a + d;
784 if (tmp1 > tmp0)
785 {
786 G4double numer = tmp1 - tmp0;
787 G4double denom = a - 2*b + c;
788 return (numer >= denom) ? C : B + (numer/denom)*(edge1-edge0);
789 }
790 // same: (d >= 0) ? A : ((-d >= a) ? B : A + (-d/a)*edge0)
791 return (tmp1 <= 0) ? B : (( d >= 0) ? A : A + (-d/a)*edge0);
792 }
793 default: // impossible case
794 return {kInfinity,kInfinity,kInfinity};
795 }
796}
G4double C(G4double temp)
int G4int
Definition G4Types.hh:85

◆ DiskExtent() [1/2]

void G4GeomTools::DiskExtent ( G4double rmin,
G4double rmax,
G4double sinPhiStart,
G4double cosPhiStart,
G4double sinPhiEnd,
G4double cosPhiEnd,
G4TwoVector & pmin,
G4TwoVector & pmax )
static

Calculates the bounding rectangle of a disk sector. Faster version without check of parameters.

Definition at line 432 of file G4GeomTools.cc.

436{
437 static const G4double kCarTolerance =
439
440 // check if 360 degrees
441 //
442 pmin.set(-rmax,-rmax);
443 pmax.set( rmax, rmax);
444
445 if (std::abs(sinEnd-sinStart) < kCarTolerance &&
446 std::abs(cosEnd-cosStart) < kCarTolerance) { return; }
447
448 // get start and end quadrants
449 //
450 // 1 | 0
451 // ---+---
452 // 3 | 2
453 //
454 G4int icase = (cosEnd < 0) ? 1 : 0;
455 if (sinEnd < 0) { icase += 2; }
456 if (cosStart < 0) { icase += 4; }
457 if (sinStart < 0) { icase += 8; }
458
459 switch (icase)
460 {
461 // start quadrant 0
462 case 0: // start->end : 0->0
463 if (sinEnd < sinStart) { break; }
464 pmin.set(rmin*cosEnd,rmin*sinStart);
465 pmax.set(rmax*cosStart,rmax*sinEnd );
466 break;
467 case 1: // start->end : 0->1
468 pmin.set(rmax*cosEnd,std::min(rmin*sinStart,rmin*sinEnd));
469 pmax.set(rmax*cosStart,rmax );
470 break;
471 case 2: // start->end : 0->2
472 pmin.set(-rmax,-rmax);
473 pmax.set(std::max(rmax*cosStart,rmax*cosEnd),rmax);
474 break;
475 case 3: // start->end : 0->3
476 pmin.set(-rmax,rmax*sinEnd);
477 pmax.set(rmax*cosStart,rmax);
478 break;
479 // start quadrant 1
480 case 4: // start->end : 1->0
481 pmin.set(-rmax,-rmax);
482 pmax.set(rmax,std::max(rmax*sinStart,rmax*sinEnd));
483 break;
484 case 5: // start->end : 1->1
485 if (sinEnd > sinStart) { break; }
486 pmin.set(rmax*cosEnd,rmin*sinEnd );
487 pmax.set(rmin*cosStart,rmax*sinStart);
488 break;
489 case 6: // start->end : 1->2
490 pmin.set(-rmax,-rmax);
491 pmax.set(rmax*cosEnd,rmax*sinStart);
492 break;
493 case 7: // start->end : 1->3
494 pmin.set(-rmax,rmax*sinEnd);
495 pmax.set(std::max(rmin*cosStart,rmin*cosEnd),rmax*sinStart);
496 break;
497 // start quadrant 2
498 case 8: // start->end : 2->0
499 pmin.set(std::min(rmin*cosStart,rmin*cosEnd),rmax*sinStart);
500 pmax.set(rmax,rmax*sinEnd);
501 break;
502 case 9: // start->end : 2->1
503 pmin.set(rmax*cosEnd,rmax*sinStart);
504 pmax.set(rmax,rmax);
505 break;
506 case 10: // start->end : 2->2
507 if (sinEnd < sinStart) { break; }
508 pmin.set(rmin*cosStart,rmax*sinStart);
509 pmax.set(rmax*cosEnd,rmin*sinEnd );
510 break;
511 case 11: // start->end : 2->3
512 pmin.set(-rmax,std::min(rmax*sinStart,rmax*sinEnd));
513 pmax.set(rmax,rmax);
514 break;
515 // start quadrant 3
516 case 12: // start->end : 3->0
517 pmin.set(rmax*cosStart,-rmax);
518 pmax.set(rmax,rmax*sinEnd);
519 break;
520 case 13: // start->end : 3->1
521 pmin.set(std::min(rmax*cosStart,rmax*cosEnd),-rmax);
522 pmax.set(rmax,rmax);
523 break;
524 case 14: // start->end : 3->2
525 pmin.set(rmax*cosStart,-rmax);
526 pmax.set(rmax*cosEnd,std::max(rmin*sinStart,rmin*sinEnd));
527 break;
528 case 15: // start->end : 3->3
529 if (sinEnd > sinStart) { break; }
530 pmin.set(rmax*cosStart,rmax*sinEnd);
531 pmax.set(rmin*cosEnd,rmin*sinStart);
532 break;
533 }
534 return;
535}
const G4double kCarTolerance
void set(double x, double y)
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()

◆ DiskExtent() [2/2]

G4bool G4GeomTools::DiskExtent ( G4double rmin,
G4double rmax,
G4double startPhi,
G4double delPhi,
G4TwoVector & pmin,
G4TwoVector & pmax )
static

Calculates the bounding rectangle of a disk sector. It returns false if the input parameters do not meet the following criteria: rmin >= 0 rmax > rmin + kCarTolerance delPhi > 0 + kCarTolerance.

Definition at line 399 of file G4GeomTools.cc.

402{
403 static const G4double kCarTolerance =
405
406 // check parameters
407 //
408 pmin.set(0,0);
409 pmax.set(0,0);
410 if (rmin < 0) { return false; }
411 if (rmax <= rmin + kCarTolerance) { return false; }
412 if (delPhi <= 0 + kCarTolerance) { return false; }
413
414 // calculate extent
415 //
416 pmin.set(-rmax,-rmax);
417 pmax.set( rmax, rmax);
418 if (delPhi >= CLHEP::twopi) { return true; }
419
420 DiskExtent(rmin,rmax,
421 std::sin(startPhi),std::cos(startPhi),
422 std::sin(startPhi+delPhi),std::cos(startPhi+delPhi),
423 pmin,pmax);
424 return true;
425}
static G4bool DiskExtent(G4double rmin, G4double rmax, G4double startPhi, G4double delPhi, G4TwoVector &pmin, G4TwoVector &pmax)

Referenced by G4Cons::BoundingLimits(), G4CutTubs::BoundingLimits(), G4GenericPolycone::BoundingLimits(), G4Polycone::BoundingLimits(), G4Sphere::BoundingLimits(), G4Torus::BoundingLimits(), G4Tubs::BoundingLimits(), G4TwistedTubs::BoundingLimits(), G4Torus::CalculateExtent(), DiskExtent(), and SphereExtent().

◆ DistancePointSegment()

G4double G4GeomTools::DistancePointSegment ( const G4ThreeVector & P,
const G4ThreeVector & A,
const G4ThreeVector & B )
static

Calculates the distance between a point 'P' and line segment AB in 3D.

Definition at line 646 of file G4GeomTools.cc.

649{
650 G4ThreeVector AP = P - A;
651 G4ThreeVector AB = B - A;
652
653 G4double u = AP.dot(AB);
654 if (u <= 0) { return AP.mag(); } // closest point is A
655
656 G4double len2 = AB.mag2();
657 if (u >= len2) { return (B-P).mag(); } // closest point is B
658
659 return ((u/len2)*AB - AP).mag(); // distance to line
660}
double mag() const

◆ EllipsePerimeter()

G4double G4GeomTools::EllipsePerimeter ( G4double a,
G4double b )
static

Computes the circumference (perimeter) of an ellipse.

Definition at line 541 of file G4GeomTools.cc.

542{
543 G4double x = std::abs(pA);
544 G4double y = std::abs(pB);
545 G4double a = std::max(x,y);
546 G4double b = std::min(x,y);
547 G4double e = std::sqrt((1. - b/a)*(1. + b/a));
548 return 4. * a * comp_ellint_2(e);
549}

◆ EllipticConeLateralArea()

G4double G4GeomTools::EllipticConeLateralArea ( G4double a,
G4double b,
G4double h )
static

Computes the lateral surface area of an elliptic cone.

Definition at line 555 of file G4GeomTools.cc.

558{
559 G4double x = std::abs(pA);
560 G4double y = std::abs(pB);
561 G4double h = std::abs(pH);
562 G4double a = std::max(x,y);
563 G4double b = std::min(x,y);
564 G4double e = std::sqrt((1. - b/a)*(1. + b/a)) / std::hypot(1.,b/h);
565 return 2. * a * std::hypot(b,h) * comp_ellint_2(e);
566}

Referenced by G4EllipticalCone::GetSurfaceArea().

◆ HyperboloidSurfaceArea()

G4double G4GeomTools::HyperboloidSurfaceArea ( G4double dphi,
G4double r0,
G4double tanstereo,
G4double zmin,
G4double zmax )
static

Calculate surface area of the hyperboloid between 'zmin' and 'zmax'.

Parameters
[in]dphiDelta phi.
[in]r0The radius at z = 0.
[in]tanstereoThe tangent of the stereo angle.
[in]zminMinimum Z.
[in]zmaxMaximum Z.

Definition at line 913 of file G4GeomTools.cc.

915{
916 static const G4double kCarTolerance =
918
919 G4double a = std::abs(r0); // radius at z = 0
920 G4double t = std::abs(tanstereo); // tan(stereo)
921 G4double phi = std::abs(dphi); // delta phi
922
923 // Check spesial cases: cylindrical and conical surfaces
924 if (t < kCarTolerance) { return a*std::abs(zmax - zmin)*phi; } // cylinder
925 G4double rmin = std::hypot(t*zmin, a); // radius at zmin
926 G4double rmax = std::hypot(t*zmax, a); // radius at zmax
927 if (a < kCarTolerance) // cone
928 {
929 G4double smin = rmin*std::hypot(rmin, zmin);
930 G4double smax = rmax*std::hypot(rmax, zmax);
931 return (zmin*zmax < 0.) ? (smin + smax)*phi/2. : std::abs(smax - smin)*phi/2.;
932 }
933 // Find surface area
934 G4double tt = t*t;
935 G4double aa = a*a;
936 G4double cc = aa/tt;
937 G4double k = std::sqrt(aa + cc)/cc;
938
939 G4double hmin = std::abs(zmin);
940 G4double smin = a*(hmin*std::hypot(1., k*hmin) + std::asinh(k*hmin)/k);
941 if (zmax == -zmin) { return smin*phi; }
942
943 G4double hmax = std::abs(zmax);
944 G4double smax = a*(hmax*std::hypot(1., k*hmax) + std::asinh(k*hmax)/k);
945 return (zmin*zmax < 0.) ? (smin + smax)*phi/2. :std::abs(smax - smin)*phi/2.;
946}

Referenced by G4Hype::SetInnerRadius(), G4Hype::SetInnerStereo(), G4Hype::SetOuterRadius(), G4Hype::SetOuterStereo(), and G4Hype::SetZHalfLength().

◆ HypeStereo()

G4double G4GeomTools::HypeStereo ( G4double r0,
G4double r,
G4double h )
static

Calculates the hyperbolic surface stereo. Stereo is a half angle at the intersection point of the two lines in the tangent plane cross-section.

Definition at line 861 of file G4GeomTools.cc.

862{
863 static const G4double kCarTolerance =
865 if (std::abs(r - r0) < kCarTolerance) { return 0.; }
866 return std::atan(std::sqrt((r - r0)*(r + r0))/std::abs(h));
867}

◆ IsConvex()

G4bool G4GeomTools::IsConvex ( const G4TwoVectorList & polygon)
static

Decides if a 2D 'polygon' is convex, i.e. if all internal angles are less than pi.

Definition at line 166 of file G4GeomTools.cc.

167{
168 static const G4double kCarTolerance =
170
171 G4bool gotNegative = false;
172 G4bool gotPositive = false;
173 auto n = (G4int)polygon.size();
174 if (n <= 0) { return false; }
175 for (G4int icur=0; icur<n; ++icur)
176 {
177 G4int iprev = (icur == 0) ? n-1 : icur-1;
178 G4int inext = (icur == n-1) ? 0 : icur+1;
179 G4TwoVector e1 = polygon[icur] - polygon[iprev];
180 G4TwoVector e2 = polygon[inext] - polygon[icur];
181 G4double cross = e1.x()*e2.y() - e1.y()*e2.x();
182 if (std::abs(cross) < kCarTolerance) { return false; }
183 if (cross < 0) { gotNegative = true; }
184 if (cross > 0) { gotPositive = true; }
185 if (gotNegative && gotPositive) { return false; }
186 }
187 return true;
188}
CLHEP::Hep2Vector G4TwoVector
bool G4bool
Definition G4Types.hh:86
double x() const
double y() const

Referenced by G4ExtrudedSolid::G4ExtrudedSolid(), and G4ExtrudedSolid::G4ExtrudedSolid().

◆ PointInPolygon()

G4bool G4GeomTools::PointInPolygon ( const G4TwoVector & P,
const G4TwoVectorList & Polygon )
static

Decides if a point P is inside the 'Polygon'.

Definition at line 146 of file G4GeomTools.cc.

148{
149 auto Nv = (G4int)v.size();
150 G4bool in = false;
151 for (G4int i = 0, k = Nv - 1; i < Nv; k = i++)
152 {
153 if ((v[i].y() > p.y()) != (v[k].y() > p.y()))
154 {
155 G4double ctg = (v[k].x()-v[i].x())/(v[k].y()-v[i].y());
156 in ^= static_cast<int>(p.x() < (p.y()-v[i].y())*ctg + v[i].x());
157 }
158 }
159 return in;
160}

◆ PointInTriangle() [1/2]

G4bool G4GeomTools::PointInTriangle ( const G4TwoVector & P,
const G4TwoVector & A,
const G4TwoVector & B,
const G4TwoVector & C )
static

Decides if a point P is inside the triangle ABC.

Definition at line 118 of file G4GeomTools.cc.

122{
123 G4double Ax = A.x(), Ay = A.y();
124 G4double Bx = B.x(), By = B.y();
125 G4double Cx = C.x(), Cy = C.y();
126 G4double Px = P.x(), Py = P.y();
127 if ((Bx-Ax)*(Cy-Ay) - (By-Ay)*(Cx-Ax) > 0.)
128 {
129 if ((Ax-Cx)*(Py-Cy) - (Ay-Cy)*(Px-Cx) < 0.) { return false; }
130 if ((Bx-Ax)*(Py-Ay) - (By-Ay)*(Px-Ax) < 0.) { return false; }
131 if ((Cx-Bx)*(Py-By) - (Cy-By)*(Px-Bx) < 0.) { return false; }
132 }
133 else
134 {
135 if ((Ax-Cx)*(Py-Cy) - (Ay-Cy)*(Px-Cx) > 0.) { return false; }
136 if ((Bx-Ax)*(Py-Ay) - (By-Ay)*(Px-Ax) > 0.) { return false; }
137 if ((Cx-Bx)*(Py-By) - (Cy-By)*(Px-Bx) > 0.) { return false; }
138 }
139 return true;
140}

◆ PointInTriangle() [2/2]

G4bool G4GeomTools::PointInTriangle ( G4double Px,
G4double Py,
G4double Ax,
G4double Ay,
G4double Bx,
G4double By,
G4double Cx,
G4double Cy )
static

Decides if a point (Px,Py) is inside the triangle (Ax,Ay)(Bx,By)(Cx,Cy).

Definition at line 93 of file G4GeomTools.cc.

98{
99 if ((Bx-Ax)*(Cy-Ay) - (By-Ay)*(Cx-Ax) > 0.)
100 {
101 if ((Ax-Cx)*(Py-Cy) - (Ay-Cy)*(Px-Cx) < 0.) { return false; }
102 if ((Bx-Ax)*(Py-Ay) - (By-Ay)*(Px-Ax) < 0.) { return false; }
103 if ((Cx-Bx)*(Py-By) - (Cy-By)*(Px-Bx) < 0.) { return false; }
104 }
105 else
106 {
107 if ((Ax-Cx)*(Py-Cy) - (Ay-Cy)*(Px-Cx) > 0.) { return false; }
108 if ((Bx-Ax)*(Py-Ay) - (By-Ay)*(Px-Ax) > 0.) { return false; }
109 if ((Cx-Bx)*(Py-By) - (Cy-By)*(Px-Bx) > 0.) { return false; }
110 }
111 return true;
112}

◆ PolygonArea()

G4double G4GeomTools::PolygonArea ( const G4TwoVectorList & polygon)
static

Calculates the area of a 2D polygon, returned value is positive if the vertices of the polygon are defined in anticlockwise order, otherwise it is negative.

Definition at line 76 of file G4GeomTools.cc.

77{
78 auto n = (G4int)p.size();
79 if (n < 3) { return 0.0; } // degenerate polygon
80
81 G4double area = p[n-1].x()*p[0].y() - p[0].x()*p[n-1].y();
82 for(G4int i=1; i<n; ++i)
83 {
84 area += p[i-1].x()*p[i].y() - p[i].x()*p[i-1].y();
85 }
86 return area*0.5;
87}

Referenced by G4GenericPolycone::CalculateExtent(), G4Polycone::CalculateExtent(), G4Polyhedra::CalculateExtent(), G4ExtrudedSolid::G4ExtrudedSolid(), G4ExtrudedSolid::G4ExtrudedSolid(), and TriangulatePolygon().

◆ PolygonAreaNormal()

G4ThreeVector G4GeomTools::PolygonAreaNormal ( const G4ThreeVectorList & polygon)
static

Finds the normal to the plane of a 3D polygon; the length of the normal is equal to the area of the polygon.

Definition at line 630 of file G4GeomTools.cc.

631{
632 auto n = (G4int)p.size();
633 if (n < 3) { return {0,0,0}; } // degerate polygon
634 G4ThreeVector normal = p[n-1].cross(p[0]);
635 for(G4int i=1; i<n; ++i)
636 {
637 normal += p[i-1].cross(p[i]);
638 }
639 return normal*0.5;
640}
Hep3Vector cross(const Hep3Vector &) const

◆ QuadArea()

G4double G4GeomTools::QuadArea ( const G4TwoVector & A,
const G4TwoVector & B,
const G4TwoVector & C,
const G4TwoVector & D )
static

Calculates the area of a 2D quadrilateral, returned value is positive if the vertices of the quadrilateral are given in anticlockwise order, otherwise it is negative.

Definition at line 64 of file G4GeomTools.cc.

68{
69 return ((C.x()-A.x())*(D.y()-B.y()) - (C.y()-A.y())*(D.x()-B.x()))*0.5;
70}
G4double D(G4double temp)

◆ QuadAreaNormal()

G4ThreeVector G4GeomTools::QuadAreaNormal ( const G4ThreeVector & A,
const G4ThreeVector & B,
const G4ThreeVector & C,
const G4ThreeVector & D )
static

Finds the normal to the plane of a 3D quadrilateral ABCD; the length of the normal is equal to the area of the quadrilateral.

Definition at line 618 of file G4GeomTools.cc.

622{
623 return ((C-A).cross(D-B))*0.5;
624}

Referenced by G4Polyhedra::GetSurfaceArea(), G4Trap::GetSurfaceArea(), and G4Trap::SetCachedValues().

◆ RemoveRedundantVertices()

void G4GeomTools::RemoveRedundantVertices ( G4TwoVectorList & polygon,
std::vector< G4int > & iout,
G4double tolerance = 0.0 )
static

Removes collinear and coincident points from a 2D 'polygon'. Indices of removed points are available in 'iout'. Allows to specify a 'tolerance'.

Definition at line 310 of file G4GeomTools.cc.

313{
314 iout.resize(0);
315 // set tolerance squared
316 G4double delta = sqr(tolerance);
317 // set special value to mark vertices for removal
318 G4double removeIt = kInfinity;
319
320 auto nv = (G4int)polygon.size();
321
322 // Main loop: check every three consecutive points, if the points
323 // are collinear then mark middle point for removal
324 //
325 G4int icur = 0, iprev = 0, inext = 0, nout = 0;
326 for (G4int i=0; i<nv; ++i)
327 {
328 icur = i; // index of current point
329
330 for (G4int k=1; k<nv+1; ++k) // set index of previous point
331 {
332 iprev = icur - k;
333 if (iprev < 0) { iprev += nv; }
334 if (polygon[iprev].x() != removeIt) { break; }
335 }
336
337 for (G4int k=1; k<nv+1; ++k) // set index of next point
338 {
339 inext = icur + k;
340 if (inext >= nv) { inext -= nv; }
341 if (polygon[inext].x() != removeIt) { break; }
342 }
343
344 if (iprev == inext) { break; } // degenerate polygon, stop
345
346 // Calculate parameters of triangle (iprev->icur->inext),
347 // if triangle is too small or too narrow then mark current
348 // point for removal
349 G4TwoVector e1 = polygon[iprev] - polygon[icur];
350 G4TwoVector e2 = polygon[inext] - polygon[icur];
351
352 // Check length of edges, then check height of the triangle
353 G4double leng1 = e1.mag2();
354 G4double leng2 = e2.mag2();
355 G4double leng3 = (e2-e1).mag2();
356 if (leng1 <= delta || leng2 <= delta || leng3 <= delta)
357 {
358 polygon[icur].setX(removeIt); ++nout;
359 }
360 else
361 {
362 G4double lmax = std::max(std::max(leng1,leng2),leng3);
363 G4double area = std::abs(e1.x()*e2.y()-e1.y()*e2.x())*0.5;
364 if (area/std::sqrt(lmax) <= std::abs(tolerance))
365 {
366 polygon[icur].setX(removeIt); ++nout;
367 }
368 }
369 }
370
371 // Remove marked points
372 //
373 icur = 0;
374 if (nv - nout < 3) // degenerate polygon, remove all points
375 {
376 for (G4int i=0; i<nv; ++i) { iout.push_back(i); }
377 polygon.resize(0);
378 nv = 0;
379 }
380 for (G4int i=0; i<nv; ++i) // move points, if required
381 {
382 if (polygon[i].x() != removeIt)
383 {
384 polygon[icur++] = polygon[i];
385 }
386 else
387 {
388 iout.push_back(i);
389 }
390 }
391 if (icur < nv) { polygon.resize(icur); }
392 return;
393}
double mag2() const
T sqr(const T &x)
Definition templates.hh:128

Referenced by G4Polycone::CalculateExtent(), G4Polyhedra::CalculateExtent(), G4ExtrudedSolid::G4ExtrudedSolid(), and G4ExtrudedSolid::G4ExtrudedSolid().

◆ SphereExtent()

G4bool G4GeomTools::SphereExtent ( G4double rmin,
G4double rmax,
G4double startTheta,
G4double delTheta,
G4double startPhi,
G4double delPhi,
G4ThreeVector & pmin,
G4ThreeVector & pmax )
static

Calculates the bounding box of a spherical sector,

Returns
false if input parameters do not meet the following criteria: rmin >= 0 rmax > rmin + kCarTolerance startTheta >= 0 && <= pi; delTheta > 0 + kCarTolerance delPhi > 0 + kCarTolerance.

Definition at line 803 of file G4GeomTools.cc.

807{
808 static const G4double kCarTolerance =
810
811 // check parameters
812 //
813 pmin.set(0,0,0);
814 pmax.set(0,0,0);
815 if (rmin < 0) { return false; }
816 if (rmax <= rmin + kCarTolerance) { return false; }
817 if (delTheta <= 0 + kCarTolerance) { return false; }
818 if (delPhi <= 0 + kCarTolerance) { return false; }
819
820 G4double stheta = startTheta;
821 G4double dtheta = delTheta;
822 if (stheta < 0 && stheta > CLHEP::pi) { return false; }
823 if (stheta + dtheta > CLHEP::pi) { dtheta = CLHEP::pi - stheta; }
824 if (dtheta <= 0 + kCarTolerance) { return false; }
825
826 // calculate extent
827 //
828 pmin.set(-rmax,-rmax,-rmax);
829 pmax.set( rmax, rmax, rmax);
830 if (dtheta >= CLHEP::pi && delPhi >= CLHEP::twopi) { return true; }
831
832 G4double etheta = stheta + dtheta;
833 G4double sinStart = std::sin(stheta);
834 G4double cosStart = std::cos(stheta);
835 G4double sinEnd = std::sin(etheta);
836 G4double cosEnd = std::cos(etheta);
837
838 G4double rhomin = rmin*std::min(sinStart,sinEnd);
839 G4double rhomax = rmax;
840 if (stheta > CLHEP::halfpi) { rhomax = rmax*sinStart; }
841 if (etheta < CLHEP::halfpi) { rhomax = rmax*sinEnd; }
842
843 G4TwoVector xymin,xymax;
844 DiskExtent(rhomin,rhomax,
845 std::sin(startPhi),std::cos(startPhi),
846 std::sin(startPhi+delPhi),std::cos(startPhi+delPhi),
847 xymin,xymax);
848
849 G4double zmin = std::min(rmin*cosEnd,rmax*cosEnd);
850 G4double zmax = std::max(rmin*cosStart,rmax*cosStart);
851 pmin.set(xymin.x(),xymin.y(),zmin);
852 pmax.set(xymax.x(),xymax.y(),zmax);
853 return true;
854}
void set(double x, double y, double z)

◆ TriangleArea() [1/2]

G4double G4GeomTools::TriangleArea ( const G4TwoVector & A,
const G4TwoVector & B,
const G4TwoVector & C )
static

Definition at line 52 of file G4GeomTools.cc.

55{
56 G4double Ax = A.x(), Ay = A.y();
57 return ((B.x()-Ax)*(C.y()-Ay) - (B.y()-Ay)*(C.x()-Ax))*0.5;
58}

◆ TriangleArea() [2/2]

G4double G4GeomTools::TriangleArea ( G4double Ax,
G4double Ay,
G4double Bx,
G4double By,
G4double Cx,
G4double Cy )
static

Functions to calculate the area of 2D triangle, returned value is positive if the vertices of the triangle are given in anticlockwise order, otherwise it is negative.

Definition at line 41 of file G4GeomTools.cc.

44{
45 return ((Bx-Ax)*(Cy-Ay) - (By-Ay)*(Cx-Ax))*0.5;
46}

◆ TriangleAreaNormal()

G4ThreeVector G4GeomTools::TriangleAreaNormal ( const G4ThreeVector & A,
const G4ThreeVector & B,
const G4ThreeVector & C )
static

Finds the normal to the plane of a 3D triangle ABC; the length of the normal is equal to the area of the triangle.

Definition at line 607 of file G4GeomTools.cc.

610{
611 return ((B-A).cross(C-A))*0.5;
612}

Referenced by G4Trap::GetPointOnSurface().

◆ TriangulatePolygon() [1/2]

G4bool G4GeomTools::TriangulatePolygon ( const G4TwoVectorList & polygon,
G4TwoVectorList & result )
static

Same using the function above and returning as 'result' a list of triangles.

Definition at line 194 of file G4GeomTools.cc.

196{
197 result.resize(0);
198 std::vector<G4int> triangles;
199 G4bool reply = TriangulatePolygon(polygon,triangles);
200
201 auto n = (G4int)triangles.size();
202 for (G4int i=0; i<n; ++i) { result.push_back(polygon[triangles[i]]); }
203 return reply;
204}
static G4bool TriangulatePolygon(const G4TwoVectorList &polygon, std::vector< G4int > &result)

◆ TriangulatePolygon() [2/2]

G4bool G4GeomTools::TriangulatePolygon ( const G4TwoVectorList & polygon,
std::vector< G4int > & result )
static

Simple implementation of "ear clipping" algorithm for triangulation of a simple contour/polygon, it places results in a std::vector as triplets of vertices. If triangulation is successful the function returns true, otherwise false.

Definition at line 210 of file G4GeomTools.cc.

212{
213 result.resize(0);
214
215 // allocate and initialize list of Vertices in polygon
216 //
217 auto n = (G4int)polygon.size();
218 if (n < 3) { return false; }
219
220 // we want a counter-clockwise polygon in V
221 //
222 G4double area = G4GeomTools::PolygonArea(polygon);
223 auto V = new G4int[n];
224 if (area > 0.)
225 {
226 for (G4int i=0; i<n; ++i) { V[i] = i; }
227 }
228 else
229 {
230 for (G4int i=0; i<n; ++i) { V[i] = (n-1)-i; }
231 }
232
233 // Triangulation: remove nv-2 Vertices, creating 1 triangle every time
234 //
235 G4int nv = n;
236 G4int count = 2*nv; // error detection counter
237 for(G4int b=nv-1; nv>2; )
238 {
239 // ERROR: if we loop, it is probably a non-simple polygon
240 if ((count--) <= 0)
241 {
242 delete [] V;
243 if (area < 0.) { std::reverse(result.begin(),result.end()); }
244 return false;
245 }
246
247 // three consecutive vertices in current polygon, <a,b,c>
248 G4int a = (b < nv) ? b : 0; // previous
249 b = (a+1 < nv) ? a+1 : 0; // current
250 G4int c = (b+1 < nv) ? b+1 : 0; // next
251
252 if (CheckSnip(polygon, a,b,c, nv,V))
253 {
254 // output Triangle
255 result.push_back(V[a]);
256 result.push_back(V[b]);
257 result.push_back(V[c]);
258
259 // remove vertex b from remaining polygon
260 nv--;
261 for(G4int i=b; i<nv; ++i) { V[i] = V[i+1]; }
262
263 count = 2*nv; // resest error detection counter
264 }
265 }
266 delete [] V;
267 if (area < 0.) { std::reverse(result.begin(),result.end()); }
268 return true;
269}
static G4double PolygonArea(const G4TwoVectorList &polygon)

Referenced by G4ExtrudedSolid::CalculateExtent(), G4GenericPolycone::CalculateExtent(), G4Polycone::CalculateExtent(), G4Polyhedra::CalculateExtent(), and TriangulatePolygon().

◆ TwistedTubeBoundingTrap()

void G4GeomTools::TwistedTubeBoundingTrap ( G4double twistAng,
G4double endInnerRad,
G4double endOuterRad,
G4double dPhi,
G4TwoVectorList & vertices )
static

Finds the XY-coordinates of the corners of a generic trap that bounds specified twisted tube.

Parameters
[in]twistAngThe twist angle.
[in]endInnerRadThe inner radius at z = halfZ.
[in]endOuterRadThe outer radius at z = halfZ.
[in]dPhiDelta phi.
[in]verticesThe corners of the generic trap.

Definition at line 875 of file G4GeomTools.cc.

880{
881 vertices.resize(8);
882 G4double rmin = std::abs(endInnerRad);
883 G4double rmax = std::abs(endOuterRad);
884
885 // Set untwisted vertices
886 G4double phi = dPhi/2.;
887 G4double sinphi = std::sin(phi);
888 G4double cosphi = std::cos(phi);
889 G4double tanphi = std::tan(phi);
890 vertices[0].set(rmin*cosphi, rmin*sinphi);
891 vertices[1].set(rmax, rmax*tanphi);
892 vertices[2].set(rmax,-rmax*tanphi);
893 vertices[3].set(rmin*cosphi,-rmin*sinphi);
894 vertices[4] = vertices[0];
895 vertices[5] = vertices[1];
896 vertices[6] = vertices[2];
897 vertices[7] = vertices[3];
898
899 // Twist vertices
900 G4double ang = twistAng/2.;
901 for(auto i = 0; i < 4; ++i)
902 {
903 vertices[i].rotate(-ang); // vertices at -halfz
904 vertices[i + 4].rotate(ang); // vertices at +halfz
905 }
906}

The documentation for this class was generated from the following files: