43 #if !defined(G4GEOM_USE_UORB)
59 using namespace CLHEP;
89 "Invalid radius < 10*kCarTolerance.");
91 fRmaxTolerance =
std::max( kRadTolerance, fEpsilon*fRmax);
101 :
G4CSGSolid(a), fRmax(0.), fRmaxTolerance(0.)
118 :
G4CSGSolid(rhs), fRmax(rhs.fRmax), fRmaxTolerance(rhs.fRmaxTolerance)
130 if (
this == &rhs) {
return *
this; }
139 fRmaxTolerance = rhs.fRmaxTolerance;
163 pMin.
set(-radius,-radius,-radius);
164 pMax.
set( radius, radius, radius);
168 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
170 std::ostringstream message;
171 message <<
"Bad bounding box (min >= max) for solid: "
173 <<
"\npMin = " << pMin
174 <<
"\npMax = " << pMax;
198 if (
true)
return bbox.
CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
202 return exist = (pMin < pMax) ?
true :
false;
207 static const G4int NTHETA = 8;
208 static const G4int NPHI = 16;
211 static const G4double sinHalfPhi = std::sin(
pi/NPHI);
212 static const G4double cosHalfPhi = std::cos(
pi/NPHI);
213 static const G4double sinStepTheta = 2.*sinHalfTheta*cosHalfTheta;
214 static const G4double cosStepTheta = 1. - 2.*sinHalfTheta*sinHalfTheta;
215 static const G4double sinStepPhi = 2.*sinHalfPhi*cosHalfPhi;
216 static const G4double cosStepPhi = 1. - 2.*sinHalfPhi*sinHalfPhi;
219 G4double rtheta = radius/cosHalfTheta;
226 for (
G4int k=0; k<NPHI; ++k)
228 xy[k].
set(cosCurPhi,sinCurPhi);
230 sinCurPhi = sinCurPhi*cosStepPhi + cosCurPhi*sinStepPhi;
231 cosCurPhi = cosCurPhi*cosStepPhi - sinTmpPhi*sinStepPhi;
236 for (
G4int i=0; i<NTHETA; ++i) circles[i].resize(NPHI);
238 G4double sinCurTheta = sinHalfTheta;
239 G4double cosCurTheta = cosHalfTheta;
240 for (
G4int i=0; i<NTHETA; ++i)
244 for (
G4int k=0; k<NPHI; ++k)
246 circles[i][k].set(rho*xy[k].x(),rho*xy[k].y(),z);
249 sinCurTheta = sinCurTheta*cosStepTheta + cosCurTheta*sinStepTheta;
250 cosCurTheta = cosCurTheta*cosStepTheta - sinTmpTheta*sinStepTheta;
254 std::vector<const G4ThreeVectorList *> polygons;
255 polygons.resize(NTHETA);
256 for (
G4int i=0; i<NTHETA; ++i) polygons[i] = &circles[i];
275 rad2 = p.
x()*p.
x()+p.
y()*p.
y()+p.
z()*p.
z();
283 tolRMax = fRmax - fRmaxTolerance*0.5;
285 if ( radius <= tolRMax ) { in =
kInside; }
288 tolRMax = fRmax + fRmaxTolerance*0.5;
289 if ( radius <= tolRMax ) { in =
kSurface; }
326 radius = std::sqrt(p.
x()*p.
x() + p.
y()*p.
y() + p.
z()*p.
z());
327 pDotV3d = p.
x()*v.
x() + p.
y()*v.
y() + p.
z()*v.
z();
348 c = (radius - fRmax)*(radius + fRmax);
350 if( radius > fRmax-fRmaxTolerance*0.5 )
352 if ( c > fRmaxTolerance*fRmax )
357 d2 = pDotV3d*pDotV3d - c;
361 sd = -pDotV3d - std::sqrt(d2);
366 G4double fTerm = sd - std::fmod(sd,dRmax);
379 if ( c > -fRmaxTolerance*fRmax )
381 d2 = pDotV3d*pDotV3d - c;
382 if ( (d2 < fRmaxTolerance*fRmax) || (pDotV3d >= 0) )
396 G4Exception(
"G4Orb::DistanceToIn(p,v)",
"GeomSolids1002",
413 radius = std::sqrt(p.
x()*p.
x()+p.
y()*p.
y()+p.
z()*p.
z());
414 safe = radius - fRmax;
415 if( safe < 0 ) { safe = 0.; }
437 rad2 = p.
x()*p.
x() + p.
y()*p.
y() + p.
z()*p.
z();
438 pDotV3d = p.
x()*v.
x() + p.
y()*v.
y() + p.
z()*v.
z();
456 const G4double Rmax_plus = fRmax + fRmaxTolerance*0.5;
459 if ( radius <= Rmax_plus )
461 c = (radius - fRmax)*(radius + fRmax);
463 if ( c < fRmaxTolerance*fRmax )
474 d2 = pDotV3d*pDotV3d - c;
476 if( ( c > -fRmaxTolerance*fRmax) &&
477 ( ( pDotV3d >= 0 ) || ( d2 < 0 )) )
489 snxt = -pDotV3d + std::sqrt(d2);
498 std::ostringstream message;
499 G4int oldprc = message.precision(16);
500 message <<
"Logic error: snxt = kInfinity ???" << G4endl
501 <<
"Position:" << G4endl << G4endl
502 <<
"p.x() = " << p.
x()/
mm <<
" mm" << G4endl
503 <<
"p.y() = " << p.
y()/
mm <<
" mm" << G4endl
504 <<
"p.z() = " << p.
z()/
mm <<
" mm" << G4endl << G4endl
505 <<
"Rp = "<< std::sqrt( p.
x()*p.
x()+p.
y()*p.
y()+p.
z()*p.
z() )/
mm
506 <<
" mm" << G4endl << G4endl
507 <<
"Direction:" << G4endl << G4endl
508 <<
"v.x() = " << v.
x() << G4endl
509 <<
"v.y() = " << v.
y() << G4endl
510 <<
"v.z() = " << v.
z() << G4endl << G4endl
511 <<
"Proposed distance :" << G4endl << G4endl
512 <<
"snxt = " << snxt/
mm <<
" mm" <<
G4endl;
513 message.precision(oldprc);
514 G4Exception(
"G4Orb::DistanceToOut(p,v,..)",
"GeomSolids1002",
531 std::ostringstream message;
532 G4int oldprc = message.precision(16);
533 message <<
"Undefined side for valid surface normal to solid."
535 <<
"Position:" << G4endl << G4endl
536 <<
"p.x() = " << p.
x()/
mm <<
" mm" << G4endl
537 <<
"p.y() = " << p.
y()/
mm <<
" mm" << G4endl
538 <<
"p.z() = " << p.
z()/
mm <<
" mm" << G4endl << G4endl
539 <<
"Direction:" << G4endl << G4endl
540 <<
"v.x() = " << v.
x() << G4endl
541 <<
"v.y() = " << v.
y() << G4endl
542 <<
"v.z() = " << v.
z() << G4endl << G4endl
543 <<
"Proposed distance :" << G4endl << G4endl
544 <<
"snxt = " << snxt/
mm <<
" mm" <<
G4endl;
545 message.precision(oldprc);
546 G4Exception(
"G4Orb::DistanceToOut(p,v,..)",
"GeomSolids1002",
560 G4double safe=0.0,radius = std::sqrt(p.
x()*p.
x()+p.
y()*p.
y()+p.
z()*p.
z());
573 G4Exception(
"G4Orb::DistanceToOut(p)",
"GeomSolids1002",
578 safe = fRmax - radius;
579 if ( safe < 0. ) safe = 0.;
598 return new G4Orb(*
this);
607 G4int oldprc = os.precision(16);
608 os <<
"-----------------------------------------------------------\n"
609 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
610 <<
" ===================================================\n"
611 <<
" Solid type: G4Orb\n"
614 <<
" outer radius: " << fRmax/
mm <<
" mm \n"
615 <<
"-----------------------------------------------------------\n";
616 os.precision(oldprc);
638 fRmax*sintheta*sinphi, fRmax*costheta);
void set(double x, double y, double z)
ThreeVector shoot(const G4int Ap, const G4int Af)
void Extent(G4ThreeVector &pMin, G4ThreeVector &pMax) const
static constexpr double mm
static const G4double kInfinity
G4Orb & operator=(const G4Orb &rhs)
CLHEP::Hep3Vector G4ThreeVector
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
void DescribeYourselfTo(G4VGraphicsScene &scene) 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
G4double GetRadius() const
G4Orb(const G4String &pName, G4double pRmax)
std::ostream & StreamInfo(std::ostream &os) const
G4GLOB_DLL std::ostream G4cout
G4GeometryType GetEntityType() const
void set(double x, double y)
G4double GetRadialTolerance() const
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool BoundingBoxVsVoxelLimits(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
std::vector< G4ThreeVector > G4ThreeVectorList
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
static constexpr double pi
static constexpr double halfpi
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)
static G4GeometryTolerance * GetInstance()
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const