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

#include <G4EllipticalCone.hh>

+ Inheritance diagram for G4EllipticalCone:

Public Member Functions

 G4EllipticalCone (const G4String &pName, G4double pxSemiAxis, G4double pySemiAxis, G4double zMax, G4double pzTopCut)
 
virtual ~G4EllipticalCone ()
 
G4double GetSemiAxisMax () const
 
G4double GetSemiAxisX () const
 
G4double GetSemiAxisY () const
 
G4double GetZMax () const
 
G4double GetZTopCut () const
 
void SetSemiAxis (G4double x, G4double y, G4double z)
 
void SetZCut (G4double newzTopCut)
 
G4double GetCubicVolume ()
 
G4double GetSurfaceArea ()
 
G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
 
EInside Inside (const G4ThreeVector &p) const
 
G4ThreeVector SurfaceNormal (const G4ThreeVector &p) const
 
G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const
 
G4double DistanceToIn (const G4ThreeVector &p) const
 
G4double DistanceToOut (const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=G4bool(false), G4bool *validNorm=0, G4ThreeVector *n=0) const
 
G4double DistanceToOut (const G4ThreeVector &p) const
 
G4GeometryType GetEntityType () const
 
G4VSolidClone () const
 
G4ThreeVector GetPointOnSurface () const
 
std::ostream & StreamInfo (std::ostream &os) const
 
G4PolyhedronGetPolyhedron () const
 
void DescribeYourselfTo (G4VGraphicsScene &scene) const
 
G4VisExtent GetExtent () const
 
G4PolyhedronCreatePolyhedron () const
 
G4NURBSCreateNURBS () const
 
 G4EllipticalCone (__void__ &)
 
 G4EllipticalCone (const G4EllipticalCone &rhs)
 
G4EllipticalConeoperator= (const G4EllipticalCone &rhs)
 
- Public Member Functions inherited from G4VSolid
 G4VSolid (const G4String &name)
 
virtual ~G4VSolid ()
 
G4bool operator== (const G4VSolid &s) const
 
G4String GetName () const
 
void SetName (const G4String &name)
 
G4double GetTolerance () const
 
virtual G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const =0
 
virtual EInside Inside (const G4ThreeVector &p) const =0
 
virtual G4ThreeVector SurfaceNormal (const G4ThreeVector &p) const =0
 
virtual G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const =0
 
virtual G4double DistanceToIn (const G4ThreeVector &p) const =0
 
