59 using namespace CLHEP;
70 :
G4VSolid(pName), fpPolyhedron(0), fCubicVolume(0.), fSurfaceArea(0.),
81 if ( (pxSemiAxis <= 0.) || (pySemiAxis <= 0.) || (pzMax <= 0.) )
83 std::ostringstream message;
84 message <<
"Invalid semi-axis or height - " <<
GetName();
85 G4Exception(
"G4EllipticalCone::G4EllipticalCone()",
"GeomSolids0002",
90 std::ostringstream message;
91 message <<
"Invalid z-coordinate for cutting plane - " <<
GetName();
92 G4Exception(
"G4EllipticalCone::G4EllipticalCone()",
"InvalidSetup",
106 :
G4VSolid(a), fpPolyhedron(0), kRadTolerance(0.),
107 halfRadTol(0.), halfCarTol(0.), fCubicVolume(0.),
108 fSurfaceArea(0.), xSemiAxis(0.), ySemiAxis(0.), zheight(0.),
109 semiAxisMax(0.), zTopCut(0.)
127 fpPolyhedron(0), kRadTolerance(rhs.kRadTolerance),
128 halfRadTol(rhs.halfRadTol), halfCarTol(rhs.halfCarTol),
129 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
130 xSemiAxis(rhs.xSemiAxis), ySemiAxis(rhs.ySemiAxis), zheight(rhs.zheight),
131 semiAxisMax(rhs.semiAxisMax), zTopCut(rhs.zTopCut)
144 if (
this == &rhs) {
return *
this; }
191 G4double rFudge = 1.0/std::cos(0.5*sigPhi);
205 cosPhi = std::cos(phi),
206 sinPhi = std::sin(phi);
208 v1( dxFudgeBot*cosPhi, dyFudgeBot*sinPhi, -
zTopCut ),
215 if (numPhi == 1) phi = 0;
216 cosPhi = std::cos(phi),
217 sinPhi = std::sin(phi);
245 phiPoly.
SetNormal( (v1-v0).cross(w0-v0).unit() );
255 }
while( --numPhi > 0 );
360 return norm /= norm.mag();
365 return norm /= norm.mag();
368 G4double k = std::fabs(p.x()/p.y());
381 return norm /= norm.mag();
392 return norm /= norm.mag();
397 return norm /= norm.mag();
400 G4double k = std::fabs(p.x()/p.y());
413 return norm /= norm.mag();
421 if( p.z() < -k*rds + c )
424 return norm /= norm.mag();
480 yi = p.y() + q*v.y();
525 yi = p.y() + q*v.y();
555 return distMin = std::fabs(lambda);
570 return distMin = std::fabs(lambda);
614 return distMin = std::fabs(-B/(2.*A));
617 G4double plus = (-B+std::sqrt(discr))/(2.*A);
618 G4double minus = (-B-std::sqrt(discr))/(2.*A);
627 if ( truenorm*v >= 0)
683 G4double distR, distR2, distZ, maxDim;
693 return distZ = std::fabs(
zTopCut + p.z());
699 return distZ = std::fabs(p.z() -
zTopCut);
707 distRad = std::sqrt(p.x()*p.x()+p.y()*p.y());
712 return std::sqrt( distR2 );
715 if( distRad > maxDim*(
zheight - p.z() ) )
721 return distR = std::sqrt(
sqr(p.z() - zVal) +
sqr(distRad - rVal));
725 if( distRad <= maxDim*(
zheight - p.z()) )
728 return std::sqrt( distR2 );
746 enum surface_e {kPlaneSurf, kCurvedSurf, kNoSurf} surface;
753 lambda = (-p.z() -
zTopCut)/v.z();
759 distMin = std::fabs(lambda);
761 if (!calcNorm) {
return distMin; }
763 distMin = std::fabs(lambda);
764 surface = kPlaneSurf;
769 lambda = (
zTopCut - p.z()) / v.z();
775 distMin = std::fabs(lambda);
776 if (!calcNorm) {
return distMin; }
778 distMin = std::fabs(lambda);
779 surface = kPlaneSurf;
795 if(!calcNorm) {
return distMin = std::fabs(-B/(2.*A)); }
800 G4double plus = (-B+std::sqrt(discr))/(2.*A);
801 G4double minus = (-B-std::sqrt(discr))/(2.*A);
807 lambda = std::fabs(plus) < std::fabs(minus) ? plus : minus;
817 if ( std::fabs(lambda) < distMin )
821 distMin = std::fabs(lambda);
822 surface = kCurvedSurf;
829 if( truenorm.dot(v) > 0 )
832 surface = kCurvedSurf;
842 if (surface == kNoSurf)
863 truenorm /= truenorm.mag();
870 std::ostringstream message;
871 G4int oldprc = message.precision(16);
872 message <<
"Undefined side for valid surface normal to solid."
875 <<
" p.x() = " << p.x()/
mm <<
" mm" <<
G4endl
876 <<
" p.y() = " << p.y()/
mm <<
" mm" <<
G4endl
877 <<
" p.z() = " << p.z()/
mm <<
" mm" <<
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,..)",
903 G4double rds,roo,roo1, distR, distZ, distMin=0.;
910 std::ostringstream message;
911 G4int oldprc = message.precision(16);
912 message <<
"Point p is outside !?" <<
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",
929 rds = std::sqrt(
sqr(p.x()) +
sqr(p.y()));
933 distZ=
zTopCut - std::fabs(p.z()) ;
934 distR=(roo-rds)/(std::sqrt(1+
sqr(minAxis)));
938 distMin=(
zTopCut-p.z())*(roo-rds)/(roo-roo1);
953 return G4String(
"G4EllipticalCone");
971 G4int oldprc = os.precision(16);
972 os <<
"-----------------------------------------------------------\n"
973 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
974 <<
" ===================================================\n"
975 <<
" Solid type: G4EllipticalCone\n"
980 <<
" height z: " <<
zheight/
mm <<
" mm \n"
981 <<
" half length in z: " <<
zTopCut/
mm <<
" mm \n"
982 <<
"-----------------------------------------------------------\n";
983 os.precision(oldprc);
997 G4double phi, sinphi, cosphi, aOne, aTwo, aThree,
998 chose, zRand, rRand1, rRand2;
1010 cosphi = std::cos(phi);
1011 sinphi = std::sin(phi);
1016 if((chose>=0.) && (chose<aOne))
1022 else if((chose>=aOne) && (chose<aOne+aTwo))
1028 }
while ( rRand2 >= rRand1 ) ;
1042 }
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