614{
616 enum surface_e {kPlaneSurf, kCurvedSurf, kNoSurf} surface;
617
618 distMin = kInfinity;
619 surface = kNoSurf;
620
622 {
624
625 if ( (
sqr((p.
x() + lambda*v.
x())/xSemiAxis) +
626 sqr((p.
y() + lambda*v.
y())/ySemiAxis)) <
627 sqr(zheight + zTopCut + halfCarTol) )
628 {
629 distMin = std::fabs(lambda);
630
631 if (!calcNorm) { return distMin; }
632 }
633 distMin = std::fabs(lambda);
634 surface = kPlaneSurf;
635 }
636
638 {
640
641 if ( (
sqr((p.
x() + lambda*v.
x())/xSemiAxis)
642 +
sqr((p.
y() + lambda*v.
y())/ySemiAxis) )
643 < (
sqr(zheight - zTopCut + halfCarTol)) )
644 {
645 distMin = std::fabs(lambda);
646 if (!calcNorm) { return distMin; }
647 }
648 distMin = std::fabs(lambda);
649 surface = kPlaneSurf;
650 }
651
652
653
654
657 v.
y()*p.
y()/
sqr(ySemiAxis) + v.
z()*(zheight-p.
z()));
659 -
sqr(zheight - p.
z());
660
662
663 if ( discr >= - halfCarTol && discr < halfCarTol )
664 {
665 if(!calcNorm) { return distMin = std::fabs(-B/(2.*A)); }
666 }
667
668 else if ( discr > halfCarTol )
669 {
670 G4double plus = (-
B+std::sqrt(discr))/(2.*A);
671 G4double minus = (-
B-std::sqrt(discr))/(2.*A);
672
673 if ( plus > halfCarTol && minus > halfCarTol )
674 {
675
676
677 lambda = std::fabs(plus) < std::fabs(minus) ? plus : minus;
678 }
679 else
680 {
681
682
683
684 lambda = plus > -halfCarTol ? plus : 0;
685 }
686
687 if ( std::fabs(lambda) < distMin )
688 {
689 if( std::fabs(lambda) > halfCarTol)
690 {
691 distMin = std::fabs(lambda);
692 surface = kCurvedSurf;
693 }
694 else
695 {
697 p.
y()/(ySemiAxis*ySemiAxis),
698 -( p.
z() - zheight ));
699 if( truenorm.dot(v) > 0 )
700 {
701 distMin = 0.0;
702 surface = kCurvedSurf;
703 }
704 }
705 }
706 }
707
708
709
710 if (calcNorm)
711 {
712 if (surface == kNoSurf)
713 {
714 *validNorm = false;
715 }
716 else
717 {
718 *validNorm = true;
719 switch (surface)
720 {
721 case kPlaneSurf:
722 {
724 }
725 break;
726
727 case kCurvedSurf:
728 {
731 pexit.
y()/(ySemiAxis*ySemiAxis),
732 -( pexit.
z() - zheight ) );
733 truenorm /= truenorm.mag();
735 }
736 break;
737
738 default:
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,..)",
757 break;
758 }
759 }
760 }
761
762 if (distMin < halfCarTol) { distMin=0; }
763
764 return distMin;
765}
CLHEP::Hep3Vector G4ThreeVector