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