60 using namespace CLHEP;
71 :
G4VSolid(pName), fpPolyhedron(0), fCubicVolume(0.), fSurfaceArea(0.),
82 if ( (pxSemiAxis <= 0.) || (pySemiAxis <= 0.) || (pzMax <= 0.) )
84 std::ostringstream message;
85 message <<
"Invalid semi-axis or height - " <<
GetName();
86 G4Exception(
"G4EllipticalCone::G4EllipticalCone()",
"GeomSolids0002",
91 std::ostringstream message;
92 message <<
"Invalid z-coordinate for cutting plane - " <<
GetName();
93 G4Exception(
"G4EllipticalCone::G4EllipticalCone()",
"InvalidSetup",
107 :
G4VSolid(a), fpPolyhedron(0), kRadTolerance(0.),
108 halfRadTol(0.), halfCarTol(0.), fCubicVolume(0.),
109 fSurfaceArea(0.), xSemiAxis(0.), ySemiAxis(0.), zheight(0.),
110 semiAxisMax(0.), zTopCut(0.)
128 fpPolyhedron(0), kRadTolerance(rhs.kRadTolerance),
129 halfRadTol(rhs.halfRadTol), halfCarTol(rhs.halfCarTol),
130 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
131 xSemiAxis(rhs.xSemiAxis), ySemiAxis(rhs.ySemiAxis), zheight(rhs.zheight),
132 semiAxisMax(rhs.semiAxisMax), zTopCut(rhs.zTopCut)
144 if (
this == &rhs) {
return *
this; }
190 G4double rFudge = 1.0/std::cos(0.5*sigPhi);
204 cosPhi = std::cos(phi),
205 sinPhi = std::sin(phi);
207 v1( dxFudgeBot*cosPhi, dyFudgeBot*sinPhi, -
zTopCut ),
214 if (numPhi == 1) phi = 0;
215 cosPhi = std::cos(phi),
216 sinPhi = std::sin(phi);
244 phiPoly.
SetNormal( (v1-v0).cross(w0-v0).unit() );
254 }
while( --numPhi > 0 );
359 return norm /= norm.mag();
364 return norm /= norm.mag();
367 G4double k = std::fabs(p.x()/p.y());
380 return norm /= norm.mag();
391 return norm /= norm.mag();
396 return norm /= norm.mag();
399 G4double k = std::fabs(p.x()/p.y());
412 return norm /= norm.mag();
420 if( p.z() < -k*rds + c )
423 return norm /= norm.mag();
479 yi = p.y() + q*v.y();
524 yi = p.y() + q*v.y();
554 return distMin = std::fabs(lambda);
569 return distMin = std::fabs(lambda);
613 return distMin = std::fabs(-B/(2.*A));
616 G4double plus = (-B+std::sqrt(discr))/(2.*A);
617 G4double minus = (-B-std::sqrt(discr))/(2.*A);
626 if ( truenorm*v >= 0)
682 G4double distR, distR2, distZ, maxDim;
692 return distZ = std::fabs(
zTopCut + p.z());
698 return distZ = std::fabs(p.z() -
zTopCut);
706 distRad = std::sqrt(p.x()*p.x()+p.y()*p.y());
711 return std::sqrt( distR2 );
714 if( distRad > maxDim*(
zheight - p.z() ) )
720 return distR = std::sqrt(
sqr(p.z() - zVal) +
sqr(distRad - rVal));
724 if( distRad <= maxDim*(
zheight - p.z()) )
727 return std::sqrt( distR2 );
745 enum surface_e {kPlaneSurf, kCurvedSurf, kNoSurf} surface;
752 lambda = (-p.z() -
zTopCut)/v.z();
758 distMin = std::fabs(lambda);
760 if (!calcNorm) {
return distMin; }
762 distMin = std::fabs(lambda);
763 surface = kPlaneSurf;
768 lambda = (
zTopCut - p.z()) / v.z();
774 distMin = std::fabs(lambda);
775 if (!calcNorm) {
return distMin; }
777 distMin = std::fabs(lambda);
778 surface = kPlaneSurf;
794 if(!calcNorm) {
return distMin = std::fabs(-B/(2.*A)); }
799 G4double plus = (-B+std::sqrt(discr))/(2.*A);
800 G4double minus = (-B-std::sqrt(discr))/(2.*A);
806 lambda = std::fabs(plus) < std::fabs(minus) ? plus : minus;
816 if ( std::fabs(lambda) < distMin )
820 distMin = std::fabs(lambda);
821 surface = kCurvedSurf;
828 if( truenorm.dot(v) > 0 )
831 surface = kCurvedSurf;
841 if (surface == kNoSurf)
862 truenorm /= truenorm.mag();
869 std::ostringstream message;
870 G4int oldprc = message.precision(16);
871 message <<
"Undefined side for valid surface normal to solid."
874 <<
" p.x() = " << p.x()/
mm <<
" mm" <<
G4endl
875 <<
" p.y() = " << p.y()/
mm <<
" mm" <<
G4endl
876 <<
" p.z() = " << p.z()/
mm <<
" mm" <<
G4endl
878 <<
" v.x() = " << v.x() <<
G4endl
879 <<
" v.y() = " << v.y() <<
G4endl
880 <<
" v.z() = " << v.z() <<
G4endl
881 <<
"Proposed distance :" <<
G4endl
882 <<
" distMin = " << distMin/
mm <<
" mm";
883 message.precision(oldprc);
884 G4Exception(
"G4EllipticalCone::DistanceToOut(p,v,..)",
902 G4double rds,roo,roo1, distR, distZ, distMin=0.;
909 std::ostringstream message;
910 G4int oldprc = message.precision(16);
911 message <<
"Point p is outside !?" <<
G4endl
913 <<
" p.x() = " << p.x()/
mm <<
" mm" <<
G4endl
914 <<
" p.y() = " << p.y()/
mm <<
" mm" <<
G4endl
915 <<
" p.z() = " << p.z()/
mm <<
" mm";
916 message.precision(oldprc) ;
917 G4Exception(
"G4Ellipsoid::DistanceToOut(p)",
"GeomSolids1002",
928 rds = std::sqrt(
sqr(p.x()) +
sqr(p.y()));
932 distZ=
zTopCut - std::fabs(p.z()) ;
933 distR=(roo-rds)/(std::sqrt(1+
sqr(minAxis)));
937 distMin=(
zTopCut-p.z())*(roo-rds)/(roo-roo1);
952 return G4String(
"G4EllipticalCone");
970 G4int oldprc = os.precision(16);
971 os <<
"-----------------------------------------------------------\n"
972 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
973 <<
" ===================================================\n"
974 <<
" Solid type: G4EllipticalCone\n"
979 <<
" height z: " <<
zheight/
mm <<
" mm \n"
980 <<
" half length in z: " <<
zTopCut/
mm <<
" mm \n"
981 <<
"-----------------------------------------------------------\n";
982 os.precision(oldprc);
996 G4double phi, sinphi, cosphi, aOne, aTwo, aThree,
997 chose, zRand, rRand1, rRand2;
1009 cosphi = std::cos(phi);
1010 sinphi = std::sin(phi);
1015 if((chose>=0.) && (chose<aOne))
1021 else if((chose>=aOne) && (chose<aOne+aTwo))
1027 }
while ( rRand2 >= rRand1 ) ;
1041 }
while ( rRand2 >= rRand1 ) ;
ThreeVector shoot(const G4int Ap, const G4int Af)
static c2_factory< G4double > c2
G4EllipticalCone & operator=(const G4EllipticalCone &rhs)
static const G4double kInfinity
CLHEP::Hep3Vector G4ThreeVector
G4bool GetExtent(G4double &min, G4double &max) const
EInside Inside(const G4ThreeVector &p) const
void SetNormal(const G4ThreeVector &newNormal)
virtual G4bool PartialClip(const G4VoxelLimits &voxelLimit, const EAxis IgnoreMe)
virtual void AddVertexInOrder(const G4ThreeVector vertex)
virtual void ClearAllVertices()
virtual void AddSolid(const G4Box &)=0
G4Polyhedron * CreatePolyhedron() const
static double normal(HepRandomEngine *eptr)
std::ostream & StreamInfo(std::ostream &os) const
G4ThreeVector GetPointOnSurface() const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
G4Polyhedron * fpPolyhedron
G4double GetRadialTolerance() const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4EllipticalCone(const G4String &pName, G4double pxSemiAxis, G4double pySemiAxis, G4double zMax, G4double pzTopCut)
void AddSurface(const G4ClippablePolygon &surface)
static const G4double A[nN]
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
void DescribeYourselfTo(G4VGraphicsScene &scene) const
void SetSemiAxis(G4double x, G4double y, G4double z)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
void SetZCut(G4double newzTopCut)
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4VSolid & operator=(const G4VSolid &rhs)
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
G4Polyhedron * GetPolyhedron() const
G4GeometryType GetEntityType() const
G4VisExtent GetExtent() const
virtual ~G4EllipticalCone()
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=G4bool(false), G4bool *validNorm=0, G4ThreeVector *n=0) const
static G4GeometryTolerance * GetInstance()
const G4int kMaxMeshSections