714{
716 const G4double dRmax = 100*std::min(fRmax1,fRmax2);
718 static const G4double halfRadTolerance=kRadTolerance*0.5;
719
720 G4double tanRMax,secRMax,rMaxAv,rMaxOAv ;
721 G4double tanRMin,secRMin,rMinAv,rMinOAv ;
723
724 G4double tolORMin,tolORMin2,tolIRMin,tolIRMin2 ;
725 G4double tolORMax2,tolIRMax,tolIRMax2 ;
727
728 G4double Dist,sd,xi,yi,zi,ri=0.,risec,rhoi2,cosPsi ;
729
733
735
736
737
738 tanRMin = (fRmin2 - fRmin1)*0.5/fDz ;
739 secRMin = std::sqrt(1.0 + tanRMin*tanRMin) ;
740 rMinAv = (fRmin1 + fRmin2)*0.5 ;
741
742 if (rMinAv > halfRadTolerance)
743 {
744 rMinOAv = rMinAv - halfRadTolerance ;
745 }
746 else
747 {
748 rMinOAv = 0.0 ;
749 }
750 tanRMax = (fRmax2 - fRmax1)*0.5/fDz ;
751 secRMax = std::sqrt(1.0 + tanRMax*tanRMax) ;
752 rMaxAv = (fRmax1 + fRmax2)*0.5 ;
753 rMaxOAv = rMaxAv + halfRadTolerance ;
754
755
756
757 tolIDz = fDz - halfCarTolerance ;
758 tolODz = fDz + halfCarTolerance ;
759
760 if (std::fabs(p.
z()) >= tolIDz)
761 {
762 if ( p.
z()*v.
z() < 0 )
763 {
764 sd = (std::fabs(p.
z()) - fDz)/std::fabs(v.
z()) ;
765
766 if( sd < 0.0 ) { sd = 0.0; }
767
768 xi = p.
x() + sd*v.
x() ;
769 yi = p.
y() + sd*v.
y() ;
770 rhoi2 = xi*xi + yi*yi ;
771
772
773
774
776 {
777 tolORMin = fRmin1 - halfRadTolerance*secRMin ;
778 tolIRMin = fRmin1 + halfRadTolerance*secRMin ;
779 tolIRMax = fRmax1 - halfRadTolerance*secRMin ;
780 tolORMax2 = (fRmax1 + halfRadTolerance*secRMax)*
781 (fRmax1 + halfRadTolerance*secRMax) ;
782 }
783 else
784 {
785 tolORMin = fRmin2 - halfRadTolerance*secRMin ;
786 tolIRMin = fRmin2 + halfRadTolerance*secRMin ;
787 tolIRMax = fRmax2 - halfRadTolerance*secRMin ;
788 tolORMax2 = (fRmax2 + halfRadTolerance*secRMax)*
789 (fRmax2 + halfRadTolerance*secRMax) ;
790 }
791 if ( tolORMin > 0 )
792 {
793 tolORMin2 = tolORMin*tolORMin ;
794 tolIRMin2 = tolIRMin*tolIRMin ;
795 }
796 else
797 {
798 tolORMin2 = 0.0 ;
799 tolIRMin2 = 0.0 ;
800 }
801 if ( tolIRMax > 0 ) { tolIRMax2 = tolIRMax*tolIRMax; }
802 else { tolIRMax2 = 0.0; }
803
804 if ( (tolIRMin2 <= rhoi2) && (rhoi2 <= tolIRMax2) )
805 {
806 if ( !fPhiFullCone && rhoi2 )
807 {
808
809
810 cosPsi = (xi*cosCPhi + yi*sinCPhi)/std::sqrt(rhoi2) ;
811
812 if (cosPsi >= cosHDPhiIT) { return sd; }
813 }
814 else
815 {
816 return sd;
817 }
818 }
819 }
820 else
821 {
822 return snxt ;
823 }
824 }
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845 t1 = 1.0 - v.
z()*v.
z() ;
846 t2 = p.
x()*v.
x() + p.
y()*v.
y() ;
847 t3 = p.
x()*p.
x() + p.
y()*p.
y() ;
848 rin = tanRMin*p.
z() + rMinAv ;
849 rout = tanRMax*p.
z() + rMaxAv ;
850
851
852
853
854 nt1 = t1 - (tanRMax*v.
z())*(tanRMax*v.
z()) ;
855 nt2 = t2 - tanRMax*v.
z()*rout ;
856 nt3 = t3 - rout*rout ;
857
858 if (std::fabs(nt1) > kRadTolerance)
859 {
860 b = nt2/nt1;
861 c = nt3/nt1;
862 d = b*b-c ;
863 if ( (nt3 > rout*rout*kRadTolerance*kRadTolerance*secRMax*secRMax)
864 || (rout < 0) )
865 {
866
867
868
869 if (d >= 0)
870 {
871
872 if ((rout < 0) && (nt3 <= 0))
873 {
874
875
876
877 if (b>0) { sd = c/(-b-std::sqrt(d)); }
878 else { sd = -b + std::sqrt(d); }
879 }
880 else
881 {
882 if ((b <= 0) && (c >= 0))
883 {
884 sd=c/(-b+std::sqrt(d));
885 }
886 else
887 {
888 if ( c <= 0 )
889 {
890 sd = -b + std::sqrt(d) ;
891 }
892 else
893 {
894 return kInfinity ;
895 }
896 }
897 }
898 if ( sd > 0 )
899 {
900 if ( sd>dRmax )
901 {
902 G4double fTerm = sd-std::fmod(sd,dRmax);
904 }
905 zi = p.
z() + sd*v.
z() ;
906
907 if (std::fabs(zi) <= tolODz)
908 {
909
910
911 if ( fPhiFullCone ) { return sd; }
912 else
913 {
914 xi = p.
x() + sd*v.
x() ;
915 yi = p.
y() + sd*v.
y() ;
916 ri = rMaxAv + zi*tanRMax ;
917 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri ;
918
919 if ( cosPsi >= cosHDPhiIT ) { return sd; }
920 }
921 }
922 }
923 }
924 }
925 else
926 {
927
928
929
930 if ( ( t3 > (rin + halfRadTolerance*secRMin)*
931 (rin + halfRadTolerance*secRMin) )
932 && (nt2 < 0) && (d >= 0) && (std::fabs(p.
z()) <= tolIDz) )
933 {
934
935
936
939 risec = std::sqrt(xi*xi + yi*yi)*secRMax ;
941 if ( !fPhiFullCone )
942 {
943 cosPsi = (p.
x()*cosCPhi + p.
y()*sinCPhi)/std::sqrt(t3) ;
944 if ( cosPsi >= cosHDPhiIT )
945 {
946 if ( Normal.
dot(v) <= 0 ) {
return 0.0; }
947 }
948 }
949 else
950 {
951 if ( Normal.
dot(v) <= 0 ) {
return 0.0; }
952 }
953 }
954 }
955 }
956 else
957 {
958 if ( std::fabs(nt2) > kRadTolerance )
959 {
960 sd = -0.5*nt3/nt2 ;
961
962 if ( sd < 0 ) { return kInfinity; }
963 else
964 {
965 zi = p.
z() + sd*v.
z() ;
966
967 if ((std::fabs(zi) <= tolODz) && (nt2 < 0))
968 {
969
970
971 if ( fPhiFullCone ) { return sd; }
972 else
973 {
974 xi = p.
x() + sd*v.
x() ;
975 yi = p.
y() + sd*v.
y() ;
976 ri = rMaxAv + zi*tanRMax ;
977 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri ;
978
979 if (cosPsi >= cosHDPhiIT) { return sd; }
980 }
981 }
982 }
983 }
984 else
985 {
986 sd = kInfinity ;
987 }
988 }
989
990
991
992
993
994
995
996
997
998
999 if (rMinAv)
1000 {
1001 nt1 = t1 - (tanRMin*v.
z())*(tanRMin*v.
z()) ;
1002 nt2 = t2 - tanRMin*v.
z()*rin ;
1003 nt3 = t3 - rin*rin ;
1004
1005 if ( nt1 )
1006 {
1007 if ( nt3 > rin*kRadTolerance*secRMin )
1008 {
1009
1010
1011
1012 b = nt2/nt1 ;
1013 c = nt3/nt1 ;
1014 d = b*b-c ;
1015 if (d >= 0)
1016 {
1017 if(b>0){sd = c/( -b-std::sqrt(d));}
1018 else {sd = -b + std::sqrt(d) ;}
1019
1020 if ( sd >= 0 )
1021 {
1022 if ( sd>dRmax )
1023 {
1024 G4double fTerm = sd-std::fmod(sd,dRmax);
1026 }
1027 zi = p.
z() + sd*v.
z() ;
1028
1029 if ( std::fabs(zi) <= tolODz )
1030 {
1031 if ( !fPhiFullCone )
1032 {
1033 xi = p.
x() + sd*v.
x() ;
1034 yi = p.
y() + sd*v.
y() ;
1035 ri = rMinAv + zi*tanRMin ;
1036 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri ;
1037
1038 if (cosPsi >= cosHDPhiIT)
1039 {
1040 if ( sd > halfRadTolerance ) { snxt=sd; }
1041 else
1042 {
1043
1044
1045 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1046 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin);
1047 if ( Normal.
dot(v) <= 0 ) { snxt = sd; }
1048 }
1049 }
1050 }
1051 else
1052 {
1053 if ( sd > halfRadTolerance ) { return sd; }
1054 else
1055 {
1056
1057
1058 xi = p.
x() + sd*v.
x() ;
1059 yi = p.
y() + sd*v.
y() ;
1060 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1061 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin) ;
1062 if ( Normal.
dot(v) <= 0 ) {
return sd; }
1063 }
1064 }
1065 }
1066 }
1067 }
1068 }
1069 else if ( nt3 < -rin*kRadTolerance*secRMin )
1070 {
1071
1072
1073
1074
1075
1076 b = nt2/nt1 ;
1077 c = nt3/nt1 ;
1078 d = b*b - c ;
1079
1080 if ( d >= 0 )
1081 {
1082 if (b>0) { sd = c/(-b-std::sqrt(d)); }
1083 else { sd = -b + std::sqrt(d); }
1084 zi = p.
z() + sd*v.
z() ;
1085 ri = rMinAv + zi*tanRMin ;
1086
1087 if ( ri > 0 )
1088 {
1089 if ( (sd >= 0) && (std::fabs(zi) <= tolODz) )
1090 {
1091 if ( sd>dRmax )
1092 {
1093 G4double fTerm = sd-std::fmod(sd,dRmax);
1095 }
1096 if ( !fPhiFullCone )
1097 {
1098 xi = p.
x() + sd*v.
x() ;
1099 yi = p.
y() + sd*v.
y() ;
1100 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri ;
1101
1102 if (cosPsi >= cosHDPhiOT)
1103 {
1104 if ( sd > halfRadTolerance ) { snxt=sd; }
1105 else
1106 {
1107
1108
1109 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1110 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin);
1111 if ( Normal.
dot(v) <= 0 ) { snxt = sd; }
1112 }
1113 }
1114 }
1115 else
1116 {
1117 if( sd > halfRadTolerance ) { return sd; }
1118 else
1119 {
1120
1121
1122 xi = p.
x() + sd*v.
x() ;
1123 yi = p.
y() + sd*v.
y() ;
1124 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1125 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin) ;
1126 if ( Normal.
dot(v) <= 0 ) {
return sd; }
1127 }
1128 }
1129 }
1130 }
1131 else
1132 {
1133 if (b>0) { sd = -b - std::sqrt(d); }
1134 else { sd = c/(-b+std::sqrt(d)); }
1135 zi = p.
z() + sd*v.
z() ;
1136 ri = rMinAv + zi*tanRMin ;
1137
1138 if ( (sd >= 0) && (ri > 0) && (std::fabs(zi) <= tolODz) )
1139 {
1140 if ( sd>dRmax )
1141 {
1142 G4double fTerm = sd-std::fmod(sd,dRmax);
1144 }
1145 if ( !fPhiFullCone )
1146 {
1147 xi = p.
x() + sd*v.
x() ;
1148 yi = p.
y() + sd*v.
y() ;
1149 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri ;
1150
1151 if (cosPsi >= cosHDPhiIT)
1152 {
1153 if ( sd > halfRadTolerance ) { snxt=sd; }
1154 else
1155 {
1156
1157
1158 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1159 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin);
1160 if ( Normal.
dot(v) <= 0 ) { snxt = sd; }
1161 }
1162 }
1163 }
1164 else
1165 {
1166 if ( sd > halfRadTolerance ) { return sd; }
1167 else
1168 {
1169
1170
1171 xi = p.
x() + sd*v.
x() ;
1172 yi = p.
y() + sd*v.
y() ;
1173 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1174 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin) ;
1175 if ( Normal.
dot(v) <= 0 ) {
return sd; }
1176 }
1177 }
1178 }
1179 }
1180 }
1181 }
1182 else
1183 {
1184
1185
1186
1187
1188
1189 if ( std::fabs(p.
z()) <= tolODz )
1190 {
1191 if ( nt2 > 0 )
1192 {
1193
1194
1195 if ( !fPhiFullCone )
1196 {
1197 cosPsi = (p.
x()*cosCPhi + p.
y()*sinCPhi)/std::sqrt(t3) ;
1198
1199 if (cosPsi >= cosHDPhiIT) { return 0.0; }
1200 }
1201 else { return 0.0; }
1202 }
1203 else
1204 {
1205
1206
1207
1208 b = nt2/nt1 ;
1209 c = nt3/nt1 ;
1210 d = b*b - c ;
1211
1212 if ( d >= 0 )
1213 {
1214 if (b>0) { sd = -b - std::sqrt(d); }
1215 else { sd = c/(-b+std::sqrt(d)); }
1216 zi = p.
z() + sd*v.
z() ;
1217 ri = rMinAv + zi*tanRMin ;
1218
1219 if ( ri > 0 )
1220 {
1221 if (b>0) { sd = c/(-b-std::sqrt(d)); }
1222 else { sd = -b + std::sqrt(d); }
1223
1224 zi = p.
z() + sd*v.
z() ;
1225
1226 if ( (sd >= 0) && (std::fabs(zi) <= tolODz) )
1227 {
1228 if ( sd>dRmax )
1229 {
1230 G4double fTerm = sd-std::fmod(sd,dRmax);
1232 }
1233 if ( !fPhiFullCone )
1234 {
1235 xi = p.
x() + sd*v.
x() ;
1236 yi = p.
y() + sd*v.
y() ;
1237 ri = rMinAv + zi*tanRMin ;
1238 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri ;
1239
1240 if ( cosPsi >= cosHDPhiIT ) { snxt = sd; }
1241 }
1242 else { return sd; }
1243 }
1244 }
1245 else { return kInfinity; }
1246 }
1247 }
1248 }
1249 else
1250 {
1251 b = nt2/nt1 ;
1252 c = nt3/nt1 ;
1253 d = b*b - c ;
1254
1255 if ( d > 0 )
1256 {
1257 if (b>0) { sd = c/(-b-std::sqrt(d)); }
1258 else { sd = -b + std::sqrt(d) ; }
1259 zi = p.
z() + sd*v.
z() ;
1260
1261 if ( (sd >= 0) && (std::fabs(zi) <= tolODz) )
1262 {
1263 if ( sd>dRmax )
1264 {
1265 G4double fTerm = sd-std::fmod(sd,dRmax);
1267 }
1268 if ( !fPhiFullCone )
1269 {
1270 xi = p.
x() + sd*v.
x();
1271 yi = p.
y() + sd*v.
y();
1272 ri = rMinAv + zi*tanRMin ;
1273 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri;
1274
1275 if (cosPsi >= cosHDPhiIT) { snxt = sd; }
1276 }
1277 else { return sd; }
1278 }
1279 }
1280 }
1281 }
1282 }
1283 }
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294 if ( !fPhiFullCone )
1295 {
1296
1297
1298 Comp = v.
x()*sinSPhi - v.
y()*cosSPhi ;
1299
1300 if ( Comp < 0 )
1301 {
1302 Dist = (p.
y()*cosSPhi - p.
x()*sinSPhi) ;
1303
1304 if (Dist < halfCarTolerance)
1305 {
1306 sd = Dist/Comp ;
1307
1308 if ( sd < snxt )
1309 {
1310 if ( sd < 0 ) { sd = 0.0; }
1311
1312 zi = p.
z() + sd*v.
z() ;
1313
1314 if ( std::fabs(zi) <= tolODz )
1315 {
1316 xi = p.
x() + sd*v.
x() ;
1317 yi = p.
y() + sd*v.
y() ;
1318 rhoi2 = xi*xi + yi*yi ;
1319 tolORMin2 = (rMinOAv + zi*tanRMin)*(rMinOAv + zi*tanRMin) ;
1320 tolORMax2 = (rMaxOAv + zi*tanRMax)*(rMaxOAv + zi*tanRMax) ;
1321
1322 if ( (rhoi2 >= tolORMin2) && (rhoi2 <= tolORMax2) )
1323 {
1324
1325
1326
1327 if ((yi*cosCPhi - xi*sinCPhi) <= 0 ) { snxt = sd; }
1328 }
1329 }
1330 }
1331 }
1332 }
1333
1334
1335
1336 Comp = -(v.
x()*sinEPhi - v.
y()*cosEPhi) ;
1337
1338 if ( Comp < 0 )
1339 {
1340 Dist = -(p.
y()*cosEPhi - p.
x()*sinEPhi) ;
1341 if (Dist < halfCarTolerance)
1342 {
1343 sd = Dist/Comp ;
1344
1345 if ( sd < snxt )
1346 {
1347 if ( sd < 0 ) { sd = 0.0; }
1348
1349 zi = p.
z() + sd*v.
z() ;
1350
1351 if (std::fabs(zi) <= tolODz)
1352 {
1353 xi = p.
x() + sd*v.
x() ;
1354 yi = p.
y() + sd*v.
y() ;
1355 rhoi2 = xi*xi + yi*yi ;
1356 tolORMin2 = (rMinOAv + zi*tanRMin)*(rMinOAv + zi*tanRMin) ;
1357 tolORMax2 = (rMaxOAv + zi*tanRMax)*(rMaxOAv + zi*tanRMax) ;
1358
1359 if ( (rhoi2 >= tolORMin2) && (rhoi2 <= tolORMax2) )
1360 {
1361
1362
1363
1364 if ( (yi*cosCPhi - xi*sinCPhi) >= 0.0 ) { snxt = sd; }
1365 }
1366 }
1367 }
1368 }
1369 }
1370 }
1371 if (snxt < halfCarTolerance) { snxt = 0.; }
1372
1373 return snxt ;
1374}
CLHEP::Hep3Vector G4ThreeVector
double dot(const Hep3Vector &) const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const