Returns the distance along the normalised vector 'v' to the shape, from the point at offset 'p'. If there is no intersection, returns kInfinity. The first intersection resulting from 'leaving' a surface/volume is discarded. Hence, it is tolerant of points on the surface of the shape.
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
847 xi = p.
x() + sd*v.
x() ;
848 yi = p.
y() + sd*v.
y() ;
849 ri = rMaxAv + zi*tanRMax ;
850 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri ;
851
852 if ( cosPsi >= cosHDPhiIT ) { return sd; }
853 }
854 }
855 }
856 }
857 else
858 {
859
860
861
862 if ( ( t3 > (rin + halfRadTolerance*secRMin)*
863 (rin + halfRadTolerance*secRMin) )
864 && (nt2 < 0) && (d >= 0) && (std::fabs(p.
z()) <= tolIDz) )
865 {
866
867
868
871 risec = std::sqrt(xi*xi + yi*yi)*secRMax ;
873 if ( !fPhiFullCone )
874 {
875 cosPsi = (p.
x()*cosCPhi + p.
y()*sinCPhi)/std::sqrt(t3) ;
876 if ( cosPsi >= cosHDPhiIT )
877 {
878 if ( Normal.
dot(v) <= 0 ) {
return 0.0; }
879 }
880 }
881 else
882 {
883 if ( Normal.
dot(v) <= 0 ) {
return 0.0; }
884 }
885 }
886 }
887 }
888 else
889 {
890 if ( std::fabs(nt2) > kRadTolerance )
891 {
892 sd = -0.5*nt3/nt2 ;
893
894 if ( sd < 0 ) { return kInfinity; }
895
896
897 zi = p.
z() + sd*v.
z() ;
898
899 if ((std::fabs(zi) <= tolODz) && (nt2 < 0))
900 {
901
902
903 if ( fPhiFullCone ) { return sd; }
904
905 xi = p.
x() + sd*v.
x() ;
906 yi = p.
y() + sd*v.
y() ;
907 ri = rMaxAv + zi*tanRMax ;
908 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri ;
909
910 if (cosPsi >= cosHDPhiIT) { return sd; }
911 }
912 }
913 else
914 {
915 sd = kInfinity ;
916 }
917 }
918
919
920
921
922
923
924
925
926
927
928 if (rMinAv != 0.0)
929 {
930 nt1 = t1 - (tanRMin*v.
z())*(tanRMin*v.
z()) ;
931 nt2 = t2 - tanRMin*v.
z()*rin ;
932 nt3 = t3 - rin*rin ;
933
934 if ( nt1 != 0.0 )
935 {
936 if ( nt3 > rin*kRadTolerance*secRMin )
937 {
938
939
940
941 b = nt2/nt1 ;
942 c = nt3/nt1 ;
943 d = b*b-c ;
944 if (d >= 0)
945 {
946 if(b>0){sd = c/( -b-std::sqrt(d));}
947 else {sd = -b + std::sqrt(d) ;}
948
949 if ( sd >= 0 )
950 {
951 if ( sd>dRmax )
952 {
953 G4double fTerm = sd-std::fmod(sd,dRmax);
955 }
956 zi = p.
z() + sd*v.
z() ;
957
958 if ( std::fabs(zi) <= tolODz )
959 {
960 if ( !fPhiFullCone )
961 {
962 xi = p.
x() + sd*v.
x() ;
963 yi = p.
y() + sd*v.
y() ;
964 ri = rMinAv + zi*tanRMin ;
965 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri ;
966
967 if (cosPsi >= cosHDPhiIT)
968 {
969 if ( sd > halfRadTolerance ) { snxt=sd; }
970 else
971 {
972
973
974 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
976 if ( Normal.
dot(v) <= 0 ) { snxt = sd; }
977 }
978 }
979 }
980 else
981 {
982 if ( sd > halfRadTolerance ) { return sd; }
983
984
985
986 xi = p.
x() + sd*v.
x() ;
987 yi = p.
y() + sd*v.
y() ;
988 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
989 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin) ;
990 if ( Normal.
dot(v) <= 0 ) {
return sd; }
991 }
992 }
993 }
994 }
995 }
996 else if ( nt3 < -rin*kRadTolerance*secRMin )
997 {
998
999
1000
1001
1002
1003 b = nt2/nt1 ;
1004 c = nt3/nt1 ;
1005 d = b*b - c ;
1006
1007 if ( d >= 0 )
1008 {
1009 if (b>0) { sd = c/(-b-std::sqrt(d)); }
1010 else { sd = -b + std::sqrt(d); }
1011 zi = p.
z() + sd*v.
z() ;
1012 ri = rMinAv + zi*tanRMin ;
1013
1014 if ( ri > 0 )
1015 {
1016 if ( (sd >= 0) && (std::fabs(zi) <= tolODz) )
1017 {
1018 if ( sd>dRmax )
1019 {
1020 G4double fTerm = sd-std::fmod(sd,dRmax);
1022 }
1023 if ( !fPhiFullCone )
1024 {
1025 xi = p.
x() + sd*v.
x() ;
1026 yi = p.
y() + sd*v.
y() ;
1027 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri ;
1028
1029 if (cosPsi >= cosHDPhiOT)
1030 {
1031 if ( sd > halfRadTolerance ) { snxt=sd; }
1032 else
1033 {
1034
1035
1036 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1037 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin);
1038 if ( Normal.
dot(v) <= 0 ) { snxt = sd; }
1039 }
1040 }
1041 }
1042 else
1043 {
1044 if( sd > halfRadTolerance ) { return sd; }
1045
1046
1047
1048 xi = p.
x() + sd*v.
x() ;
1049 yi = p.
y() + sd*v.
y() ;
1050 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1051 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin) ;
1052 if ( Normal.
dot(v) <= 0 ) {
return sd; }
1053 }
1054 }
1055 }
1056 else
1057 {
1058 if (b>0) { sd = -b - std::sqrt(d); }
1059 else { sd = c/(-b+std::sqrt(d)); }
1060 zi = p.
z() + sd*v.
z() ;
1061 ri = rMinAv + zi*tanRMin ;
1062
1063 if ( (sd >= 0) && (ri > 0) && (std::fabs(zi) <= tolODz) )
1064 {
1065 if ( sd>dRmax )
1066 {
1067 G4double fTerm = sd-std::fmod(sd,dRmax);
1069 }
1070 if ( !fPhiFullCone )
1071 {
1072 xi = p.
x() + sd*v.
x() ;
1073 yi = p.
y() + sd*v.
y() ;
1074 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri ;
1075
1076 if (cosPsi >= cosHDPhiIT)
1077 {
1078 if ( sd > halfRadTolerance ) { snxt=sd; }
1079 else
1080 {
1081
1082
1083 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1084 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin);
1085 if ( Normal.
dot(v) <= 0 ) { snxt = sd; }
1086 }
1087 }
1088 }
1089 else
1090 {
1091 if ( sd > halfRadTolerance ) { return sd; }
1092
1093
1094
1095 xi = p.
x() + sd*v.
x() ;
1096 yi = p.
y() + sd*v.
y() ;
1097 risec = std::sqrt(xi*xi + yi*yi)*secRMin ;
1098 Normal =
G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin) ;
1099 if ( Normal.
dot(v) <= 0 ) {
return sd; }
1100 }
1101 }
1102 }
1103 }
1104 }
1105 else
1106 {
1107
1108
1109
1110
1111
1112 if ( std::fabs(p.
z()) <= tolODz )
1113 {
1114 if ( nt2 > 0 )
1115 {
1116
1117
1118 if ( !fPhiFullCone )
1119 {
1120 cosPsi = (p.
x()*cosCPhi + p.
y()*sinCPhi)/std::sqrt(t3) ;
1121
1122 if (cosPsi >= cosHDPhiIT) { return 0.0; }
1123 }
1124 else { return 0.0; }
1125 }
1126 else
1127 {
1128
1129
1130
1131 b = nt2/nt1 ;
1132 c = nt3/nt1 ;
1133 d = b*b - c ;
1134
1135 if ( d >= 0 )
1136 {
1137 if (b>0) { sd = -b - std::sqrt(d); }
1138 else { sd = c/(-b+std::sqrt(d)); }
1139 zi = p.
z() + sd*v.
z() ;
1140 ri = rMinAv + zi*tanRMin ;
1141
1142 if ( ri > 0 )
1143 {
1144 if (b>0) { sd = c/(-b-std::sqrt(d)); }
1145 else { sd = -b + std::sqrt(d); }
1146
1147 zi = p.
z() + sd*v.
z() ;
1148
1149 if ( (sd >= 0) && (std::fabs(zi) <= tolODz) )
1150 {
1151 if ( sd>dRmax )
1152 {
1153 G4double fTerm = sd-std::fmod(sd,dRmax);
1155 }
1156 if ( !fPhiFullCone )
1157 {
1158 xi = p.
x() + sd*v.
x() ;
1159 yi = p.
y() + sd*v.
y() ;
1160 ri = rMinAv + zi*tanRMin ;
1161 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri ;
1162
1163 if ( cosPsi >= cosHDPhiIT ) { snxt = sd; }
1164 }
1165 else { return sd; }
1166 }
1167 }
1168 else { return kInfinity; }
1169 }
1170 }
1171 }
1172 else
1173 {
1174 b = nt2/nt1 ;
1175 c = nt3/nt1 ;
1176 d = b*b - c ;
1177
1178 if ( d > 0 )
1179 {
1180 if (b>0) { sd = c/(-b-std::sqrt(d)); }
1181 else { sd = -b + std::sqrt(d) ; }
1182 zi = p.
z() + sd*v.
z() ;
1183
1184 if ( (sd >= 0) && (std::fabs(zi) <= tolODz) )
1185 {
1186 if ( sd>dRmax )
1187 {
1188 G4double fTerm = sd-std::fmod(sd,dRmax);
1190 }
1191 if ( !fPhiFullCone )
1192 {
1193 xi = p.
x() + sd*v.
x();
1194 yi = p.
y() + sd*v.
y();
1195 ri = rMinAv + zi*tanRMin ;
1196 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri;
1197
1198 if (cosPsi >= cosHDPhiIT) { snxt = sd; }
1199 }
1200 else { return sd; }
1201 }
1202 }
1203 }
1204 }
1205 }
1206 }
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217 if ( !fPhiFullCone )
1218 {
1219
1220
1221 Comp = v.
x()*sinSPhi - v.
y()*cosSPhi ;
1222
1223 if ( Comp < 0 )
1224 {
1225 Dist = (p.
y()*cosSPhi - p.
x()*sinSPhi) ;
1226
1227 if (Dist < halfCarTolerance)
1228 {
1229 sd = Dist/Comp ;
1230
1231 if ( sd < snxt )
1232 {
1233 if ( sd < 0 ) { sd = 0.0; }
1234
1235 zi = p.
z() + sd*v.
z() ;
1236
1237 if ( std::fabs(zi) <= tolODz )
1238 {
1239 xi = p.
x() + sd*v.
x() ;
1240 yi = p.
y() + sd*v.
y() ;
1241 rhoi2 = xi*xi + yi*yi ;
1242 tolORMin2 = (rMinOAv + zi*tanRMin)*(rMinOAv + zi*tanRMin) ;
1243 tolORMax2 = (rMaxOAv + zi*tanRMax)*(rMaxOAv + zi*tanRMax) ;
1244
1245 if ( (rhoi2 >= tolORMin2) && (rhoi2 <= tolORMax2) )
1246 {
1247
1248
1249
1250 if ((yi*cosCPhi - xi*sinCPhi) <= 0 ) { snxt = sd; }
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 if (Dist < halfCarTolerance)
1265 {
1266 sd = Dist/Comp ;
1267
1268 if ( sd < snxt )
1269 {
1270 if ( sd < 0 ) { sd = 0.0; }
1271
1272 zi = p.
z() + sd*v.
z() ;
1273
1274 if (std::fabs(zi) <= tolODz)
1275 {
1276 xi = p.
x() + sd*v.
x() ;
1277 yi = p.
y() + sd*v.
y() ;
1278 rhoi2 = xi*xi + yi*yi ;
1279 tolORMin2 = (rMinOAv + zi*tanRMin)*(rMinOAv + zi*tanRMin) ;
1280 tolORMax2 = (rMaxOAv + zi*tanRMax)*(rMaxOAv + zi*tanRMax) ;
1281
1282 if ( (rhoi2 >= tolORMin2) && (rhoi2 <= tolORMax2) )
1283 {
1284
1285
1286
1287 if ( (yi*cosCPhi - xi*sinCPhi) >= 0.0 ) { snxt = sd; }
1288 }
1289 }
1290 }
1291 }
1292 }
1293 }
1294 if (snxt < halfCarTolerance) { snxt = 0.; }
1295
1296 return snxt ;
1297}
double dot(const Hep3Vector &) const
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const override