Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // Implementation of G4IntersectingCone, a uti << 27 // the intersection of an arbitrary line with << 28 // 26 // 29 // Author: David C. Williams (davidw@scipp.ucs << 27 // $Id: G4IntersectingCone.cc 72937 2013-08-14 13:20:38Z gcosmo $ >> 28 // >> 29 // >> 30 // -------------------------------------------------------------------- >> 31 // GEANT 4 class source file >> 32 // >> 33 // >> 34 // G4IntersectingCone.cc >> 35 // >> 36 // Implementation of a utility class which calculates the intersection >> 37 // of an arbitrary line with a fixed cone 30 // ------------------------------------------- 38 // -------------------------------------------------------------------- 31 39 32 #include "G4IntersectingCone.hh" 40 #include "G4IntersectingCone.hh" 33 #include "G4GeometryTolerance.hh" 41 #include "G4GeometryTolerance.hh" 34 42 >> 43 // 35 // Constructor 44 // Constructor 36 // 45 // 37 G4IntersectingCone::G4IntersectingCone( const 46 G4IntersectingCone::G4IntersectingCone( const G4double r[2], 38 const 47 const G4double z[2] ) 39 { << 48 { 40 const G4double halfCarTolerance 49 const G4double halfCarTolerance 41 = 0.5 * G4GeometryTolerance::GetInstance() 50 = 0.5 * G4GeometryTolerance::GetInstance()->GetSurfaceTolerance(); 42 51 >> 52 // 43 // What type of cone are we? 53 // What type of cone are we? 44 // 54 // 45 type1 = (std::abs(z[1]-z[0]) > std::abs(r[1] << 55 type1 = (std::fabs(z[1]-z[0]) > std::fabs(r[1]-r[0])); 46 << 56 47 if (type1) // tube like << 57 if (type1) 48 { 58 { 49 B = (r[1] - r[0]) / (z[1] - z[0]); << 59 B = (r[1]-r[0])/(z[1]-z[0]); // tube like 50 A = (r[0]*z[1] - r[1]*z[0]) / (z[1] -z[0]) << 60 A = 0.5*( r[1]+r[0] - B*(z[1]+z[0]) ); 51 } 61 } 52 else // disk like << 62 else 53 { 63 { 54 B = (z[1] - z[0]) / (r[1] - r[0]); << 64 B = (z[1]-z[0])/(r[1]-r[0]); // disk like 55 A = (z[0]*r[1] - z[1]*r[0]) / (r[1] - r[0] << 65 A = 0.5*( z[1]+z[0] - B*(r[1]+r[0]) ); 56 } 66 } 57 << 67 // 58 // Calculate extent 68 // Calculate extent 59 // 69 // 60 rLo = std::min(r[0], r[1]) - halfCarToleranc << 70 if (r[0] < r[1]) 61 rHi = std::max(r[0], r[1]) + halfCarToleranc << 71 { 62 zLo = std::min(z[0], z[1]) - halfCarToleranc << 72 rLo = r[0]-halfCarTolerance; rHi = r[1]+halfCarTolerance; 63 zHi = std::max(z[0], z[1]) + halfCarToleranc << 73 } >> 74 else >> 75 { >> 76 rLo = r[1]-halfCarTolerance; rHi = r[0]+halfCarTolerance; >> 77 } >> 78 >> 79 if (z[0] < z[1]) >> 80 { >> 81 zLo = z[0]-halfCarTolerance; zHi = z[1]+halfCarTolerance; >> 82 } >> 83 else >> 84 { >> 85 zLo = z[1]-halfCarTolerance; zHi = z[0]+halfCarTolerance; >> 86 } 64 } 87 } 65 88 >> 89 >> 90 // 66 // Fake default constructor - sets only member 91 // Fake default constructor - sets only member data and allocates memory 67 // for usage restri 92 // for usage restricted to object persistency. 68 // 93 // 69 G4IntersectingCone::G4IntersectingCone( __void 94 G4IntersectingCone::G4IntersectingCone( __void__& ) 70 : zLo(0.), zHi(0.), rLo(0.), rHi(0.), A(0.), << 95 : zLo(0.), zHi(0.), rLo(0.), rHi(0.), type1(false), A(0.), B(0.) 71 { 96 { 72 } 97 } 73 98 >> 99 >> 100 // 74 // Destructor 101 // Destructor 75 // 102 // 76 G4IntersectingCone::~G4IntersectingCone() = de << 103 G4IntersectingCone::~G4IntersectingCone() >> 104 { >> 105 } >> 106 77 107 >> 108 // 78 // HitOn 109 // HitOn 79 // 110 // 80 // Check r or z extent, as appropriate, to see 111 // Check r or z extent, as appropriate, to see if the point is possibly 81 // on the cone. 112 // on the cone. 82 // 113 // 83 G4bool G4IntersectingCone::HitOn( const G4doub 114 G4bool G4IntersectingCone::HitOn( const G4double r, 84 const G4doub 115 const G4double z ) 85 { 116 { 86 // 117 // 87 // Be careful! The inequalities cannot be "< 118 // Be careful! The inequalities cannot be "<=" and ">=" here without 88 // punching a tiny hole in our shape! 119 // punching a tiny hole in our shape! 89 // 120 // 90 if (type1) 121 if (type1) 91 { 122 { 92 if (z < zLo || z > zHi) return false; 123 if (z < zLo || z > zHi) return false; 93 } 124 } 94 else 125 else 95 { 126 { 96 if (r < rLo || r > rHi) return false; 127 if (r < rLo || r > rHi) return false; 97 } 128 } 98 129 99 return true; 130 return true; 100 } 131 } 101 132 >> 133 >> 134 // 102 // LineHitsCone 135 // LineHitsCone 103 // 136 // 104 // Calculate the intersection of a line with o 137 // Calculate the intersection of a line with our conical surface, ignoring 105 // any phi division 138 // any phi division 106 // 139 // 107 G4int G4IntersectingCone::LineHitsCone( const << 140 G4int G4IntersectingCone::LineHitsCone( const G4ThreeVector &p, 108 const << 141 const G4ThreeVector &v, 109 << 142 G4double *s1, G4double *s2 ) 110 { 143 { 111 if (type1) 144 if (type1) 112 { 145 { 113 return LineHitsCone1( p, v, s1, s2 ); 146 return LineHitsCone1( p, v, s1, s2 ); 114 } 147 } 115 else 148 else 116 { 149 { 117 return LineHitsCone2( p, v, s1, s2 ); 150 return LineHitsCone2( p, v, s1, s2 ); 118 } 151 } 119 } 152 } 120 153 >> 154 >> 155 // 121 // LineHitsCone1 156 // LineHitsCone1 122 // 157 // 123 // Calculate the intersections of a line with 158 // Calculate the intersections of a line with a conical surface. Only 124 // suitable if zPlane[0] != zPlane[1]. 159 // suitable if zPlane[0] != zPlane[1]. 125 // 160 // 126 // Equation of a line: 161 // Equation of a line: 127 // 162 // 128 // x = x0 + s*tx y = y0 + s*ty 163 // x = x0 + s*tx y = y0 + s*ty z = z0 + s*tz 129 // 164 // 130 // Equation of a conical surface: 165 // Equation of a conical surface: 131 // 166 // 132 // x**2 + y**2 = (A + B*z)**2 167 // x**2 + y**2 = (A + B*z)**2 133 // 168 // 134 // Solution is quadratic: 169 // Solution is quadratic: 135 // 170 // 136 // a*s**2 + b*s + c = 0 171 // a*s**2 + b*s + c = 0 137 // 172 // 138 // where: 173 // where: 139 // 174 // 140 // a = tx**2 + ty**2 - (B*tz)**2 << 175 // a = x0**2 + y0**2 - (A + B*z0)**2 141 // 176 // 142 // b = 2*( px*vx + py*vy - B*(A + B*pz)*vz ) << 177 // b = 2*( x0*tx + y0*ty - (A*B - B*B*z0)*tz) 143 // 178 // 144 // c = x0**2 + y0**2 - (A + B*z0)**2 << 179 // c = tx**2 + ty**2 - (B*tz)**2 145 // 180 // 146 // Notice, that if a < 0, this indicates that 181 // Notice, that if a < 0, this indicates that the two solutions (assuming 147 // they exist) are in opposite cones (that is, 182 // they exist) are in opposite cones (that is, given z0 = -A/B, one z < z0 148 // and the other z > z0). For our shapes, the 183 // and the other z > z0). For our shapes, the invalid solution is one 149 // which produces A + Bz < 0, or the one where 184 // which produces A + Bz < 0, or the one where Bz is smallest (most negative). 150 // Since Bz = B*s*tz, if B*tz > 0, we want the 185 // Since Bz = B*s*tz, if B*tz > 0, we want the largest s, otherwise, 151 // the smaller. 186 // the smaller. 152 // 187 // 153 // If there are two solutions on one side of t 188 // If there are two solutions on one side of the cone, we want to make 154 // sure that they are on the "correct" side, t 189 // sure that they are on the "correct" side, that is A + B*z0 + s*B*tz >= 0. 155 // 190 // 156 // If a = 0, we have a linear problem: s = c/b 191 // If a = 0, we have a linear problem: s = c/b, which again gives one solution. 157 // This should be rare. 192 // This should be rare. 158 // 193 // 159 // For b*b - 4*a*c = 0, we also have one solut 194 // For b*b - 4*a*c = 0, we also have one solution, which is almost always 160 // a line just grazing the surface of a the co << 195 // a line just grazing the surface of a the cone, which we want to ignore. 161 // However, there are two other, very rare, po 196 // However, there are two other, very rare, possibilities: 162 // a line intersecting the z axis and either: 197 // a line intersecting the z axis and either: 163 // 1. At the same angle std::atan(B) to 198 // 1. At the same angle std::atan(B) to just miss one side of the cone, or 164 // 2. Intersecting the cone apex (0,0,-A 199 // 2. Intersecting the cone apex (0,0,-A/B) 165 // We *don't* want to miss these! How do we id 200 // We *don't* want to miss these! How do we identify them? Well, since 166 // this case is rare, we can at least swallow 201 // this case is rare, we can at least swallow a little more CPU than we would 167 // normally be comfortable with. Intersection 202 // normally be comfortable with. Intersection with the z axis means 168 // x0*ty - y0*tx = 0. Case (1) means a==0, and 203 // x0*ty - y0*tx = 0. Case (1) means a==0, and we've already dealt with that 169 // above. Case (2) means a < 0. 204 // above. Case (2) means a < 0. 170 // 205 // 171 // Now: x0*tx + y0*ty = 0 in terms of roundoff 206 // Now: x0*tx + y0*ty = 0 in terms of roundoff error. We can write: 172 // Delta = x0*tx + y0*ty 207 // Delta = x0*tx + y0*ty 173 // b = 2*( Delta - B*(A + B*z0)*tz << 208 // b = 2*( Delta - (A*B + B*B*z0)*tz ) 174 // For: 209 // For: 175 // b*b - 4*a*c = epsilon 210 // b*b - 4*a*c = epsilon 176 // where epsilon is small, then: 211 // where epsilon is small, then: 177 // Delta = epsilon/2/B 212 // Delta = epsilon/2/B 178 // << 213 // 179 G4int G4IntersectingCone::LineHitsCone1( const << 214 G4int G4IntersectingCone::LineHitsCone1( const G4ThreeVector &p, 180 const << 215 const G4ThreeVector &v, 181 << 216 G4double *s1, G4double *s2 ) 182 { 217 { 183 static const G4double EPS = DBL_EPSILON; // << 184 // << 185 G4double x0 = p.x(), y0 = p.y(), z0 = p.z(); 218 G4double x0 = p.x(), y0 = p.y(), z0 = p.z(); 186 G4double tx = v.x(), ty = v.y(), tz = v.z(); 219 G4double tx = v.x(), ty = v.y(), tz = v.z(); 187 220 188 // Value of radical can be inaccurate due to << 221 G4double a = tx*tx + ty*ty - sqr(B*tz); 189 // if to calculate the coefficiets a,b,c lik << 222 G4double b = 2*( x0*tx + y0*ty - (A*B + B*B*z0)*tz); 190 // G4double a = tx*tx + ty*ty - sqr(B*tz << 223 G4double c = x0*x0 + y0*y0 - sqr(A + B*z0); 191 // G4double b = 2*( x0*tx + y0*ty - B*(A << 224 192 // G4double c = x0*x0 + y0*y0 - sqr(A + << 225 G4double radical = b*b - 4*a*c; 193 // << 226 194 // For more accurate calculation of radical << 227 if (radical < -1E-6*std::fabs(b)) { return 0; } // No solution 195 // are splitted in two components, radial an << 228 196 // << 229 if (radical < 1E-6*std::fabs(b)) 197 G4double ar = tx*tx + ty*ty; << 198 G4double az = sqr(B*tz); << 199 G4double br = 2*(x0*tx + y0*ty); << 200 G4double bz = 2*B*(A + B*z0)*tz; << 201 G4double cr = x0*x0 + y0*y0; << 202 G4double cz = sqr(A + B*z0); << 203 << 204 // Instead radical = b*b - 4*a*c << 205 G4double arcz = 4*ar*cz; << 206 G4double azcr = 4*az*cr; << 207 G4double radical = (br*br - 4*ar*cr) + ((std << 208 << 209 // Find the coefficients << 210 G4double a = ar - az; << 211 G4double b = br - bz; << 212 G4double c = cr - cz; << 213 << 214 if (radical < -EPS*std::fabs(b)) { return 0 << 215 << 216 if (radical < EPS*std::fabs(b)) << 217 { 230 { 218 // 231 // 219 // The radical is roughly zero: check for 232 // The radical is roughly zero: check for special, very rare, cases 220 // 233 // 221 if (std::fabs(a) > 1/kInfinity) 234 if (std::fabs(a) > 1/kInfinity) 222 { 235 { 223 if(B==0.) { return 0; } 236 if(B==0.) { return 0; } 224 if ( std::fabs(x0*ty - y0*tx) < std::fab << 237 if ( std::fabs(x0*ty - y0*tx) < std::fabs(1E-6/B) ) 225 { 238 { 226 *s1 = -0.5*b/a; 239 *s1 = -0.5*b/a; 227 return 1; 240 return 1; 228 } 241 } 229 return 0; 242 return 0; 230 } 243 } 231 } 244 } 232 else 245 else 233 { 246 { 234 radical = std::sqrt(radical); 247 radical = std::sqrt(radical); 235 } 248 } 236 << 249 237 if (a > 1/kInfinity) 250 if (a > 1/kInfinity) 238 { 251 { 239 G4double sa, sb, q = -0.5*( b + (b < 0 ? - 252 G4double sa, sb, q = -0.5*( b + (b < 0 ? -radical : +radical) ); 240 sa = q/a; 253 sa = q/a; 241 sb = c/q; 254 sb = c/q; 242 if (sa < sb) { *s1 = sa; *s2 = sb; } else 255 if (sa < sb) { *s1 = sa; *s2 = sb; } else { *s1 = sb; *s2 = sa; } 243 if (A + B*(z0+(*s1)*tz) < 0) { return 0; 256 if (A + B*(z0+(*s1)*tz) < 0) { return 0; } 244 return 2; 257 return 2; 245 } 258 } 246 else if (a < -1/kInfinity) 259 else if (a < -1/kInfinity) 247 { 260 { 248 G4double sa, sb, q = -0.5*( b + (b < 0 ? - 261 G4double sa, sb, q = -0.5*( b + (b < 0 ? -radical : +radical) ); 249 sa = q/a; 262 sa = q/a; 250 sb = c/q; 263 sb = c/q; 251 *s1 = (B*tz > 0)^(sa > sb) ? sb : sa; 264 *s1 = (B*tz > 0)^(sa > sb) ? sb : sa; 252 return 1; 265 return 1; 253 } 266 } 254 else if (std::fabs(b) < 1/kInfinity) 267 else if (std::fabs(b) < 1/kInfinity) 255 { 268 { 256 return 0; 269 return 0; 257 } 270 } 258 else 271 else 259 { 272 { 260 *s1 = -c/b; 273 *s1 = -c/b; 261 if (A + B*(z0+(*s1)*tz) < 0) { return 0; 274 if (A + B*(z0+(*s1)*tz) < 0) { return 0; } 262 return 1; 275 return 1; 263 } 276 } 264 } 277 } 265 278 >> 279 >> 280 // 266 // LineHitsCone2 281 // LineHitsCone2 267 // 282 // 268 // See comments under LineHitsCone1. In this r 283 // See comments under LineHitsCone1. In this routine, case2, we have: 269 // 284 // 270 // Z = A + B*R 285 // Z = A + B*R 271 // 286 // 272 // The solution is still quadratic: 287 // The solution is still quadratic: 273 // 288 // 274 // a = tz**2 - B*B*(tx**2 + ty**2) 289 // a = tz**2 - B*B*(tx**2 + ty**2) 275 // 290 // 276 // b = 2*( (z0-A)*tz - B*B*(x0*tx+y0*ty) ) 291 // b = 2*( (z0-A)*tz - B*B*(x0*tx+y0*ty) ) 277 // 292 // 278 // c = ( (z0-A)**2 - B*B*(x0**2 + y0**2) ) 293 // c = ( (z0-A)**2 - B*B*(x0**2 + y0**2) ) 279 // 294 // 280 // The rest is much the same, except some deta 295 // The rest is much the same, except some details. 281 // 296 // 282 // a > 0 now means we intersect only once in t 297 // a > 0 now means we intersect only once in the correct hemisphere. 283 // 298 // 284 // a > 0 ? We only want solution which produce << 299 // a > 0 ? We only want solution which produces R > 0. 285 // since R = (z0+s*tz-A)/B, for tz/B > 0, this 300 // since R = (z0+s*tz-A)/B, for tz/B > 0, this is the largest s 286 // for tz/B < 0, this is the smallest 301 // for tz/B < 0, this is the smallest s 287 // thus, same as in case 1 ( since sign(tz/B) 302 // thus, same as in case 1 ( since sign(tz/B) = sign(tz*B) ) 288 // 303 // 289 G4int G4IntersectingCone::LineHitsCone2( const << 304 G4int G4IntersectingCone::LineHitsCone2( const G4ThreeVector &p, 290 const << 305 const G4ThreeVector &v, 291 << 306 G4double *s1, G4double *s2 ) 292 { 307 { 293 static const G4double EPS = DBL_EPSILON; // << 294 // << 295 G4double x0 = p.x(), y0 = p.y(), z0 = p.z(); 308 G4double x0 = p.x(), y0 = p.y(), z0 = p.z(); 296 G4double tx = v.x(), ty = v.y(), tz = v.z(); 309 G4double tx = v.x(), ty = v.y(), tz = v.z(); 297 << 310 >> 311 298 // Special case which might not be so rare: 312 // Special case which might not be so rare: B = 0 (precisely) 299 // 313 // 300 if (B==0) 314 if (B==0) 301 { 315 { 302 if (std::fabs(tz) < 1/kInfinity) { return 316 if (std::fabs(tz) < 1/kInfinity) { return 0; } 303 << 317 304 *s1 = (A-z0)/tz; 318 *s1 = (A-z0)/tz; 305 return 1; 319 return 1; 306 } 320 } 307 321 308 // Value of radical can be inaccurate due to << 309 // if to calculate the coefficiets a,b,c lik << 310 // G4double a = tz*tz - B2*(tx*tx + ty*ty) << 311 // G4double b = 2*( (z0-A)*tz - B2*(x0*tx << 312 // G4double c = sqr(z0-A) - B2*( x0*x0 + y << 313 // << 314 // For more accurate calculation of radical << 315 // are splitted in two components, radial an << 316 // << 317 G4double B2 = B*B; 322 G4double B2 = B*B; 318 323 319 G4double az = tz*tz; << 324 G4double a = tz*tz - B2*(tx*tx + ty*ty); 320 G4double ar = B2*(tx*tx + ty*ty); << 325 G4double b = 2*( (z0-A)*tz - B2*(x0*tx + y0*ty) ); 321 G4double bz = 2*(z0-A)*tz; << 326 G4double c = sqr(z0-A) - B2*( x0*x0 + y0*y0 ); 322 G4double br = 2*B2*(x0*tx + y0*ty); << 327 323 G4double cz = sqr(z0-A); << 328 G4double radical = b*b - 4*a*c; 324 G4double cr = B2*(x0*x0 + y0*y0); << 329 325 << 330 if (radical < -1E-6*std::fabs(b)) { return 0; } // No solution 326 // Instead radical = b*b - 4*a*c << 331 327 G4double arcz = 4*ar*cz; << 332 if (radical < 1E-6*std::fabs(b)) 328 G4double azcr = 4*az*cr; << 329 G4double radical = (br*br - 4*ar*cr) + ((std << 330 << 331 // Find the coefficients << 332 G4double a = az - ar; << 333 G4double b = bz - br; << 334 G4double c = cz - cr; << 335 << 336 if (radical < -EPS*std::fabs(b)) { return 0; << 337 << 338 if (radical < EPS*std::fabs(b)) << 339 { 333 { 340 // 334 // 341 // The radical is roughly zero: check for 335 // The radical is roughly zero: check for special, very rare, cases 342 // 336 // 343 if (std::fabs(a) > 1/kInfinity) 337 if (std::fabs(a) > 1/kInfinity) 344 { 338 { 345 if ( std::fabs(x0*ty - y0*tx) < std::fab << 339 if ( std::fabs(x0*ty - y0*tx) < std::fabs(1E-6/B) ) 346 { 340 { 347 *s1 = -0.5*b/a; 341 *s1 = -0.5*b/a; 348 return 1; 342 return 1; 349 } 343 } 350 return 0; 344 return 0; 351 } 345 } 352 } 346 } 353 else 347 else 354 { 348 { 355 radical = std::sqrt(radical); 349 radical = std::sqrt(radical); 356 } 350 } 357 << 351 358 if (a < -1/kInfinity) 352 if (a < -1/kInfinity) 359 { 353 { 360 G4double sa, sb, q = -0.5*( b + (b < 0 ? - 354 G4double sa, sb, q = -0.5*( b + (b < 0 ? -radical : +radical) ); 361 sa = q/a; 355 sa = q/a; 362 sb = c/q; 356 sb = c/q; 363 if (sa < sb) { *s1 = sa; *s2 = sb; } else 357 if (sa < sb) { *s1 = sa; *s2 = sb; } else { *s1 = sb; *s2 = sa; } 364 if ((z0 + (*s1)*tz - A)/B < 0) { return 358 if ((z0 + (*s1)*tz - A)/B < 0) { return 0; } 365 return 2; 359 return 2; 366 } 360 } 367 else if (a > 1/kInfinity) 361 else if (a > 1/kInfinity) 368 { 362 { 369 G4double sa, sb, q = -0.5*( b + (b < 0 ? - 363 G4double sa, sb, q = -0.5*( b + (b < 0 ? -radical : +radical) ); 370 sa = q/a; 364 sa = q/a; 371 sb = c/q; 365 sb = c/q; 372 *s1 = (tz*B > 0)^(sa > sb) ? sb : sa; 366 *s1 = (tz*B > 0)^(sa > sb) ? sb : sa; 373 return 1; 367 return 1; 374 } 368 } 375 else if (std::fabs(b) < 1/kInfinity) 369 else if (std::fabs(b) < 1/kInfinity) 376 { 370 { 377 return 0; 371 return 0; 378 } 372 } 379 else 373 else 380 { 374 { 381 *s1 = -c/b; 375 *s1 = -c/b; 382 if ((z0 + (*s1)*tz - A)/B < 0) { return 376 if ((z0 + (*s1)*tz - A)/B < 0) { return 0; } 383 return 1; 377 return 1; 384 } 378 } 385 } 379 } 386 380