Returns the distance along the normalised vector 'v' to the shape, from the point at offset 'p'. If there is no intersection, returns kInfinity. The first intersection resulting from 'leaving' a surface/volume is discarded. Hence, it is tolerant of points on the surface of the shape.
776{
782
783
784
785 G4double Dist, sd=0, xi, yi, zi, rho2, inum, iden, cosPsi, Comp,calf ;
788
789
790 if (fRMin > kRadTolerance)
791 {
792 tolORMin2 = (fRMin - halfRadTolerance)*(fRMin - halfRadTolerance) ;
793 tolIRMin2 = (fRMin + halfRadTolerance)*(fRMin + halfRadTolerance) ;
794 }
795 else
796 {
797 tolORMin2 = 0.0 ;
798 tolIRMin2 = 0.0 ;
799 }
800 tolORMax2 = (fRMax + halfRadTolerance)*(fRMax + halfRadTolerance) ;
801 tolIRMax2 = (fRMax - halfRadTolerance)*(fRMax - halfRadTolerance) ;
802
803
804
805
806
807 distZLow =(p+vZ).dot(fLowNorm);
808
809
810
811 distZHigh = (p-vZ).dot(fHighNorm);
812
813 if ( distZLow >= -halfCarTolerance )
814 {
815 calf = v.
dot(fLowNorm);
816 if (calf<0)
817 {
818 sd = -distZLow/calf;
819 if(sd < 0.0) { sd = 0.0; }
820
821 xi = p.
x() + sd*v.
x() ;
822 yi = p.
y() + sd*v.
y() ;
823 rho2 = xi*xi + yi*yi ;
824
825
826
827 if ((tolIRMin2 <= rho2) && (rho2 <= tolIRMax2))
828 {
829 if (!fPhiFullCutTube && (rho2 != 0.0))
830 {
831
832
833 inum = xi*cosCPhi + yi*sinCPhi ;
834 iden = std::sqrt(rho2) ;
835 cosPsi = inum/iden ;
836 if (cosPsi >= cosHDPhiIT) { return sd ; }
837 }
838 else
839 {
840 return sd ;
841 }
842 }
843 }
844 else
845 {
846 if ( sd<halfCarTolerance )
847 {
848 if(calf>=0) { sd=kInfinity; }
849 return sd ;
850 }
851 }
852 }
853
854 if(distZHigh >= -halfCarTolerance )
855 {
856 calf = v.
dot(fHighNorm);
857 if (calf<0)
858 {
859 sd = -distZHigh/calf;
860
861 if(sd < 0.0) { sd = 0.0; }
862
863 xi = p.
x() + sd*v.
x() ;
864 yi = p.
y() + sd*v.
y() ;
865 rho2 = xi*xi + yi*yi ;
866
867
868
869 if ((tolIRMin2 <= rho2) && (rho2 <= tolIRMax2))
870 {
871 if (!fPhiFullCutTube && (rho2 != 0.0))
872 {
873
874
875 inum = xi*cosCPhi + yi*sinCPhi ;
876 iden = std::sqrt(rho2) ;
877 cosPsi = inum/iden ;
878 if (cosPsi >= cosHDPhiIT) { return sd ; }
879 }
880 else
881 {
882 return sd ;
883 }
884 }
885 }
886 else
887 {
888 if ( sd<halfCarTolerance )
889 {
890 if(calf>=0) { sd=kInfinity; }
891 return sd ;
892 }
893 }
894 }
895
896
897
898
899
900
901
902
903
904
905
906
907 t1 = 1.0 - v.
z()*v.
z() ;
908 t2 = p.
x()*v.
x() + p.
y()*v.
y() ;
909 t3 = p.
x()*p.
x() + p.
y()*p.
y() ;
910 if ( t1 > 0 )
911 {
912 b = t2/t1 ;
913 c = t3 - fRMax*fRMax ;
914
915 if ((t3 >= tolORMax2) && (t2<0))
916 {
917
918
919 c /= t1 ;
920 d = b*b - c ;
921
922 if (d >= 0)
923 {
924 sd = c/(-b+std::sqrt(d));
925 if (sd >= 0)
926 {
927 if ( sd>dRmax )
928 {
929 G4double fTerm = sd-std::fmod(sd,dRmax);
931 }
932
933
934 zi = p.
z() + sd*v.
z() ;
935 xi = p.
x() + sd*v.
x() ;
936 yi = p.
y() + sd*v.
y() ;
937 if ((-xi*fLowNorm.x()-yi*fLowNorm.y()
938 -(zi+fDz)*fLowNorm.z())>-halfCarTolerance)
939 {
940 if ((-xi*fHighNorm.x()-yi*fHighNorm.y()
941 +(fDz-zi)*fHighNorm.z())>-halfCarTolerance)
942 {
943
944
945 if (fPhiFullCutTube)
946 {
947 return sd ;
948 }
949
950 xi = p.
x() + sd*v.
x() ;
951 yi = p.
y() + sd*v.
y() ;
952 cosPsi = (xi*cosCPhi + yi*sinCPhi)/fRMax ;
953 if (cosPsi >= cosHDPhiIT) { return sd ; }
954 }
955 }
956 }
957 }
958 }
959 else
960 {
961
962
963 if ((t3 > tolIRMin2) && (t2 < 0)
964 && (std::fabs(p.
z()) <= std::fabs(
GetCutZ(p))-halfCarTolerance ))
965 {
966
967
968 if (!fPhiFullCutTube)
969 {
970 inum = p.
x()*cosCPhi + p.
y()*sinCPhi ;
971 iden = std::sqrt(t3) ;
972 cosPsi = inum/iden ;
973 if (cosPsi >= cosHDPhiIT)
974 {
975
976
977
978
979
980
981 c = t3-fRMax*fRMax;
982 if ( c<=0.0 )
983 {
984 return 0.0;
985 }
986
987 c = c/t1 ;
988 d = b*b-c;
989 if ( d>=0.0 )
990 {
991 snxt = c/(-b+std::sqrt(d));
992
993 if ( snxt < halfCarTolerance ) { snxt=0; }
994 return snxt ;
995 }
996
997 return kInfinity;
998 }
999 }
1000 else
1001 {
1002
1003
1004
1005
1006
1007
1008 c = t3 - fRMax*fRMax;
1009 if ( c<=0.0 )
1010 {
1011 return 0.0;
1012 }
1013
1014 c = c/t1 ;
1015 d = b*b-c;
1016 if ( d>=0.0 )
1017 {
1018 snxt= c/(-b+std::sqrt(d));
1019
1020 if ( snxt < halfCarTolerance ) { snxt=0; }
1021 return snxt ;
1022 }
1023
1024 return kInfinity;
1025 }
1026 }
1027 }
1028
1029 if ( fRMin != 0.0 )
1030 {
1031 c = (t3 - fRMin*fRMin)/t1 ;
1032 d = b*b - c ;
1033 if ( d >= 0.0 )
1034 {
1035
1036
1037
1038 sd =( b > 0. )? c/(-b - std::sqrt(d)) : (-b + std::sqrt(d));
1039 if (sd >= -10*halfCarTolerance)
1040 {
1041
1042
1043 if (sd < 0.0) { sd = 0.0; }
1044 if (sd>dRmax)
1045 {
1046 G4double fTerm = sd-std::fmod(sd,dRmax);
1048 }
1049 zi = p.
z() + sd*v.
z() ;
1050 xi = p.
x() + sd*v.
x() ;
1051 yi = p.
y() + sd*v.
y() ;
1052 if ((-xi*fLowNorm.x()-yi*fLowNorm.y()
1053 -(zi+fDz)*fLowNorm.z())>-halfCarTolerance)
1054 {
1055 if ((-xi*fHighNorm.x()-yi*fHighNorm.y()
1056 +(fDz-zi)*fHighNorm.z())>-halfCarTolerance)
1057 {
1058
1059
1060 if ( fPhiFullCutTube )
1061 {
1062 return sd ;
1063 }
1064
1065 cosPsi = (xi*cosCPhi + yi*sinCPhi)/fRMin ;
1066 if (cosPsi >= cosHDPhiIT)
1067 {
1068
1069
1070
1071 snxt = sd ;
1072 }
1073 }
1074 }
1075 }
1076 }
1077 }
1078 }
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089 if ( !fPhiFullCutTube )
1090 {
1091
1092
1093 Comp = v.
x()*sinSPhi - v.
y()*cosSPhi ;
1094
1095 if ( Comp < 0 )
1096 {
1097 Dist = (p.
y()*cosSPhi - p.
x()*sinSPhi) ;
1098
1099 if ( Dist < halfCarTolerance )
1100 {
1101 sd = Dist/Comp ;
1102
1103 if (sd < snxt)
1104 {
1105 if ( sd < 0 ) { sd = 0.0; }
1106 zi = p.
z() + sd*v.
z() ;
1107 xi = p.
x() + sd*v.
x() ;
1108 yi = p.
y() + sd*v.
y() ;
1109 if ((-xi*fLowNorm.x()-yi*fLowNorm.y()
1110 -(zi+fDz)*fLowNorm.z())>-halfCarTolerance)
1111 {
1112 if ((-xi*fHighNorm.x()-yi*fHighNorm.y()
1113 +(fDz-zi)*fHighNorm.z())>-halfCarTolerance)
1114 {
1115 rho2 = xi*xi + yi*yi ;
1116 if ( ( (rho2 >= tolIRMin2) && (rho2 <= tolIRMax2) )
1117 || ( (rho2 > tolORMin2) && (rho2 < tolIRMin2)
1118 && ( v.
y()*cosSPhi - v.
x()*sinSPhi > 0 )
1119 && ( v.
x()*cosSPhi + v.
y()*sinSPhi >= 0 ) )
1120 || ( (rho2 > tolIRMax2) && (rho2 < tolORMax2)
1121 && (v.
y()*cosSPhi - v.
x()*sinSPhi > 0)
1122 && (v.
x()*cosSPhi + v.
y()*sinSPhi < 0) ) )
1123 {
1124
1125
1126
1127 if ((yi*cosCPhi-xi*sinCPhi) <= halfCarTolerance) { snxt = sd; }
1128 }
1129 }
1130 }
1131 }
1132 }
1133 }
1134
1135
1136
1137 Comp = -(v.
x()*sinEPhi - v.
y()*cosEPhi) ;
1138
1139 if (Comp < 0 )
1140 {
1141 Dist = -(p.
y()*cosEPhi - p.
x()*sinEPhi) ;
1142
1143 if ( Dist < halfCarTolerance )
1144 {
1145 sd = Dist/Comp ;
1146
1147 if (sd < snxt)
1148 {
1149 if ( sd < 0 ) { sd = 0; }
1150 zi = p.
z() + sd*v.
z() ;
1151 xi = p.
x() + sd*v.
x() ;
1152 yi = p.
y() + sd*v.
y() ;
1153 if ((-xi*fLowNorm.x()-yi*fLowNorm.y()
1154 -(zi+fDz)*fLowNorm.z())>-halfCarTolerance)
1155 {
1156 if ((-xi*fHighNorm.x()-yi*fHighNorm.y()
1157 +(fDz-zi)*fHighNorm.z())>-halfCarTolerance)
1158 {
1159 xi = p.
x() + sd*v.
x() ;
1160 yi = p.
y() + sd*v.
y() ;
1161 rho2 = xi*xi + yi*yi ;
1162 if ( ( (rho2 >= tolIRMin2) && (rho2 <= tolIRMax2) )
1163 || ( (rho2 > tolORMin2) && (rho2 < tolIRMin2)
1164 && (v.
x()*sinEPhi - v.
y()*cosEPhi > 0)
1165 && (v.
x()*cosEPhi + v.
y()*sinEPhi >= 0) )
1166 || ( (rho2 > tolIRMax2) && (rho2 < tolORMax2)
1167 && (v.
x()*sinEPhi - v.
y()*cosEPhi > 0)
1168 && (v.
x()*cosEPhi + v.
y()*sinEPhi < 0) ) )
1169 {
1170
1171
1172
1173 if ( (yi*cosCPhi-xi*sinCPhi) >= -halfCarTolerance )
1174 {
1175 snxt = sd;
1176 }
1177 }
1178 }
1179 }
1180 }
1181 }
1182 }
1183 }
1184 if ( snxt<halfCarTolerance ) { snxt=0; }
1185
1186 return snxt ;
1187}
double dot(const Hep3Vector &) const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const override