886{
892
893
894
895 G4double Dist, sd=0, xi, yi, zi, rho2, inum, iden, cosPsi, Comp,calf ;
898
899
900 if (fRMin > kRadTolerance)
901 {
902 tolORMin2 = (fRMin - halfRadTolerance)*(fRMin - halfRadTolerance) ;
903 tolIRMin2 = (fRMin + halfRadTolerance)*(fRMin + halfRadTolerance) ;
904 }
905 else
906 {
907 tolORMin2 = 0.0 ;
908 tolIRMin2 = 0.0 ;
909 }
910 tolORMax2 = (fRMax + halfRadTolerance)*(fRMax + halfRadTolerance) ;
911 tolIRMax2 = (fRMax - halfRadTolerance)*(fRMax - halfRadTolerance) ;
912
913
914
915
916
917 distZLow =(p+vZ).dot(fLowNorm);
918
919
920
921 distZHigh = (p-vZ).dot(fHighNorm);
922
923 if ( distZLow >= -halfCarTolerance )
924 {
925 calf = v.
dot(fLowNorm);
926 if (calf<0)
927 {
928 sd = -distZLow/calf;
929 if(sd < 0.0) { sd = 0.0; }
930
931 xi = p.
x() + sd*v.
x() ;
932 yi = p.
y() + sd*v.
y() ;
933 rho2 = xi*xi + yi*yi ;
934
935
936
937 if ((tolIRMin2 <= rho2) && (rho2 <= tolIRMax2))
938 {
939 if (!fPhiFullCutTube && (rho2 != 0.0))
940 {
941
942
943 inum = xi*cosCPhi + yi*sinCPhi ;
944 iden = std::sqrt(rho2) ;
945 cosPsi = inum/iden ;
946 if (cosPsi >= cosHDPhiIT) { return sd ; }
947 }
948 else
949 {
950 return sd ;
951 }
952 }
953 }
954 else
955 {
956 if ( sd<halfCarTolerance )
957 {
958 if(calf>=0) { sd=kInfinity; }
959 return sd ;
960 }
961 }
962 }
963
964 if(distZHigh >= -halfCarTolerance )
965 {
966 calf = v.
dot(fHighNorm);
967 if (calf<0)
968 {
969 sd = -distZHigh/calf;
970
971 if(sd < 0.0) { sd = 0.0; }
972
973 xi = p.
x() + sd*v.
x() ;
974 yi = p.
y() + sd*v.
y() ;
975 rho2 = xi*xi + yi*yi ;
976
977
978
979 if ((tolIRMin2 <= rho2) && (rho2 <= tolIRMax2))
980 {
981 if (!fPhiFullCutTube && (rho2 != 0.0))
982 {
983
984
985 inum = xi*cosCPhi + yi*sinCPhi ;
986 iden = std::sqrt(rho2) ;
987 cosPsi = inum/iden ;
988 if (cosPsi >= cosHDPhiIT) { return sd ; }
989 }
990 else
991 {
992 return sd ;
993 }
994 }
995 }
996 else
997 {
998 if ( sd<halfCarTolerance )
999 {
1000 if(calf>=0) { sd=kInfinity; }
1001 return sd ;
1002 }
1003 }
1004 }
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017 t1 = 1.0 - v.
z()*v.
z() ;
1018 t2 = p.
x()*v.
x() + p.
y()*v.
y() ;
1019 t3 = p.
x()*p.
x() + p.
y()*p.
y() ;
1020 if ( t1 > 0 )
1021 {
1022 b = t2/t1 ;
1023 c = t3 - fRMax*fRMax ;
1024
1025 if ((t3 >= tolORMax2) && (t2<0))
1026 {
1027
1028
1029 c /= t1 ;
1030 d = b*b - c ;
1031
1032 if (d >= 0)
1033 {
1034 sd = c/(-b+std::sqrt(d));
1035 if (sd >= 0)
1036 {
1037 if ( sd>dRmax )
1038 {
1039 G4double fTerm = sd-std::fmod(sd,dRmax);
1041 }
1042
1043
1044 zi = p.
z() + sd*v.
z() ;
1045 xi = p.
x() + sd*v.
x() ;
1046 yi = p.
y() + sd*v.
y() ;
1047 if ((-xi*fLowNorm.
x()-yi*fLowNorm.
y()
1048 -(zi+fDz)*fLowNorm.
z())>-halfCarTolerance)
1049 {
1050 if ((-xi*fHighNorm.
x()-yi*fHighNorm.
y()
1051 +(fDz-zi)*fHighNorm.
z())>-halfCarTolerance)
1052 {
1053
1054
1055 if (fPhiFullCutTube)
1056 {
1057 return sd ;
1058 }
1059 else
1060 {
1061 xi = p.
x() + sd*v.
x() ;
1062 yi = p.
y() + sd*v.
y() ;
1063 cosPsi = (xi*cosCPhi + yi*sinCPhi)/fRMax ;
1064 if (cosPsi >= cosHDPhiIT) { return sd ; }
1065 }
1066 }
1067 }
1068 }
1069 }
1070 }
1071 else
1072 {
1073
1074
1075 if ((t3 > tolIRMin2) && (t2 < 0)
1076 && (std::fabs(p.
z()) <= std::fabs(
GetCutZ(p))-halfCarTolerance ))
1077 {
1078
1079
1080 if (!fPhiFullCutTube)
1081 {
1082 inum = p.
x()*cosCPhi + p.
y()*sinCPhi ;
1083 iden = std::sqrt(t3) ;
1084 cosPsi = inum/iden ;
1085 if (cosPsi >= cosHDPhiIT)
1086 {
1087
1088
1089
1090
1091
1092
1093 c = t3-fRMax*fRMax;
1094 if ( c<=0.0 )
1095 {
1096 return 0.0;
1097 }
1098 else
1099 {
1100 c = c/t1 ;
1101 d = b*b-c;
1102 if ( d>=0.0 )
1103 {
1104 snxt = c/(-b+std::sqrt(d));
1105
1106 if ( snxt < halfCarTolerance ) { snxt=0; }
1107 return snxt ;
1108 }
1109 else
1110 {
1111 return kInfinity;
1112 }
1113 }
1114 }
1115 }
1116 else
1117 {
1118
1119
1120
1121
1122
1123
1124 c = t3 - fRMax*fRMax;
1125 if ( c<=0.0 )
1126 {
1127 return 0.0;
1128 }
1129 else
1130 {
1131 c = c/t1 ;
1132 d = b*b-c;
1133 if ( d>=0.0 )
1134 {
1135 snxt= c/(-b+std::sqrt(d));
1136
1137 if ( snxt < halfCarTolerance ) { snxt=0; }
1138 return snxt ;
1139 }
1140 else
1141 {
1142 return kInfinity;
1143 }
1144 }
1145 }
1146 }
1147 }
1148
1149 if ( fRMin != 0.0 )
1150 {
1151 c = (t3 - fRMin*fRMin)/t1 ;
1152 d = b*b - c ;
1153 if ( d >= 0.0 )
1154 {
1155
1156
1157
1158 sd =( b > 0. )? c/(-b - std::sqrt(d)) : (-b + std::sqrt(d));
1159 if (sd >= -10*halfCarTolerance)
1160 {
1161
1162
1163 if (sd < 0.0) { sd = 0.0; }
1164 if (sd>dRmax)
1165 {
1166 G4double fTerm = sd-std::fmod(sd,dRmax);
1168 }
1169 zi = p.
z() + sd*v.
z() ;
1170 xi = p.
x() + sd*v.
x() ;
1171 yi = p.
y() + sd*v.
y() ;
1172 if ((-xi*fLowNorm.
x()-yi*fLowNorm.
y()
1173 -(zi+fDz)*fLowNorm.
z())>-halfCarTolerance)
1174 {
1175 if ((-xi*fHighNorm.
x()-yi*fHighNorm.
y()
1176 +(fDz-zi)*fHighNorm.
z())>-halfCarTolerance)
1177 {
1178
1179
1180 if ( fPhiFullCutTube )
1181 {
1182 return sd ;
1183 }
1184 else
1185 {
1186 cosPsi = (xi*cosCPhi + yi*sinCPhi)/fRMin ;
1187 if (cosPsi >= cosHDPhiIT)
1188 {
1189
1190
1191
1192 snxt = sd ;
1193 }
1194 }
1195 }
1196 }
1197 }
1198 }
1199 }
1200 }
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211 if ( !fPhiFullCutTube )
1212 {
1213
1214
1215 Comp = v.
x()*sinSPhi - v.
y()*cosSPhi ;
1216
1217 if ( Comp < 0 )
1218 {
1219 Dist = (p.
y()*cosSPhi - p.
x()*sinSPhi) ;
1220
1221 if ( Dist < halfCarTolerance )
1222 {
1223 sd = Dist/Comp ;
1224
1225 if (sd < snxt)
1226 {
1227 if ( sd < 0 ) { sd = 0.0; }
1228 zi = p.
z() + sd*v.
z() ;
1229 xi = p.
x() + sd*v.
x() ;
1230 yi = p.
y() + sd*v.
y() ;
1231 if ((-xi*fLowNorm.
x()-yi*fLowNorm.
y()
1232 -(zi+fDz)*fLowNorm.
z())>-halfCarTolerance)
1233 {
1234 if ((-xi*fHighNorm.
x()-yi*fHighNorm.
y()
1235 +(fDz-zi)*fHighNorm.
z())>-halfCarTolerance)
1236 {
1237 rho2 = xi*xi + yi*yi ;
1238 if ( ( (rho2 >= tolIRMin2) && (rho2 <= tolIRMax2) )
1239 || ( (rho2 > tolORMin2) && (rho2 < tolIRMin2)
1240 && ( v.
y()*cosSPhi - v.
x()*sinSPhi > 0 )
1241 && ( v.
x()*cosSPhi + v.
y()*sinSPhi >= 0 ) )
1242 || ( (rho2 > tolIRMax2) && (rho2 < tolORMax2)
1243 && (v.
y()*cosSPhi - v.
x()*sinSPhi > 0)
1244 && (v.
x()*cosSPhi + v.
y()*sinSPhi < 0) ) )
1245 {
1246
1247
1248
1249 if ((yi*cosCPhi-xi*sinCPhi) <= halfCarTolerance) { snxt = sd; }
1250 }
1251 }
1252 }
1253 }
1254 }
1255 }
1256
1257
1258
1259 Comp = -(v.
x()*sinEPhi - v.
y()*cosEPhi) ;
1260
1261 if (Comp < 0 )
1262 {
1263 Dist = -(p.
y()*cosEPhi - p.
x()*sinEPhi) ;
1264
1265 if ( Dist < halfCarTolerance )
1266 {
1267 sd = Dist/Comp ;
1268
1269 if (sd < snxt)
1270 {
1271 if ( sd < 0 ) { sd = 0; }
1272 zi = p.
z() + sd*v.
z() ;
1273 xi = p.
x() + sd*v.
x() ;
1274 yi = p.
y() + sd*v.
y() ;
1275 if ((-xi*fLowNorm.
x()-yi*fLowNorm.
y()
1276 -(zi+fDz)*fLowNorm.
z())>-halfCarTolerance)
1277 {
1278 if ((-xi*fHighNorm.
x()-yi*fHighNorm.
y()
1279 +(fDz-zi)*fHighNorm.
z())>-halfCarTolerance)
1280 {
1281 xi = p.
x() + sd*v.
x() ;
1282 yi = p.
y() + sd*v.
y() ;
1283 rho2 = xi*xi + yi*yi ;
1284 if ( ( (rho2 >= tolIRMin2) && (rho2 <= tolIRMax2) )
1285 || ( (rho2 > tolORMin2) && (rho2 < tolIRMin2)
1286 && (v.
x()*sinEPhi - v.
y()*cosEPhi > 0)
1287 && (v.
x()*cosEPhi + v.
y()*sinEPhi >= 0) )
1288 || ( (rho2 > tolIRMax2) && (rho2 < tolORMax2)
1289 && (v.
x()*sinEPhi - v.
y()*cosEPhi > 0)
1290 && (v.
x()*cosEPhi + v.
y()*sinEPhi < 0) ) )
1291 {
1292
1293
1294
1295 if ( (yi*cosCPhi-xi*sinCPhi) >= -halfCarTolerance )
1296 {
1297 snxt = sd;
1298 }
1299 }
1300 }
1301 }
1302 }
1303 }
1304 }
1305 }
1306 if ( snxt<halfCarTolerance ) { snxt=0; }
1307
1308 return snxt ;
1309}
double dot(const Hep3Vector &) const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const override