744{
746 enum surface_e {kPlaneSurf, kCurvedSurf, kNoSurf} surface;
747
748 distMin = kInfinity;
749 surface = kNoSurf;
750
752 {
754
755 if ( (
sqr((p.
x() + lambda*v.
x())/xSemiAxis) +
756 sqr((p.
y() + lambda*v.
y())/ySemiAxis)) <
758 {
759 distMin = std::fabs(lambda);
760
761 if (!calcNorm) { return distMin; }
762 }
763 distMin = std::fabs(lambda);
764 surface = kPlaneSurf;
765 }
766
768 {
770
771 if ( (
sqr((p.
x() + lambda*v.
x())/xSemiAxis)
772 +
sqr((p.
y() + lambda*v.
y())/ySemiAxis) )
774 {
775 distMin = std::fabs(lambda);
776 if (!calcNorm) { return distMin; }
777 }
778 distMin = std::fabs(lambda);
779 surface = kPlaneSurf;
780 }
781
782
783
784
787 v.
y()*p.
y()/
sqr(ySemiAxis) + v.
z()*(zheight-p.
z()));
789 -
sqr(zheight - p.
z());
790
792
794 {
795 if(!calcNorm) { return distMin = std::fabs(-B/(2.*A)); }
796 }
797
799 {
800 G4double plus = (-B+std::sqrt(discr))/(2.*A);
801 G4double minus = (-B-std::sqrt(discr))/(2.*A);
802
804 {
805
806
807 lambda = std::fabs(plus) < std::fabs(minus) ? plus : minus;
808 }
809 else
810 {
811
812
813
815 }
816
817 if ( std::fabs(lambda) < distMin )
818 {
820 {
821 distMin = std::fabs(lambda);
822 surface = kCurvedSurf;
823 }
824 else
825 {
827 p.
y()/(ySemiAxis*ySemiAxis),
828 -( p.
z() - zheight ));
829 if( truenorm.dot(v) > 0 )
830 {
831 distMin = 0.0;
832 surface = kCurvedSurf;
833 }
834 }
835 }
836 }
837
838
839
840 if (calcNorm)
841 {
842 if (surface == kNoSurf)
843 {
844 *validNorm = false;
845 }
846 else
847 {
848 *validNorm = true;
849 switch (surface)
850 {
851 case kPlaneSurf:
852 {
854 }
855 break;
856
857 case kCurvedSurf:
858 {
861 pexit.
y()/(ySemiAxis*ySemiAxis),
862 -( pexit.
z() - zheight ) );
863 truenorm /= truenorm.mag();
865 }
866 break;
867
868 default:
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,..)",
887 break;
888 }
889 }
890 }
891
893
894 return distMin;
895}