Changeset 1228 for trunk/source/geometry/solids/CSG/src
- Timestamp:
- Jan 8, 2010, 11:56:51 AM (14 years ago)
- Location:
- trunk/source/geometry/solids/CSG/src
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/geometry/solids/CSG/src/G4Box.cc
r1058 r1228 26 26 // 27 27 // $Id: G4Box.cc,v 1.44 2006/10/19 15:33:37 gcosmo Exp $ 28 // GEANT4 tag $Name: geant4-09-0 2-ref-02$28 // GEANT4 tag $Name: geant4-09-03 $ 29 29 // 30 30 // -
trunk/source/geometry/solids/CSG/src/G4CSGSolid.cc
r1058 r1228 26 26 // 27 27 // $Id: G4CSGSolid.cc,v 1.13 2006/10/19 15:33:37 gcosmo Exp $ 28 // GEANT4 tag $Name: geant4-09-0 2-ref-02$28 // GEANT4 tag $Name: geant4-09-03 $ 29 29 // 30 30 // -------------------------------------------------------------------- -
trunk/source/geometry/solids/CSG/src/G4Cons.cc
r1058 r1228 25 25 // 26 26 // 27 // $Id: G4Cons.cc,v 1.6 0 2008/11/06 15:26:53gcosmo Exp $28 // GEANT4 tag $Name: geant4-09-0 2-ref-02$27 // $Id: G4Cons.cc,v 1.67 2009/11/12 11:53:11 gcosmo Exp $ 28 // GEANT4 tag $Name: geant4-09-03 $ 29 29 // 30 30 // … … 35 35 // History: 36 36 // 37 // 12.10.09 T.Nikitina: Added to DistanceToIn(p,v) check on the direction in 38 // case of point on surface 37 39 // 03.05.05 V.Grichine: SurfaceNormal(p) according to J. Apostolakis proposal 38 40 // 13.09.96 V.Grichine: Review and final modifications … … 79 81 G4double pDz, 80 82 G4double pSPhi, G4double pDPhi) 81 : G4CSGSolid(pName) 83 : G4CSGSolid(pName), fSPhi(0), fDPhi(0) 82 84 { 83 // Check z-len84 85 85 kRadTolerance = G4GeometryTolerance::GetInstance()->GetRadialTolerance(); 86 86 kAngTolerance = G4GeometryTolerance::GetInstance()->GetAngularTolerance(); 87 87 88 // Check z-len 89 // 88 90 if ( pDz > 0 ) 89 91 { … … 100 102 101 103 // Check radii 102 104 // 103 105 if ( (pRmin1<pRmax1) && (pRmin2<pRmax2) && (pRmin1>=0) && (pRmin2>=0) ) 104 106 { … … 121 123 } 122 124 123 fPhiFullCone = true; 124 if ( pDPhi >= twopi-kAngTolerance*0.5 ) // Check angles 125 { 126 fDPhi=twopi; 127 fSPhi=0; 128 } 129 else 130 { 131 fPhiFullCone = false; 132 if ( pDPhi > 0 ) 133 { 134 fDPhi = pDPhi; 135 } 136 else 137 { 138 G4cerr << "ERROR - G4Cons()::G4Cons(): " << GetName() << G4endl 139 << " Negative delta-Phi ! - " 140 << pDPhi << G4endl; 141 G4Exception("G4Cons::G4Cons()", "InvalidSetup", 142 FatalException, "Invalid dphi."); 143 } 144 145 // Ensure fSphi in 0-2PI or -2PI-0 range if shape crosses 0 146 147 if ( pSPhi < 0 ) 148 { 149 fSPhi = twopi - std::fmod(std::fabs(pSPhi),twopi); 150 } 151 else 152 { 153 fSPhi = std::fmod(pSPhi,twopi) ; 154 } 155 if ( fSPhi+fDPhi > twopi ) 156 { 157 fSPhi -= twopi ; 158 } 159 } 160 InitializeTrigonometry(); 125 // Check angles 126 // 127 CheckPhiAngles(pSPhi, pDPhi); 161 128 } 162 129 … … 705 672 { 706 673 G4double snxt = kInfinity ; // snxt = default return value 707 674 const G4double dRmax = 100*std::min(fRmax1,fRmax2); 708 675 static const G4double halfCarTolerance=kCarTolerance*0.5; 709 676 static const G4double halfRadTolerance=kRadTolerance*0.5; … … 717 684 G4double tolODz,tolIDz ; 718 685 719 G4double Dist,s,xi,yi,zi,ri=0.,r hoi2,cosPsi ; // Intersection point variables686 G4double Dist,s,xi,yi,zi,ri=0.,risec,rhoi2,cosPsi ; // Intersection point vars 720 687 721 688 G4double t1,t2,t3,b,c,d ; // Quadratic solver variables 722 689 G4double nt1,nt2,nt3 ; 723 690 G4double Comp ; 691 692 G4ThreeVector Normal; 724 693 725 694 // Cone Precalcs … … 887 856 if ( s > 0 ) // If 'forwards'. Check z intersection 888 857 { 858 if ( s>dRmax ) // Avoid rounding errors due to precision issues on 859 { // 64 bits systems. Split long distances and recompute 860 G4double fTerm = s-std::fmod(s,dRmax); 861 s = fTerm + DistanceToIn(p+fTerm*v,v); 862 } 889 863 zi = p.z() + s*v.z() ; 890 864 … … 917 891 { 918 892 // Inside cones, delta r -ve, inside z extent 919 893 // Point is on the Surface => check Direction using Normal.dot(v) 894 895 xi = p.x() ; 896 yi = p.y() ; 897 risec = std::sqrt(xi*xi + yi*yi)*secRMax ; 898 Normal = G4ThreeVector(xi/risec,yi/risec,-tanRMax/secRMax) ; 920 899 if ( !fPhiFullCone ) 921 900 { 922 901 cosPsi = (p.x()*cosCPhi + p.y()*sinCPhi)/std::sqrt(t3) ; 923 924 if (cosPsi >= cosHDPhiIT) { return 0.0; } 925 } 926 else { return 0.0; } 902 if ( cosPsi >= cosHDPhiIT ) 903 { 904 if ( Normal.dot(v) <= 0 ) { return 0.0; } 905 } 906 } 907 else 908 { 909 if ( Normal.dot(v) <= 0 ) { return 0.0; } 910 } 927 911 } 928 912 } … … 972 956 973 957 if (rMinAv) 974 { 958 { 975 959 nt1 = t1 - (tanRMin*v.z())*(tanRMin*v.z()) ; 976 960 nt2 = t2 - tanRMin*v.z()*rin ; … … 993 977 if ( s >= 0 ) // > 0 994 978 { 979 if ( s>dRmax ) // Avoid rounding errors due to precision issues on 980 { // 64 bits systems. Split long distance and recompute 981 G4double fTerm = s-std::fmod(s,dRmax); 982 s = fTerm + DistanceToIn(p+fTerm*v,v); 983 } 995 984 zi = p.z() + s*v.z() ; 996 985 … … 1004 993 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri ; 1005 994 1006 if (cosPsi >= cosHDPhiIT) { snxt = s; } 995 if (cosPsi >= cosHDPhiIT) 996 { 997 if ( s > halfRadTolerance ) { snxt=s; } 998 else 999 { 1000 // Calculate a normal vector in order to check Direction 1001 1002 risec = std::sqrt(xi*xi + yi*yi)*secRMin ; 1003 Normal = G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin); 1004 if ( Normal.dot(v) <= 0 ) { snxt = s; } 1005 } 1006 } 1007 1007 } 1008 else { return s; } 1008 else 1009 { 1010 if ( s > halfRadTolerance ) { return s; } 1011 else 1012 { 1013 // Calculate a normal vector in order to check Direction 1014 1015 xi = p.x() + s*v.x() ; 1016 yi = p.y() + s*v.y() ; 1017 risec = std::sqrt(xi*xi + yi*yi)*secRMin ; 1018 Normal = G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin) ; 1019 if ( Normal.dot(v) <= 0 ) { return s; } 1020 } 1021 } 1009 1022 } 1010 1023 } … … 1032 1045 if ( (s >= 0) && (std::fabs(zi) <= tolODz) ) // s > 0 1033 1046 { 1047 if ( s>dRmax ) // Avoid rounding errors due to precision issues 1048 { // seen on 64 bits systems. Split and recompute 1049 G4double fTerm = s-std::fmod(s,dRmax); 1050 s = fTerm + DistanceToIn(p+fTerm*v,v); 1051 } 1034 1052 if ( !fPhiFullCone ) 1035 1053 { … … 1038 1056 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri ; 1039 1057 1040 if (cosPsi >= cosHDPhiOT) { snxt = s; } 1058 if (cosPsi >= cosHDPhiOT) 1059 { 1060 if ( s > halfRadTolerance ) { snxt=s; } 1061 else 1062 { 1063 // Calculate a normal vector in order to check Direction 1064 1065 risec = std::sqrt(xi*xi + yi*yi)*secRMin ; 1066 Normal = G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin); 1067 if ( Normal.dot(v) <= 0 ) { snxt = s; } 1068 } 1069 } 1041 1070 } 1042 else { return s; } 1071 else 1072 { 1073 if( s > halfRadTolerance ) { return s; } 1074 else 1075 { 1076 // Calculate a normal vector in order to check Direction 1077 1078 xi = p.x() + s*v.x() ; 1079 yi = p.y() + s*v.y() ; 1080 risec = std::sqrt(xi*xi + yi*yi)*secRMin ; 1081 Normal = G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin) ; 1082 if ( Normal.dot(v) <= 0 ) { return s; } 1083 } 1084 } 1043 1085 } 1044 1086 } … … 1051 1093 if ( (s >= 0) && (ri > 0) && (std::fabs(zi) <= tolODz) ) // s>0 1052 1094 { 1095 if ( s>dRmax ) // Avoid rounding errors due to precision issues 1096 { // seen on 64 bits systems. Split and recompute 1097 G4double fTerm = s-std::fmod(s,dRmax); 1098 s = fTerm + DistanceToIn(p+fTerm*v,v); 1099 } 1053 1100 if ( !fPhiFullCone ) 1054 1101 { … … 1057 1104 cosPsi = (xi*cosCPhi + yi*sinCPhi)/ri ; 1058 1105 1059 if (cosPsi >= cosHDPhiIT) { snxt = s; } 1106 if (cosPsi >= cosHDPhiIT) 1107 { 1108 if ( s > halfRadTolerance ) { snxt=s; } 1109 else 1110 { 1111 // Calculate a normal vector in order to check Direction 1112 1113 risec = std::sqrt(xi*xi + yi*yi)*secRMin ; 1114 Normal = G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin); 1115 if ( Normal.dot(v) <= 0 ) { snxt = s; } 1116 } 1117 } 1060 1118 } 1061 else { return s; } 1119 else 1120 { 1121 if ( s > halfRadTolerance ) { return s; } 1122 else 1123 { 1124 // Calculate a normal vector in order to check Direction 1125 1126 xi = p.x() + s*v.x() ; 1127 yi = p.y() + s*v.y() ; 1128 risec = std::sqrt(xi*xi + yi*yi)*secRMin ; 1129 Normal = G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin) ; 1130 if ( Normal.dot(v) <= 0 ) { return s; } 1131 } 1132 } 1062 1133 } 1063 1134 } … … 1099 1170 zi = p.z() + s*v.z() ; 1100 1171 ri = rMinAv + zi*tanRMin ; 1101 1172 1102 1173 if ( ri > 0 ) // 2nd root 1103 1174 { … … 1107 1178 if ( (s >= 0) && (std::fabs(zi) <= tolODz) ) // s>0 1108 1179 { 1180 if ( s>dRmax ) // Avoid rounding errors due to precision issue 1181 { // seen on 64 bits systems. Split and recompute 1182 G4double fTerm = s-std::fmod(s,dRmax); 1183 s = fTerm + DistanceToIn(p+fTerm*v,v); 1184 } 1109 1185 if ( !fPhiFullCone ) 1110 1186 { … … 1136 1212 if ( (s >= 0) && (std::fabs(zi) <= tolODz) ) // s>0 1137 1213 { 1214 if ( s>dRmax ) // Avoid rounding errors due to precision issues 1215 { // seen on 64 bits systems. Split and recompute 1216 G4double fTerm = s-std::fmod(s,dRmax); 1217 s = fTerm + DistanceToIn(p+fTerm*v,v); 1218 } 1138 1219 if ( !fPhiFullCone ) 1139 1220 { … … 1335 1416 // Vars for intersection within tolerance 1336 1417 1337 ESide sidetol ;1418 ESide sidetol = kNull ; 1338 1419 G4double slentol = kInfinity ; 1339 1420 … … 1669 1750 xi = p.x() + slentol*v.x() ; 1670 1751 yi = p.y() + slentol*v.y() ; 1671 risec = std::sqrt(xi*xi + yi*yi)*secRMin ; 1672 Normal = G4ThreeVector(xi/risec,yi/risec,-tanRMin/secRMin) ; 1673 1752 if( sidetol==kRMax ) 1753 { 1754 risec = std::sqrt(xi*xi + yi*yi)*secRMax ; 1755 Normal = G4ThreeVector(xi/risec,yi/risec,-tanRMax/secRMax) ; 1756 } 1757 else 1758 { 1759 risec = std::sqrt(xi*xi + yi*yi)*secRMin ; 1760 Normal = G4ThreeVector(-xi/risec,-yi/risec,tanRMin/secRMin) ; 1761 } 1674 1762 if( Normal.dot(v) > 0 ) 1675 1763 { -
trunk/source/geometry/solids/CSG/src/G4Orb.cc
r1058 r1228 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4Orb.cc,v 1. 24 2007/05/18 07:38:01gcosmo Exp $27 // GEANT4 tag $Name: geant4-09-0 2-ref-02$26 // $Id: G4Orb.cc,v 1.30 2009/11/30 10:20:38 gcosmo Exp $ 27 // GEANT4 tag $Name: geant4-09-03 $ 28 28 // 29 29 // class G4Orb … … 298 298 rad2 = p.x()*p.x()+p.y()*p.y()+p.z()*p.z() ; 299 299 300 G4double rad = std::sqrt(rad2); 301 300 302 // G4double rad = std::sqrt(rad2); 301 303 // Check radial surface … … 304 306 tolRMax = fRmax - fRmaxTolerance*0.5 ; 305 307 306 if ( rad 2 <= tolRMax*tolRMax ) in = kInside ;308 if ( rad <= tolRMax ) { in = kInside ; } 307 309 else 308 310 { 309 311 tolRMax = fRmax + fRmaxTolerance*0.5 ; 310 if ( rad 2 <= tolRMax*tolRMax ) in = kSurface ;311 else in = kOutside ;312 if ( rad <= tolRMax ) { in = kSurface ; } 313 else { in = kOutside ; } 312 314 } 313 315 return in; … … 360 362 G4double c, d2, s = kInfinity ; 361 363 364 const G4double dRmax = 100.*fRmax; 365 362 366 // General Precalcs 363 367 … … 384 388 // => s=-pDotV3d+-std::sqrt(pDotV3d^2-(rad2-R^2)) 385 389 386 c = rad2 - fRmax*fRmax ; 390 391 G4double rad = std::sqrt(rad2); 392 c = (rad - fRmax)*(rad + fRmax); 387 393 388 394 if ( c > fRmaxTolerance*fRmax ) … … 396 402 { 397 403 s = -pDotV3d - std::sqrt(d2) ; 398 399 if (s >= 0 ) return snxt = s; 400 404 if ( s >= 0 ) 405 { 406 if ( s>dRmax ) // Avoid rounding errors due to precision issues seen on 407 { // 64 bits systems. Split long distances and recompute 408 G4double fTerm = s-std::fmod(s,dRmax); 409 s = fTerm + DistanceToIn(p+fTerm*v,v); 410 } 411 return snxt = s; 412 } 401 413 } 402 414 else // No intersection with G4Orb … … 410 422 { 411 423 d2 = pDotV3d*pDotV3d - c ; 412 // if ( pDotV3d >= 0 ) return snxt = kInfinity; 413 if ( d2 < fRmaxTolerance*fRmax || pDotV3d >= 0 ) return snxt = kInfinity; 414 else return snxt = 0.; 415 } 424 if ( (d2 < fRmaxTolerance*fRmax) || (pDotV3d >= 0) ) 425 { 426 return snxt = kInfinity; 427 } 428 else 429 { 430 return snxt = 0.; 431 } 432 } 433 #ifdef G4CSGDEBUG 416 434 else // inside ??? 417 435 { … … 419 437 JustWarning, "Point p is inside !?"); 420 438 } 439 #endif 421 440 } 422 441 return snxt; … … 431 450 G4double G4Orb::DistanceToIn( const G4ThreeVector& p ) const 432 451 { 433 G4double safe=0.0, rad = std::sqrt(p.x()*p.x()+p.y()*p.y()+p.z()*p.z()); 434 safe = rad - fRmax; 435 if( safe < 0 ) safe = 0. ; 452 G4double safe = 0.0, 453 rad = std::sqrt(p.x()*p.x()+p.y()*p.y()+p.z()*p.z()); 454 safe = rad - fRmax; 455 if( safe < 0 ) { safe = 0.; } 436 456 return safe; 437 457 } … … 475 495 476 496 const G4double Rmax_plus = fRmax + fRmaxTolerance*0.5; 477 478 if( rad2 <= Rmax_plus*Rmax_plus ) 479 { 480 c = rad2-fRmax*fRmax ; 481 482 if ( c < fRmaxTolerance*fRmax) 497 G4double rad = std::sqrt(rad2); 498 499 if ( rad <= Rmax_plus ) 500 { 501 c = (rad - fRmax)*(rad + fRmax); 502 503 if ( c < fRmaxTolerance*fRmax ) 483 504 { 484 505 // Within tolerant Outer radius -
trunk/source/geometry/solids/CSG/src/G4Para.cc
r1058 r1228 26 26 // 27 27 // $Id: G4Para.cc,v 1.39 2006/10/19 15:33:37 gcosmo Exp $ 28 // GEANT4 tag $Name: geant4-09-0 2-ref-02$28 // GEANT4 tag $Name: geant4-09-03 $ 29 29 // 30 30 // class G4Para -
trunk/source/geometry/solids/CSG/src/G4Sphere.cc
r1058 r1228 25 25 // 26 26 // 27 // $Id: G4Sphere.cc,v 1. 68 2008/07/07 09:35:16 grichineExp $28 // GEANT4 tag $Name: geant4-09-0 2-ref-02$27 // $Id: G4Sphere.cc,v 1.84 2009/08/07 15:56:23 gcosmo Exp $ 28 // GEANT4 tag $Name: geant4-09-03 $ 29 29 // 30 30 // class G4Sphere … … 34 34 // History: 35 35 // 36 // 14.09.09 T.Nikitina: fix for phi section in DistanceToOut(p,v,..),as for G4Tubs,G4Cons 37 // 26.03.09 G.Cosmo : optimisations and uniform use of local radial tolerance 36 38 // 12.06.08 V.Grichine: fix for theta intersections in DistanceToOut(p,v,...) 37 39 // 22.07.05 O.Link : Added check for intersection with double cone … … 41 43 // 02.06.04 V.Grichine: bug fixed in DistanceToIn(p,v), on Rmax,Rmin go inside 42 44 // 30.10.03 J.Apostolakis: new algorithm in Inside for SPhi-sections 43 // 29.10.03 J.Apostolakis: fix in Inside for SPhi-0.5*kAngTol < phi <SPhi, SPhi<045 // 29.10.03 J.Apostolakis: fix in Inside for SPhi-0.5*kAngTol < phi<SPhi, SPhi<0 44 46 // 19.06.02 V.Grichine: bug fixed in Inside(p), && -> && fDTheta - kAngTolerance 45 47 // 30.01.02 V.Grichine: bug fixed in Inside(p), && -> || at l.451 … … 53 55 // -------------------------------------------------------------------- 54 56 55 #include <assert.h>56 57 57 #include "G4Sphere.hh" 58 58 … … 92 92 G4double pSPhi, G4double pDPhi, 93 93 G4double pSTheta, G4double pDTheta ) 94 : G4CSGSolid(pName) 94 : G4CSGSolid(pName), fFullPhiSphere(true), fFullThetaSphere(true) 95 95 { 96 fEpsilon = 1.0e-14; 97 98 kRadTolerance = G4GeometryTolerance::GetInstance()->GetRadialTolerance(); 96 fEpsilon = 2.0e-11; // relative radial tolerance constant 97 99 98 kAngTolerance = G4GeometryTolerance::GetInstance()->GetAngularTolerance(); 100 99 101 // Check radii 102 103 if (pRmin<pRmax&&pRmin>=0) 100 // Check radii and set radial tolerances 101 102 G4double kRadTolerance = G4GeometryTolerance::GetInstance() 103 ->GetRadialTolerance(); 104 if ( (pRmin < pRmax) && (pRmax >= 10*kRadTolerance) && (pRmin >= 0) ) 104 105 { 105 106 fRmin=pRmin; fRmax=pRmax; 107 fRminTolerance = (pRmin) ? std::max( kRadTolerance, fEpsilon*fRmin ) : 0; 108 fRmaxTolerance = std::max( kRadTolerance, fEpsilon*fRmax ); 106 109 } 107 110 else … … 116 119 // Check angles 117 120 118 if (pDPhi>=twopi) 119 { 120 fDPhi=twopi; 121 } 122 else if (pDPhi>0) 123 { 124 fDPhi=pDPhi; 125 } 126 else 127 { 128 G4cerr << "ERROR - G4Sphere()::G4Sphere(): " << GetName() << G4endl 129 << " Negative Z delta-Phi ! - " 130 << pDPhi << G4endl; 131 G4Exception("G4Sphere::G4Sphere()", "InvalidSetup", FatalException, 132 "Invalid DPhi."); 133 } 134 135 // Convert fSPhi to 0-2PI 136 137 if (pSPhi<0) 138 { 139 fSPhi=twopi-std::fmod(std::fabs(pSPhi),twopi); 140 } 141 else 142 { 143 fSPhi=std::fmod(pSPhi,twopi); 144 } 145 146 // Sphere is placed such that fSPhi+fDPhi>twopi ! 147 // fSPhi could be < 0 !!? 148 // 149 if (fSPhi+fDPhi>twopi) fSPhi-=twopi; 150 151 // Check theta angles 152 153 if (pSTheta<0 || pSTheta>pi) 154 { 155 G4cerr << "ERROR - G4Sphere()::G4Sphere(): " << GetName() << G4endl; 156 G4Exception("G4Sphere::G4Sphere()", "InvalidSetup", FatalException, 157 "stheta outside 0-PI range."); 158 } 159 else 160 { 161 fSTheta=pSTheta; 162 } 163 164 if (pDTheta+pSTheta>=pi) 165 { 166 fDTheta=pi-pSTheta; 167 } 168 else if (pDTheta>0) 169 { 170 fDTheta=pDTheta; 171 } 172 else 173 { 174 G4cerr << "ERROR - G4Sphere()::G4Sphere(): " << GetName() << G4endl 175 << " Negative delta-Theta ! - " 176 << pDTheta << G4endl; 177 G4Exception("G4Sphere::G4Sphere()", "InvalidSetup", FatalException, 178 "Invalid pDTheta."); 179 } 121 CheckPhiAngles(pSPhi, pDPhi); 122 CheckThetaAngles(pSTheta, pDTheta); 180 123 } 181 124 … … 219 162 G4double& pMin, G4double& pMax ) const 220 163 { 221 if ( f DPhi==twopi && fDTheta==pi) // !pTransform.IsRotated() &&164 if ( fFullSphere ) 222 165 { 223 166 // Special case handling for solid spheres-shells … … 310 253 yoff1=yoffset-yMin; 311 254 yoff2=yMax-yoffset; 312 if ( yoff1>=0&&yoff2>=0)255 if ((yoff1>=0) && (yoff2>=0)) 313 256 { 314 257 // Y limits cross max/min x => no change … … 334 277 xoff1=xoffset-xMin; 335 278 xoff2=xMax-xoffset; 336 if ( xoff1>=0&&xoff2>=0)279 if ((xoff1>=0) && (xoff2>=0)) 337 280 { 338 281 // X limits cross max/min y => no change … … 416 359 } 417 360 418 if ( pMin!=kInfinity || pMax!=-kInfinity)361 if ((pMin!=kInfinity) || (pMax!=-kInfinity)) 419 362 { 420 363 existsAfterClip=true; … … 453 396 // Return whether point inside/outside/on surface 454 397 // Split into radius, phi, theta checks 455 // Each check modifies `in', or returns as approprate398 // Each check modifies 'in', or returns as approprate 456 399 457 400 EInside G4Sphere::Inside( const G4ThreeVector& p ) const … … 459 402 G4double rho,rho2,rad2,tolRMin,tolRMax; 460 403 G4double pPhi,pTheta; 461 EInside in=kOutside; 404 EInside in = kOutside; 405 static const G4double halfAngTolerance = kAngTolerance*0.5; 406 const G4double halfRmaxTolerance = fRmaxTolerance*0.5; 407 const G4double halfRminTolerance = fRminTolerance*0.5; 408 const G4double Rmax_minus = fRmax - halfRmaxTolerance; 409 const G4double Rmin_plus = (fRmin > 0) ? fRmin+halfRminTolerance : 0; 462 410 463 411 rho2 = p.x()*p.x() + p.y()*p.y() ; 464 412 rad2 = rho2 + p.z()*p.z() ; 465 413 466 // if(rad2 >= 1.369e+19) DBG(); 467 // G4double rad = std::sqrt(rad2); 468 // Check radial surfaces 469 // sets `in' 470 471 if ( fRmin ) tolRMin = fRmin + kRadTolerance*0.5; 472 else tolRMin = 0 ; 473 474 tolRMax = fRmax - kRadTolerance*0.5 ; 475 // const G4double fractionTolerance = 1.0e-12; 476 const G4double flexRadMaxTolerance = // kRadTolerance; 477 std::max(kRadTolerance, fEpsilon * fRmax); 478 479 const G4double Rmax_minus = fRmax - flexRadMaxTolerance*0.5; 480 const G4double flexRadMinTolerance = std::max(kRadTolerance, 481 fEpsilon * fRmin); 482 const G4double Rmin_plus = (fRmin > 0) ? fRmin + flexRadMinTolerance*0.5 : 0 ; 414 // Check radial surfaces. Sets 'in' 415 416 tolRMin = Rmin_plus; 417 tolRMax = Rmax_minus; 418 419 if ( (rad2 <= Rmax_minus*Rmax_minus) && (rad2 >= Rmin_plus*Rmin_plus) ) 420 { 421 in = kInside; 422 } 423 else 424 { 425 tolRMax = fRmax + halfRmaxTolerance; // outside case 426 tolRMin = std::max(fRmin-halfRminTolerance, 0.); // outside case 427 if ( (rad2 <= tolRMax*tolRMax) && (rad2 >= tolRMin*tolRMin) ) 428 { 429 in = kSurface; 430 } 431 else 432 { 433 return in = kOutside; 434 } 435 } 436 437 // Phi boundaries : Do not check if it has no phi boundary! 438 439 if ( !fFullPhiSphere && rho2 ) // [fDPhi < twopi] and [p.x or p.y] 440 { 441 pPhi = std::atan2(p.y(),p.x()) ; 442 443 if ( pPhi < fSPhi - halfAngTolerance ) { pPhi += twopi; } 444 else if ( pPhi > ePhi + halfAngTolerance ) { pPhi -= twopi; } 483 445 484 if(rad2 <= Rmax_minus*Rmax_minus && rad2 >= Rmin_plus*Rmin_plus) in = kInside ; 485 486 // if ( rad2 <= tolRMax*tolRMax && rad2 >= tolRMin*tolRMin ) in = kInside ; 487 // if ( rad <= tolRMax && rad >= tolRMin ) in = kInside ; 488 else 489 { 490 tolRMax = fRmax + kRadTolerance*0.5 ; 491 tolRMin = fRmin - kRadTolerance*0.5 ; 492 493 if ( tolRMin < 0.0 ) tolRMin = 0.0 ; 494 495 if ( rad2 <= tolRMax*tolRMax && rad2 >= tolRMin*tolRMin ) in = kSurface ; 496 // if ( rad <= tolRMax && rad >= tolRMin ) in = kSurface ; 497 else return in = kOutside ; 498 } 499 500 // Phi boundaries : Do not check if it has no phi boundary! 501 // (in != kOutside). It is new J.Apostolakis proposal of 30.10.03 502 503 if ( ( fDPhi < twopi - kAngTolerance ) && 504 ( (p.x() != 0.0 ) || (p.y() != 0.0) ) ) 505 { 506 pPhi = std::atan2(p.y(),p.x()) ; 507 508 if ( pPhi < fSPhi - kAngTolerance*0.5 ) pPhi += twopi ; 509 else if ( pPhi > fSPhi + fDPhi + kAngTolerance*0.5 ) pPhi -= twopi; 510 511 if ((pPhi < fSPhi - kAngTolerance*0.5) || 512 (pPhi > fSPhi + fDPhi + kAngTolerance*0.5) ) return in = kOutside ; 446 if ( (pPhi < fSPhi - halfAngTolerance) 447 || (pPhi > ePhi + halfAngTolerance) ) { return in = kOutside; } 513 448 514 449 else if (in == kInside) // else it's kSurface anyway already 515 450 { 516 if ( (pPhi < fSPhi + kAngTolerance*0.5) ||517 (pPhi > fSPhi + fDPhi - kAngTolerance*0.5) ) in = kSurface ;451 if ( (pPhi < fSPhi + halfAngTolerance) 452 || (pPhi > ePhi - halfAngTolerance) ) { in = kSurface; } 518 453 } 519 454 } 520 455 521 456 // Theta bondaries 522 // (in!=kOutside)523 457 524 if ( (rho2 || p.z()) && fDTheta < pi - kAngTolerance*0.5)458 if ( (rho2 || p.z()) && (!fFullThetaSphere) ) 525 459 { 526 460 rho = std::sqrt(rho2); … … 529 463 if ( in == kInside ) 530 464 { 531 if ( (pTheta < fSTheta + kAngTolerance*0.5)532 || (pTheta > fSTheta + fDTheta - kAngTolerance*0.5) )533 { 534 if ( (pTheta >= fSTheta - kAngTolerance*0.5)535 && (pTheta <= fSTheta + fDTheta + kAngTolerance*0.5) )536 { 537 in = kSurface 465 if ( (pTheta < fSTheta + halfAngTolerance) 466 || (pTheta > eTheta - halfAngTolerance) ) 467 { 468 if ( (pTheta >= fSTheta - halfAngTolerance) 469 && (pTheta <= eTheta + halfAngTolerance) ) 470 { 471 in = kSurface; 538 472 } 539 473 else 540 474 { 541 in = kOutside 475 in = kOutside; 542 476 } 543 477 } … … 545 479 else 546 480 { 547 if ( (pTheta < fSTheta - kAngTolerance*0.5)548 || (pTheta > fSTheta + fDTheta + kAngTolerance*0.5) )549 { 550 in = kOutside 481 if ( (pTheta < fSTheta - halfAngTolerance) 482 || (pTheta > eTheta + halfAngTolerance) ) 483 { 484 in = kOutside; 551 485 } 552 486 } … … 568 502 G4double distSPhi = kInfinity, distEPhi = kInfinity; 569 503 G4double distSTheta = kInfinity, distETheta = kInfinity; 570 G4double delta = 0.5*kCarTolerance, dAngle = 0.5*kAngTolerance;571 504 G4ThreeVector nR, nPs, nPe, nTs, nTe, nZ(0.,0.,1.); 572 505 G4ThreeVector norm, sumnorm(0.,0.,0.); 506 507 static const G4double halfCarTolerance = 0.5*kCarTolerance; 508 static const G4double halfAngTolerance = 0.5*kAngTolerance; 573 509 574 510 rho2 = p.x()*p.x()+p.y()*p.y(); … … 579 515 if (fRmin) distRMin = std::fabs(rad-fRmin); 580 516 581 if ( rho && (fDPhi < twopi || fDTheta < pi))517 if ( rho && !fFullSphere ) 582 518 { 583 519 pPhi = std::atan2(p.y(),p.x()); 584 520 585 if (pPhi < fSPhi-dAngle) pPhi += twopi;586 else if (pPhi > fSPhi+fDPhi+dAngle) pPhi -= twopi;587 } 588 if ( fDPhi < twopi ) // && rho ) // old limitation against (0,0,z)521 if (pPhi < fSPhi-halfAngTolerance) { pPhi += twopi; } 522 else if (pPhi > ePhi+halfAngTolerance) { pPhi -= twopi; } 523 } 524 if ( !fFullPhiSphere ) 589 525 { 590 526 if ( rho ) 591 527 { 592 distSPhi = std::fabs( pPhi -fSPhi );593 distEPhi = std::fabs( pPhi-fSPhi-fDPhi);528 distSPhi = std::fabs( pPhi-fSPhi ); 529 distEPhi = std::fabs( pPhi-ePhi ); 594 530 } 595 531 else if( !fRmin ) … … 598 534 distEPhi = 0.; 599 535 } 600 nPs = G4ThreeVector(s td::sin(fSPhi),-std::cos(fSPhi),0);601 nPe = G4ThreeVector(-s td::sin(fSPhi+fDPhi),std::cos(fSPhi+fDPhi),0);536 nPs = G4ThreeVector(sinSPhi,-cosSPhi,0); 537 nPe = G4ThreeVector(-sinEPhi,cosEPhi,0); 602 538 } 603 if ( fDTheta < pi ) // && rad ) // old limitation against (0,0,0)539 if ( !fFullThetaSphere ) 604 540 { 605 541 if ( rho ) … … 607 543 pTheta = std::atan2(rho,p.z()); 608 544 distSTheta = std::fabs(pTheta-fSTheta); 609 distETheta = std::fabs(pTheta- fSTheta-fDTheta);545 distETheta = std::fabs(pTheta-eTheta); 610 546 611 nTs = G4ThreeVector(- std::cos(fSTheta)*p.x()/rho, // *std::cos(pPhi),612 - std::cos(fSTheta)*p.y()/rho, // *std::sin(pPhi),613 s td::sin(fSTheta));614 615 nTe = G4ThreeVector( std::cos(fSTheta+fDTheta)*p.x()/rho, // *std::cos(pPhi),616 std::cos(fSTheta+fDTheta)*p.y()/rho, // *std::sin(pPhi),617 -s td::sin(fSTheta+fDTheta));547 nTs = G4ThreeVector(-cosSTheta*p.x()/rho, 548 -cosSTheta*p.y()/rho, 549 sinSTheta ); 550 551 nTe = G4ThreeVector( cosETheta*p.x()/rho, 552 cosETheta*p.y()/rho, 553 -sinETheta ); 618 554 } 619 555 else if( !fRmin ) … … 622 558 { 623 559 distSTheta = 0.; 624 625 } 626 if ( fSTheta + fDTheta < pi ) // distETheta = 0.;560 nTs = G4ThreeVector(0.,0.,-1.); 561 } 562 if ( eTheta < pi ) 627 563 { 628 564 distETheta = 0.; 629 565 nTe = G4ThreeVector(0.,0.,1.); 630 566 } 631 567 } 632 568 } 633 if( rad ) nR = G4ThreeVector(p.x()/rad,p.y()/rad,p.z()/rad);634 635 if( distRMax <= delta)569 if( rad ) { nR = G4ThreeVector(p.x()/rad,p.y()/rad,p.z()/rad); } 570 571 if( distRMax <= halfCarTolerance ) 636 572 { 637 573 noSurfaces ++; 638 574 sumnorm += nR; 639 575 } 640 if( fRmin && distRMin <= delta)576 if( fRmin && (distRMin <= halfCarTolerance) ) 641 577 { 642 578 noSurfaces ++; 643 579 sumnorm -= nR; 644 580 } 645 if( fDPhi < twopi)646 { 647 if (distSPhi <= dAngle)581 if( !fFullPhiSphere ) 582 { 583 if (distSPhi <= halfAngTolerance) 648 584 { 649 585 noSurfaces ++; 650 586 sumnorm += nPs; 651 587 } 652 if (distEPhi <= dAngle)588 if (distEPhi <= halfAngTolerance) 653 589 { 654 590 noSurfaces ++; … … 656 592 } 657 593 } 658 if ( fDTheta < pi)659 { 660 if ( distSTheta <= dAngle && fSTheta > 0.)594 if ( !fFullThetaSphere ) 595 { 596 if ((distSTheta <= halfAngTolerance) && (fSTheta > 0.)) 661 597 { 662 598 noSurfaces ++; 663 if ( rad <= delta && fDPhi >= twopi) sumnorm += nZ;664 else sumnorm += nTs;665 } 666 if ( distETheta <= dAngle && fSTheta+fDTheta < pi)599 if ((rad <= halfCarTolerance) && fFullPhiSphere) { sumnorm += nZ; } 600 else { sumnorm += nTs; } 601 } 602 if ((distETheta <= halfAngTolerance) && (eTheta < pi)) 667 603 { 668 604 noSurfaces ++; 669 if ( rad <= delta && fDPhi >= twopi) sumnorm -= nZ;670 else sumnorm += nTe;671 if(sumnorm.z() == 0.) sumnorm += nZ;605 if ((rad <= halfCarTolerance) && fFullPhiSphere) { sumnorm -= nZ; } 606 else { sumnorm += nTe; } 607 if(sumnorm.z() == 0.) { sumnorm += nZ; } 672 608 } 673 609 } … … 680 616 norm = ApproxSurfaceNormal(p); 681 617 } 682 else if ( noSurfaces == 1 ) norm = sumnorm;683 else norm = sumnorm.unit();618 else if ( noSurfaces == 1 ) { norm = sumnorm; } 619 else { norm = sumnorm.unit(); } 684 620 return norm; 685 621 } … … 735 671 736 672 pPhi = std::atan2(p.y(),p.x()); 737 if (pPhi<0) pPhi += twopi;738 739 if ( fDPhi<twopi&&rho)673 if (pPhi<0) { pPhi += twopi; } 674 675 if (!fFullPhiSphere && rho) 740 676 { 741 677 if (fSPhi<0) … … 774 710 // 775 711 776 if ( fDTheta<pi&&rad)712 if (!fFullThetaSphere && rad) 777 713 { 778 714 pTheta=std::atan2(rho,p.z()); … … 809 745 break; 810 746 case kNSPhi: 811 norm=G4ThreeVector(s td::sin(fSPhi),-std::cos(fSPhi),0);747 norm=G4ThreeVector(sinSPhi,-cosSPhi,0); 812 748 break; 813 749 case kNEPhi: 814 norm=G4ThreeVector(-s td::sin(fSPhi+fDPhi),std::cos(fSPhi+fDPhi),0);750 norm=G4ThreeVector(-sinEPhi,cosEPhi,0); 815 751 break; 816 752 case kNSTheta: 817 norm=G4ThreeVector(-std::cos(fSTheta)*std::cos(pPhi), 818 -std::cos(fSTheta)*std::sin(pPhi), 819 std::sin(fSTheta) ); 820 // G4cout<<G4endl<<" case kNSTheta:"<<G4endl; 821 // G4cout<<"pPhi = "<<pPhi<<G4endl; 822 // G4cout<<"rad = "<<rad<<G4endl; 823 // G4cout<<"pho = "<<rho<<G4endl; 824 // G4cout<<"p: "<<p.x()<<"; "<<p.y()<<"; "<<p.z()<<G4endl; 825 // G4cout<<"norm: "<<norm.x()<<"; "<<norm.y()<<"; "<<norm.z()<<G4endl; 753 norm=G4ThreeVector(-cosSTheta*std::cos(pPhi), 754 -cosSTheta*std::sin(pPhi), 755 sinSTheta ); 826 756 break; 827 757 case kNETheta: 828 norm=G4ThreeVector( std::cos(fSTheta+fDTheta)*std::cos(pPhi), 829 std::cos(fSTheta+fDTheta)*std::sin(pPhi), 830 -std::sin(fSTheta+fDTheta) ); 831 832 // G4cout<<G4endl<<" case kNETheta:"<<G4endl; 833 // G4cout<<"pPhi = "<<pPhi<<G4endl; 834 // G4cout<<"rad = "<<rad<<G4endl; 835 // G4cout<<"pho = "<<rho<<G4endl; 836 // G4cout<<"p: "<<p.x()<<"; "<<p.y()<<"; "<<p.z()<<G4endl; 837 // G4cout<<"norm: "<<norm.x()<<"; "<<norm.y()<<"; "<<norm.z()<<G4endl; 758 norm=G4ThreeVector( cosETheta*std::cos(pPhi), 759 cosETheta*std::sin(pPhi), 760 -sinETheta ); 838 761 break; 839 762 default: 840 763 DumpInfo(); 841 G4Exception("G4Sphere::ApproxSurfaceNormal()", "Notification",JustWarning,764 G4Exception("G4Sphere::ApproxSurfaceNormal()","Notification",JustWarning, 842 765 "Undefined side for valid surface normal to solid."); 843 766 break; 844 } // end case767 } 845 768 846 769 return norm; … … 880 803 { 881 804 G4double snxt = kInfinity ; // snxt = default return value 882 883 805 G4double rho2, rad2, pDotV2d, pDotV3d, pTheta ; 884 885 G4double tolIRMin2, tolORMin2, tolORMax2, tolIRMax2 ;886 806 G4double tolSTheta=0., tolETheta=0. ; 807 const G4double dRmax = 100.*fRmax; 808 809 static const G4double halfCarTolerance = kCarTolerance*0.5; 810 static const G4double halfAngTolerance = kAngTolerance*0.5; 811 const G4double halfRmaxTolerance = fRmaxTolerance*0.5; 812 const G4double halfRminTolerance = fRminTolerance*0.5; 813 const G4double tolORMin2 = (fRmin>halfRminTolerance) 814 ? (fRmin-halfRminTolerance)*(fRmin-halfRminTolerance) : 0; 815 const G4double tolIRMin2 = 816 (fRmin+halfRminTolerance)*(fRmin+halfRminTolerance); 817 const G4double tolORMax2 = 818 (fRmax+halfRmaxTolerance)*(fRmax+halfRmaxTolerance); 819 const G4double tolIRMax2 = 820 (fRmax-halfRmaxTolerance)*(fRmax-halfRmaxTolerance); 887 821 888 822 // Intersection point 889 823 // 890 824 G4double xi, yi, zi, rhoi, rhoi2, radi2, iTheta ; 891 825 892 826 // Phi intersection 893 894 G4double sinSPhi, cosSPhi, ePhi, sinEPhi, cosEPhi , Comp ; 895 896 // Phi flag and precalcs 897 898 G4bool segPhi ; 899 G4double hDPhi, hDPhiOT, hDPhiIT, cPhi, sinCPhi=0., cosCPhi=0. ; 900 G4double cosHDPhiOT=0., cosHDPhiIT=0. ; 827 // 828 G4double Comp ; 829 830 // Phi precalcs 831 // 901 832 G4double Dist, cosPsi ; 902 833 903 G4bool segTheta ; // Theta flag and precals 904 G4double tanSTheta, tanETheta ; 905 G4double tanSTheta2, tanETheta2 ; 834 // Theta precalcs 835 // 906 836 G4double dist2STheta, dist2ETheta ; 907 837 G4double t1, t2, b, c, d2, d, s = kInfinity ; 908 838 909 839 // General Precalcs 910 840 // 911 841 rho2 = p.x()*p.x() + p.y()*p.y() ; 912 842 rad2 = rho2 + p.z()*p.z() ; … … 916 846 pDotV3d = pDotV2d + p.z()*v.z() ; 917 847 918 // Radial Precalcs919 920 if (fRmin > kRadTolerance*0.5)921 {922 tolORMin2=(fRmin-kRadTolerance*0.5)*(fRmin-kRadTolerance*0.5);923 }924 else925 {926 tolORMin2 = 0 ;927 }928 tolIRMin2 = (fRmin+kRadTolerance*0.5)*(fRmin+kRadTolerance*0.5) ;929 tolORMax2 = (fRmax+kRadTolerance*0.5)*(fRmax+kRadTolerance*0.5) ;930 tolIRMax2 = (fRmax-kRadTolerance*0.5)*(fRmax-kRadTolerance*0.5) ;931 932 // Set phi divided flag and precalcs933 934 if (fDPhi < twopi)935 {936 segPhi = true ;937 hDPhi = 0.5*fDPhi ; // half delta phi938 cPhi = fSPhi + hDPhi ;939 940 hDPhiOT = hDPhi+0.5*kAngTolerance; // Outer Tolerant half delta phi941 hDPhiIT = hDPhi-0.5*kAngTolerance;942 943 sinCPhi = std::sin(cPhi) ;944 cosCPhi = std::cos(cPhi) ;945 cosHDPhiOT = std::cos(hDPhiOT) ;946 cosHDPhiIT = std::cos(hDPhiIT) ;947 }948 else949 {950 segPhi = false ;951 }952 953 848 // Theta precalcs 954 955 if (fDTheta < pi ) 956 { 957 segTheta = true ; 958 tolSTheta = fSTheta - kAngTolerance*0.5 ; 959 tolETheta = fSTheta + fDTheta + kAngTolerance*0.5 ; 960 } 961 else 962 { 963 segTheta = false ; 849 // 850 if (!fFullThetaSphere) 851 { 852 tolSTheta = fSTheta - halfAngTolerance ; 853 tolETheta = eTheta + halfAngTolerance ; 964 854 } 965 855 … … 979 869 980 870 c = rad2 - fRmax*fRmax ; 981 const G4double flexRadMaxTolerance = // kRadTolerance; 982 std::max(kRadTolerance, fEpsilon * fRmax); 983 984 // if (c > kRadTolerance*fRmax) 985 if (c > flexRadMaxTolerance*fRmax) 986 { 987 // If outside toleranct boundary of outer G4Sphere 988 // [should be std::sqrt(rad2)-fRmax > kRadTolerance*0.5] 871 872 if (c > fRmaxTolerance*fRmax) 873 { 874 // If outside tolerant boundary of outer G4Sphere 875 // [should be std::sqrt(rad2)-fRmax > halfRmaxTolerance] 989 876 990 877 d2 = pDotV3d*pDotV3d - c ; … … 996 883 if (s >= 0 ) 997 884 { 885 if ( s>dRmax ) // Avoid rounding errors due to precision issues seen on 886 { // 64 bits systems. Split long distances and recompute 887 G4double fTerm = s-std::fmod(s,dRmax); 888 s = fTerm + DistanceToIn(p+fTerm*v,v); 889 } 998 890 xi = p.x() + s*v.x() ; 999 891 yi = p.y() + s*v.y() ; 1000 892 rhoi = std::sqrt(xi*xi + yi*yi) ; 1001 893 1002 if ( segPhi&& rhoi) // Check phi intersection894 if (!fFullPhiSphere && rhoi) // Check phi intersection 1003 895 { 1004 896 cosPsi = (xi*cosCPhi + yi*sinCPhi)/rhoi ; … … 1006 898 if (cosPsi >= cosHDPhiOT) 1007 899 { 1008 if ( segTheta) // Check theta intersection900 if (!fFullThetaSphere) // Check theta intersection 1009 901 { 1010 902 zi = p.z() + s*v.z() ; … … 1027 919 else 1028 920 { 1029 if ( segTheta) // Check theta intersection921 if (!fFullThetaSphere) // Check theta intersection 1030 922 { 1031 923 zi = p.z() + s*v.z() ; … … 1059 951 d2 = pDotV3d*pDotV3d - c ; 1060 952 1061 // if (rad2 > tolIRMin2 && pDotV3d < 0 ) 1062 1063 if (rad2 > tolIRMax2 && ( d2 >= flexRadMaxTolerance*fRmax && pDotV3d < 0 ) ) 1064 { 1065 if (segPhi) 953 if ( (rad2 > tolIRMax2) 954 && ( (d2 >= fRmaxTolerance*fRmax) && (pDotV3d < 0) ) ) 955 { 956 if (!fFullPhiSphere) 1066 957 { 1067 958 // Use inner phi tolerant boundary -> if on tolerant … … 1074 965 // inside radii, delta r -ve, inside phi 1075 966 1076 if ( segTheta)967 if ( !fFullThetaSphere ) 1077 968 { 1078 969 if ( (pTheta >= tolSTheta + kAngTolerance) … … 1090 981 else 1091 982 { 1092 if ( segTheta)983 if ( !fFullThetaSphere ) 1093 984 { 1094 985 if ( (pTheta >= tolSTheta + kAngTolerance) … … 1109 1000 // - Always farthest root, because would have passed through outer 1110 1001 // surface first. 1111 // - Tolerant check forif travelling through solid1002 // - Tolerant check if travelling through solid 1112 1003 1113 1004 if (fRmin) … … 1119 1010 // Check for immediate entry/already inside and travelling outwards 1120 1011 1121 // if (c >- kRadTolerance*0.5 && pDotV3d >= 0 && rad2 < tolIRMin2 ) 1122 1123 if ( c > -kRadTolerance*0.5 && rad2 < tolIRMin2 && 1124 ( d2 < fRmin*kCarTolerance || pDotV3d >= 0 ) ) 1125 { 1126 if (segPhi) 1012 if ( (c > -halfRminTolerance) && (rad2 < tolIRMin2) 1013 && ( (d2 < fRmin*kCarTolerance) || (pDotV3d >= 0) ) ) 1014 { 1015 if ( !fFullPhiSphere ) 1127 1016 { 1128 1017 // Use inner phi tolerant boundary -> if on tolerant … … 1134 1023 // inside radii, delta r -ve, inside phi 1135 1024 // 1136 if ( segTheta)1025 if ( !fFullThetaSphere ) 1137 1026 { 1138 1027 if ( (pTheta >= tolSTheta + kAngTolerance) … … 1150 1039 else 1151 1040 { 1152 if ( segTheta)1041 if ( !fFullThetaSphere ) 1153 1042 { 1154 1043 if ( (pTheta >= tolSTheta + kAngTolerance) … … 1166 1055 else // Not special tolerant case 1167 1056 { 1168 // d2 = pDotV3d*pDotV3d - c ;1169 1170 1057 if (d2 >= 0) 1171 1058 { 1172 1059 s = -pDotV3d + std::sqrt(d2) ; 1173 if ( s >= kRadTolerance*0.5) // It was >= 0 ??1060 if ( s >= halfRminTolerance ) // It was >= 0 ?? 1174 1061 { 1175 1062 xi = p.x() + s*v.x() ; … … 1177 1064 rhoi = std::sqrt(xi*xi+yi*yi) ; 1178 1065 1179 if ( segPhi&& rhoi ) // Check phi intersection1066 if ( !fFullPhiSphere && rhoi ) // Check phi intersection 1180 1067 { 1181 1068 cosPsi = (xi*cosCPhi + yi*sinCPhi)/rhoi ; … … 1183 1070 if (cosPsi >= cosHDPhiOT) 1184 1071 { 1185 if ( segTheta) // Check theta intersection1072 if ( !fFullThetaSphere ) // Check theta intersection 1186 1073 { 1187 1074 zi = p.z() + s*v.z() ; … … 1204 1091 else 1205 1092 { 1206 if ( segTheta) // Check theta intersection1093 if ( !fFullThetaSphere ) // Check theta intersection 1207 1094 { 1208 1095 zi = p.z() + s*v.z() ; … … 1214 1101 if ( (iTheta >= tolSTheta) && (iTheta <= tolETheta) ) 1215 1102 { 1216 snxt = s 1103 snxt = s; 1217 1104 } 1218 1105 } 1219 1106 else 1220 1107 { 1221 snxt =s;1108 snxt = s; 1222 1109 } 1223 1110 } … … 1236 1123 // -> Should use some form of loop Construct 1237 1124 // 1238 if ( segPhi ) 1239 { 1240 // First phi surface (`S'tarting phi) 1241 1242 sinSPhi = std::sin(fSPhi) ; 1243 cosSPhi = std::cos(fSPhi) ; 1244 1125 if ( !fFullPhiSphere ) 1126 { 1127 // First phi surface ('S'tarting phi) 1245 1128 // Comp = Component in outwards normal dirn 1246 1129 // 1247 Comp = v.x()*sinSPhi - v.y()*cosSPhi;1130 Comp = v.x()*sinSPhi - v.y()*cosSPhi ; 1248 1131 1249 1132 if ( Comp < 0 ) … … 1251 1134 Dist = p.y()*cosSPhi - p.x()*sinSPhi ; 1252 1135 1253 if (Dist < kCarTolerance*0.5)1136 if (Dist < halfCarTolerance) 1254 1137 { 1255 1138 s = Dist/Comp ; … … 1282 1165 // (=>intersect at origin =>fRmax=0) 1283 1166 // 1284 if ( segTheta)1167 if ( !fFullThetaSphere ) 1285 1168 { 1286 1169 iTheta = std::atan2(std::sqrt(rhoi2),zi) ; … … 1305 1188 } 1306 1189 1307 // Second phi surface (`E'nding phi) 1308 1309 ePhi = fSPhi + fDPhi ; 1310 sinEPhi = std::sin(ePhi) ; 1311 cosEPhi = std::cos(ePhi) ; 1312 1313 // Compnent in outwards normal dirn 1314 1315 Comp = -( v.x()*sinEPhi-v.y()*cosEPhi ) ; 1190 // Second phi surface ('E'nding phi) 1191 // Component in outwards normal dirn 1192 1193 Comp = -( v.x()*sinEPhi-v.y()*cosEPhi ) ; 1316 1194 1317 1195 if (Comp < 0) 1318 1196 { 1319 1197 Dist = -(p.y()*cosEPhi-p.x()*sinEPhi) ; 1320 if ( Dist < kCarTolerance*0.5)1198 if ( Dist < halfCarTolerance ) 1321 1199 { 1322 1200 s = Dist/Comp ; … … 1340 1218 rhoi2 = rho2 ; 1341 1219 radi2 = rad2 ; 1342 } if ( (radi2 <= tolORMax2) 1220 } 1221 if ( (radi2 <= tolORMax2) 1343 1222 && (radi2 >= tolORMin2) 1344 1223 && ((yi*cosCPhi-xi*sinCPhi) >= 0) ) … … 1348 1227 // (=>intersect at origin =>fRmax=0) 1349 1228 // 1350 if ( segTheta)1229 if ( !fFullThetaSphere ) 1351 1230 { 1352 1231 iTheta = std::atan2(std::sqrt(rhoi2),zi) ; … … 1374 1253 // Theta segment intersection 1375 1254 1376 if ( segTheta)1255 if ( !fFullThetaSphere ) 1377 1256 { 1378 1257 … … 1396 1275 // => s^2(1-vz^2(1+tan^2(t))+2s(pdotv2d-pzvztan^2(t))+(rho2-pz^2tan^2(t))=0 1397 1276 1398 tanSTheta = std::tan(fSTheta) ;1399 tanSTheta2 = tanSTheta*tanSTheta ;1400 tanETheta = std::tan(fSTheta+fDTheta) ;1401 tanETheta2 = tanETheta*tanETheta ;1402 1403 1277 if (fSTheta) 1404 1278 { … … 1409 1283 dist2STheta = kInfinity ; 1410 1284 } 1411 if ( fSTheta + fDTheta < pi )1285 if ( eTheta < pi ) 1412 1286 { 1413 1287 dist2ETheta=rho2-p.z()*p.z()*tanETheta2; 1414 1288 } 1415 1289 else 1416 1290 { 1417 1291 dist2ETheta=kInfinity; 1418 1292 } 1419 if ( pTheta < tolSTheta ) // dist2STheta<-kRadTolerance*0.5 && dist2ETheta>0)1293 if ( pTheta < tolSTheta ) 1420 1294 { 1421 1295 // Inside (theta<stheta-tol) s theta cone … … 1424 1298 t1 = 1 - v.z()*v.z()*(1 + tanSTheta2) ; 1425 1299 t2 = pDotV2d - p.z()*v.z()*tanSTheta2 ; 1426 1427 b = t2/t1 ; 1428 c = dist2STheta/t1 ; 1429 d2 = b*b - c ; 1430 1431 if ( d2 >= 0 ) 1432 { 1433 d = std::sqrt(d2) ; 1434 s = -b - d ; // First root 1435 zi = p.z() + s*v.z(); 1436 1437 if ( s < 0 || zi*(fSTheta - halfpi) > 0 ) 1438 { 1439 s = -b+d; // Second root 1440 } 1441 if (s >= 0 && s < snxt) 1442 { 1443 xi = p.x() + s*v.x(); 1444 yi = p.y() + s*v.y(); 1300 if (t1) 1301 { 1302 b = t2/t1 ; 1303 c = dist2STheta/t1 ; 1304 d2 = b*b - c ; 1305 1306 if ( d2 >= 0 ) 1307 { 1308 d = std::sqrt(d2) ; 1309 s = -b - d ; // First root 1445 1310 zi = p.z() + s*v.z(); 1446 rhoi2 = xi*xi + yi*yi; 1447 radi2 = rhoi2 + zi*zi; 1448 if ( (radi2 <= tolORMax2) 1449 && (radi2 >= tolORMin2) 1450 && (zi*(fSTheta - halfpi) <= 0) ) 1451 { 1452 if ( segPhi && rhoi2 ) // Check phi intersection 1453 { 1454 cosPsi = (xi*cosCPhi + yi*sinCPhi)/std::sqrt(rhoi2) ; 1455 if (cosPsi >= cosHDPhiOT) 1311 1312 if ( (s < 0) || (zi*(fSTheta - halfpi) > 0) ) 1313 { 1314 s = -b+d; // Second root 1315 } 1316 if ((s >= 0) && (s < snxt)) 1317 { 1318 xi = p.x() + s*v.x(); 1319 yi = p.y() + s*v.y(); 1320 zi = p.z() + s*v.z(); 1321 rhoi2 = xi*xi + yi*yi; 1322 radi2 = rhoi2 + zi*zi; 1323 if ( (radi2 <= tolORMax2) 1324 && (radi2 >= tolORMin2) 1325 && (zi*(fSTheta - halfpi) <= 0) ) 1326 { 1327 if ( !fFullPhiSphere && rhoi2 ) // Check phi intersection 1328 { 1329 cosPsi = (xi*cosCPhi + yi*sinCPhi)/std::sqrt(rhoi2) ; 1330 if (cosPsi >= cosHDPhiOT) 1331 { 1332 snxt = s ; 1333 } 1334 } 1335 else 1456 1336 { 1457 1337 snxt = s ; 1458 1338 } 1459 }1460 else1461 {1462 snxt = s ;1463 1339 } 1464 1340 } … … 1469 1345 // Second >= 0 root should be considered 1470 1346 1471 if ( fSTheta + fDTheta < pi )1347 if ( eTheta < pi ) 1472 1348 { 1473 1349 t1 = 1 - v.z()*v.z()*(1 + tanETheta2) ; 1474 1350 t2 = pDotV2d - p.z()*v.z()*tanETheta2 ; 1475 1351 if (t1) 1352 { 1353 b = t2/t1 ; 1354 c = dist2ETheta/t1 ; 1355 d2 = b*b - c ; 1356 1357 if (d2 >= 0) 1358 { 1359 d = std::sqrt(d2) ; 1360 s = -b + d ; // Second root 1361 1362 if ( (s >= 0) && (s < snxt) ) 1363 { 1364 xi = p.x() + s*v.x() ; 1365 yi = p.y() + s*v.y() ; 1366 zi = p.z() + s*v.z() ; 1367 rhoi2 = xi*xi + yi*yi ; 1368 radi2 = rhoi2 + zi*zi ; 1369 1370 if ( (radi2 <= tolORMax2) 1371 && (radi2 >= tolORMin2) 1372 && (zi*(eTheta - halfpi) <= 0) ) 1373 { 1374 if (!fFullPhiSphere && rhoi2) // Check phi intersection 1375 { 1376 cosPsi = (xi*cosCPhi + yi*sinCPhi)/std::sqrt(rhoi2) ; 1377 if (cosPsi >= cosHDPhiOT) 1378 { 1379 snxt = s ; 1380 } 1381 } 1382 else 1383 { 1384 snxt = s ; 1385 } 1386 } 1387 } 1388 } 1389 } 1390 } 1391 } 1392 else if ( pTheta > tolETheta ) 1393 { 1394 // dist2ETheta<-kRadTolerance*0.5 && dist2STheta>0) 1395 // Inside (theta > etheta+tol) e-theta cone 1396 // First root of etheta cone, second if first root 'imaginary' 1397 1398 t1 = 1 - v.z()*v.z()*(1 + tanETheta2) ; 1399 t2 = pDotV2d - p.z()*v.z()*tanETheta2 ; 1400 if (t1) 1401 { 1476 1402 b = t2/t1 ; 1477 1403 c = dist2ETheta/t1 ; … … 1481 1407 { 1482 1408 d = std::sqrt(d2) ; 1483 s = -b + d ; // Second root 1484 1485 if (s >= 0 && s < snxt) 1409 s = -b - d ; // First root 1410 zi = p.z() + s*v.z(); 1411 1412 if ( (s < 0) || (zi*(eTheta - halfpi) > 0) ) 1413 { 1414 s = -b + d ; // second root 1415 } 1416 if ( (s >= 0) && (s < snxt) ) 1486 1417 { 1487 1418 xi = p.x() + s*v.x() ; … … 1492 1423 1493 1424 if ( (radi2 <= tolORMax2) 1494 && (radi2 >= tolORMin2) 1495 && (zi*( fSTheta + fDTheta - halfpi) <= 0) )1496 { 1497 if ( segPhi && rhoi2)// Check phi intersection1425 && (radi2 >= tolORMin2) 1426 && (zi*(eTheta - halfpi) <= 0) ) 1427 { 1428 if (!fFullPhiSphere && rhoi2) // Check phi intersection 1498 1429 { 1499 1430 cosPsi = (xi*cosCPhi + yi*sinCPhi)/std::sqrt(rhoi2) ; … … 1511 1442 } 1512 1443 } 1513 }1514 else if ( pTheta > tolETheta )1515 {1516 // dist2ETheta<-kRadTolerance*0.5 && dist2STheta>0)1517 // Inside (theta > etheta+tol) e-theta cone1518 // First root of etheta cone, second if first root `imaginary'1519 1520 t1 = 1 - v.z()*v.z()*(1 + tanETheta2) ;1521 t2 = pDotV2d - p.z()*v.z()*tanETheta2 ;1522 1523 b = t2/t1 ;1524 c = dist2ETheta/t1 ;1525 d2 = b*b - c ;1526 1527 if (d2 >= 0)1528 {1529 d = std::sqrt(d2) ;1530 s = -b - d ; // First root1531 zi = p.z() + s*v.z();1532 1533 if (s < 0 || zi*(fSTheta + fDTheta - halfpi) > 0)1534 {1535 s = -b + d ; // second root1536 }1537 if (s >= 0 && s < snxt)1538 {1539 xi = p.x() + s*v.x() ;1540 yi = p.y() + s*v.y() ;1541 zi = p.z() + s*v.z() ;1542 rhoi2 = xi*xi + yi*yi ;1543 radi2 = rhoi2 + zi*zi ;1544 1545 if ( (radi2 <= tolORMax2)1546 && (radi2 >= tolORMin2)1547 && (zi*(fSTheta + fDTheta - halfpi) <= 0) )1548 {1549 if (segPhi && rhoi2) // Check phi intersection1550 {1551 cosPsi = (xi*cosCPhi + yi*sinCPhi)/std::sqrt(rhoi2) ;1552 if (cosPsi >= cosHDPhiOT)1553 {1554 snxt = s ;1555 }1556 }1557 else1558 {1559 snxt = s ;1560 }1561 }1562 }1563 }1564 1444 1565 1445 // Possible intersection with STheta cone. … … 1570 1450 t1 = 1 - v.z()*v.z()*(1 + tanSTheta2) ; 1571 1451 t2 = pDotV2d - p.z()*v.z()*tanSTheta2 ; 1572 1452 if (t1) 1453 { 1454 b = t2/t1 ; 1455 c = dist2STheta/t1 ; 1456 d2 = b*b - c ; 1457 1458 if (d2 >= 0) 1459 { 1460 d = std::sqrt(d2) ; 1461 s = -b + d ; // Second root 1462 1463 if ( (s >= 0) && (s < snxt) ) 1464 { 1465 xi = p.x() + s*v.x() ; 1466 yi = p.y() + s*v.y() ; 1467 zi = p.z() + s*v.z() ; 1468 rhoi2 = xi*xi + yi*yi ; 1469 radi2 = rhoi2 + zi*zi ; 1470 1471 if ( (radi2 <= tolORMax2) 1472 && (radi2 >= tolORMin2) 1473 && (zi*(fSTheta - halfpi) <= 0) ) 1474 { 1475 if (!fFullPhiSphere && rhoi2) // Check phi intersection 1476 { 1477 cosPsi = (xi*cosCPhi + yi*sinCPhi)/std::sqrt(rhoi2) ; 1478 if (cosPsi >= cosHDPhiOT) 1479 { 1480 snxt = s ; 1481 } 1482 } 1483 else 1484 { 1485 snxt = s ; 1486 } 1487 } 1488 } 1489 } 1490 } 1491 } 1492 } 1493 else if ( (pTheta < tolSTheta + kAngTolerance) 1494 && (fSTheta > halfAngTolerance) ) 1495 { 1496 // In tolerance of stheta 1497 // If entering through solid [r,phi] => 0 to in 1498 // else try 2nd root 1499 1500 t2 = pDotV2d - p.z()*v.z()*tanSTheta2 ; 1501 if ( (t2>=0 && tolIRMin2<rad2 && rad2<tolIRMax2 && fSTheta<halfpi) 1502 || (t2<0 && tolIRMin2<rad2 && rad2<tolIRMax2 && fSTheta>halfpi) 1503 || (v.z()<0 && tolIRMin2<rad2 && rad2<tolIRMax2 && fSTheta==halfpi) ) 1504 { 1505 if (!fFullPhiSphere && rho2) // Check phi intersection 1506 { 1507 cosPsi = (p.x()*cosCPhi + p.y()*sinCPhi)/std::sqrt(rho2) ; 1508 if (cosPsi >= cosHDPhiIT) 1509 { 1510 return 0 ; 1511 } 1512 } 1513 else 1514 { 1515 return 0 ; 1516 } 1517 } 1518 1519 // Not entering immediately/travelling through 1520 1521 t1 = 1 - v.z()*v.z()*(1 + tanSTheta2) ; 1522 if (t1) 1523 { 1573 1524 b = t2/t1 ; 1574 1525 c = dist2STheta/t1 ; … … 1578 1529 { 1579 1530 d = std::sqrt(d2) ; 1580 s = -b + d ; // Second root 1581 1582 if ( (s >= 0) && (s < snxt) ) 1583 { 1531 s = -b + d ; 1532 if ( (s >= halfCarTolerance) && (s < snxt) && (fSTheta < halfpi) ) 1533 { // ^^^^^^^^^^^^^^^^^^^^^ shouldn't it be >=0 instead ? 1584 1534 xi = p.x() + s*v.x() ; 1585 1535 yi = p.y() + s*v.y() ; … … 1592 1542 && (zi*(fSTheta - halfpi) <= 0) ) 1593 1543 { 1594 if (segPhi && rhoi2) // Check phi intersection 1544 if ( !fFullPhiSphere && rhoi2 ) // Check phi intersection 1545 { 1546 cosPsi = (xi*cosCPhi + yi*sinCPhi)/std::sqrt(rhoi2) ; 1547 if ( cosPsi >= cosHDPhiOT ) 1548 { 1549 snxt = s ; 1550 } 1551 } 1552 else 1553 { 1554 snxt = s ; 1555 } 1556 } 1557 } 1558 } 1559 } 1560 } 1561 else if ((pTheta > tolETheta-kAngTolerance) && (eTheta < pi-kAngTolerance)) 1562 { 1563 1564 // In tolerance of etheta 1565 // If entering through solid [r,phi] => 0 to in 1566 // else try 2nd root 1567 1568 t2 = pDotV2d - p.z()*v.z()*tanETheta2 ; 1569 1570 if ( ((t2<0) && (eTheta < halfpi) 1571 && (tolIRMin2 < rad2) && (rad2 < tolIRMax2)) 1572 || ((t2>=0) && (eTheta > halfpi) 1573 && (tolIRMin2 < rad2) && (rad2 < tolIRMax2)) 1574 || ((v.z()>0) && (eTheta == halfpi) 1575 && (tolIRMin2 < rad2) && (rad2 < tolIRMax2)) ) 1576 { 1577 if (!fFullPhiSphere && rho2) // Check phi intersection 1578 { 1579 cosPsi = (p.x()*cosCPhi + p.y()*sinCPhi)/std::sqrt(rho2) ; 1580 if (cosPsi >= cosHDPhiIT) 1581 { 1582 return 0 ; 1583 } 1584 } 1585 else 1586 { 1587 return 0 ; 1588 } 1589 } 1590 1591 // Not entering immediately/travelling through 1592 1593 t1 = 1 - v.z()*v.z()*(1 + tanETheta2) ; 1594 if (t1) 1595 { 1596 b = t2/t1 ; 1597 c = dist2ETheta/t1 ; 1598 d2 = b*b - c ; 1599 1600 if (d2 >= 0) 1601 { 1602 d = std::sqrt(d2) ; 1603 s = -b + d ; 1604 1605 if ( (s >= halfCarTolerance) 1606 && (s < snxt) && (eTheta > halfpi) ) 1607 { 1608 xi = p.x() + s*v.x() ; 1609 yi = p.y() + s*v.y() ; 1610 zi = p.z() + s*v.z() ; 1611 rhoi2 = xi*xi + yi*yi ; 1612 radi2 = rhoi2 + zi*zi ; 1613 1614 if ( (radi2 <= tolORMax2) 1615 && (radi2 >= tolORMin2) 1616 && (zi*(eTheta - halfpi) <= 0) ) 1617 { 1618 if (!fFullPhiSphere && rhoi2) // Check phi intersection 1595 1619 { 1596 1620 cosPsi = (xi*cosCPhi + yi*sinCPhi)/std::sqrt(rhoi2) ; … … 1606 1630 } 1607 1631 } 1608 } 1609 } 1610 } 1611 else if ( (pTheta <tolSTheta + kAngTolerance) 1612 && (fSTheta > kAngTolerance) ) 1613 { 1614 // In tolerance of stheta 1615 // If entering through solid [r,phi] => 0 to in 1616 // else try 2nd root 1617 1618 t2 = pDotV2d - p.z()*v.z()*tanSTheta2 ; 1619 if ( (t2>=0 && tolIRMin2<rad2 && rad2<tolIRMax2 && fSTheta<pi*.5) 1620 || (t2<0 && tolIRMin2<rad2 && rad2<tolIRMax2 && fSTheta>pi*.5) 1621 || (v.z()<0 && tolIRMin2<rad2 && rad2<tolIRMax2 && fSTheta==pi*.5) ) 1622 { 1623 if (segPhi && rho2) // Check phi intersection 1624 { 1625 cosPsi = (p.x()*cosCPhi + p.y()*sinCPhi)/std::sqrt(rho2) ; 1626 if (cosPsi >= cosHDPhiIT) 1627 { 1628 return 0 ; 1629 } 1630 } 1631 else 1632 { 1633 return 0 ; 1634 } 1635 } 1636 1637 // Not entering immediately/travelling through 1638 1639 t1 = 1 - v.z()*v.z()*(1 + tanSTheta2) ; 1640 b = t2/t1 ; 1641 c = dist2STheta/t1 ; 1642 d2 = b*b - c ; 1643 1644 if (d2 >= 0) 1645 { 1646 d = std::sqrt(d2) ; 1647 s = -b + d ; 1648 if ( (s >= kCarTolerance*0.5) && (s < snxt) && (fSTheta < pi*0.5) ) 1649 { 1650 xi = p.x() + s*v.x() ; 1651 yi = p.y() + s*v.y() ; 1652 zi = p.z() + s*v.z() ; 1653 rhoi2 = xi*xi + yi*yi ; 1654 radi2 = rhoi2 + zi*zi ; 1655 1656 if ( (radi2 <= tolORMax2) 1657 && (radi2 >= tolORMin2) 1658 && (zi*(fSTheta - halfpi) <= 0) ) 1659 { 1660 if ( segPhi && rhoi2 ) // Check phi intersection 1661 { 1662 cosPsi = (xi*cosCPhi + yi*sinCPhi)/std::sqrt(rhoi2) ; 1663 if ( cosPsi >= cosHDPhiOT ) 1664 { 1665 snxt = s ; 1666 } 1667 } 1668 else 1669 { 1670 snxt = s ; 1671 } 1672 } 1673 } 1674 } 1675 } 1676 else if ( (pTheta > tolETheta - kAngTolerance) 1677 && ((fSTheta + fDTheta) < pi-kAngTolerance) ) 1678 { 1679 1680 // In tolerance of etheta 1681 // If entering through solid [r,phi] => 0 to in 1682 // else try 2nd root 1683 1684 t2 = pDotV2d - p.z()*v.z()*tanETheta2 ; 1685 1686 if ( 1687 (t2<0 && (fSTheta+fDTheta) <pi*0.5 && tolIRMin2<rad2 && rad2<tolIRMax2) 1688 || (t2>=0 && (fSTheta+fDTheta) >pi*0.5 && tolIRMin2<rad2 && rad2<tolIRMax2) 1689 || (v.z()>0 && (fSTheta+fDTheta)==pi*0.5 && tolIRMin2<rad2 && rad2<tolIRMax2) 1690 ) 1691 { 1692 if (segPhi && rho2) // Check phi intersection 1693 { 1694 cosPsi = (p.x()*cosCPhi + p.y()*sinCPhi)/std::sqrt(rho2) ; 1695 if (cosPsi >= cosHDPhiIT) 1696 { 1697 return 0 ; 1698 } 1699 } 1700 else 1701 { 1702 return 0 ; 1703 } 1704 } 1705 1706 // Not entering immediately/travelling through 1707 1708 t1 = 1 - v.z()*v.z()*(1 + tanETheta2) ; 1709 b = t2/t1 ; 1710 c = dist2ETheta/t1 ; 1711 d2 = b*b - c ; 1712 1713 if (d2 >= 0) 1714 { 1715 d = std::sqrt(d2) ; 1716 s = -b + d ; 1717 1718 if ( (s >= kCarTolerance*0.5) 1719 && (s < snxt) && ((fSTheta + fDTheta) > pi*0.5) ) 1720 { 1721 xi = p.x() + s*v.x() ; 1722 yi = p.y() + s*v.y() ; 1723 zi = p.z() + s*v.z() ; 1724 rhoi2 = xi*xi + yi*yi ; 1725 radi2 = rhoi2 + zi*zi ; 1726 1727 if ( (radi2 <= tolORMax2) 1728 && (radi2 >= tolORMin2) 1729 && (zi*(fSTheta + fDTheta - halfpi) <= 0) ) 1730 { 1731 if (segPhi && rhoi2) // Check phi intersection 1732 { 1733 cosPsi = (xi*cosCPhi + yi*sinCPhi)/std::sqrt(rhoi2) ; 1734 if (cosPsi>=cosHDPhiOT) 1735 { 1736 snxt = s ; 1737 } 1738 } 1739 else 1740 { 1741 snxt = s ; 1742 } 1743 } 1744 } 1745 } 1632 } 1633 } 1746 1634 } 1747 1635 else … … 1752 1640 t1 = 1 - v.z()*v.z()*(1 + tanSTheta2) ; 1753 1641 t2 = pDotV2d - p.z()*v.z()*tanSTheta2 ; 1754 1755 b = t2/t1; 1756 c = dist2STheta/t1 ; 1757 d2 = b*b - c ; 1758 1759 if (d2 >= 0) 1760 { 1761 d = std::sqrt(d2) ; 1762 s = -b + d ; // second root 1763 1764 if (s >= 0 && s < snxt) 1765 { 1766 xi = p.x() + s*v.x() ; 1767 yi = p.y() + s*v.y() ; 1768 zi = p.z() + s*v.z() ; 1769 rhoi2 = xi*xi + yi*yi ; 1770 radi2 = rhoi2 + zi*zi ; 1771 1772 if ( (radi2 <= tolORMax2) 1773 && (radi2 >= tolORMin2) 1774 && (zi*(fSTheta - halfpi) <= 0) ) 1775 { 1776 if (segPhi && rhoi2) // Check phi intersection 1777 { 1778 cosPsi = (xi*cosCPhi + yi*sinCPhi)/std::sqrt(rhoi2) ; 1779 if (cosPsi >= cosHDPhiOT) 1642 if (t1) 1643 { 1644 b = t2/t1; 1645 c = dist2STheta/t1 ; 1646 d2 = b*b - c ; 1647 1648 if (d2 >= 0) 1649 { 1650 d = std::sqrt(d2) ; 1651 s = -b + d ; // second root 1652 1653 if ((s >= 0) && (s < snxt)) 1654 { 1655 xi = p.x() + s*v.x() ; 1656 yi = p.y() + s*v.y() ; 1657 zi = p.z() + s*v.z() ; 1658 rhoi2 = xi*xi + yi*yi ; 1659 radi2 = rhoi2 + zi*zi ; 1660 1661 if ( (radi2 <= tolORMax2) 1662 && (radi2 >= tolORMin2) 1663 && (zi*(fSTheta - halfpi) <= 0) ) 1664 { 1665 if (!fFullPhiSphere && rhoi2) // Check phi intersection 1666 { 1667 cosPsi = (xi*cosCPhi + yi*sinCPhi)/std::sqrt(rhoi2) ; 1668 if (cosPsi >= cosHDPhiOT) 1669 { 1670 snxt = s ; 1671 } 1672 } 1673 else 1780 1674 { 1781 1675 snxt = s ; 1782 1676 } 1783 }1784 else1785 {1786 snxt = s ;1787 1677 } 1788 1678 } … … 1791 1681 t1 = 1 - v.z()*v.z()*(1 + tanETheta2) ; 1792 1682 t2 = pDotV2d - p.z()*v.z()*tanETheta2 ; 1793 1794 b = t2/t1 ; 1795 c = dist2ETheta/t1 ; 1796 d2 = b*b - c ; 1797 1798 if (d2 >= 0) 1799 { 1800 d = std::sqrt(d2) ; 1801 s = -b + d; // second root 1802 1803 if (s >= 0 && s < snxt) 1804 { 1805 xi = p.x() + s*v.x() ; 1806 yi = p.y() + s*v.y() ; 1807 zi = p.z() + s*v.z() ; 1808 rhoi2 = xi*xi + yi*yi ; 1809 radi2 = rhoi2 + zi*zi ; 1810 1811 if ( (radi2 <= tolORMax2) 1812 && (radi2 >= tolORMin2) 1813 && (zi*(fSTheta + fDTheta - halfpi) <= 0) ) 1814 { 1815 if (segPhi && rhoi2) // Check phi intersection 1816 { 1817 cosPsi = (xi*cosCPhi + yi*sinCPhi)/std::sqrt(rhoi2) ; 1818 if ( cosPsi >= cosHDPhiOT ) 1819 { 1820 snxt=s; 1821 } 1822 } 1823 else 1824 { 1825 snxt = s ; 1683 if (t1) 1684 { 1685 b = t2/t1 ; 1686 c = dist2ETheta/t1 ; 1687 d2 = b*b - c ; 1688 1689 if (d2 >= 0) 1690 { 1691 d = std::sqrt(d2) ; 1692 s = -b + d; // second root 1693 1694 if ((s >= 0) && (s < snxt)) 1695 { 1696 xi = p.x() + s*v.x() ; 1697 yi = p.y() + s*v.y() ; 1698 zi = p.z() + s*v.z() ; 1699 rhoi2 = xi*xi + yi*yi ; 1700 radi2 = rhoi2 + zi*zi ; 1701 1702 if ( (radi2 <= tolORMax2) 1703 && (radi2 >= tolORMin2) 1704 && (zi*(eTheta - halfpi) <= 0) ) 1705 { 1706 if (!fFullPhiSphere && rhoi2) // Check phi intersection 1707 { 1708 cosPsi = (xi*cosCPhi + yi*sinCPhi)/std::sqrt(rhoi2) ; 1709 if ( cosPsi >= cosHDPhiOT ) 1710 { 1711 snxt=s; 1712 } 1713 } 1714 else 1715 { 1716 snxt = s ; 1717 } 1826 1718 } 1827 1719 } … … 1844 1736 { 1845 1737 G4double safe=0.0,safeRMin,safeRMax,safePhi,safeTheta; 1846 G4double rho2,r ad,rho;1847 G4double phiC,cosPhiC,sinPhiC,cosPsi,ePhi;1738 G4double rho2,rds,rho; 1739 G4double cosPsi; 1848 1740 G4double pTheta,dTheta1,dTheta2; 1849 1741 rho2=p.x()*p.x()+p.y()*p.y(); 1850 r ad=std::sqrt(rho2+p.z()*p.z());1742 rds=std::sqrt(rho2+p.z()*p.z()); 1851 1743 rho=std::sqrt(rho2); 1852 1744 … … 1856 1748 if (fRmin) 1857 1749 { 1858 safeRMin=fRmin-r ad;1859 safeRMax=r ad-fRmax;1750 safeRMin=fRmin-rds; 1751 safeRMax=rds-fRmax; 1860 1752 if (safeRMin>safeRMax) 1861 1753 { … … 1869 1761 else 1870 1762 { 1871 safe=r ad-fRmax;1763 safe=rds-fRmax; 1872 1764 } 1873 1765 … … 1875 1767 // Distance to phi extent 1876 1768 // 1877 if (fDPhi<twopi&&rho) 1878 { 1879 phiC=fSPhi+fDPhi*0.5; 1880 cosPhiC=std::cos(phiC); 1881 sinPhiC=std::sin(phiC); 1882 1769 if (!fFullPhiSphere && rho) 1770 { 1883 1771 // Psi=angle from central phi to point 1884 1772 // 1885 cosPsi=(p.x()*cos PhiC+p.y()*sinPhiC)/rho;1886 if (cosPsi<std::cos( fDPhi*0.5))1773 cosPsi=(p.x()*cosCPhi+p.y()*sinCPhi)/rho; 1774 if (cosPsi<std::cos(hDPhi)) 1887 1775 { 1888 1776 // Point lies outside phi range 1889 1777 // 1890 if ((p.y()*cos PhiC-p.x()*sinPhiC)<=0)1891 { 1892 safePhi=std::fabs(p.x()*s td::sin(fSPhi)-p.y()*std::cos(fSPhi));1778 if ((p.y()*cosCPhi-p.x()*sinCPhi)<=0) 1779 { 1780 safePhi=std::fabs(p.x()*sinSPhi-p.y()*cosSPhi); 1893 1781 } 1894 1782 else 1895 1783 { 1896 ePhi=fSPhi+fDPhi; 1897 safePhi=std::fabs(p.x()*std::sin(ePhi)-p.y()*std::cos(ePhi)); 1898 } 1899 if (safePhi>safe) safe=safePhi; 1784 safePhi=std::fabs(p.x()*sinEPhi-p.y()*cosEPhi); 1785 } 1786 if (safePhi>safe) { safe=safePhi; } 1900 1787 } 1901 1788 } … … 1903 1790 // Distance to Theta extent 1904 1791 // 1905 if ((r ad!=0.0) && (fDTheta<pi))1906 { 1907 pTheta=std::acos(p.z()/r ad);1908 if (pTheta<0) pTheta+=pi;1792 if ((rds!=0.0) && (!fFullThetaSphere)) 1793 { 1794 pTheta=std::acos(p.z()/rds); 1795 if (pTheta<0) { pTheta+=pi; } 1909 1796 dTheta1=fSTheta-pTheta; 1910 dTheta2=pTheta- (fSTheta+fDTheta);1797 dTheta2=pTheta-eTheta; 1911 1798 if (dTheta1>dTheta2) 1912 1799 { 1913 1800 if (dTheta1>=0) // WHY ??????????? 1914 1801 { 1915 safeTheta=r ad*std::sin(dTheta1);1802 safeTheta=rds*std::sin(dTheta1); 1916 1803 if (safe<=safeTheta) 1917 1804 { … … 1924 1811 if (dTheta2>=0) 1925 1812 { 1926 safeTheta=r ad*std::sin(dTheta2);1813 safeTheta=rds*std::sin(dTheta2); 1927 1814 if (safe<=safeTheta) 1928 1815 { … … 1933 1820 } 1934 1821 1935 if (safe<0) safe=0;1822 if (safe<0) { safe=0; } 1936 1823 return safe; 1937 1824 } … … 1939 1826 ///////////////////////////////////////////////////////////////////// 1940 1827 // 1941 // Calculate distance to surface of shape from `inside', allowing for tolerance1828 // Calculate distance to surface of shape from 'inside', allowing for tolerance 1942 1829 // - Only Calc rmax intersection if no valid rmin intersection 1943 1830 … … 1952 1839 ESide side=kNull,sidephi=kNull,sidetheta=kNull; 1953 1840 1841 static const G4double halfCarTolerance = kCarTolerance*0.5; 1842 static const G4double halfAngTolerance = kAngTolerance*0.5; 1843 const G4double halfRmaxTolerance = fRmaxTolerance*0.5; 1844 const G4double halfRminTolerance = fRminTolerance*0.5; 1845 const G4double Rmax_plus = fRmax + halfRmaxTolerance; 1846 const G4double Rmin_minus = (fRmin) ? fRmin-halfRminTolerance : 0; 1954 1847 G4double t1,t2; 1955 1848 G4double b,c,d; … … 1957 1850 // Variables for phi intersection: 1958 1851 1959 G4double sinSPhi,cosSPhi,ePhi,sinEPhi,cosEPhi;1960 G4double cPhi,sinCPhi,cosCPhi;1961 1852 G4double pDistS,compS,pDistE,compE,sphi2,vphi; 1962 1853 … … 1966 1857 G4double xi,yi,zi; // Intersection point 1967 1858 1968 // G4double Comp; // Phi intersection 1969 1970 G4bool segPhi; // Phi flag and precalcs 1971 G4double hDPhi,hDPhiOT,hDPhiIT; 1972 G4double cosHDPhiOT,cosHDPhiIT; 1973 1974 G4bool segTheta; // Theta flag and precals 1975 G4double tanSTheta=0.,tanETheta=0., rhoSecTheta; 1976 G4double tanSTheta2=0.,tanETheta2=0.; 1859 // Theta precals 1860 // 1861 G4double rhoSecTheta; 1977 1862 G4double dist2STheta, dist2ETheta, distTheta; 1978 1863 G4double d2,s; 1979 1864 1980 1865 // General Precalcs 1981 1866 // 1982 1867 rho2 = p.x()*p.x()+p.y()*p.y(); 1983 1868 rad2 = rho2+p.z()*p.z(); 1984 // G4double rad=std::sqrt(rad2);1985 1869 1986 1870 pTheta = std::atan2(std::sqrt(rho2),p.z()); … … 1989 1873 pDotV3d = pDotV2d+p.z()*v.z(); 1990 1874 1991 // Set phi divided flag and precalcs1992 1993 if( fDPhi < twopi )1994 {1995 segPhi=true;1996 hDPhi=0.5*fDPhi; // half delta phi1997 cPhi=fSPhi+hDPhi;;1998 hDPhiOT=hDPhi+0.5*kAngTolerance; // Outer Tolerant half delta phi1999 hDPhiIT=hDPhi-0.5*kAngTolerance;2000 sinCPhi=std::sin(cPhi);2001 cosCPhi=std::cos(cPhi);2002 cosHDPhiOT=std::cos(hDPhiOT);2003 cosHDPhiIT=std::cos(hDPhiIT);2004 }2005 else2006 {2007 segPhi=false;2008 }2009 2010 1875 // Theta precalcs 2011 1876 2012 if ( fDTheta < pi ) 2013 { 2014 segTheta = true; 2015 tolSTheta = fSTheta - kAngTolerance*0.5; 2016 tolETheta = fSTheta + fDTheta + kAngTolerance*0.5; 2017 } 2018 else segTheta = false; 2019 1877 if ( !fFullThetaSphere ) 1878 { 1879 tolSTheta = fSTheta - halfAngTolerance; 1880 tolETheta = eTheta + halfAngTolerance; 1881 } 2020 1882 2021 1883 // Radial Intersections from G4Sphere::DistanceToIn … … 2034 1896 // 2035 1897 // => s=-pDotV3d+-std::sqrt(pDotV3d^2-(rad2-R^2)) 2036 // 2037 // const G4double fractionTolerance = 1.0e-12; 2038 2039 const G4double flexRadMaxTolerance = // kRadTolerance; 2040 std::max(kRadTolerance, fEpsilon * fRmax); 2041 2042 const G4double Rmax_plus = fRmax + flexRadMaxTolerance*0.5; 2043 2044 const G4double flexRadMinTolerance = std::max(kRadTolerance, 2045 fEpsilon * fRmin); 2046 2047 const G4double Rmin_minus= (fRmin > 0) ? fRmin-flexRadMinTolerance*0.5 : 0 ; 2048 2049 if(rad2 <= Rmax_plus*Rmax_plus && rad2 >= Rmin_minus*Rmin_minus) 2050 // if(rad <= Rmax_plus && rad >= Rmin_minus) 1898 1899 if( (rad2 <= Rmax_plus*Rmax_plus) && (rad2 >= Rmin_minus*Rmin_minus) ) 2051 1900 { 2052 1901 c = rad2 - fRmax*fRmax; 2053 1902 2054 if (c < f lexRadMaxTolerance*fRmax)1903 if (c < fRmaxTolerance*fRmax) 2055 1904 { 2056 1905 // Within tolerant Outer radius … … 2065 1914 d2 = pDotV3d*pDotV3d - c; 2066 1915 2067 if( (c >- f lexRadMaxTolerance*fRmax) // on tolerant surface2068 && ((pDotV3d >=0) || (d2 < 0)) ) 2069 1916 if( (c >- fRmaxTolerance*fRmax) // on tolerant surface 1917 && ((pDotV3d >=0) || (d2 < 0)) ) // leaving outside from Rmax 1918 // not re-entering 2070 1919 { 2071 1920 if(calcNorm) … … 2092 1941 d2 = pDotV3d*pDotV3d - c; 2093 1942 2094 if ( c >- flexRadMinTolerance*fRmin) // 2.0 * (0.5*kRadTolerance) * fRmin2095 { 2096 if ( c < flexRadMinTolerance*fRmin &&2097 d2 >= flexRadMinTolerance*fRmin && pDotV3d < 0 ) // leaving from Rmin2098 { 2099 if(calcNorm) *validNorm = false ;// Rmin surface is concave2100 1943 if (c >- fRminTolerance*fRmin) // 2.0 * (0.5*kRadTolerance) * fRmin 1944 { 1945 if ( (c < fRminTolerance*fRmin) // leaving from Rmin 1946 && (d2 >= fRminTolerance*fRmin) && (pDotV3d < 0) ) 1947 { 1948 if(calcNorm) { *validNorm = false; } // Rmin surface is concave 1949 return snxt = 0 ; 2101 1950 } 2102 1951 else … … 2119 1968 // Theta segment intersection 2120 1969 2121 if ( segTheta)1970 if ( !fFullThetaSphere ) 2122 1971 { 2123 1972 // Intersection with theta surfaces … … 2143 1992 // 2144 1993 2145 /* ////////////////////////////////////////////////////////2146 2147 tanSTheta=std::tan(fSTheta);2148 tanSTheta2=tanSTheta*tanSTheta;2149 tanETheta=std::tan(fSTheta+fDTheta);2150 tanETheta2=tanETheta*tanETheta;2151 2152 if (fSTheta)2153 {2154 dist2STheta=rho2-p.z()*p.z()*tanSTheta2;2155 }2156 else2157 {2158 dist2STheta = kInfinity;2159 }2160 if (fSTheta + fDTheta < pi)2161 {2162 dist2ETheta = rho2-p.z()*p.z()*tanETheta2;2163 }2164 else2165 {2166 dist2ETheta = kInfinity ;2167 }2168 if (pTheta > tolSTheta && pTheta < tolETheta) // Inside theta2169 {2170 // In tolerance of STheta and possible leaving out to small thetas N-2171 2172 if(pTheta < tolSTheta + kAngTolerance && fSTheta > kAngTolerance)2173 {2174 t2=pDotV2d-p.z()*v.z()*tanSTheta2 ; // =(VdotN+)*rhoSecSTheta2175 2176 if( fSTheta < pi*0.5 && t2 < 0)2177 {2178 if(calcNorm) *validNorm = false ;2179 return snxt = 0 ;2180 }2181 else if(fSTheta > pi*0.5 && t2 >= 0)2182 {2183 if(calcNorm)2184 {2185 rhoSecTheta = std::sqrt(rho2*(1+tanSTheta2)) ;2186 *validNorm = true ;2187 *n = G4ThreeVector(-p.x()/rhoSecTheta, // N-2188 -p.y()/rhoSecTheta,2189 tanSTheta/std::sqrt(1+tanSTheta2) ) ;2190 }2191 return snxt = 0 ;2192 }2193 else if( fSTheta == pi*0.5 && v.z() > 0)2194 {2195 if(calcNorm)2196 {2197 *validNorm = true ;2198 *n = G4ThreeVector(0,0,1) ;2199 }2200 return snxt = 0 ;2201 }2202 }2203 2204 // In tolerance of ETheta and possible leaving out to larger thetas N+2205 2206 if ( (pTheta > tolETheta - kAngTolerance)2207 && (( fSTheta + fDTheta) < pi - kAngTolerance) )2208 {2209 t2=pDotV2d-p.z()*v.z()*tanETheta2 ;2210 if((fSTheta+fDTheta)>pi*0.5 && t2<0)2211 {2212 if(calcNorm) *validNorm = false ;2213 return snxt = 0 ;2214 }2215 else if( (fSTheta+fDTheta) < pi*0.5 && t2 >= 0 )2216 {2217 if(calcNorm)2218 {2219 rhoSecTheta = std::sqrt(rho2*(1+tanETheta2)) ;2220 *validNorm = true ;2221 *n = G4ThreeVector( p.x()/rhoSecTheta, // N+2222 p.y()/rhoSecTheta,2223 -tanETheta/std::sqrt(1+tanETheta2) ) ;2224 }2225 return snxt = 0 ;2226 }2227 else if( ( fSTheta+fDTheta) == pi*0.5 && v.z() < 0 )2228 {2229 if(calcNorm)2230 {2231 *validNorm = true ;2232 *n = G4ThreeVector(0,0,-1) ;2233 }2234 return snxt = 0 ;2235 }2236 }2237 if( fSTheta > 0 )2238 {2239 // First root of fSTheta cone, second if first root -ve2240 2241 t1 = 1-v.z()*v.z()*(1+tanSTheta2);2242 t2 = pDotV2d-p.z()*v.z()*tanSTheta2;2243 2244 b = t2/t1;2245 c = dist2STheta/t1;2246 d2 = b*b - c ;2247 2248 if ( d2 >= 0 )2249 {2250 d = std::sqrt(d2) ;2251 s = -b - d ; // First root2252 2253 if ( s < 0 )2254 {2255 s = -b + d ; // Second root2256 }2257 if (s > flexRadMaxTolerance*0.5 ) // && s<sr)2258 {2259 // check against double cone solution2260 zi=p.z()+s*v.z();2261 if (fSTheta<pi*0.5 && zi<0)2262 {2263 s = kInfinity ; // wrong cone2264 }2265 if (fSTheta>pi*0.5 && zi>0)2266 {2267 s = kInfinity ; // wrong cone2268 }2269 stheta = s ;2270 sidetheta = kSTheta ;2271 }2272 }2273 }2274 2275 // Possible intersection with ETheta cone2276 2277 if (fSTheta + fDTheta < pi)2278 {2279 t1 = 1-v.z()*v.z()*(1+tanETheta2);2280 t2 = pDotV2d-p.z()*v.z()*tanETheta2;2281 b = t2/t1;2282 c = dist2ETheta/t1;2283 d2 = b*b-c ;2284 2285 if ( d2 >= 0 )2286 {2287 d = std::sqrt(d2);2288 s = -b - d ; // First root2289 2290 if ( s < 0 )2291 {2292 s=-b+d; // Second root2293 }2294 if (s > flexRadMaxTolerance*0.5 && s < stheta )2295 {2296 // check against double cone solution2297 zi=p.z()+s*v.z();2298 if (fSTheta+fDTheta<pi*0.5 && zi<0)2299 {2300 s = kInfinity ; // wrong cone2301 }2302 if (fSTheta+fDTheta>pi*0.5 && zi>0)2303 {2304 s = kInfinity ; // wrong cone2305 }2306 }2307 if (s < stheta)2308 {2309 stheta = s ;2310 sidetheta = kETheta ;2311 }2312 }2313 }2314 }2315 */ ////////////////////////////////////////////////////////////2316 2317 1994 if(fSTheta) // intersection with first cons 2318 1995 { 2319 2320 tanSTheta = std::tan(fSTheta);2321 2322 1996 if( std::fabs(tanSTheta) > 5./kAngTolerance ) // kons is plane z=0 2323 1997 { 2324 1998 if( v.z() > 0. ) 2325 1999 { 2326 if ( std::fabs( p.z() ) <= flexRadMaxTolerance*0.5)2000 if ( std::fabs( p.z() ) <= halfRmaxTolerance ) 2327 2001 { 2328 2002 if(calcNorm) … … 2333 2007 return snxt = 0 ; 2334 2008 } 2335 // s = -p.z()/v.z();2336 2009 stheta = -p.z()/v.z(); 2337 2010 sidetheta = kSTheta; … … 2340 2013 else // kons is not plane 2341 2014 { 2342 tanSTheta2 = tanSTheta*tanSTheta;2343 2015 t1 = 1-v.z()*v.z()*(1+tanSTheta2); 2344 2016 t2 = pDotV2d-p.z()*v.z()*tanSTheta2; // ~vDotN if p on cons 2345 dist2STheta = rho2-p.z()*p.z()*tanSTheta2; // t3 2346 2347 // distTheta = std::sqrt(std::fabs(dist2STheta/(1+tanSTheta2))); 2017 dist2STheta = rho2-p.z()*p.z()*tanSTheta2; // t3 2018 2348 2019 distTheta = std::sqrt(rho2)-p.z()*tanSTheta; 2349 2020 2350 if( std::fabs(t1) < 0.5*kAngTolerance ) // 1st order equation, v parallel to kons2351 { 2021 if( std::fabs(t1) < halfAngTolerance ) // 1st order equation, 2022 { // v parallel to kons 2352 2023 if( v.z() > 0. ) 2353 2024 { 2354 if(std::fabs(distTheta) < flexRadMaxTolerance*0.5) // p on surface2355 { 2356 if( fSTheta < halfpi && p.z() > 0.)2357 { 2358 if( calcNorm ) *validNorm = false;2359 2360 } 2361 else if( fSTheta > halfpi && p.z() <= 0)2025 if(std::fabs(distTheta) < halfRmaxTolerance) // p on surface 2026 { 2027 if( (fSTheta < halfpi) && (p.z() > 0.) ) 2028 { 2029 if( calcNorm ) { *validNorm = false; } 2030 return snxt = 0.; 2031 } 2032 else if( (fSTheta > halfpi) && (p.z() <= 0) ) 2362 2033 { 2363 2034 if( calcNorm ) … … 2377 2048 } 2378 2049 } 2379 // s = -0.5*dist2STheta/t2;2380 2381 2050 stheta = -0.5*dist2STheta/t2; 2382 2051 sidetheta = kSTheta; 2383 2052 } 2384 } 2385 else // 2nd order equation, 1st root of fSTheta cone, 2ndif 1st root -ve2386 { 2387 if( std::fabs(distTheta) < flexRadMaxTolerance*0.5) // && t2 >= 0.) surface2388 { 2389 if( fSTheta > halfpi && t2 >= 0.) // leave2053 } // 2nd order equation, 1st root of fSTheta cone, 2054 else // 2nd if 1st root -ve 2055 { 2056 if( std::fabs(distTheta) < halfRmaxTolerance ) 2057 { 2058 if( (fSTheta > halfpi) && (t2 >= 0.) ) // leave 2390 2059 { 2391 2060 if( calcNorm ) … … 2394 2063 if (rho2) 2395 2064 { 2396 2065 rhoSecTheta = std::sqrt(rho2*(1+tanSTheta2)); 2397 2066 2398 2399 2400 2067 *n = G4ThreeVector( p.x()/rhoSecTheta, 2068 p.y()/rhoSecTheta, 2069 std::sin(fSTheta) ); 2401 2070 } 2402 else *n = G4ThreeVector(0.,0.,1.);2403 } 2071 else { *n = G4ThreeVector(0.,0.,1.); } 2072 } 2404 2073 return snxt = 0.; 2405 2074 } 2406 else if( fSTheta < halfpi && t2 < 0. && p.z() >=0.) // leave2407 { 2408 if( calcNorm ) *validNorm = false;2409 2075 else if( (fSTheta < halfpi) && (t2 < 0.) && (p.z() >=0.) ) // leave 2076 { 2077 if( calcNorm ) { *validNorm = false; } 2078 return snxt = 0.; 2410 2079 } 2411 2080 } … … 2422 2091 s = -b - d; // First root 2423 2092 2424 if( (std::fabs(s) < flexRadMaxTolerance*0.5 && t2 < 0.) || 2425 s < 0. || 2426 ( s > 0. && p.z() + s*v.z() > 0.) ) 2093 if ( ((std::fabs(s) < halfRmaxTolerance) && (t2 < 0.)) 2094 || (s < 0.) || ( (s > 0.) && (p.z() + s*v.z() > 0.) ) ) 2427 2095 { 2428 2096 s = -b + d ; // 2nd root 2429 2097 } 2430 if( s > flexRadMaxTolerance*0.5 && p.z() + s*v.z() <= 0.)2098 if( (s > halfRmaxTolerance) && (p.z() + s*v.z() <= 0.) ) 2431 2099 { 2432 2100 stheta = s; … … 2438 2106 s = -b - d; // First root 2439 2107 2440 if( (std::fabs(s) < flexRadMaxTolerance*0.5 && t2 >= 0.) || 2441 s < 0. || 2442 ( s > 0. && p.z() + s*v.z() < 0.) ) 2108 if ( ( (std::fabs(s) < halfRmaxTolerance) && (t2 >= 0.) ) 2109 || (s < 0.) || ( (s > 0.) && (p.z() + s*v.z() < 0.) ) ) 2443 2110 { 2444 2111 s = -b + d ; // 2nd root 2445 2112 } 2446 if( s > flexRadMaxTolerance*0.5 && p.z() + s*v.z() >= 0.)2113 if( (s > halfRmaxTolerance) && (p.z() + s*v.z() >= 0.) ) 2447 2114 { 2448 2115 stheta = s; … … 2454 2121 } 2455 2122 } 2456 if (fSTheta + fDTheta < pi) // intersection with second cons 2457 { 2458 2459 tanETheta = std::tan(fSTheta+fDTheta); 2460 2123 if (eTheta < pi) // intersection with second cons 2124 { 2461 2125 if( std::fabs(tanETheta) > 5./kAngTolerance ) // kons is plane z=0 2462 2126 { 2463 2127 if( v.z() < 0. ) 2464 2128 { 2465 if ( std::fabs( p.z() ) <= flexRadMaxTolerance*0.5)2129 if ( std::fabs( p.z() ) <= halfRmaxTolerance ) 2466 2130 { 2467 2131 if(calcNorm) … … 2474 2138 s = -p.z()/v.z(); 2475 2139 2476 if( s < stheta )2140 if( s < stheta ) 2477 2141 { 2478 2142 stheta = s; … … 2483 2147 else // kons is not plane 2484 2148 { 2485 tanETheta2 = tanETheta*tanETheta;2486 2149 t1 = 1-v.z()*v.z()*(1+tanETheta2); 2487 2150 t2 = pDotV2d-p.z()*v.z()*tanETheta2; // ~vDotN if p on cons 2488 dist2ETheta = rho2-p.z()*p.z()*tanETheta2; // t3 2489 2490 // distTheta = std::sqrt(std::fabs(dist2ETheta/(1+tanETheta2))); 2151 dist2ETheta = rho2-p.z()*p.z()*tanETheta2; // t3 2152 2491 2153 distTheta = std::sqrt(rho2)-p.z()*tanETheta; 2492 2154 2493 if( std::fabs(t1) < 0.5*kAngTolerance ) // 1st order equation, v parallel to kons2494 { 2155 if( std::fabs(t1) < halfAngTolerance ) // 1st order equation, 2156 { // v parallel to kons 2495 2157 if( v.z() < 0. ) 2496 2158 { 2497 if(std::fabs(distTheta) < flexRadMaxTolerance*0.5) // p on surface2498 { 2499 if( fSTheta+fDTheta > halfpi && p.z() < 0.)2500 { 2501 if( calcNorm ) *validNorm = false;2502 2503 } 2504 else if ( fSTheta+fDTheta < halfpi && p.z() >= 0)2159 if(std::fabs(distTheta) < halfRmaxTolerance) // p on surface 2160 { 2161 if( (eTheta > halfpi) && (p.z() < 0.) ) 2162 { 2163 if( calcNorm ) { *validNorm = false; } 2164 return snxt = 0.; 2165 } 2166 else if ( (eTheta < halfpi) && (p.z() >= 0) ) 2505 2167 { 2506 2168 if( calcNorm ) … … 2510 2172 { 2511 2173 rhoSecTheta = std::sqrt(rho2*(1+tanETheta2)); 2512 2513 2174 *n = G4ThreeVector( p.x()/rhoSecTheta, 2514 2175 p.y()/rhoSecTheta, 2515 -s td::sin(fSTheta+fDTheta));2176 -sinETheta ); 2516 2177 } 2517 else *n = G4ThreeVector(0.,0.,-1.);2178 else { *n = G4ThreeVector(0.,0.,-1.); } 2518 2179 } 2519 2180 return snxt = 0.; … … 2522 2183 s = -0.5*dist2ETheta/t2; 2523 2184 2524 if( s < stheta )2185 if( s < stheta ) 2525 2186 { 2526 2187 stheta = s; … … 2528 2189 } 2529 2190 } 2530 } 2531 else // 2nd order equation, 1st root of fSTheta cone, 2ndif 1st root -ve2532 { 2533 if ( std::fabs(distTheta) < flexRadMaxTolerance*0.5) // && t2 >= 0.) surface2534 { 2535 if( fSTheta+fDTheta < halfpi && t2 >= 0.) // leave2191 } // 2nd order equation, 1st root of fSTheta cone 2192 else // 2nd if 1st root -ve 2193 { 2194 if ( std::fabs(distTheta) < halfRmaxTolerance ) 2195 { 2196 if( (eTheta < halfpi) && (t2 >= 0.) ) // leave 2536 2197 { 2537 2198 if( calcNorm ) … … 2541 2202 { 2542 2203 rhoSecTheta = std::sqrt(rho2*(1+tanETheta2)); 2543 2544 2204 *n = G4ThreeVector( p.x()/rhoSecTheta, 2545 2205 p.y()/rhoSecTheta, 2546 -s td::sin(fSTheta+fDTheta));2206 -sinETheta ); 2547 2207 } 2548 2208 else *n = G4ThreeVector(0.,0.,-1.); … … 2550 2210 return snxt = 0.; 2551 2211 } 2552 else if( fSTheta+fDTheta > halfpi && t2 < 0. && p.z() <=0. ) // leave 2553 { 2554 if( calcNorm ) *validNorm = false; 2555 return snxt = 0.; 2212 else if ( (eTheta > halfpi) 2213 && (t2 < 0.) && (p.z() <=0.) ) // leave 2214 { 2215 if( calcNorm ) { *validNorm = false; } 2216 return snxt = 0.; 2556 2217 } 2557 2218 } … … 2564 2225 d = std::sqrt(d2); 2565 2226 2566 if( fSTheta+fDTheta < halfpi )2227 if( eTheta < halfpi ) 2567 2228 { 2568 2229 s = -b - d; // First root 2569 2230 2570 if( ( std::fabs(s) < flexRadMaxTolerance*0.5 && t2 < 0.) ||2571 s < 0.)2231 if( ((std::fabs(s) < halfRmaxTolerance) && (t2 < 0.)) 2232 || (s < 0.) ) 2572 2233 { 2573 2234 s = -b + d ; // 2nd root 2574 2235 } 2575 if( s > flexRadMaxTolerance*0.5)2236 if( s > halfRmaxTolerance ) 2576 2237 { 2577 2238 if( s < stheta ) … … 2586 2247 s = -b - d; // First root 2587 2248 2588 if( (std::fabs(s) < flexRadMaxTolerance*0.5 && t2 >= 0.) || 2589 s < 0. || 2590 ( s > 0. && p.z() + s*v.z() > 0.) ) 2249 if ( ((std::fabs(s) < halfRmaxTolerance) && (t2 >= 0.)) 2250 || (s < 0.) || ( (s > 0.) && (p.z() + s*v.z() > 0.) ) ) 2591 2251 { 2592 2252 s = -b + d ; // 2nd root 2593 2253 } 2594 if( s > flexRadMaxTolerance*0.5 && p.z() + s*v.z() <= 0.)2254 if( (s > halfRmaxTolerance) && (p.z() + s*v.z() <= 0.) ) 2595 2255 { 2596 2256 if( s < stheta ) … … 2610 2270 // Phi Intersection 2611 2271 2612 if ( fDPhi < twopi) 2613 { 2614 sinSPhi=std::sin(fSPhi); 2615 cosSPhi=std::cos(fSPhi); 2616 ePhi=fSPhi+fDPhi; 2617 sinEPhi=std::sin(ePhi); 2618 cosEPhi=std::cos(ePhi); 2619 cPhi=fSPhi+fDPhi*0.5; 2620 sinCPhi=std::sin(cPhi); 2621 cosCPhi=std::cos(cPhi); 2622 2623 if ( p.x()||p.y() ) // Check if on z axis (rho not needed later) 2272 if ( !fFullPhiSphere ) 2273 { 2274 if ( p.x() || p.y() ) // Check if on z axis (rho not needed later) 2624 2275 { 2625 2276 // pDist -ve when inside … … 2634 2285 sidephi = kNull ; 2635 2286 2636 if ( pDistS <= 0 && pDistE <= 0)2287 if ( (pDistS <= 0) && (pDistE <= 0) ) 2637 2288 { 2638 2289 // Inside both phi *full* planes … … 2644 2295 yi = p.y()+sphi*v.y() ; 2645 2296 2646 // Check intersecting with correct half-plane 2647 // (if not -> no intersect) 2648 2649 if ( ( yi*cosCPhi - xi*sinCPhi ) >= 0 ) 2297 // Check intersection with correct half-plane (if not -> no intersect) 2298 // 2299 if( (std::abs(xi)<=kCarTolerance) && (std::abs(yi)<=kCarTolerance) ) 2300 { 2301 vphi = std::atan2(v.y(),v.x()); 2302 sidephi = kSPhi; 2303 if ( ( (fSPhi-halfAngTolerance) <= vphi) 2304 && ( (ePhi+halfAngTolerance) >= vphi) ) 2305 { 2306 sphi = kInfinity; 2307 } 2308 } 2309 else if ( ( yi*cosCPhi - xi*sinCPhi ) >= 0 ) 2650 2310 { 2651 2311 sphi=kInfinity; … … 2654 2314 { 2655 2315 sidephi = kSPhi ; 2656 if ( pDistS > - 0.5*kCarTolerance) sphi =0 ;// Leave by sphi2657 } 2658 } 2659 else sphi = kInfinity ;2316 if ( pDistS > -halfCarTolerance) { sphi = 0; } // Leave by sphi 2317 } 2318 } 2319 else { sphi = kInfinity; } 2660 2320 2661 2321 if ( compE < 0 ) … … 2667 2327 yi = p.y()+sphi2*v.y() ; 2668 2328 2669 // Check intersecting with correct half-plane 2670 2671 if ((yi*cosCPhi-xi*sinCPhi)>=0) // Leaving via ending phi 2329 // Check intersection with correct half-plane 2330 // 2331 if ((std::abs(xi)<=kCarTolerance) && (std::abs(yi)<=kCarTolerance)) 2332 { 2333 // Leaving via ending phi 2334 // 2335 vphi = std::atan2(v.y(),v.x()) ; 2336 2337 if( !((fSPhi-halfAngTolerance <= vphi) 2338 &&(fSPhi+fDPhi+halfAngTolerance >= vphi)) ) 2339 { 2340 sidephi = kEPhi; 2341 if ( pDistE <= -halfCarTolerance ) { sphi = sphi2; } 2342 else { sphi = 0.0; } 2343 } 2344 } 2345 else if ((yi*cosCPhi-xi*sinCPhi)>=0) // Leaving via ending phi 2672 2346 { 2673 2347 sidephi = kEPhi ; 2674 if ( pDistE <= - 0.5*kCarTolerance )2348 if ( pDistE <= -halfCarTolerance ) 2675 2349 { 2676 2350 sphi=sphi2; … … 2684 2358 } 2685 2359 } 2686 else if ( pDistS >= 0 && pDistE >= 0) // Outside both *full* phi planes2360 else if ((pDistS >= 0) && (pDistE >= 0)) // Outside both *full* phi planes 2687 2361 { 2688 2362 if ( pDistS <= pDistE ) … … 2696 2370 if ( fDPhi > pi ) 2697 2371 { 2698 if ( compS < 0 && compE < 0 ) sphi = 0 ;2699 else sphi = kInfinity ;2372 if ( (compS < 0) && (compE < 0) ) { sphi = 0; } 2373 else { sphi = kInfinity; } 2700 2374 } 2701 2375 else … … 2704 2378 // will remain inside 2705 2379 2706 if ( compS >= 0 && compE >= 0 ) 2707 { 2708 sphi=kInfinity; 2709 } 2710 else 2711 { 2712 sphi=0; 2713 } 2380 if ( (compS >= 0) && (compE >= 0) ) { sphi = kInfinity; } 2381 else { sphi = 0; } 2714 2382 } 2715 2383 } 2716 else if ( pDistS > 0 && pDistE < 0)2384 else if ( (pDistS > 0) && (pDistE < 0) ) 2717 2385 { 2718 2386 // Outside full starting plane, inside full ending plane … … 2729 2397 // (if not -> not leaving phi extent) 2730 2398 // 2731 if ( ( yi*cosCPhi - xi*sinCPhi ) <= 0 ) 2399 if( (std::abs(xi)<=kCarTolerance)&&(std::abs(yi)<=kCarTolerance) ) 2400 { 2401 vphi = std::atan2(v.y(),v.x()); 2402 sidephi = kSPhi; 2403 if ( ( (fSPhi-halfAngTolerance) <= vphi) 2404 && ( (ePhi+halfAngTolerance) >= vphi) ) 2405 { 2406 sphi = kInfinity; 2407 } 2408 } 2409 else if ( ( yi*cosCPhi - xi*sinCPhi ) <= 0 ) 2732 2410 { 2733 2411 sphi = kInfinity ; … … 2736 2414 { 2737 2415 sidephi = kEPhi ; 2738 if ( pDistE > - 0.5*kCarTolerance ) sphi = 0. ;2416 if ( pDistE > -halfCarTolerance ) { sphi = 0.; } 2739 2417 } 2740 2418 } … … 2757 2435 // (if not -> remain in extent) 2758 2436 // 2759 if ( ( yi*cosCPhi - xi*sinCPhi) <= 0 ) 2437 if( (std::abs(xi)<=kCarTolerance)&&(std::abs(yi)<=kCarTolerance) ) 2438 { 2439 vphi = std::atan2(v.y(),v.x()); 2440 sidephi = kSPhi; 2441 if ( ( (fSPhi-halfAngTolerance) <= vphi) 2442 && ( (ePhi+halfAngTolerance) >= vphi) ) 2443 { 2444 sphi = kInfinity; 2445 } 2446 } 2447 else if ( ( yi*cosCPhi - xi*sinCPhi) <= 0 ) 2760 2448 { 2761 2449 sphi=kInfinity; … … 2787 2475 xi=p.x()+sphi*v.x(); 2788 2476 yi=p.y()+sphi*v.y(); 2789 2477 2790 2478 // Check intersection in correct half-plane 2791 2479 // (if not -> not leaving phi extent) 2792 2480 // 2793 if ( ( yi*cosCPhi - xi*sinCPhi ) >= 0 ) 2481 if( (std::abs(xi)<=kCarTolerance)&&(std::abs(yi)<=kCarTolerance) ) 2482 { 2483 vphi = std::atan2(v.y(),v.x()) ; 2484 sidephi = kSPhi; 2485 if ( ( (fSPhi-halfAngTolerance) <= vphi) 2486 && ( (ePhi+halfAngTolerance) >= vphi) ) 2487 { 2488 sphi = kInfinity; 2489 } 2490 } 2491 else if ( ( yi*cosCPhi - xi*sinCPhi ) >= 0 ) 2794 2492 { 2795 2493 sphi = kInfinity ; 2796 2494 } 2797 else // Leaving via Starting phi2798 {2495 else // Leaving via Starting phi 2496 { 2799 2497 sidephi = kSPhi ; 2800 if ( pDistS > -0.5*kCarTolerance ) sphi = 0 ;2498 if ( pDistS > -halfCarTolerance ) { sphi = 0; } 2801 2499 } 2802 2500 } … … 2815 2513 xi = p.x()+sphi*v.x() ; 2816 2514 yi = p.y()+sphi*v.y() ; 2817 2515 2818 2516 // Check intersection in correct half-plane 2819 2517 // (if not -> remain in extent) 2820 2518 // 2821 if ( ( yi*cosCPhi - xi*sinCPhi ) >= 0 ) 2519 if((std::abs(xi)<=kCarTolerance) && (std::abs(yi)<=kCarTolerance)) 2520 { 2521 vphi = std::atan2(v.y(),v.x()) ; 2522 sidephi = kSPhi; 2523 if ( ( (fSPhi-halfAngTolerance) <= vphi) 2524 && ( (ePhi+halfAngTolerance) >= vphi) ) 2525 { 2526 sphi = kInfinity; 2527 } 2528 } 2529 else if ( ( yi*cosCPhi - xi*sinCPhi ) >= 0 ) 2822 2530 { 2823 2531 sphi = kInfinity ; … … 2849 2557 { 2850 2558 vphi = std::atan2(v.y(),v.x()) ; 2851 if ( fSPhi < vphi && vphi < fSPhi + fDPhi)2852 { 2853 sphi =kInfinity;2559 if ((fSPhi-halfAngTolerance < vphi) && (vphi < ePhi+halfAngTolerance)) 2560 { 2561 sphi = kInfinity; 2854 2562 } 2855 2563 else … … 2859 2567 } 2860 2568 } 2861 else // travel along z - no phi inters action2569 else // travel along z - no phi intersection 2862 2570 { 2863 2571 sphi = kInfinity ; … … 2895 2603 if ( fDPhi <= pi ) // Normal to Phi- 2896 2604 { 2897 *n=G4ThreeVector(s td::sin(fSPhi),-std::cos(fSPhi),0);2605 *n=G4ThreeVector(sinSPhi,-cosSPhi,0); 2898 2606 *validNorm=true; 2899 2607 } 2900 else *validNorm=false;2608 else { *validNorm=false; } 2901 2609 break ; 2902 2610 … … 2904 2612 if ( fDPhi <= pi ) // Normal to Phi+ 2905 2613 { 2906 *n=G4ThreeVector(-s td::sin(fSPhi+fDPhi),std::cos(fSPhi+fDPhi),0);2614 *n=G4ThreeVector(-sinEPhi,cosEPhi,0); 2907 2615 *validNorm=true; 2908 2616 } 2909 else *validNorm=false;2617 else { *validNorm=false; } 2910 2618 break; 2911 2619 … … 2920 2628 xi = p.x() + snxt*v.x(); 2921 2629 yi = p.y() + snxt*v.y(); 2922 rhoSecTheta = std::sqrt((xi*xi+yi*yi)*(1+tanSTheta2)); 2923 *n = G4ThreeVector( xi/rhoSecTheta, // N- 2924 yi/rhoSecTheta, 2925 -tanSTheta/std::sqrt(1+tanSTheta2)); 2630 rho2=xi*xi+yi*yi; 2631 if (rho2) 2632 { 2633 rhoSecTheta = std::sqrt(rho2*(1+tanSTheta2)); 2634 *n = G4ThreeVector( xi/rhoSecTheta, yi/rhoSecTheta, 2635 -tanSTheta/std::sqrt(1+tanSTheta2)); 2636 } 2637 else 2638 { 2639 *n = G4ThreeVector(0.,0.,1.); 2640 } 2926 2641 *validNorm=true; 2927 2642 } 2928 else *validNorm=false;// Concave STheta cone2643 else { *validNorm=false; } // Concave STheta cone 2929 2644 break; 2930 2645 2931 2646 case kETheta: 2932 if( ( fSTheta + fDTheta )== halfpi )2647 if( eTheta == halfpi ) 2933 2648 { 2934 2649 *n = G4ThreeVector(0.,0.,-1.); 2935 2650 *validNorm = true; 2936 2651 } 2937 else if ( ( fSTheta + fDTheta ) < halfpi)2652 else if ( eTheta < halfpi ) 2938 2653 { 2939 2654 xi=p.x()+snxt*v.x(); 2940 2655 yi=p.y()+snxt*v.y(); 2941 rhoSecTheta = std::sqrt((xi*xi+yi*yi)*(1+tanETheta2)); 2942 *n = G4ThreeVector( xi/rhoSecTheta, // N+ 2943 yi/rhoSecTheta, 2944 -tanETheta/std::sqrt(1+tanETheta2) ); 2656 rho2=xi*xi+yi*yi; 2657 if (rho2) 2658 { 2659 rhoSecTheta = std::sqrt(rho2*(1+tanETheta2)); 2660 *n = G4ThreeVector( xi/rhoSecTheta, yi/rhoSecTheta, 2661 -tanETheta/std::sqrt(1+tanETheta2) ); 2662 } 2663 else 2664 { 2665 *n = G4ThreeVector(0.,0.,-1.); 2666 } 2945 2667 *validNorm=true; 2946 2668 } 2947 else *validNorm=false;// Concave ETheta cone2669 else { *validNorm=false; } // Concave ETheta cone 2948 2670 break; 2949 2671 … … 2995 2717 ///////////////////////////////////////////////////////////////////////// 2996 2718 // 2997 // Calc luate distance (<=actual) to closest surface of shape from inside2719 // Calculate distance (<=actual) to closest surface of shape from inside 2998 2720 2999 2721 G4double G4Sphere::DistanceToOut( const G4ThreeVector& p ) const 3000 2722 { 3001 2723 G4double safe=0.0,safeRMin,safeRMax,safePhi,safeTheta; 3002 G4double rho2,rad,rho; 3003 G4double phiC,cosPhiC,sinPhiC,ePhi; 2724 G4double rho2,rds,rho; 3004 2725 G4double pTheta,dTheta1,dTheta2; 3005 2726 rho2=p.x()*p.x()+p.y()*p.y(); 3006 r ad=std::sqrt(rho2+p.z()*p.z());2727 rds=std::sqrt(rho2+p.z()*p.z()); 3007 2728 rho=std::sqrt(rho2); 3008 2729 … … 3027 2748 if (fRmin) 3028 2749 { 3029 safeRMin=r ad-fRmin;3030 safeRMax=fRmax-r ad;2750 safeRMin=rds-fRmin; 2751 safeRMax=fRmax-rds; 3031 2752 if (safeRMin<safeRMax) 3032 2753 { … … 3040 2761 else 3041 2762 { 3042 safe=fRmax-r ad;2763 safe=fRmax-rds; 3043 2764 } 3044 2765 … … 3046 2767 // Distance to phi extent 3047 2768 // 3048 if (fDPhi<twopi && rho) 3049 { 3050 phiC=fSPhi+fDPhi*0.5; 3051 cosPhiC=std::cos(phiC); 3052 sinPhiC=std::sin(phiC); 3053 if ((p.y()*cosPhiC-p.x()*sinPhiC)<=0) 3054 { 3055 safePhi=-(p.x()*std::sin(fSPhi)-p.y()*std::cos(fSPhi)); 2769 if (!fFullPhiSphere && rho) 2770 { 2771 if ((p.y()*cosCPhi-p.x()*sinCPhi)<=0) 2772 { 2773 safePhi=-(p.x()*sinSPhi-p.y()*cosSPhi); 3056 2774 } 3057 2775 else 3058 2776 { 3059 ePhi=fSPhi+fDPhi; 3060 safePhi=(p.x()*std::sin(ePhi)-p.y()*std::cos(ePhi)); 3061 } 3062 if (safePhi<safe) safe=safePhi; 2777 safePhi=(p.x()*sinEPhi-p.y()*cosEPhi); 2778 } 2779 if (safePhi<safe) { safe=safePhi; } 3063 2780 } 3064 2781 … … 3066 2783 // Distance to Theta extent 3067 2784 // 3068 if (r ad)3069 { 3070 pTheta=std::acos(p.z()/r ad);3071 if (pTheta<0) pTheta+=pi;2785 if (rds) 2786 { 2787 pTheta=std::acos(p.z()/rds); 2788 if (pTheta<0) { pTheta+=pi; } 3072 2789 dTheta1=pTheta-fSTheta; 3073 dTheta2=(fSTheta+fDTheta)-pTheta; 3074 if (dTheta1<dTheta2) 3075 { 3076 safeTheta=rad*std::sin(dTheta1); 3077 if (safe>safeTheta) 3078 { 3079 safe=safeTheta; 3080 } 3081 } 3082 else 3083 { 3084 safeTheta=rad*std::sin(dTheta2); 3085 if (safe>safeTheta) 3086 { 3087 safe=safeTheta; 3088 } 3089 } 3090 } 3091 3092 if (safe<0) safe=0; 3093 return safe; 2790 dTheta2=eTheta-pTheta; 2791 if (dTheta1<dTheta2) { safeTheta=rds*std::sin(dTheta1); } 2792 else { safeTheta=rds*std::sin(dTheta2); } 2793 if (safe>safeTheta) { safe=safeTheta; } 2794 } 2795 2796 if (safe<0) { safe=0; } 2797 return safe; 3094 2798 } 3095 2799 … … 3119 2823 // Phi cross sections 3120 2824 3121 noPhiCrossSections =G4int(fDPhi/kMeshAngleDefault)+1;2825 noPhiCrossSections = G4int(fDPhi/kMeshAngleDefault)+1; 3122 2826 3123 2827 if (noPhiCrossSections<kMinMeshSections) … … 3134 2838 // on the x axis. Will give better extent calculations when not rotated. 3135 2839 3136 if (f DPhi==pi*2.0 && fSPhi==0)2840 if (fFullPhiSphere) 3137 2841 { 3138 2842 sAnglePhi = -meshAnglePhi*0.5; … … 3160 2864 // on the z axis. Will give better extent calculations when not rotated. 3161 2865 3162 if (f DTheta==pi && fSTheta==0)2866 if (fFullThetaSphere) 3163 2867 { 3164 2868 startTheta = -meshTheta*0.5; … … 3223 2927 } 3224 2928 3225 delete [] cosCrossTheta;3226 delete [] sinCrossTheta;2929 delete [] cosCrossTheta; 2930 delete [] sinCrossTheta; 3227 2931 3228 2932 return vertices; … … 3269 2973 G4double height1, height2, slant1, slant2, costheta, sintheta,theta,rRand; 3270 2974 3271 height1 = (fRmax-fRmin)*std::cos(fSTheta); 3272 height2 = (fRmax-fRmin)*std::cos(fSTheta+fDTheta); 3273 slant1 = std::sqrt(sqr((fRmax - fRmin)*std::sin(fSTheta)) 3274 + height1*height1); 3275 slant2 = std::sqrt(sqr((fRmax - fRmin)*std::sin(fSTheta+fDTheta)) 3276 + height2*height2); 2975 height1 = (fRmax-fRmin)*cosSTheta; 2976 height2 = (fRmax-fRmin)*cosETheta; 2977 slant1 = std::sqrt(sqr((fRmax - fRmin)*sinSTheta) + height1*height1); 2978 slant2 = std::sqrt(sqr((fRmax - fRmin)*sinETheta) + height2*height2); 3277 2979 rRand = RandFlat::shoot(fRmin,fRmax); 3278 2980 3279 aOne = fRmax*fRmax*fDPhi*( std::cos(fSTheta)-std::cos(fSTheta+fDTheta));3280 aTwo = fRmin*fRmin*fDPhi*( std::cos(fSTheta)-std::cos(fSTheta+fDTheta));3281 aThr = fDPhi*((fRmax + fRmin)*s td::sin(fSTheta))*slant1;3282 aFou = fDPhi*((fRmax + fRmin)*s td::sin(fSTheta+fDTheta))*slant2;2981 aOne = fRmax*fRmax*fDPhi*(cosSTheta-cosETheta); 2982 aTwo = fRmin*fRmin*fDPhi*(cosSTheta-cosETheta); 2983 aThr = fDPhi*((fRmax + fRmin)*sinSTheta)*slant1; 2984 aFou = fDPhi*((fRmax + fRmin)*sinETheta)*slant2; 3283 2985 aFiv = 0.5*fDTheta*(fRmax*fRmax-fRmin*fRmin); 3284 2986 3285 phi = RandFlat::shoot(fSPhi, fSPhi + fDPhi);2987 phi = RandFlat::shoot(fSPhi, ePhi); 3286 2988 cosphi = std::cos(phi); 3287 2989 sinphi = std::sin(phi); 3288 theta = RandFlat::shoot(fSTheta, fSTheta+fDTheta);2990 theta = RandFlat::shoot(fSTheta,eTheta); 3289 2991 costheta = std::cos(theta); 3290 2992 sintheta = std::sqrt(1.-sqr(costheta)); 3291 2993 3292 if( ((fSPhi==0) && (fDPhi==2.*pi)) || (fDPhi==2.*pi) ) {aFiv = 0;}3293 if(fSTheta == 0) {aThr=0;}3294 if( fDTheta + fSTheta == pi) {aFou = 0;}3295 if(fSTheta == 0.5*pi) {aThr = pi*(fRmax*fRmax-fRmin*fRmin);}3296 if( fSTheta + fDTheta == 0.5*pi) { aFou = pi*(fRmax*fRmax-fRmin*fRmin);}2994 if(fFullPhiSphere) { aFiv = 0; } 2995 if(fSTheta == 0) { aThr=0; } 2996 if(eTheta == pi) { aFou = 0; } 2997 if(fSTheta == halfpi) { aThr = pi*(fRmax*fRmax-fRmin*fRmin); } 2998 if(eTheta == halfpi) { aFou = pi*(fRmax*fRmax-fRmin*fRmin); } 3297 2999 3298 3000 chose = RandFlat::shoot(0.,aOne+aTwo+aThr+aFou+2.*aFiv); … … 3309 3011 else if( (chose>=aOne+aTwo) && (chose<aOne+aTwo+aThr) ) 3310 3012 { 3311 if (fSTheta != 0.5*pi)3312 { 3313 zRand = RandFlat::shoot(fRmin* std::cos(fSTheta),fRmax*std::cos(fSTheta));3314 return G4ThreeVector( std::tan(fSTheta)*zRand*cosphi,3315 std::tan(fSTheta)*zRand*sinphi,zRand);3013 if (fSTheta != halfpi) 3014 { 3015 zRand = RandFlat::shoot(fRmin*cosSTheta,fRmax*cosSTheta); 3016 return G4ThreeVector(tanSTheta*zRand*cosphi, 3017 tanSTheta*zRand*sinphi,zRand); 3316 3018 } 3317 3019 else … … 3322 3024 else if( (chose>=aOne+aTwo+aThr) && (chose<aOne+aTwo+aThr+aFou) ) 3323 3025 { 3324 if(fSTheta + fDTheta != 0.5*pi) 3325 { 3326 zRand = RandFlat::shoot(fRmin*std::cos(fSTheta+fDTheta), 3327 fRmax*std::cos(fSTheta+fDTheta)); 3328 return G4ThreeVector (std::tan(fSTheta+fDTheta)*zRand*cosphi, 3329 std::tan(fSTheta+fDTheta)*zRand*sinphi,zRand); 3026 if(eTheta != halfpi) 3027 { 3028 zRand = RandFlat::shoot(fRmin*cosETheta, fRmax*cosETheta); 3029 return G4ThreeVector (tanETheta*zRand*cosphi, 3030 tanETheta*zRand*sinphi,zRand); 3330 3031 } 3331 3032 else … … 3336 3037 else if( (chose>=aOne+aTwo+aThr+aFou) && (chose<aOne+aTwo+aThr+aFou+aFiv) ) 3337 3038 { 3338 return G4ThreeVector(rRand*sintheta* std::cos(fSPhi),3339 rRand*sintheta*s td::sin(fSPhi),rRand*costheta);3039 return G4ThreeVector(rRand*sintheta*cosSPhi, 3040 rRand*sintheta*sinSPhi,rRand*costheta); 3340 3041 } 3341 3042 else 3342 3043 { 3343 return G4ThreeVector(rRand*sintheta*std::cos(fSPhi+fDPhi), 3344 rRand*sintheta*std::sin(fSPhi+fDPhi),rRand*costheta); 3345 } 3044 return G4ThreeVector(rRand*sintheta*cosEPhi, 3045 rRand*sintheta*sinEPhi,rRand*costheta); 3046 } 3047 } 3048 3049 //////////////////////////////////////////////////////////////////////////////// 3050 // 3051 // GetSurfaceArea 3052 3053 G4double G4Sphere::GetSurfaceArea() 3054 { 3055 if(fSurfaceArea != 0.) {;} 3056 else 3057 { 3058 G4double Rsq=fRmax*fRmax; 3059 G4double rsq=fRmin*fRmin; 3060 3061 fSurfaceArea = fDPhi*(rsq+Rsq)*(cosSTheta - cosETheta); 3062 if(!fFullPhiSphere) 3063 { 3064 fSurfaceArea = fSurfaceArea + fDTheta*(Rsq-rsq); 3065 } 3066 if(fSTheta >0) 3067 { 3068 G4double acos1=std::acos( std::pow(sinSTheta,2) * std::cos(fDPhi) 3069 + std::pow(cosSTheta,2)); 3070 if(fDPhi>pi) 3071 { 3072 fSurfaceArea = fSurfaceArea + 0.5*(Rsq-rsq)*(twopi-acos1); 3073 } 3074 else 3075 { 3076 fSurfaceArea = fSurfaceArea + 0.5*(Rsq-rsq)*acos1; 3077 } 3078 } 3079 if(eTheta < pi) 3080 { 3081 G4double acos2=std::acos( std::pow(sinETheta,2) * std::cos(fDPhi) 3082 + std::pow(cosETheta,2)); 3083 if(fDPhi>pi) 3084 { 3085 fSurfaceArea = fSurfaceArea + 0.5*(Rsq-rsq)*(twopi-acos2); 3086 } 3087 else 3088 { 3089 fSurfaceArea = fSurfaceArea + 0.5*(Rsq-rsq)*acos2; 3090 } 3091 } 3092 } 3093 return fSurfaceArea; 3346 3094 } 3347 3095 -
trunk/source/geometry/solids/CSG/src/G4Torus.cc
r1058 r1228 25 25 // 26 26 // 27 // $Id: G4Torus.cc,v 1.6 3 2007/10/02 09:34:17gcosmo Exp $28 // GEANT4 tag $Name: geant4-09-0 2-ref-02$27 // $Id: G4Torus.cc,v 1.65 2009/11/26 10:31:06 gcosmo Exp $ 28 // GEANT4 tag $Name: geant4-09-03 $ 29 29 // 30 30 // … … 284 284 285 285 G4double theta = std::atan2(ptmp.y(),ptmp.x()); 286 287 if (theta < 0) { theta += twopi; }288 286 287 if ( fSPhi >= 0 ) 288 { 289 if ( theta < - kAngTolerance*0.5 ) { theta += twopi; } 290 if ( (std::abs(theta) < kAngTolerance*0.5) 291 && (std::abs(fSPhi + fDPhi - twopi) < kAngTolerance*0.5) ) 292 { 293 theta += twopi ; // 0 <= theta < 2pi 294 } 295 } 296 if ((fSPhi <= -pi )&&(theta>kAngTolerance*0.5)) { theta = theta-twopi; } 297 289 298 // We have to verify if this root is inside the region between 290 299 // fSPhi and fSPhi + fDPhi -
trunk/source/geometry/solids/CSG/src/G4Trap.cc
r1058 r1228 26 26 // 27 27 // $Id: G4Trap.cc,v 1.45 2008/04/23 09:49:57 gcosmo Exp $ 28 // GEANT4 tag $Name: geant4-09-0 2-ref-02$28 // GEANT4 tag $Name: geant4-09-03 $ 29 29 // 30 30 // class G4Trap -
trunk/source/geometry/solids/CSG/src/G4Trd.cc
r1058 r1228 26 26 // 27 27 // $Id: G4Trd.cc,v 1.34 2006/10/19 15:33:38 gcosmo Exp $ 28 // GEANT4 tag $Name: geant4-09-0 2-ref-02$28 // GEANT4 tag $Name: geant4-09-03 $ 29 29 // 30 30 // -
trunk/source/geometry/solids/CSG/src/G4Tubs.cc
r1058 r1228 25 25 // 26 26 // 27 // $Id: G4Tubs.cc,v 1.7 4 2008/11/06 15:26:53gcosmo Exp $28 // GEANT4 tag $Name: geant4-09-0 2-ref-02$27 // $Id: G4Tubs.cc,v 1.79 2009/06/30 10:10:11 gcosmo Exp $ 28 // GEANT4 tag $Name: geant4-09-03 $ 29 29 // 30 30 // … … 90 90 G4double pDz, 91 91 G4double pSPhi, G4double pDPhi ) 92 : G4CSGSolid(pName) 92 : G4CSGSolid(pName), fSPhi(0), fDPhi(0) 93 93 { 94 94 … … 102 102 else 103 103 { 104 G4cerr << "ERROR - G4Tubs()::G4Tubs() : " << GetName()<< G4endl105 << " Negative Z half-length ! -"106 << pDz<< G4endl;104 G4cerr << "ERROR - G4Tubs()::G4Tubs()" << G4endl 105 << " Negative Z half-length (" << pDz << ") in solid: " 106 << GetName() << G4endl; 107 107 G4Exception("G4Tubs::G4Tubs()", "InvalidSetup", FatalException, 108 108 "Invalid Z half-length"); … … 115 115 else 116 116 { 117 G4cerr << "ERROR - G4Tubs()::G4Tubs(): " << GetName() << G4endl 118 << " Invalid values for radii !" << G4endl 117 G4cerr << "ERROR - G4Tubs()::G4Tubs()" << G4endl 118 << " Invalid values for radii in solid " << GetName() 119 << G4endl 119 120 << " pRMin = " << pRMin << ", pRMax = " << pRMax << G4endl; 120 121 G4Exception("G4Tubs::G4Tubs()", "InvalidSetup", FatalException, … … 122 123 } 123 124 124 fPhiFullTube = true; 125 if ( pDPhi >= twopi-kAngTolerance*0.5 ) // Check angles 126 { 127 fDPhi=twopi; 128 fSPhi=0; 129 } 130 else 131 { 132 fPhiFullTube = false; 133 if ( pDPhi > 0 ) 134 { 135 fDPhi = pDPhi; 136 } 137 else 138 { 139 G4cerr << "ERROR - G4Tubs()::G4Tubs(): " << GetName() << G4endl 140 << " Negative delta-Phi ! - " 141 << pDPhi << G4endl; 142 G4Exception("G4Tubs::G4Tubs()", "InvalidSetup", 143 FatalException, "Invalid dphi."); 144 } 145 146 // Ensure fSphi in 0-2PI or -2PI-0 range if shape crosses 0 147 148 if ( pSPhi < 0 ) 149 { 150 fSPhi = twopi - std::fmod(std::fabs(pSPhi),twopi); 151 } 152 else 153 { 154 fSPhi = std::fmod(pSPhi,twopi) ; 155 } 156 if ( fSPhi+fDPhi > twopi ) 157 { 158 fSPhi -= twopi ; 159 } 160 } 161 InitializeTrigonometry(); 125 // Check angles 126 127 CheckPhiAngles(pSPhi, pDPhi); 162 128 } 163 129 … … 203 169 { 204 170 205 if ( !pTransform.IsRotated() && fDPhi == twopi && fRMin == 0)171 if ( (!pTransform.IsRotated()) && (fDPhi == twopi) && (fRMin == 0) ) 206 172 { 207 173 // Special case handling for unrotated solid tubes … … 210 176 // and compute exact x and y limit for x/y case 211 177 212 G4double xoffset, xMin, xMax 213 G4double yoffset, yMin, yMax 214 G4double zoffset, zMin, zMax 215 216 G4double diff1, diff2, maxDiff, newMin, newMax 217 G4double xoff1, xoff2, yoff1, yoff2, delta 218 219 xoffset = pTransform.NetTranslation().x() 220 xMin = xoffset - fRMax 221 xMax = xoffset + fRMax 178 G4double xoffset, xMin, xMax; 179 G4double yoffset, yMin, yMax; 180 G4double zoffset, zMin, zMax; 181 182 G4double diff1, diff2, maxDiff, newMin, newMax; 183 G4double xoff1, xoff2, yoff1, yoff2, delta; 184 185 xoffset = pTransform.NetTranslation().x(); 186 xMin = xoffset - fRMax; 187 xMax = xoffset + fRMax; 222 188 223 189 if (pVoxelLimit.IsXLimited()) … … 230 196 else 231 197 { 232 if ( xMin < pVoxelLimit.GetMinXExtent())233 { 234 xMin = pVoxelLimit.GetMinXExtent() 235 } 236 if (xMax > pVoxelLimit.GetMaxXExtent() 237 { 238 xMax = pVoxelLimit.GetMaxXExtent() 239 } 240 } 241 } 242 yoffset = pTransform.NetTranslation().y() 243 yMin = yoffset - fRMax 244 yMax = yoffset + fRMax 198 if (xMin < pVoxelLimit.GetMinXExtent()) 199 { 200 xMin = pVoxelLimit.GetMinXExtent(); 201 } 202 if (xMax > pVoxelLimit.GetMaxXExtent()) 203 { 204 xMax = pVoxelLimit.GetMaxXExtent(); 205 } 206 } 207 } 208 yoffset = pTransform.NetTranslation().y(); 209 yMin = yoffset - fRMax; 210 yMax = yoffset + fRMax; 245 211 246 212 if ( pVoxelLimit.IsYLimited() ) … … 249 215 || (yMax < pVoxelLimit.GetMinYExtent()) ) 250 216 { 251 return false 217 return false; 252 218 } 253 219 else 254 220 { 255 if ( yMin < pVoxelLimit.GetMinYExtent())256 { 257 yMin = pVoxelLimit.GetMinYExtent() 258 } 259 if ( yMax > pVoxelLimit.GetMaxYExtent())221 if (yMin < pVoxelLimit.GetMinYExtent()) 222 { 223 yMin = pVoxelLimit.GetMinYExtent(); 224 } 225 if (yMax > pVoxelLimit.GetMaxYExtent()) 260 226 { 261 227 yMax=pVoxelLimit.GetMaxYExtent(); … … 263 229 } 264 230 } 265 zoffset = pTransform.NetTranslation().z() 266 zMin = zoffset - fDz 267 zMax = zoffset + fDz 231 zoffset = pTransform.NetTranslation().z(); 232 zMin = zoffset - fDz; 233 zMax = zoffset + fDz; 268 234 269 235 if ( pVoxelLimit.IsZLimited() ) … … 272 238 || (zMax < pVoxelLimit.GetMinZExtent()) ) 273 239 { 274 return false 240 return false; 275 241 } 276 242 else 277 243 { 278 if ( zMin < pVoxelLimit.GetMinZExtent())279 { 280 zMin = pVoxelLimit.GetMinZExtent() 281 } 282 if ( zMax > pVoxelLimit.GetMaxZExtent())244 if (zMin < pVoxelLimit.GetMinZExtent()) 245 { 246 zMin = pVoxelLimit.GetMinZExtent(); 247 } 248 if (zMax > pVoxelLimit.GetMaxZExtent()) 283 249 { 284 250 zMax = pVoxelLimit.GetMaxZExtent(); … … 290 256 case kXAxis : 291 257 { 292 yoff1 = yoffset - yMin 293 yoff2 = yMax - yoffset 258 yoff1 = yoffset - yMin; 259 yoff2 = yMax - yoffset; 294 260 295 261 if ( (yoff1 >= 0) && (yoff2 >= 0) ) // Y limits cross max/min x 296 262 { // => no change 297 pMin = xMin 298 pMax = xMax 263 pMin = xMin; 264 pMax = xMax; 299 265 } 300 266 else … … 317 283 case kYAxis : 318 284 { 319 xoff1 = xoffset - xMin 320 xoff2 = xMax - xoffset 285 xoff1 = xoffset - xMin; 286 xoff2 = xMax - xoffset; 321 287 322 288 if ( (xoff1 >= 0) && (xoff2 >= 0) ) // X limits cross max/min y 323 289 { // => no change 324 pMin = yMin 325 pMax = yMax 290 pMin = yMin; 291 pMax = yMax; 326 292 } 327 293 else … … 334 300 delta = fRMax*fRMax - xoff2*xoff2; 335 301 diff2 = (delta>0.) ? std::sqrt(delta) : 0.; 336 maxDiff = (diff1 > diff2) ? diff1 : diff2 337 newMin = yoffset - maxDiff 338 newMax = yoffset + maxDiff 339 pMin = (newMin < yMin) ? yMin : newMin 340 pMax =(newMax > yMax) ? yMax : newMax;341 } 342 break 302 maxDiff = (diff1 > diff2) ? diff1 : diff2; 303 newMin = yoffset - maxDiff; 304 newMax = yoffset + maxDiff; 305 pMin = (newMin < yMin) ? yMin : newMin; 306 pMax = (newMax > yMax) ? yMax : newMax; 307 } 308 break; 343 309 } 344 310 case kZAxis: 345 311 { 346 pMin = zMin 347 pMax = zMax 348 break 312 pMin = zMin; 313 pMax = zMax; 314 break; 349 315 } 350 316 default: 351 317 break; 352 318 } 353 pMin -= kCarTolerance 354 pMax += kCarTolerance 355 return true; 319 pMin -= kCarTolerance; 320 pMax += kCarTolerance; 321 return true; 356 322 } 357 323 else // Calculate rotated vertex coordinates 358 324 { 359 G4int i, noEntries, noBetweenSections4 ; 360 G4bool existsAfterClip = false ; 361 G4ThreeVectorList* vertices = CreateRotatedVertices(pTransform) ; 325 G4int i, noEntries, noBetweenSections4; 326 G4bool existsAfterClip = false; 327 G4ThreeVectorList* vertices = CreateRotatedVertices(pTransform); 328 329 pMin = kInfinity; 330 pMax = -kInfinity; 331 332 noEntries = vertices->size(); 333 noBetweenSections4 = noEntries - 4; 362 334 363 pMin = +kInfinity ; 364 pMax = -kInfinity ; 365 366 noEntries = vertices->size() ; 367 noBetweenSections4 = noEntries - 4 ; 368 369 for (i = 0 ; i < noEntries ; i += 4 ) 370 { 371 ClipCrossSection(vertices, i, pVoxelLimit, pAxis, pMin, pMax) ; 372 } 373 for (i = 0 ; i < noBetweenSections4 ; i += 4 ) 374 { 375 ClipBetweenSections(vertices, i, pVoxelLimit, pAxis, pMin, pMax) ; 376 } 377 if ((pMin != kInfinity) || (pMax != -kInfinity) ) 378 { 379 existsAfterClip = true ; 380 pMin -= kCarTolerance ; // Add 2*tolerance to avoid precision troubles 381 pMax += kCarTolerance ; 335 for ( i = 0 ; i < noEntries ; i += 4 ) 336 { 337 ClipCrossSection(vertices, i, pVoxelLimit, pAxis, pMin, pMax); 338 } 339 for ( i = 0 ; i < noBetweenSections4 ; i += 4 ) 340 { 341 ClipBetweenSections(vertices, i, pVoxelLimit, pAxis, pMin, pMax); 342 } 343 if ( (pMin != kInfinity) || (pMax != -kInfinity) ) 344 { 345 existsAfterClip = true; 346 pMin -= kCarTolerance; // Add 2*tolerance to avoid precision troubles 347 pMax += kCarTolerance; 382 348 } 383 349 else … … 391 357 (pVoxelLimit.GetMinXExtent()+pVoxelLimit.GetMaxXExtent())*0.5, 392 358 (pVoxelLimit.GetMinYExtent()+pVoxelLimit.GetMaxYExtent())*0.5, 393 (pVoxelLimit.GetMinZExtent()+pVoxelLimit.GetMaxZExtent())*0.5 ) 359 (pVoxelLimit.GetMinZExtent()+pVoxelLimit.GetMaxZExtent())*0.5 ); 394 360 395 361 if ( Inside(pTransform.Inverse().TransformPoint(clipCentre)) != kOutside ) 396 362 { 397 existsAfterClip = true 398 pMin = pVoxelLimit.GetMinExtent(pAxis) 399 pMax = pVoxelLimit.GetMaxExtent(pAxis) 363 existsAfterClip = true; 364 pMin = pVoxelLimit.GetMinExtent(pAxis); 365 pMax = pVoxelLimit.GetMaxExtent(pAxis); 400 366 } 401 367 } … … 808 774 G4double tolORMin2, tolIRMax2 ; // 'generous' radii squared 809 775 G4double tolORMax2, tolIRMin2, tolODz, tolIDz ; 776 const G4double dRmax = 100.*fRMax; 810 777 811 778 static const G4double halfCarTolerance = 0.5*kCarTolerance; … … 908 875 if (s >= 0) // If 'forwards' 909 876 { 877 if ( s>dRmax ) // Avoid rounding errors due to precision issues on 878 { // 64 bits systems. Split long distances and recompute 879 G4double fTerm = s-std::fmod(s,dRmax); 880 s = fTerm + DistanceToIn(p+fTerm*v,v); 881 } 910 882 // Check z intersection 911 883 // … … 1022 994 // 1023 995 if(s < 0.0) { s = 0.0; } 996 if ( s>dRmax ) // Avoid rounding errors due to precision issues seen 997 { // 64 bits systems. Split long distances and recompute 998 G4double fTerm = s-std::fmod(s,dRmax); 999 s = fTerm + DistanceToIn(p+fTerm*v,v); 1000 } 1024 1001 zi = p.z() + s*v.z() ; 1025 1002 if (std::fabs(zi) <= tolODz)
Note: See TracChangeset
for help on using the changeset viewer.