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