900{
901#ifdef G4TESS_TEST
902 if ( fTessellatedSolid )
903 {
904 return fTessellatedSolid->
DistanceToOut(p, v, calcNorm, validNorm, n);
905 }
906#endif
907
909
911 G4bool lateral_cross =
false;
912 ESide side = kUndefined;
913
914 if (calcNorm) { *validNorm=true; }
915
917 {
918 distmin=(-fDz-p.
z())/v.
z();
920 }
921 else
922 {
924 {
925 distmin = (fDz-p.
z())/v.
z();
927 }
928 else { distmin = kInfinity; }
929 }
930
934
935 for (
G4int ipl=0; ipl<4; ipl++)
936 {
938 xa=fVertices[ipl].x();
939 ya=fVertices[ipl].y();
940 xb=fVertices[ipl+4].x();
941 yb=fVertices[ipl+4].y();
942 xc=fVertices[j].x();
943 yc=fVertices[j].y();
944 xd=fVertices[4+j].x();
945 yd=fVertices[4+j].y();
946
947 if ( ((std::fabs(xb-xd)+std::fabs(yb-yd))<halfCarTolerance)
948 || ((std::fabs(xa-xc)+std::fabs(ya-yc))<halfCarTolerance) )
949 {
950 G4double q=DistToTriangle(p,v,ipl) ;
951 if ( (q>=0) && (q<distmin) )
952 {
953 distmin=q;
954 lateral_cross=true;
956 }
957 continue;
958 }
972 G4double a = (dtx*v.
y()-dty*v.
x()+(tx1*ty2-tx2*ty1)*v.
z())*v.
z();
973 G4double b = dxs*v.
y()-dys*v.
x()+(dtx*p.
y()-dty*p.
x()+ty2*xs1-ty1*xs2
974 + tx1*ys2-tx2*ys1)*v.
z();
975 G4double c=dxs*p.
y()-dys*p.
x()+xs1*ys2-xs2*ys1;
977
979 {
981 q=-c/b;
982
983
984
985 if ((q > -halfCarTolerance) && (q < distmin))
986 {
987 if (q < halfCarTolerance)
988 {
989 if (NormalToPlane(p,ipl).
dot(v)<0.) {
continue; }
990 }
991 distmin =q;
992 lateral_cross=true;
994 }
995 continue;
996 }
998 if (d >= 0.)
999 {
1000 if (a > 0) { q=0.5*(-b-std::sqrt(d))/a; }
1001 else { q=0.5*(-b+std::sqrt(d))/a; }
1002
1003
1004
1005 if (q > -halfCarTolerance )
1006 {
1007 if (q < distmin)
1008 {
1009 if(q < halfCarTolerance)
1010 {
1011 if (NormalToPlane(p,ipl).
dot(v)<0.)
1012 {
1013 if (a > 0) { q=0.5*(-b+std::sqrt(d))/a; }
1014 else { q=0.5*(-b-std::sqrt(d))/a; }
1015 if (( q > halfCarTolerance) && (q < distmin))
1016 {
1017 distmin=q;
1018 lateral_cross = true;
1020 }
1021 continue;
1022 }
1023 }
1024 distmin = q;
1025 lateral_cross = true;
1027 }
1028 }
1029 else
1030 {
1031 if (a > 0) { q=0.5*(-b+std::sqrt(d))/a; }
1032 else { q=0.5*(-b-std::sqrt(d))/a; }
1033
1034
1035
1036 if ((q > -halfCarTolerance) && (q < distmin))
1037 {
1038 if (q < halfCarTolerance)
1039 {
1040 if (NormalToPlane(p,ipl).
dot(v)<0.)
1041 {
1042 if (a > 0) { q=0.5*(-b-std::sqrt(d))/a; }
1043 else { q=0.5*(-b+std::sqrt(d))/a; }
1044 if ( ( q > halfCarTolerance) && (q < distmin) )
1045 {
1046 distmin=q;
1047 lateral_cross = true;
1049 }
1050 continue;
1051 }
1052 }
1053 distmin =q;
1054 lateral_cross = true;
1056 }
1057 }
1058 }
1059 }
1060 if (!lateral_cross)
1061 {
1064
1065
1066
1068 if (v.z()>0.) { i=4; }
1069 std::vector<G4TwoVector> xy;
1070 for (
G4int j=0; j<4; j++) { xy.push_back(fVertices[i+j]); }
1071
1072
1073
1074 if (InsidePolygone(pt,xy)==
kOutside)
1075 {
1076 if(calcNorm)
1077 {
1080 }
1081 return 0.;
1082 }
1083 else
1084 {
1085 if(v.z()>0) {side=kPZ;}
1086 else {side=kMZ;}
1087 }
1088 }
1089
1090 if (calcNorm)
1091 {
1093 switch (side)
1094 {
1095 case kXY0:
1096 *
n=NormalToPlane(pt,0);
1097 break;
1098 case kXY1:
1099 *
n=NormalToPlane(pt,1);
1100 break;
1101 case kXY2:
1102 *
n=NormalToPlane(pt,2);
1103 break;
1104 case kXY3:
1105 *
n=NormalToPlane(pt,3);
1106 break;
1107 case kPZ:
1109 break;
1110 case kMZ:
1112 break;
1113 default:
1115 std::ostringstream message;
1116 G4int oldprc = message.precision(16);
1117 message <<
"Undefined side for valid surface normal to solid." <<
G4endl
1119 <<
" p.x() = " << p.
x()/mm <<
" mm" <<
G4endl
1120 <<
" p.y() = " << p.
y()/mm <<
" mm" <<
G4endl
1121 <<
" p.z() = " << p.
z()/mm <<
" mm" <<
G4endl
1122 <<
"Direction:" <<
G4endl
1123 <<
" v.x() = " << v.x() <<
G4endl
1124 <<
" v.y() = " << v.y() <<
G4endl
1125 <<
" v.z() = " << v.z() <<
G4endl
1126 <<
"Proposed distance :" <<
G4endl
1127 << " distmin = " << distmin/mm << " mm";
1128 message.precision(oldprc);
1129 G4Exception(
"G4GenericTrap::DistanceToOut(p,v,..)",
1131 break;
1132 }
1133 }
1134
1135 if (distmin<halfCarTolerance) { distmin=0.; }
1136
1137 return distmin;
1138}
double dot(const Hep3Vector &) const