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