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