42 #if !defined(G4GEOM_USE_UORB)
57 using namespace CLHEP;
87 "Invalid radius > 10*kCarTolerance.");
89 fRmaxTolerance =
std::max( kRadTolerance, fEpsilon*fRmax);
116 :
G4CSGSolid(rhs), fRmax(rhs.fRmax), fRmaxTolerance(rhs.fRmaxTolerance)
128 if (
this == &rhs) {
return *
this; }
137 fRmaxTolerance = rhs.fRmaxTolerance;
171 G4double diff1,diff2,delta,maxDiff,newMin,newMax;
252 if ( yoff1 >= 0 && yoff2 >= 0 )
264 delta=fRmax*fRmax-yoff1*yoff1;
265 diff1=(delta>0.) ? std::sqrt(delta) : 0.;
266 delta=fRmax*fRmax-yoff2*yoff2;
267 diff2=(delta>0.) ? std::sqrt(delta) : 0.;
268 maxDiff=(diff1>diff2) ? diff1:diff2;
269 newMin=xoffset-maxDiff;
270 newMax=xoffset+maxDiff;
271 pMin=(newMin<xMin) ? xMin : newMin;
272 pMax=(newMax>xMax) ? xMax : newMax;
278 if (xoff1>=0&&xoff2>=0)
290 delta=fRmax*fRmax-xoff1*xoff1;
291 diff1=(delta>0.) ? std::sqrt(delta) : 0.;
292 delta=fRmax*fRmax-xoff2*xoff2;
293 diff2=(delta>0.) ? std::sqrt(delta) : 0.;
294 maxDiff=(diff1>diff2) ? diff1:diff2;
295 newMin=yoffset-maxDiff;
296 newMax=yoffset+maxDiff;
297 pMin=(newMin<yMin) ? yMin : newMin;
298 pMax=(newMax>yMax) ? yMax : newMax;
308 pMin -= fRmaxTolerance;
309 pMax += fRmaxTolerance;
327 rad2 = p.
x()*p.
x()+p.
y()*p.
y()+p.
z()*p.
z();
335 tolRMax = fRmax - fRmaxTolerance*0.5;
337 if ( radius <= tolRMax ) { in =
kInside; }
340 tolRMax = fRmax + fRmaxTolerance*0.5;
341 if ( radius <= tolRMax ) { in =
kSurface; }
367 "Undefined side for valid surface normal to solid.");
395 radius = std::sqrt(p.
x()*p.
x() + p.
y()*p.
y() + p.
z()*p.
z());
396 pDotV3d = p.
x()*v.
x() + p.
y()*v.
y() + p.
z()*v.
z();
417 c = (radius - fRmax)*(radius + fRmax);
419 if( radius > fRmax-fRmaxTolerance*0.5 )
421 if ( c > fRmaxTolerance*fRmax )
426 d2 = pDotV3d*pDotV3d -
c;
430 sd = -pDotV3d - std::sqrt(d2);
435 G4double fTerm = sd - std::fmod(sd,dRmax);
443 return snxt = kInfinity;
448 if ( c > -fRmaxTolerance*fRmax )
450 d2 = pDotV3d*pDotV3d -
c;
451 if ( (d2 < fRmaxTolerance*fRmax) || (pDotV3d >= 0) )
453 return snxt = kInfinity;
465 G4Exception(
"G4Orb::DistanceToIn(p,v)",
"GeomSolids1002",
482 radius = std::sqrt(p.
x()*p.
x()+p.
y()*p.
y()+p.
z()*p.
z());
483 safe = radius - fRmax;
484 if( safe < 0 ) { safe = 0.; }
506 rad2 = p.
x()*p.
x() + p.
y()*p.
y() + p.
z()*p.
z();
507 pDotV3d = p.
x()*v.
x() + p.
y()*v.
y() + p.
z()*v.
z();
525 const G4double Rmax_plus = fRmax + fRmaxTolerance*0.5;
528 if ( radius <= Rmax_plus )
530 c = (radius - fRmax)*(radius + fRmax);
532 if ( c < fRmaxTolerance*fRmax )
543 d2 = pDotV3d*pDotV3d -
c;
545 if( ( c > -fRmaxTolerance*fRmax) &&
546 ( ( pDotV3d >= 0 ) || ( d2 < 0 )) )
558 snxt = -pDotV3d + std::sqrt(d2);
567 std::ostringstream message;
568 G4int oldprc = message.precision(16);
569 message <<
"Logic error: snxt = kInfinity ???" << G4endl
570 <<
"Position:" << G4endl << G4endl
571 <<
"p.x() = " << p.
x()/
mm <<
" mm" << G4endl
572 <<
"p.y() = " << p.
y()/
mm <<
" mm" << G4endl
573 <<
"p.z() = " << p.
z()/
mm <<
" mm" << G4endl << G4endl
574 <<
"Rp = "<< std::sqrt( p.
x()*p.
x()+p.
y()*p.
y()+p.
z()*p.
z() )/
mm
575 <<
" mm" << G4endl << G4endl
576 <<
"Direction:" << G4endl << G4endl
577 <<
"v.x() = " << v.
x() << G4endl
578 <<
"v.y() = " << v.
y() << G4endl
579 <<
"v.z() = " << v.
z() << G4endl << G4endl
580 <<
"Proposed distance :" << G4endl << G4endl
581 <<
"snxt = " << snxt/
mm <<
" mm" <<
G4endl;
582 message.precision(oldprc);
583 G4Exception(
"G4Orb::DistanceToOut(p,v,..)",
"GeomSolids1002",
600 std::ostringstream message;
601 G4int oldprc = message.precision(16);
602 message <<
"Undefined side for valid surface normal to solid."
604 <<
"Position:" << G4endl << G4endl
605 <<
"p.x() = " << p.
x()/
mm <<
" mm" << G4endl
606 <<
"p.y() = " << p.
y()/
mm <<
" mm" << G4endl
607 <<
"p.z() = " << p.
z()/
mm <<
" mm" << G4endl << G4endl
608 <<
"Direction:" << G4endl << G4endl
609 <<
"v.x() = " << v.
x() << G4endl
610 <<
"v.y() = " << v.
y() << G4endl
611 <<
"v.z() = " << v.
z() << G4endl << G4endl
612 <<
"Proposed distance :" << G4endl << G4endl
613 <<
"snxt = " << snxt/
mm <<
" mm" <<
G4endl;
614 message.precision(oldprc);
615 G4Exception(
"G4Orb::DistanceToOut(p,v,..)",
"GeomSolids1002",
629 G4double safe=0.0,radius = std::sqrt(p.
x()*p.
x()+p.
y()*p.
y()+p.
z()*p.
z());
642 G4Exception(
"G4Orb::DistanceToOut(p)",
"GeomSolids1002",
647 safe = fRmax - radius;
648 if ( safe < 0. ) safe = 0.;
667 return new G4Orb(*
this);
676 G4int oldprc = os.precision(16);
677 os <<
"-----------------------------------------------------------\n"
678 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
679 <<
" ===================================================\n"
680 <<
" Solid type: G4Orb\n"
683 <<
" outer radius: " << fRmax/
mm <<
" mm \n"
684 <<
"-----------------------------------------------------------\n";
685 os.precision(oldprc);
707 fRmax*sintheta*sinphi, fRmax*costheta);
ThreeVector shoot(const G4int Ap, const G4int Af)
G4Orb & operator=(const G4Orb &rhs)
G4double GetMinYExtent() const
CLHEP::Hep3Vector G4ThreeVector
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
G4bool IsYLimited() const
void DescribeYourselfTo(G4VGraphicsScene &scene) const
G4bool IsXLimited() const
G4ThreeVector GetPointOnSurface() const
virtual void AddSolid(const G4Box &)=0
EInside Inside(const G4ThreeVector &p) const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4Polyhedron * CreatePolyhedron() const
G4Orb(const G4String &pName, G4double pRmax)
std::ostream & StreamInfo(std::ostream &os) const
G4double GetMaxXExtent() const
G4double GetMinZExtent() const
G4GLOB_DLL std::ostream G4cout
G4GeometryType GetEntityType() const
G4double GetRadialTolerance() const
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
G4double GetMinXExtent() const
G4double GetMaxZExtent() const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
G4double GetMaxYExtent() const
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=G4bool(false), G4bool *validNorm=0, G4ThreeVector *n=0) const
G4CSGSolid & operator=(const G4CSGSolid &rhs)
G4bool IsZLimited() const
static G4GeometryTolerance * GetInstance()
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const