73 :
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.), fCubicVolume(0.),
107 fSurfaceArea(0.), xSemiAxis(0.), ySemiAxis(0.), zheight(0.),
108 semiAxisMax(0.), zTopCut(0.)
126 fpPolyhedron(0), kRadTolerance(rhs.kRadTolerance),
127 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
128 xSemiAxis(rhs.xSemiAxis), ySemiAxis(rhs.ySemiAxis), zheight(rhs.zheight),
129 semiAxisMax(rhs.semiAxisMax), zTopCut(rhs.zTopCut)
141 if (
this == &rhs) {
return *
this; }
150 fCubicVolume = rhs.fCubicVolume; fSurfaceArea = rhs.fSurfaceArea;
151 xSemiAxis = rhs.xSemiAxis; ySemiAxis = rhs.ySemiAxis;
152 zheight = rhs.zheight; semiAxisMax = rhs.semiAxisMax; zTopCut = rhs.zTopCut;
186 G4double rFudge = 1.0/std::cos(0.5*sigPhi);
187 G4double dxFudgeBot = xSemiAxis*2.*zheight*rFudge,
188 dyFudgeBot = ySemiAxis*2.*zheight*rFudge;
189 G4double dxFudgeTop = xSemiAxis*(zheight-zTopCut)*rFudge,
190 dyFudgeTop = ySemiAxis*(zheight-zTopCut)*rFudge;
200 cosPhi = std::cos(phi),
201 sinPhi = std::sin(phi);
202 G4ThreeVector v0( dxFudgeTop*cosPhi, dyFudgeTop*sinPhi, +zTopCut ),
203 v1( dxFudgeBot*cosPhi, dyFudgeBot*sinPhi, -zTopCut ),
210 if (numPhi == 1) phi = 0;
211 cosPhi = std::cos(phi),
212 sinPhi = std::sin(phi);
214 w0 =
G4ThreeVector( dxFudgeTop*cosPhi, dyFudgeTop*sinPhi, +zTopCut );
215 w1 =
G4ThreeVector( dxFudgeBot*cosPhi, dyFudgeBot*sinPhi, -zTopCut );
240 phiPoly.
SetNormal( (v1-v0).cross(w0-v0).unit() );
250 }
while( --numPhi > 0 );
288 static const G4double halfRadTol = 0.5*kRadTolerance;
294 if ( (p.
z() < -zTopCut - halfCarTol)
295 || (p.
z() > zTopCut + halfCarTol ) )
300 rad2oo=
sqr(p.
x()/( xSemiAxis + halfRadTol ))
301 +
sqr(p.
y()/( ySemiAxis + halfRadTol ));
303 if ( rad2oo >
sqr( zheight-p.
z() ) )
310 rad2oi =
sqr(p.
x()/( xSemiAxis - halfRadTol ))
311 +
sqr(p.
y()/( ySemiAxis - halfRadTol ));
313 if (rad2oi <
sqr( zheight-p.
z() ) )
315 in = ( ( p.
z() < -zTopCut + halfRadTol )
334 ry =
sqr(p.
y()/ySemiAxis);
340 if( (p.
z() < -zTopCut) && ((rx+ry) <
sqr(zTopCut + zheight)) )
345 if( (p.
z() > (zheight > zTopCut ? zheight : zTopCut)) &&
346 ((rx+ry) <
sqr(zheight-zTopCut)) )
351 if( p.
z() > rds + 2.*zTopCut - zheight )
353 if ( p.
z() > zTopCut )
358 return norm /= norm.
mag();
363 return norm /= norm.
mag();
376 - ( zheight - zTopCut ) );
379 return norm /= norm.
mag();
385 if( p.
z() < rds - 2.*zTopCut - zheight )
390 return norm /= norm.
mag();
395 return norm /= norm.
mag();
408 - ( zheight - zTopCut ) );
411 return norm /= norm.
mag();
417 G4double c = -zTopCut - k*(zTopCut + zheight);
419 if( p.
z() < -k*rds + c )
422 return norm /= norm.
mag();
457 if (sigz < 0)
return kInfinity;
464 if (
sqr(p.
x()/( xSemiAxis - halfTol ))
465 +
sqr(p.
y()/( ySemiAxis - halfTol )) <=
sqr( zheight+zTopCut ) )
480 yi = p.
y() + q*v.
y();
485 if (
sqr(xi/xSemiAxis) +
sqr(yi/ySemiAxis) <=
sqr( zheight + zTopCut ) )
490 return (sigz < -halfTol) ? q : 0;
492 else if (xi/(xSemiAxis*xSemiAxis)*v.
x()
493 + yi/(ySemiAxis*ySemiAxis)*v.
y() >= 0)
507 sigz = p.
z() - zTopCut;
514 if (sigz > 0)
return kInfinity;
516 if (
sqr(p.
x()/( xSemiAxis - halfTol ))
517 +
sqr(p.
y()/( ySemiAxis - halfTol )) <=
sqr( zheight-zTopCut ) )
525 yi = p.
y() + q*v.
y();
527 if (
sqr(xi/xSemiAxis) +
sqr(yi/ySemiAxis) <=
sqr( zheight - zTopCut ) )
529 return (sigz > -halfTol) ? q : 0;
531 else if (xi/(xSemiAxis*xSemiAxis)*v.
x()
532 + yi/(ySemiAxis*ySemiAxis)*v.
y() >= 0)
551 if (
sqr((lambda*v.
x()+p.
x())/xSemiAxis) +
552 sqr((lambda*v.
y()+p.
y())/ySemiAxis) <=
553 sqr(zTopCut + zheight + 0.5*kRadTolerance) )
555 return distMin = std::fabs(lambda);
566 if (
sqr((lambda*v.
x() + p.
x())/xSemiAxis) +
567 sqr((lambda*v.
y() + p.
y())/ySemiAxis) <=
568 sqr(zheight - zTopCut + 0.5*kRadTolerance) )
570 return distMin = std::fabs(lambda);
574 if (p.
z() > zTopCut - halfTol
575 && p.
z() < zTopCut + halfTol )
578 {
return kInfinity; }
583 if (p.
z() < -zTopCut + halfTol
584 && p.
z() > -zTopCut - halfTol)
587 {
return distMin = kInfinity; }
599 v.
y()*p.
y()/
sqr(ySemiAxis) + v.
z()*(zheight-p.
z()));
601 sqr(zheight - p.
z());
607 if ( discr < -halfTol )
612 if ( (discr >= - halfTol ) && (discr < halfTol ) )
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);
622 if ( ( std::fabs(plus) < halfTol )||( std::fabs(minus) < halfTol ) )
625 p.
y()/(ySemiAxis*ySemiAxis),
626 -( p.
z() - zheight ));
627 if ( truenorm*v >= 0)
640 if ( minus > halfTol && minus < distMin )
648 pin.
y()/(ySemiAxis*ySemiAxis),
649 - ( pin.
z() - zheight ));
656 if ( plus > halfTol && plus < distMin )
664 pin.
y()/(ySemiAxis*ySemiAxis),
665 - ( pin.
z() - zheight ) );
672 if (distMin < halfTol) distMin=0.;
683 G4double distR, distR2, distZ, maxDim;
689 if( (p.
z() <= -zTopCut) && (
sqr(p.
x()/xSemiAxis) +
sqr(p.
y()/ySemiAxis)
693 return distZ = std::fabs(zTopCut + p.
z());
696 if( (p.
z() >= zTopCut) && (
sqr(p.
x()/xSemiAxis)+
sqr(p.
y()/ySemiAxis)
699 return distZ = std::fabs(p.
z() - zTopCut);
706 maxDim = xSemiAxis >= ySemiAxis ? xSemiAxis:ySemiAxis;
707 distRad = std::sqrt(p.
x()*p.
x()+p.
y()*p.
y());
709 if( p.
z() > maxDim*distRad + zTopCut*(1.+maxDim)-
sqr(maxDim)*zheight )
711 distR2 =
sqr(p.
z() - zTopCut) +
sqr(distRad - maxDim*(zheight - zTopCut));
712 return std::sqrt( distR2 );
715 if( distRad > maxDim*( zheight - p.
z() ) )
717 if( p.
z() > maxDim*distRad - (zTopCut*(1.+maxDim)+
sqr(maxDim)*zheight) )
719 G4double zVal = (p.
z()-maxDim*(distRad-maxDim*zheight))/(1.+
sqr(maxDim));
720 G4double rVal = maxDim*(zheight - zVal);
721 return distR = std::sqrt(
sqr(p.
z() - zVal) +
sqr(distRad - rVal));
725 if( distRad <= maxDim*(zheight - p.
z()) )
727 distR2 =
sqr(distRad - maxDim*(zheight + zTopCut)) +
sqr(p.
z() + zTopCut);
728 return std::sqrt( distR2 );
746 enum surface_e {kPlaneSurf, kCurvedSurf, kNoSurf} surface;
753 lambda = (-p.
z() - zTopCut)/v.
z();
755 if ( (
sqr((p.
x() + lambda*v.
x())/xSemiAxis) +
756 sqr((p.
y() + lambda*v.
y())/ySemiAxis)) <
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();
771 if ( (
sqr((p.
x() + lambda*v.
x())/xSemiAxis)
772 +
sqr((p.
y() + lambda*v.
y())/ySemiAxis) )
775 distMin = std::fabs(lambda);
776 if (!calcNorm) {
return distMin; }
778 distMin = std::fabs(lambda);
779 surface = kPlaneSurf;
787 v.
y()*p.
y()/
sqr(ySemiAxis) + v.
z()*(zheight-p.
z()));
789 -
sqr(zheight - p.
z());
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;
827 p.
y()/(ySemiAxis*ySemiAxis),
828 -( p.
z() - zheight ));
829 if( truenorm.
dot(v) > 0 )
832 surface = kCurvedSurf;
842 if (surface == kNoSurf)
861 pexit.
y()/(ySemiAxis*ySemiAxis),
862 -( pexit.
z() - zheight ) );
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.;
904 G4double minAxis = xSemiAxis < ySemiAxis ? xSemiAxis : ySemiAxis;
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",
927 if(
sqr(p.
x()/minAxis)+
sqr(p.
y()/minAxis) <
sqr(zheight - p.
z()) )
929 rds = std::sqrt(
sqr(p.
x()) +
sqr(p.
y()));
930 roo = minAxis*(zheight-p.
z());
931 roo1 = minAxis*(zheight-zTopCut);
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);
939 distMin=std::min(distMin,distR);
941 distMin=std::min(distR,distZ);
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"
978 <<
" semi-axis x: " << xSemiAxis/mm <<
" mm \n"
979 <<
" semi-axis y: " << ySemiAxis/mm <<
" mm \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;
1001 +
sqr(ySemiAxis))*(zheight - zTopCut);
1003 +
sqr(ySemiAxis))*(zheight + zTopCut);
1005 aOne = pi*(rOne + rTwo)*std::sqrt(
sqr(rOne - rTwo)+
sqr(2.*zTopCut));
1006 aTwo = pi*xSemiAxis*ySemiAxis*
sqr(zheight+zTopCut);
1007 aThree = pi*xSemiAxis*ySemiAxis*
sqr(zheight-zTopCut);
1010 cosphi = std::cos(phi);
1011 sinphi = std::sin(phi);
1013 if(zTopCut >= zheight) aThree = 0.;
1016 if((chose>=0.) && (chose<aOne))
1020 ySemiAxis*(zheight-zRand)*sinphi,zRand);
1022 else if((chose>=aOne) && (chose<aOne+aTwo))
1028 }
while ( rRand2 >= rRand1 ) ;
1031 return G4ThreeVector(rRand1*xSemiAxis*(zheight+zTopCut)*cosphi,
1032 rRand1*ySemiAxis*(zheight+zTopCut)*sinphi, -zTopCut);
1042 }
while ( rRand2 >= rRand1 ) ;
1044 return G4ThreeVector(rRand1*xSemiAxis*(zheight-zTopCut)*cosphi,
1045 rRand1*ySemiAxis*(zheight-zTopCut)*sinphi, zTopCut);
1062 maxDim = xSemiAxis > ySemiAxis ? xSemiAxis : ySemiAxis;
1063 maxDim = maxDim > zTopCut ? maxDim : zTopCut;
1074 return new G4NURBSbox(xSemiAxis, ySemiAxis,zheight);
CLHEP::Hep3Vector G4ThreeVector
double dot(const Hep3Vector &) const
virtual G4bool PartialClip(const G4VoxelLimits &voxelLimit, const EAxis IgnoreMe)
virtual void AddVertexInOrder(const G4ThreeVector vertex)
virtual void ClearAllVertices()
void SetNormal(const G4ThreeVector &newNormal)
G4VisExtent GetExtent() const
void SetSemiAxis(G4double x, G4double y, G4double z)
G4Polyhedron * GetPolyhedron() const
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
G4NURBS * CreateNURBS() const
G4GeometryType GetEntityType() const
G4EllipticalCone(const G4String &pName, G4double pxSemiAxis, G4double pySemiAxis, G4double zMax, G4double pzTopCut)
void SetZCut(G4double newzTopCut)
virtual ~G4EllipticalCone()
G4ThreeVector GetPointOnSurface() const
G4Polyhedron * CreatePolyhedron() const
G4Polyhedron * fpPolyhedron
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=G4bool(false), G4bool *validNorm=0, G4ThreeVector *n=0) const
std::ostream & StreamInfo(std::ostream &os) const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
EInside Inside(const G4ThreeVector &p) const
G4EllipticalCone & operator=(const G4EllipticalCone &rhs)
void DescribeYourselfTo(G4VGraphicsScene &scene) const
G4double GetRadialTolerance() const
static G4GeometryTolerance * GetInstance()
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
void AddSurface(const G4ClippablePolygon &surface)
G4bool GetExtent(G4double &min, G4double &max) const
virtual void AddSolid(const G4Box &)=0
G4VSolid & operator=(const G4VSolid &rhs)
static G4int GetNumberOfRotationSteps()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
const G4int kMaxMeshSections