38#if !(defined(G4GEOM_USE_UELLIPTICALCONE) && defined(G4GEOM_USE_SYS_USOLIDS))
83 if ( (pxSemiAxis <= 0.) || (pySemiAxis <= 0.) || (pzMax <= 0.) )
85 std::ostringstream message;
86 message <<
"Invalid semi-axis or height for solid: " <<
GetName()
87 <<
"\n X semi-axis, Y semi-axis, height = "
88 << pxSemiAxis <<
", " << pySemiAxis <<
", " << pzMax;
89 G4Exception(
"G4EllipticalCone::G4EllipticalCone()",
"GeomSolids0002",
95 std::ostringstream message;
96 message <<
"Invalid z-coordinate for cutting plane for solid: " <<
GetName()
97 <<
"\n Z top cut = " << pzTopCut;
98 G4Exception(
"G4EllipticalCone::G4EllipticalCone()",
"GeomSolids0002",
113 xSemiAxis(0.), ySemiAxis(0.), zheight(0.), zTopCut(0.),
114 cosAxisMin(0.), invXX(0.), invYY(0.)
132 :
G4VSolid(rhs), halfCarTol(rhs.halfCarTol),
133 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
134 xSemiAxis(rhs.xSemiAxis), ySemiAxis(rhs.ySemiAxis),
135 zheight(rhs.zheight), zTopCut(rhs.zTopCut),
136 cosAxisMin(rhs.cosAxisMin), invXX(rhs.invXX), invYY(rhs.invYY)
148 if (
this == &rhs) {
return *
this; }
179 pMin.set(-xmax,-ymax,-zcut);
180 pMax.set( xmax, ymax, zcut);
186 std::ostringstream message;
187 message <<
"Bad bounding box (min >= max) for solid: "
189 <<
"\npMin = " <<
pMin
190 <<
"\npMax = " <<
pMax;
191 G4Exception(
"G4EllipticalCone::BoundingLimits()",
"GeomMgt0001",
219 return exist = (
pMin <
pMax) ?
true :
false;
224 static const G4int NSTEPS = 48;
226 static const G4double sinHalf = std::sin(0.5*ang);
227 static const G4double cosHalf = std::cos(0.5*ang);
228 static const G4double sinStep = 2.*sinHalf*cosHalf;
229 static const G4double cosStep = 1. - 2.*sinHalf*sinHalf;
240 for (
G4int k=0; k<NSTEPS; ++k)
242 baseA[k].set(sxmax*cosCur,symax*sinCur,-zcut);
243 baseB[k].set(sxmin*cosCur,symin*sinCur, zcut);
246 sinCur = sinCur*cosStep + cosCur*sinStep;
247 cosCur = cosCur*cosStep - sinTmp*sinStep;
250 std::vector<const G4ThreeVectorList *> polygons(2);
251 polygons[0] = &baseA;
252 polygons[1] = &baseB;
299 if (nsurf == 1)
return norm;
300 else if (nsurf > 1)
return norm.
unit();
306 std::ostringstream message;
307 G4int oldprc = message.precision(16);
308 message <<
"Point p is not on surface (!?) of solid: "
310 message <<
"Position:\n";
311 message <<
" p.x() = " << p.
x()/
mm <<
" mm\n";
312 message <<
" p.y() = " << p.
y()/
mm <<
" mm\n";
313 message <<
" p.z() = " << p.
z()/
mm <<
" mm";
315 G4Exception(
"G4EllipticalCone::SurfaceNormal(p)",
"GeomSolids1002",
394 yi = p.
y() + q*v.
y();
439 yi = p.
y() + q*v.
y();
469 return distMin = std::fabs(
lambda);
484 return distMin = std::fabs(
lambda);
528 return distMin = std::fabs(-
B/(2.*
A));
532 G4double minus = (-
B-std::sqrt(discr))/(2.*
A);
541 if ( truenorm*v >= 0)
601 return (dist > 0) ? dist : 0.;
616 enum surface_e {kPlaneSurf, kCurvedSurf, kNoSurf} surface;
629 distMin = std::fabs(
lambda);
631 if (!calcNorm) {
return distMin; }
633 distMin = std::fabs(
lambda);
634 surface = kPlaneSurf;
645 distMin = std::fabs(
lambda);
646 if (!calcNorm) {
return distMin; }
648 distMin = std::fabs(
lambda);
649 surface = kPlaneSurf;
665 if(!calcNorm) {
return distMin = std::fabs(-
B/(2.*
A)); }
671 G4double minus = (-
B-std::sqrt(discr))/(2.*
A);
677 lambda = std::fabs(plus) < std::fabs(minus) ? plus : minus;
687 if ( std::fabs(
lambda) < distMin )
691 distMin = std::fabs(
lambda);
692 surface = kCurvedSurf;
699 if( truenorm.
dot(v) > 0 )
702 surface = kCurvedSurf;
712 if (surface == kNoSurf)
733 truenorm /= truenorm.
mag();
740 std::ostringstream message;
741 G4int oldprc = message.precision(16);
742 message <<
"Undefined side for valid surface normal to solid."
745 <<
" p.x() = " << p.
x()/
mm <<
" mm" <<
G4endl
746 <<
" p.y() = " << p.
y()/
mm <<
" mm" <<
G4endl
747 <<
" p.z() = " << p.
z()/
mm <<
" mm" <<
G4endl
749 <<
" v.x() = " << v.
x() <<
G4endl
750 <<
" v.y() = " << v.
y() <<
G4endl
751 <<
" v.z() = " << v.
z() <<
G4endl
752 <<
"Proposed distance :" <<
G4endl
753 <<
" distMin = " << distMin/
mm <<
" mm";
754 message.precision(oldprc);
755 G4Exception(
"G4EllipticalCone::DistanceToOut(p,v,..)",
776 std::ostringstream message;
777 G4int oldprc = message.precision(16);
778 message <<
"Point p is outside (!?) of solid: " <<
GetName() <<
"\n"
780 <<
" p.x() = " << p.
x()/
mm <<
" mm\n"
781 <<
" p.y() = " << p.
y()/
mm <<
" mm\n"
782 <<
" p.z() = " << p.
z()/
mm <<
" mm";
783 message.precision(oldprc) ;
784 G4Exception(
"G4Ellipsoid::DistanceToOut(p)",
"GeomSolids1002",
793 return (dist > 0) ? dist : 0.;
802 return G4String(
"G4EllipticalCone");
820 G4int oldprc = os.precision(16);
821 os <<
"-----------------------------------------------------------\n"
822 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
823 <<
" ===================================================\n"
824 <<
" Solid type: G4EllipticalCone\n"
829 <<
" height z: " <<
zheight/
mm <<
" mm \n"
830 <<
" half length in z: " <<
zTopCut/
mm <<
" mm \n"
831 <<
"-----------------------------------------------------------\n";
832 os.precision(oldprc);
854 G4double ssurf[3] = { szmin, sside, szmax };
855 for (
auto i=1; i<3; ++i) { ssurf[i] += ssurf[i-1]; }
861 if (select <= ssurf[1]) k = 1;
862 if (select <= ssurf[0]) k = 0;
886 G4double mu_max = R*std::sqrt(hh + R*R);
889 for (
auto i=0; i<1000; ++i)
929 fCubicVolume = (kmax - kmin)*(kmax*kmax + kmax*kmin + kmin*kmin)*v0;
948 +
CLHEP::pi*x0*y0*(kmin*kmin + kmax*kmax);
std::vector< G4ThreeVector > G4ThreeVectorList
G4double C(G4double temp)
G4double B(G4double temperature)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
static const G4double pMax
static const G4double pMin
static constexpr double twopi
static constexpr double mm
static constexpr double pi
#define G4MUTEX_INITIALIZER
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
double dot(const Hep3Vector &) const
void set(double x, double y, double z)
G4bool BoundingBoxVsVoxelLimits(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4VisExtent GetExtent() const
void SetSemiAxis(G4double x, G4double y, G4double z)
G4Polyhedron * GetPolyhedron() const
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
G4GeometryType GetEntityType() const
G4double GetSurfaceArea()
G4EllipticalCone(const G4String &pName, G4double pxSemiAxis, G4double pySemiAxis, G4double zMax, G4double pzTopCut)
G4ThreeVector ApproxSurfaceNormal(const G4ThreeVector &p) const
void SetZCut(G4double newzTopCut)
G4double GetSemiAxisX() const
virtual ~G4EllipticalCone()
G4ThreeVector GetPointOnSurface() const
G4Polyhedron * CreatePolyhedron() const
G4bool fRebuildPolyhedron
G4Polyhedron * fpPolyhedron
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4double GetSemiAxisY() const
G4double GetCubicVolume()
std::ostream & StreamInfo(std::ostream &os) const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const
EInside Inside(const G4ThreeVector &p) const
G4double GetZTopCut() const
G4EllipticalCone & operator=(const G4EllipticalCone &rhs)
void DescribeYourselfTo(G4VGraphicsScene &scene) const
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
virtual void AddSolid(const G4Box &)=0
G4VSolid & operator=(const G4VSolid &rhs)
static G4int GetNumberOfRotationSteps()
static const G4double kInfinity
static constexpr double twopi
static constexpr double pi
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