Changeset 1228 for trunk/source/geometry/solids/CSG/src
- Timestamp:
- Jan 8, 2010, 11:56:51 AM (16 years ago)
- Location:
- trunk/source/geometry/solids/CSG/src
- Files:
-
- 10 edited
-
G4Box.cc (modified) (1 diff)
-
G4CSGSolid.cc (modified) (1 diff)
-
G4Cons.cc (modified) (21 diffs)
-
G4Orb.cc (modified) (10 diffs)
-
G4Para.cc (modified) (1 diff)
-
G4Sphere.cc (modified) (126 diffs)
-
G4Torus.cc (modified) (2 diffs)
-
G4Trap.cc (modified) (1 diff)
-
G4Trd.cc (modified) (1 diff)
-
G4Tubs.cc (modified) (18 diffs)
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 nTs = G4ThreeVector(0.,0.,-1.);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 nTe = G4ThreeVector(0.,0.,1.);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 else1289 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)) ) // leaving outside from Rmax2069 // not re-entering1916 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 return snxt = 0 ;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 return snxt = 0.;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 rhoSecTheta = std::sqrt(rho2*(1+tanSTheta2));2065 rhoSecTheta = std::sqrt(rho2*(1+tanSTheta2)); 2397 2066 2398 *n = G4ThreeVector( p.x()/rhoSecTheta,2399 p.y()/rhoSecTheta,2400 std::sin(fSTheta) );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 return snxt = 0.;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 return snxt = 0.;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.