virtual G4double DistanceToOut (const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const =0
 
virtual G4double DistanceToOut (const G4ThreeVector &p) const =0
 
virtual void ComputeDimensions (G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
 
virtual G4double GetCubicVolume ()
 
virtual G4double GetSurfaceArea ()
 
virtual G4GeometryType GetEntityType () const =0
 
virtual G4ThreeVector GetPointOnSurface () const
 
virtual G4VSolidClone () const
 
virtual std::ostream & StreamInfo (std::ostream &os) const =0
 
void DumpInfo () const
 
virtual void DescribeYourselfTo (G4VGraphicsScene &scene) const =0
 
virtual G4VisExtent GetExtent () const
 
virtual G4PolyhedronCreatePolyhedron () const
 
virtual G4NURBSCreateNURBS () const
 
virtual G4PolyhedronGetPolyhedron () const
 
virtual const G4VSolidGetConstituentSolid (G4int no) const
 
virtual G4VSolidGetConstituentSolid (G4int no)
 
virtual const G4DisplacedSolidGetDisplacedSolidPtr () const
 
virtual G4DisplacedSolidGetDisplacedSolidPtr ()
 
 G4VSolid (__void__ &)
 
 G4VSolid (const G4VSolid &rhs)
 
G4VSolidoperator= (const G4VSolid &rhs)
 

Protected Member Functions

G4ThreeVectorListCreateRotatedVertices (const G4AffineTransform &pT, G4int &noPV) const
 
- Protected Member Functions inherited from G4VSolid
void CalculateClippedPolygonExtent (G4ThreeVectorList &pPolygon, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
 
void ClipCrossSection (G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
 
void ClipBetweenSections (G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
 
void ClipPolygon (G4ThreeVectorList &pPolygon, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis) const
 
G4double EstimateCubicVolume (G4int nStat, G4double epsilon) const
 
G4double EstimateSurfaceArea (G4int nStat, G4double ell) const
 

Protected Attributes

G4PolyhedronfpPolyhedron
 
- Protected Attributes inherited from G4VSolid
G4double kCarTolerance
 

Detailed Description

Definition at line 84 of file G4EllipticalCone.hh.

Constructor & Destructor Documentation

◆ G4EllipticalCone() [1/3]

G4EllipticalCone::G4EllipticalCone ( const G4String pName,
G4double  pxSemiAxis,
G4double  pySemiAxis,
G4double  zMax,
G4double  pzTopCut 
)

Definition at line 68 of file G4EllipticalCone.cc.

73 : G4VSolid(pName), fpPolyhedron(0), fCubicVolume(0.), fSurfaceArea(0.),
74 zTopCut(0.)
75{
76
78
79 // Check Semi-Axis & Z-cut
80 //
81 if ( (pxSemiAxis <= 0.) || (pySemiAxis <= 0.) || (pzMax <= 0.) )
82 {
83 std::ostringstream message;
84 message << "Invalid semi-axis or height - " << GetName();
85 G4Exception("G4EllipticalCone::G4EllipticalCone()", "GeomSolids0002",
86 FatalErrorInArgument, message);
87 }
88 if ( pzTopCut <= 0 )
89 {
90 std::ostringstream message;
91 message << "Invalid z-coordinate for cutting plane - " << GetName();
92 G4Exception("G4EllipticalCone::G4EllipticalCone()", "InvalidSetup",
93 FatalErrorInArgument, message);
94 }
95
96 SetSemiAxis( pxSemiAxis, pySemiAxis, pzMax );
97 SetZCut(pzTopCut);
98}
@ FatalErrorInArgument
void SetSemiAxis(G4double x, G4double y, G4double z)
void SetZCut(G4double newzTopCut)
G4Polyhedron * fpPolyhedron
G4double GetRadialTolerance() const
static G4GeometryTolerance * GetInstance()
G4String GetName() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41

◆ ~G4EllipticalCone()

G4EllipticalCone::~G4EllipticalCone ( )
virtual

Definition at line 116 of file G4EllipticalCone.cc.

117{
118}

◆ G4EllipticalCone() [2/3]

G4EllipticalCone::G4EllipticalCone ( __void__ &  a)

Definition at line 105 of file G4EllipticalCone.cc.

106 : G4VSolid(a), fpPolyhedron(0), kRadTolerance(0.), fCubicVolume(0.),
107 fSurfaceArea(0.), xSemiAxis(0.), ySemiAxis(0.), zheight(0.),
108 semiAxisMax(0.), zTopCut(0.)
109{
110}

◆ G4EllipticalCone() [3/3]

G4EllipticalCone::G4EllipticalCone ( const G4EllipticalCone rhs)

Definition at line 124 of file G4EllipticalCone.cc.

125 : G4VSolid(rhs),
126 fpPolyhedron(0), kRadTolerance(rhs.kRadTolerance),
127 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
128 xSemiAxis(rhs.xSemiAxis), ySemiAxis(rhs.ySemiAxis), zheight(rhs.zheight),
129 semiAxisMax(rhs.semiAxisMax), zTopCut(rhs.zTopCut)
130{
131}

Member Function Documentation

◆ CalculateExtent()

G4bool G4EllipticalCone::CalculateExtent ( const EAxis  pAxis,
const G4VoxelLimits pVoxelLimit,
const G4AffineTransform pTransform,
G4double pmin,
G4double pmax 
) const
virtual

Implements G4VSolid.

Definition at line 162 of file G4EllipticalCone.cc.

166{
167 G4SolidExtentList extentList( axis, voxelLimit );
168
169 //
170 // We are going to divide up our elliptical face into small pieces
171 //
172
173 //
174 // Choose phi size of our segment(s) based on constants as
175 // defined in meshdefs.hh
176 //
177 G4int numPhi = kMaxMeshSections;
178 G4double sigPhi = twopi/numPhi;
179
180 //
181 // We have to be careful to keep our segments completely outside
182 // of the elliptical surface. To do so we imagine we have
183 // a simple (unit radius) circular cross section (as in G4Tubs)
184 // and then "stretch" the dimensions as necessary to fit the ellipse.
185 //
186 G4double rFudge = 1.0/std::cos(0.5*sigPhi);
187 G4double dxFudgeBot = xSemiAxis*2.*zheight*rFudge,
188 dyFudgeBot = ySemiAxis*2.*zheight*rFudge;
189 G4double dxFudgeTop = xSemiAxis*(zheight-zTopCut)*rFudge,
190 dyFudgeTop = ySemiAxis*(zheight-zTopCut)*rFudge;
191
192 //
193 // As we work around the elliptical surface, we build
194 // a "phi" segment on the way, and keep track of two
195 // additional polygons for the two ends.
196 //
197 G4ClippablePolygon endPoly1, endPoly2, phiPoly;
198
199 G4double phi = 0,
200 cosPhi = std::cos(phi),
201 sinPhi = std::sin(phi);
202 G4ThreeVector v0( dxFudgeTop*cosPhi, dyFudgeTop*sinPhi, +zTopCut ),
203 v1( dxFudgeBot*cosPhi, dyFudgeBot*sinPhi, -zTopCut ),
204 w0, w1;
205 transform.ApplyPointTransform( v0 );
206 transform.ApplyPointTransform( v1 );
207 do
208 {
209 phi += sigPhi;
210 if (numPhi == 1) phi = 0; // Try to avoid roundoff
211 cosPhi = std::cos(phi),
212 sinPhi = std::sin(phi);
213
214 w0 = G4ThreeVector( dxFudgeTop*cosPhi, dyFudgeTop*sinPhi, +zTopCut );
215 w1 = G4ThreeVector( dxFudgeBot*cosPhi, dyFudgeBot*sinPhi, -zTopCut );
216 transform.ApplyPointTransform( w0 );
217 transform.ApplyPointTransform( w1 );
218
219 //
220 // Add a point to our z ends
221 //
222 endPoly1.AddVertexInOrder( v0 );
223 endPoly2.AddVertexInOrder( v1 );
224
225 //
226 // Build phi polygon
227 //
228 phiPoly.ClearAllVertices();
229
230 phiPoly.AddVertexInOrder( v0 );
231 phiPoly.AddVertexInOrder( v1 );
232 phiPoly.AddVertexInOrder( w1 );
233 phiPoly.AddVertexInOrder( w0 );
234
235 if (phiPoly.PartialClip( voxelLimit, axis ))
236 {
237 //
238 // Get unit normal
239 //
240 phiPoly.SetNormal( (v1-v0).cross(w0-v0).unit() );
241
242 extentList.AddSurface( phiPoly );
243 }
244
245 //
246 // Next vertex
247 //
248 v0 = w0;
249 v1 = w1;
250 } while( --numPhi > 0 );
251
252 //
253 // Process the end pieces
254 //
255 if (endPoly1.PartialClip( voxelLimit, axis ))
256 {
257 static const G4ThreeVector normal(0,0,+1);
258 endPoly1.SetNormal( transform.TransformAxis(normal) );
259 extentList.AddSurface( endPoly1 );
260 }
261
262 if (endPoly2.PartialClip( voxelLimit, axis ))
263 {
264 static const G4ThreeVector normal(0,0,-1);
265 endPoly2.SetNormal( transform.TransformAxis(normal) );
266 extentList.AddSurface( endPoly2 );
267 }
268
269 //
270 // Return min/max value
271 //
272 return extentList.GetExtent( min, max );
273}
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
virtual G4bool PartialClip(const G4VoxelLimits &voxelLimit, const EAxis IgnoreMe)
virtual void AddVertexInOrder(const G4ThreeVector vertex)
virtual void ClearAllVertices()
void SetNormal(const G4ThreeVector &newNormal)
const G4int kMaxMeshSections
Definition: meshdefs.hh:46

◆ Clone()

G4VSolid * G4EllipticalCone::Clone ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 960 of file G4EllipticalCone.cc.

961{
962 return new G4EllipticalCone(*this);
963}

◆ CreateNURBS()

G4NURBS * G4EllipticalCone::CreateNURBS ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 1070 of file G4EllipticalCone.cc.

1071{
1072 // Box for now!!!
1073 //
1074 return new G4NURBSbox(xSemiAxis, ySemiAxis,zheight);
1075}

◆ CreatePolyhedron()

G4Polyhedron * G4EllipticalCone::CreatePolyhedron ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 1077 of file G4EllipticalCone.cc.

1078{
1079 return new G4PolyhedronEllipticalCone(xSemiAxis, ySemiAxis, zheight, zTopCut);
1080}

Referenced by GetPolyhedron().

◆ CreateRotatedVertices()

G4ThreeVectorList * G4EllipticalCone::CreateRotatedVertices ( const G4AffineTransform pT,
G4int noPV 
) const
protected

◆ DescribeYourselfTo()

void G4EllipticalCone::DescribeYourselfTo ( G4VGraphicsScene scene) const
virtual

Implements G4VSolid.

Definition at line 1052 of file G4EllipticalCone.cc.

1053{
1054 scene.AddSolid(*this);
1055}
virtual void AddSolid(const G4Box &)=0

◆ DistanceToIn() [1/2]

G4double G4EllipticalCone::DistanceToIn ( const G4ThreeVector p) const
virtual

Implements G4VSolid.

Definition at line 681 of file G4EllipticalCone.cc.

682{
683 G4double distR, distR2, distZ, maxDim;
684 G4double distRad;
685
686 // check if the point lies either below z=-zTopCut in bottom elliptical
687 // region or on top within cut elliptical region
688 //
689 if( (p.z() <= -zTopCut) && (sqr(p.x()/xSemiAxis) + sqr(p.y()/ySemiAxis)
690 <= sqr(zTopCut + zheight + 0.5*kCarTolerance )) )
691 {
692 //return distZ = std::fabs(zTopCut - p.z());
693 return distZ = std::fabs(zTopCut + p.z());
694 }
695
696 if( (p.z() >= zTopCut) && (sqr(p.x()/xSemiAxis)+sqr(p.y()/ySemiAxis)
697 <= sqr(zheight - zTopCut + kCarTolerance/2.0 )) )
698 {
699 return distZ = std::fabs(p.z() - zTopCut);
700 }
701
702 // below we use the following approximation: we take the largest of the
703 // axes and find the shortest distance to the circular (cut) cone of that
704 // radius.
705 //
706 maxDim = xSemiAxis >= ySemiAxis ? xSemiAxis:ySemiAxis;
707 distRad = std::sqrt(p.x()*p.x()+p.y()*p.y());
708
709 if( p.z() > maxDim*distRad + zTopCut*(1.+maxDim)-sqr(maxDim)*zheight )
710 {
711 distR2 = sqr(p.z() - zTopCut) + sqr(distRad - maxDim*(zheight - zTopCut));
712 return std::sqrt( distR2 );
713 }
714
715 if( distRad > maxDim*( zheight - p.z() ) )
716 {
717 if( p.z() > maxDim*distRad - (zTopCut*(1.+maxDim)+sqr(maxDim)*zheight) )
718 {
719 G4double zVal = (p.z()-maxDim*(distRad-maxDim*zheight))/(1.+sqr(maxDim));
720 G4double rVal = maxDim*(zheight - zVal);
721 return distR = std::sqrt(sqr(p.z() - zVal) + sqr(distRad - rVal));
722 }
723 }
724
725 if( distRad <= maxDim*(zheight - p.z()) )
726 {
727 distR2 = sqr(distRad - maxDim*(zheight + zTopCut)) + sqr(p.z() + zTopCut);
728 return std::sqrt( distR2 );
729 }
730
731 return distR = 0;
732}
double z() const
double x() const
double y() const
G4double kCarTolerance
Definition: G4VSolid.hh:307
T sqr(const T &x)
Definition: templates.hh:145

◆ DistanceToIn() [2/2]

G4double G4EllipticalCone::DistanceToIn ( const G4ThreeVector p,
const G4ThreeVector v 
) const
virtual

Implements G4VSolid.

Definition at line 430 of file G4EllipticalCone.cc.

432{
433 static const G4double halfTol = 0.5*kCarTolerance;
434
435 G4double distMin = kInfinity;
436
437 // code from EllipticalTube
438
439 G4double sigz = p.z()+zTopCut;
440
441 //
442 // Check z = -dz planer surface
443 //
444
445 if (sigz < halfTol)
446 {
447 //
448 // We are "behind" the shape in z, and so can
449 // potentially hit the rear face. Correct direction?
450 //
451 if (v.z() <= 0)
452 {
453 //
454 // As long as we are far enough away, we know we
455 // can't intersect
456 //
457 if (sigz < 0) return kInfinity;
458
459 //
460 // Otherwise, we don't intersect unless we are
461 // on the surface of the ellipse
462 //
463
464 if ( sqr(p.x()/( xSemiAxis - halfTol ))
465 + sqr(p.y()/( ySemiAxis - halfTol )) <= sqr( zheight+zTopCut ) )
466 return kInfinity;
467
468 }
469 else
470 {
471 //
472 // How far?
473 //
474 G4double q = -sigz/v.z();
475
476 //
477 // Where does that place us?
478 //
479 G4double xi = p.x() + q*v.x(),
480 yi = p.y() + q*v.y();
481
482 //
483 // Is this on the surface (within ellipse)?
484 //
485 if ( sqr(xi/xSemiAxis) + sqr(yi/ySemiAxis) <= sqr( zheight + zTopCut ) )
486 {
487 //
488 // Yup. Return q, unless we are on the surface
489 //
490 return (sigz < -halfTol) ? q : 0;
491 }
492 else if (xi/(xSemiAxis*xSemiAxis)*v.x()
493 + yi/(ySemiAxis*ySemiAxis)*v.y() >= 0)
494 {
495 //
496 // Else, if we are traveling outwards, we know
497 // we must miss
498 //
499 // return kInfinity;
500 }
501 }
502 }
503
504 //
505 // Check z = +dz planer surface
506 //
507 sigz = p.z() - zTopCut;
508
509 if (sigz > -halfTol)
510 {
511 if (v.z() >= 0)
512 {
513
514 if (sigz > 0) return kInfinity;
515
516 if ( sqr(p.x()/( xSemiAxis - halfTol ))
517 + sqr(p.y()/( ySemiAxis - halfTol )) <= sqr( zheight-zTopCut ) )
518 return kInfinity;
519
520 }
521 else {
522 G4double q = -sigz/v.z();
523
524 G4double xi = p.x() + q*v.x(),
525 yi = p.y() + q*v.y();
526
527 if ( sqr(xi/xSemiAxis) + sqr(yi/ySemiAxis) <= sqr( zheight - zTopCut ) )
528 {
529 return (sigz > -halfTol) ? q : 0;
530 }
531 else if (xi/(xSemiAxis*xSemiAxis)*v.x()
532 + yi/(ySemiAxis*ySemiAxis)*v.y() >= 0)
533 {
534 // return kInfinity;
535 }
536 }
537 }
538
539
540#if 0
541
542 // check to see if Z plane is relevant
543 //
544 if (p.z() < -zTopCut - 0.5*kCarTolerance)
545 {
546 if (v.z() <= 0.0)
547 return distMin;
548
549 G4double lambda = (-zTopCut - p.z())/v.z();
550
551 if ( sqr((lambda*v.x()+p.x())/xSemiAxis) +
552 sqr((lambda*v.y()+p.y())/ySemiAxis) <=
553 sqr(zTopCut + zheight + 0.5*kRadTolerance) )
554 {
555 return distMin = std::fabs(lambda);
556 }
557 }
558
559 if (p.z() > zTopCut+0.5*kCarTolerance)
560 {
561 if (v.z() >= 0.0)
562 { return distMin; }
563
564 G4double lambda = (zTopCut - p.z()) / v.z();
565
566 if ( sqr((lambda*v.x() + p.x())/xSemiAxis) +
567 sqr((lambda*v.y() + p.y())/ySemiAxis) <=
568 sqr(zheight - zTopCut + 0.5*kRadTolerance) )
569 {
570 return distMin = std::fabs(lambda);
571 }
572 }
573
574 if (p.z() > zTopCut - halfTol
575 && p.z() < zTopCut + halfTol )
576 {
577 if (v.z() > 0.)
578 { return kInfinity; }
579
580 return distMin = 0.;
581 }
582
583 if (p.z() < -zTopCut + halfTol
584 && p.z() > -zTopCut - halfTol)
585 {
586 if (v.z() < 0.)
587 { return distMin = kInfinity; }
588
589 return distMin = 0.;
590 }
591
592#endif
593
594 // if we are here then it either intersects or grazes the curved surface
595 // or it does not intersect at all
596 //
597 G4double A = sqr(v.x()/xSemiAxis) + sqr(v.y()/ySemiAxis) - sqr(v.z());
598 G4double B = 2*(v.x()*p.x()/sqr(xSemiAxis) +
599 v.y()*p.y()/sqr(ySemiAxis) + v.z()*(zheight-p.z()));
600 G4double C = sqr(p.x()/xSemiAxis) + sqr(p.y()/ySemiAxis) -
601 sqr(zheight - p.z());
602
603 G4double discr = B*B - 4.*A*C;
604
605 // if the discriminant is negative it never hits the curved object
606 //
607 if ( discr < -halfTol )
608 { return distMin; }
609
610 // case below is when it hits or grazes the surface
611 //
612 if ( (discr >= - halfTol ) && (discr < halfTol ) )
613 {
614 return distMin = std::fabs(-B/(2.*A));
615 }
616
617 G4double plus = (-B+std::sqrt(discr))/(2.*A);
618 G4double minus = (-B-std::sqrt(discr))/(2.*A);
619
620 // Special case::Point on Surface, Check norm.dot(v)
621
622 if ( ( std::fabs(plus) < halfTol )||( std::fabs(minus) < halfTol ) )
623 {
624 G4ThreeVector truenorm(p.x()/(xSemiAxis*xSemiAxis),
625 p.y()/(ySemiAxis*ySemiAxis),
626 -( p.z() - zheight ));
627 if ( truenorm*v >= 0) // going outside the solid from surface
628 {
629 return kInfinity;
630 }
631 else
632 {
633 return 0;
634 }
635 }
636
637 // G4double lambda = std::fabs(plus) < std::fabs(minus) ? plus : minus;
638 G4double lambda = 0;
639
640 if ( minus > halfTol && minus < distMin )
641 {
642 lambda = minus ;
643 // check normal vector n * v < 0
644 G4ThreeVector pin = p + lambda*v;
645 if(std::fabs(pin.z())<zTopCut+0.5*kCarTolerance)
646 {
647 G4ThreeVector truenorm(pin.x()/(xSemiAxis*xSemiAxis),
648 pin.y()/(ySemiAxis*ySemiAxis),
649 - ( pin.z() - zheight ));
650 if ( truenorm*v < 0)
651 { // yes, going inside the solid
652 distMin = lambda;
653 }
654 }
655 }
656 if ( plus > halfTol && plus < distMin )
657 {
658 lambda = plus ;
659 // check normal vector n * v < 0
660 G4ThreeVector pin = p + lambda*v;
661 if(std::fabs(pin.z())<zTopCut+0.5*kCarTolerance)
662 {
663 G4ThreeVector truenorm(pin.x()/(xSemiAxis*xSemiAxis),
664 pin.y()/(ySemiAxis*ySemiAxis),
665 - ( pin.z() - zheight ) );
666 if ( truenorm*v < 0)
667 { // yes, going inside the solid
668 distMin = lambda;
669 }
670 }
671 }
672 if (distMin < halfTol) distMin=0.;
673 return distMin ;
674}

◆ DistanceToOut() [1/2]

G4double G4EllipticalCone::DistanceToOut ( const G4ThreeVector p) const
virtual

Implements G4VSolid.

Definition at line 901 of file G4EllipticalCone.cc.

902{
903 G4double rds,roo,roo1, distR, distZ, distMin=0.;
904 G4double minAxis = xSemiAxis < ySemiAxis ? xSemiAxis : ySemiAxis;
905
906#ifdef G4SPECSDEBUG
907 if( Inside(p) == kOutside )
908 {
909 DumpInfo();
910 std::ostringstream message;
911 G4int oldprc = message.precision(16);
912 message << "Point p is outside !?" << G4endl
913 << "Position:" << G4endl
914 << " p.x() = " << p.x()/mm << " mm" << G4endl
915 << " p.y() = " << p.y()/mm << " mm" << G4endl
916 << " p.z() = " << p.z()/mm << " mm";
917 message.precision(oldprc) ;
918 G4Exception("G4Ellipsoid::DistanceToOut(p)", "GeomSolids1002",
919 JustWarning, message);
920 }
921#endif
922
923 // since we have made the above warning, below we are working assuming p
924 // is inside check how close it is to the circular cone with radius equal
925 // to the smaller of the axes
926 //
927 if( sqr(p.x()/minAxis)+sqr(p.y()/minAxis) < sqr(zheight - p.z()) )
928 {
929 rds = std::sqrt(sqr(p.x()) + sqr(p.y()));
930 roo = minAxis*(zheight-p.z()); // radius of cone at z= p.z()
931 roo1 = minAxis*(zheight-zTopCut); // radius of cone at z=+zTopCut
932
933 distZ=zTopCut - std::fabs(p.z()) ;
934 distR=(roo-rds)/(std::sqrt(1+sqr(minAxis)));
935
936 if(rds>roo1)
937 {
938 distMin=(zTopCut-p.z())*(roo-rds)/(roo-roo1);
939 distMin=std::min(distMin,distR);
940 }
941 distMin=std::min(distR,distZ);
942 }
943
944 return distMin;
945}
@ JustWarning
#define G4endl
Definition: G4ios.hh:52
EInside Inside(const G4ThreeVector &p) const
void DumpInfo() const
@ kOutside
Definition: geomdefs.hh:58

◆ DistanceToOut() [2/2]

G4double G4EllipticalCone::DistanceToOut ( const G4ThreeVector p,
const G4ThreeVector v,
const G4bool  calcNorm = G4bool(false),
G4bool validNorm = 0,
G4ThreeVector n = 0 
) const
virtual

Implements G4VSolid.

Definition at line 739 of file G4EllipticalCone.cc.

744{
745 G4double distMin, lambda;
746 enum surface_e {kPlaneSurf, kCurvedSurf, kNoSurf} surface;
747
748 distMin = kInfinity;
749 surface = kNoSurf;
750
751 if (v.z() < 0.0)
752 {
753 lambda = (-p.z() - zTopCut)/v.z();
754
755 if ( (sqr((p.x() + lambda*v.x())/xSemiAxis) +
756 sqr((p.y() + lambda*v.y())/ySemiAxis)) <
757 sqr(zheight + zTopCut + 0.5*kCarTolerance) )
758 {
759 distMin = std::fabs(lambda);
760
761 if (!calcNorm) { return distMin; }
762 }
763 distMin = std::fabs(lambda);
764 surface = kPlaneSurf;
765 }
766
767 if (v.z() > 0.0)
768 {
769 lambda = (zTopCut - p.z()) / v.z();
770
771 if ( (sqr((p.x() + lambda*v.x())/xSemiAxis)
772 + sqr((p.y() + lambda*v.y())/ySemiAxis) )
773 < (sqr(zheight - zTopCut + 0.5*kCarTolerance)) )
774 {
775 distMin = std::fabs(lambda);
776 if (!calcNorm) { return distMin; }
777 }
778 distMin = std::fabs(lambda);
779 surface = kPlaneSurf;
780 }
781
782 // if we are here then it either intersects or grazes the
783 // curved surface...
784 //
785 G4double A = sqr(v.x()/xSemiAxis) + sqr(v.y()/ySemiAxis) - sqr(v.z());
786 G4double B = 2.*(v.x()*p.x()/sqr(xSemiAxis) +
787 v.y()*p.y()/sqr(ySemiAxis) + v.z()*(zheight-p.z()));
788 G4double C = sqr(p.x()/xSemiAxis) + sqr(p.y()/ySemiAxis)
789 - sqr(zheight - p.z());
790
791 G4double discr = B*B - 4.*A*C;
792
793 if ( discr >= - 0.5*kCarTolerance && discr < 0.5*kCarTolerance )
794 {
795 if(!calcNorm) { return distMin = std::fabs(-B/(2.*A)); }
796 }
797
798 else if ( discr > 0.5*kCarTolerance )
799 {
800 G4double plus = (-B+std::sqrt(discr))/(2.*A);
801 G4double minus = (-B-std::sqrt(discr))/(2.*A);
802
803 if ( plus > 0.5*kCarTolerance && minus > 0.5*kCarTolerance )
804 {
805 // take the shorter distance
806 //
807 lambda = std::fabs(plus) < std::fabs(minus) ? plus : minus;
808 }
809 else
810 {
811 // at least one solution is close to zero or negative
812 // so, take small positive solution or zero
813 //
814 lambda = plus > -0.5*kCarTolerance ? plus : 0;
815 }
816
817 if ( std::fabs(lambda) < distMin )
818 {
819 if( std::fabs(lambda) > 0.5*kCarTolerance)
820 {
821 distMin = std::fabs(lambda);
822 surface = kCurvedSurf;
823 }
824 else // Point is On the Surface, Check Normal
825 {
826 G4ThreeVector truenorm(p.x()/(xSemiAxis*xSemiAxis),
827 p.y()/(ySemiAxis*ySemiAxis),
828 -( p.z() - zheight ));
829 if( truenorm.dot(v) > 0 )
830 {
831 distMin = 0.0;
832 surface = kCurvedSurf;
833 }
834 }
835 }
836 }
837
838 // set normal if requested
839 //
840 if (calcNorm)
841 {
842 if (surface == kNoSurf)
843 {
844 *validNorm = false;
845 }
846 else
847 {
848 *validNorm = true;
849 switch (surface)
850 {
851 case kPlaneSurf:
852 {
853 *n = G4ThreeVector(0.,0.,(v.z() > 0.0 ? 1. : -1.));
854 }
855 break;
856
857 case kCurvedSurf:
858 {
859 G4ThreeVector pexit = p + distMin*v;
860 G4ThreeVector truenorm( pexit.x()/(xSemiAxis*xSemiAxis),
861 pexit.y()/(ySemiAxis*ySemiAxis),
862 -( pexit.z() - zheight ) );
863 truenorm /= truenorm.mag();
864 *n= truenorm;
865 }
866 break;
867
868 default: // Should never reach this case ...
869 DumpInfo();
870 std::ostringstream message;
871 G4int oldprc = message.precision(16);
872 message << "Undefined side for valid surface normal to solid."
873 << G4endl
874 << "Position:" << G4endl
875 << " p.x() = " << p.x()/mm << " mm" << G4endl
876 << " p.y() = " << p.y()/mm << " mm" << G4endl
877 << " p.z() = " << p.z()/mm << " mm" << G4endl
878 << "Direction:" << G4endl
879 << " v.x() = " << v.x() << G4endl
880 << " v.y() = " << v.y() << G4endl
881 << " v.z() = " << v.z() << G4endl
882 << "Proposed distance :" << G4endl
883 << " distMin = " << distMin/mm << " mm";
884 message.precision(oldprc);
885 G4Exception("G4EllipticalCone::DistanceToOut(p,v,..)",
886 "GeomSolids1002", JustWarning, message);
887 break;
888 }
889 }
890 }
891
892 if (distMin<0.5*kCarTolerance) { distMin=0; }
893
894 return distMin;
895}

◆ GetCubicVolume()

G4double G4EllipticalCone::GetCubicVolume ( )
inlinevirtual

Reimplemented from G4VSolid.

◆ GetEntityType()

G4GeometryType G4EllipticalCone::GetEntityType ( ) const
virtual

Implements G4VSolid.

Definition at line 951 of file G4EllipticalCone.cc.

952{
953 return G4String("G4EllipticalCone");
954}

◆ GetExtent()

G4VisExtent G4EllipticalCone::GetExtent ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 1057 of file G4EllipticalCone.cc.

1058{
1059 // Define the sides of the box into which the solid instance would fit.
1060 //
1061 G4double maxDim;
1062 maxDim = xSemiAxis > ySemiAxis ? xSemiAxis : ySemiAxis;
1063 maxDim = maxDim > zTopCut ? maxDim : zTopCut;
1064
1065 return G4VisExtent (-maxDim, maxDim,
1066 -maxDim, maxDim,
1067 -maxDim, maxDim);
1068}

◆ GetPointOnSurface()

G4ThreeVector G4EllipticalCone::GetPointOnSurface ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 994 of file G4EllipticalCone.cc.

995{
996
997 G4double phi, sinphi, cosphi, aOne, aTwo, aThree,
998 chose, zRand, rRand1, rRand2;
999
1000 G4double rOne = std::sqrt(sqr(xSemiAxis)
1001 + sqr(ySemiAxis))*(zheight - zTopCut);
1002 G4double rTwo = std::sqrt(sqr(xSemiAxis)
1003 + sqr(ySemiAxis))*(zheight + zTopCut);
1004
1005 aOne = pi*(rOne + rTwo)*std::sqrt(sqr(rOne - rTwo)+sqr(2.*zTopCut));
1006 aTwo = pi*xSemiAxis*ySemiAxis*sqr(zheight+zTopCut);
1007 aThree = pi*xSemiAxis*ySemiAxis*sqr(zheight-zTopCut);
1008
1009 phi = RandFlat::shoot(0.,twopi);
1010 cosphi = std::cos(phi);
1011 sinphi = std::sin(phi);
1012
1013 if(zTopCut >= zheight) aThree = 0.;
1014
1015 chose = RandFlat::shoot(0.,aOne+aTwo+aThree);
1016 if((chose>=0.) && (chose<aOne))
1017 {
1018 zRand = RandFlat::shoot(-zTopCut,zTopCut);
1019 return G4ThreeVector(xSemiAxis*(zheight-zRand)*cosphi,
1020 ySemiAxis*(zheight-zRand)*sinphi,zRand);
1021 }
1022 else if((chose>=aOne) && (chose<aOne+aTwo))
1023 {
1024 do
1025 {
1026 rRand1 = RandFlat::shoot(0.,1.) ;
1027 rRand2 = RandFlat::shoot(0.,1.) ;
1028 } while ( rRand2 >= rRand1 ) ;
1029
1030 // rRand2 = RandFlat::shoot(0.,std::sqrt(1.-sqr(rRand1)));
1031 return G4ThreeVector(rRand1*xSemiAxis*(zheight+zTopCut)*cosphi,
1032 rRand1*ySemiAxis*(zheight+zTopCut)*sinphi, -zTopCut);
1033
1034 }
1035 // else
1036 //
1037
1038 do
1039 {
1040 rRand1 = RandFlat::shoot(0.,1.) ;
1041 rRand2 = RandFlat::shoot(0.,1.) ;
1042 } while ( rRand2 >= rRand1 ) ;
1043
1044 return G4ThreeVector(rRand1*xSemiAxis*(zheight-zTopCut)*cosphi,
1045 rRand1*ySemiAxis*(zheight-zTopCut)*sinphi, zTopCut);
1046}
static double shoot()
Definition: RandFlat.cc:59
const G4double pi

◆ GetPolyhedron()

G4Polyhedron * G4EllipticalCone::GetPolyhedron ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 1082 of file G4EllipticalCone.cc.

1083{
1084 if ( (!fpPolyhedron)
1087 {
1088 delete fpPolyhedron;
1090 }
1091 return fpPolyhedron;
1092}
G4Polyhedron * CreatePolyhedron() const
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
static G4int GetNumberOfRotationSteps()

◆ GetSemiAxisMax()

G4double G4EllipticalCone::GetSemiAxisMax ( ) const
inline

◆ GetSemiAxisX()

G4double G4EllipticalCone::GetSemiAxisX ( ) const
inline

◆ GetSemiAxisY()

G4double G4EllipticalCone::GetSemiAxisY ( ) const
inline

◆ GetSurfaceArea()

G4double G4EllipticalCone::GetSurfaceArea ( )
inlinevirtual

Reimplemented from G4VSolid.

◆ GetZMax()

G4double G4EllipticalCone::GetZMax ( ) const
inline

◆ GetZTopCut()

G4double G4EllipticalCone::GetZTopCut ( ) const
inline

◆ Inside()

EInside G4EllipticalCone::Inside ( const G4ThreeVector p) const
virtual

Implements G4VSolid.

Definition at line 281 of file G4EllipticalCone.cc.

282{
283 G4double rad2oo, // outside surface outer tolerance
284 rad2oi; // outside surface inner tolerance
285
286 EInside in;
287
288 static const G4double halfRadTol = 0.5*kRadTolerance;
289 static const G4double halfCarTol = 0.5*kCarTolerance;
290
291 // check this side of z cut first, because that's fast
292 //
293
294 if ( (p.z() < -zTopCut - halfCarTol)
295 || (p.z() > zTopCut + halfCarTol ) )
296 {
297 return in = kOutside;
298 }
299
300 rad2oo= sqr(p.x()/( xSemiAxis + halfRadTol ))
301 + sqr(p.y()/( ySemiAxis + halfRadTol ));
302
303 if ( rad2oo > sqr( zheight-p.z() ) )
304 {
305 return in = kOutside;
306 }
307
308 // rad2oi= sqr( p.x()*(1.0 + 0.5*kRadTolerance/(xSemiAxis*xSemiAxis)) )
309 // + sqr( p.y()*(1.0 + 0.5*kRadTolerance/(ySemiAxis*ySemiAxis)) );
310 rad2oi = sqr(p.x()/( xSemiAxis - halfRadTol ))
311 + sqr(p.y()/( ySemiAxis - halfRadTol ));
312
313 if (rad2oi < sqr( zheight-p.z() ) )
314 {
315 in = ( ( p.z() < -zTopCut + halfRadTol )
316 || ( p.z() > zTopCut - halfRadTol ) ) ? kSurface : kInside;
317 }
318 else
319 {
320 in = kSurface;
321 }
322
323 return in;
324}
EInside
Definition: geomdefs.hh:58
@ kInside
Definition: geomdefs.hh:58
@ kSurface
Definition: geomdefs.hh:58

Referenced by DistanceToOut().

◆ operator=()

G4EllipticalCone & G4EllipticalCone::operator= ( const G4EllipticalCone rhs)

Definition at line 137 of file G4EllipticalCone.cc.

138{
139 // Check assignment to self
140 //
141 if (this == &rhs) { return *this; }
142
143 // Copy base class data
144 //
146
147 // Copy data
148 //
149 fpPolyhedron = 0; kRadTolerance = rhs.kRadTolerance;
150 fCubicVolume = rhs.fCubicVolume; fSurfaceArea = rhs.fSurfaceArea;
151 xSemiAxis = rhs.xSemiAxis; ySemiAxis = rhs.ySemiAxis;
152 zheight = rhs.zheight; semiAxisMax = rhs.semiAxisMax; zTopCut = rhs.zTopCut;
153
154 return *this;
155}
G4VSolid & operator=(const G4VSolid &rhs)
Definition: G4VSolid.cc:110

◆ SetSemiAxis()

void G4EllipticalCone::SetSemiAxis ( G4double  x,
G4double  y,
G4double  z 
)
inline

Referenced by G4EllipticalCone().

◆ SetZCut()

void G4EllipticalCone::SetZCut ( G4double  newzTopCut)
inline

Referenced by G4EllipticalCone().

◆ StreamInfo()

std::ostream & G4EllipticalCone::StreamInfo ( std::ostream &  os) const
virtual

Implements G4VSolid.

Definition at line 969 of file G4EllipticalCone.cc.

970{
971 G4int oldprc = os.precision(16);
972 os << "-----------------------------------------------------------\n"
973 << " *** Dump for solid - " << GetName() << " ***\n"
974 << " ===================================================\n"
975 << " Solid type: G4EllipticalCone\n"
976 << " Parameters: \n"
977
978 << " semi-axis x: " << xSemiAxis/mm << " mm \n"
979 << " semi-axis y: " << ySemiAxis/mm << " mm \n"
980 << " height z: " << zheight/mm << " mm \n"
981 << " half length in z: " << zTopCut/mm << " mm \n"
982 << "-----------------------------------------------------------\n";
983 os.precision(oldprc);
984
985 return os;
986}

◆ SurfaceNormal()

G4ThreeVector G4EllipticalCone::SurfaceNormal ( const G4ThreeVector p) const
virtual

Implements G4VSolid.

Definition at line 330 of file G4EllipticalCone.cc.

331{
332
333 G4double rx = sqr(p.x()/xSemiAxis),
334 ry = sqr(p.y()/ySemiAxis);
335
336 G4double rds = std::sqrt(rx + ry);
337
338 G4ThreeVector norm;
339
340 if( (p.z() < -zTopCut) && ((rx+ry) < sqr(zTopCut + zheight)) )
341 {
342 return G4ThreeVector( 0., 0., -1. );
343 }
344
345 if( (p.z() > (zheight > zTopCut ? zheight : zTopCut)) &&
346 ((rx+ry) < sqr(zheight-zTopCut)) )
347 {
348 return G4ThreeVector( 0., 0., 1. );
349 }
350
351 if( p.z() > rds + 2.*zTopCut - zheight )
352 {
353 if ( p.z() > zTopCut )
354 {
355 if( p.x() == 0. )
356 {
357 norm = G4ThreeVector( 0., p.y() < 0. ? -1. : 1., 1. );
358 return norm /= norm.mag();
359 }
360 if( p.y() == 0. )
361 {
362 norm = G4ThreeVector( p.x() < 0. ? -1. : 1., 0., 1. );
363 return norm /= norm.mag();
364 }
365
366 G4double k = std::fabs(p.x()/p.y());
367 G4double c2 = sqr(zheight-zTopCut)/(1./sqr(xSemiAxis)+sqr(k/ySemiAxis));
368 G4double x = std::sqrt(c2);
369 G4double y = k*x;
370
371 x /= sqr(xSemiAxis);
372 y /= sqr(ySemiAxis);
373
374 norm = G4ThreeVector( p.x() < 0. ? -x : x,
375 p.y() < 0. ? -y : y,
376 - ( zheight - zTopCut ) );
377 norm /= norm.mag();
378 norm += G4ThreeVector( 0., 0., 1. );
379 return norm /= norm.mag();
380 }
381
382 return G4ThreeVector( 0., 0., 1. );
383 }
384
385 if( p.z() < rds - 2.*zTopCut - zheight )
386 {
387 if( p.x() == 0. )
388 {
389 norm = G4ThreeVector( 0., p.y() < 0. ? -1. : 1., -1. );
390 return norm /= norm.mag();
391 }
392 if( p.y() == 0. )
393 {
394 norm = G4ThreeVector( p.x() < 0. ? -1. : 1., 0., -1. );
395 return norm /= norm.mag();
396 }
397
398 G4double k = std::fabs(p.x()/p.y());
399 G4double c2 = sqr(zheight+zTopCut)/(1./sqr(xSemiAxis)+sqr(k/ySemiAxis));
400 G4double x = std::sqrt(c2);
401 G4double y = k*x;
402
403 x /= sqr(xSemiAxis);
404 y /= sqr(ySemiAxis);
405
406 norm = G4ThreeVector( p.x() < 0. ? -x : x,
407 p.y() < 0. ? -y : y,
408 - ( zheight - zTopCut ) );
409 norm /= norm.mag();
410 norm += G4ThreeVector( 0., 0., -1. );
411 return norm /= norm.mag();
412 }
413
414 norm = G4ThreeVector(p.x()/sqr(xSemiAxis), p.y()/sqr(ySemiAxis), rds);
415
416 G4double k = std::tan(pi/8.);
417 G4double c = -zTopCut - k*(zTopCut + zheight);
418
419 if( p.z() < -k*rds + c )
420 return G4ThreeVector (0.,0.,-1.);
421
422 return norm /= norm.mag();
423}
double mag() const

Member Data Documentation

◆ fpPolyhedron

G4Polyhedron* G4EllipticalCone::fpPolyhedron
mutableprotected

Definition at line 165 of file G4EllipticalCone.hh.

Referenced by GetPolyhedron(), and operator=().


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