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