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