1154{
1155 ESide side = kNull, sidephi = kNull ;
1156 G4double snxt = kInfinity, sphi, sd[4] ;
1157
1158
1159
1160 G4double sinSPhi, cosSPhi, ePhi, sinEPhi, cosEPhi;
1162 G4double pDistS, compS, pDistE, compE, sphi2, xi, yi, zi, vphi ;
1163
1164
1165
1166
1167
1168#if 1
1169
1170
1171
1172
1173
1174
1177
1179
1180 G4double tolRMax = fRmax - fRmaxTolerance ;
1181
1182 G4double vDotNmax = pDotV - fRtor*(v.
x()*p.
x() + v.
y()*p.
y())/rho ;
1183 G4double pDotxyNmax = (1 - fRtor/rho) ;
1184
1185 if( (pt*pt > tolRMax*tolRMax) && (vDotNmax >= 0) )
1186 {
1187
1188
1189
1190
1191 if ( calcNorm && (pDotxyNmax >= -2.*fRmaxTolerance) )
1192 {
1194 p.
y()*(1 - fRtor/rho)/pt,
1196 *validNorm = true ;
1197 }
1198
1199 return snxt = 0 ;
1200 }
1201
1202 snxt = SolveNumericJT(p,v,fRmax,false);
1203 side = kRMax ;
1204
1205
1206
1207 if ( fRmin )
1208 {
1209 G4double tolRMin = fRmin + fRminTolerance ;
1210
1211 if ( (pt*pt < tolRMin*tolRMin) && (vDotNmax < 0) )
1212 {
1213 if (calcNorm) { *validNorm = false ; }
1214 return snxt = 0 ;
1215 }
1216
1217 sd[0] = SolveNumericJT(p,v,fRmin,false);
1218 if ( sd[0] < snxt )
1219 {
1220 snxt = sd[0] ;
1221 side = kRMin ;
1222 }
1223 }
1224
1225#else
1226
1227
1228
1229
1230 snxt = SolveNumericJT(p,v,fRmax,false);
1231 side = kRMax ;
1232
1233 if ( fRmin )
1234 {
1235 sd[0] = SolveNumericJT(p,v,fRmin,false);
1236 if ( sd[0] < snxt )
1237 {
1238 snxt = sd[0] ;
1239 side = kRMin ;
1240 }
1241 }
1242
1243 if ( calcNorm && (snxt == 0.0) )
1244 {
1245 *validNorm = false ;
1246 return snxt ;
1247 }
1248
1249#endif
1250
1251 if (fDPhi < twopi)
1252 {
1253 sinSPhi = std::sin(fSPhi) ;
1254 cosSPhi = std::cos(fSPhi) ;
1255 ePhi = fSPhi + fDPhi ;
1256 sinEPhi = std::sin(ePhi) ;
1257 cosEPhi = std::cos(ePhi) ;
1258 cPhi = fSPhi + fDPhi*0.5 ;
1259 sinCPhi = std::sin(cPhi) ;
1260 cosCPhi = std::cos(cPhi) ;
1261
1262
1263
1264
1265 vphi = std::atan2(v.
y(),v.
x()) ;
1266
1267 if ( vphi < fSPhi - halfAngTolerance ) { vphi += twopi; }
1268 else if ( vphi > ePhi + halfAngTolerance ) { vphi -= twopi; }
1269
1270 if ( p.
x() || p.
y() )
1271 {
1272 pDistS = p.
x()*sinSPhi - p.
y()*cosSPhi ;
1273 pDistE = -p.
x()*sinEPhi + p.
y()*cosEPhi ;
1274
1275
1276
1277 compS = -sinSPhi*v.
x() + cosSPhi*v.
y() ;
1278 compE = sinEPhi*v.
x() - cosEPhi*v.
y() ;
1279 sidephi = kNull ;
1280
1281 if( ( (fDPhi <= pi) && ( (pDistS <= halfCarTolerance)
1282 && (pDistE <= halfCarTolerance) ) )
1283 || ( (fDPhi > pi) && !((pDistS > halfCarTolerance)
1284 && (pDistE > halfCarTolerance) ) ) )
1285 {
1286
1287
1288 if ( compS < 0 )
1289 {
1290 sphi = pDistS/compS ;
1291
1292 if (sphi >= -halfCarTolerance)
1293 {
1294 xi = p.
x() + sphi*v.
x() ;
1295 yi = p.
y() + sphi*v.
y() ;
1296
1297
1298
1299
1302 {
1303 sidephi = kSPhi;
1304 if ( ((fSPhi-halfAngTolerance)<=vphi)
1305 && ((ePhi+halfAngTolerance)>=vphi) )
1306 {
1307 sphi = kInfinity;
1308 }
1309 }
1310 else if ( yi*cosCPhi-xi*sinCPhi >=0 )
1311 {
1312 sphi = kInfinity ;
1313 }
1314 else
1315 {
1316 sidephi = kSPhi ;
1317 }
1318 }
1319 else
1320 {
1321 sphi = kInfinity ;
1322 }
1323 }
1324 else
1325 {
1326 sphi = kInfinity ;
1327 }
1328
1329 if ( compE < 0 )
1330 {
1331 sphi2 = pDistE/compE ;
1332
1333
1334
1336 {
1337 xi = p.
x() + sphi2*v.
x() ;
1338 yi = p.
y() + sphi2*v.
y() ;
1339
1342 {
1343
1344
1345 if( !( (fSPhi-halfAngTolerance <= vphi)
1346 && (ePhi+halfAngTolerance >= vphi) ) )
1347 {
1348 sidephi = kEPhi ;
1349 sphi = sphi2;
1350 }
1351 }
1352 else
1353 {
1354 if ( (yi*cosCPhi-xi*sinCPhi) >= 0)
1355 {
1356
1357
1358 sidephi = kEPhi ;
1359 sphi = sphi2;
1360
1361 }
1362 }
1363 }
1364 }
1365 }
1366 else
1367 {
1368 sphi = kInfinity ;
1369 }
1370 }
1371 else
1372 {
1373
1374
1375
1376 vphi = std::atan2(v.
y(),v.
x());
1377
1378 if ( ( fSPhi-halfAngTolerance <= vphi ) &&
1379 ( vphi <= ( ePhi+halfAngTolerance ) ) )
1380 {
1381 sphi = kInfinity;
1382 }
1383 else
1384 {
1385 sidephi = kSPhi ;
1386 sphi=0;
1387 }
1388 }
1389
1390
1391
1392 if (sphi<snxt)
1393 {
1394 snxt=sphi;
1395 side=sidephi;
1396 }
1397 }
1398
1400
1401
1402
1403 if (calcNorm)
1404 {
1405 switch(side)
1406 {
1407 case kRMax:
1408 xi = p.
x() + snxt*v.
x() ;
1409 yi = p.
y() + snxt*v.
y() ;
1410 zi = p.
z() + snxt*v.
z() ;
1411 rhoi = std::hypot(xi,yi);
1412 it = hypot(zi,rhoi-fRtor);
1413
1414 iDotxyNmax = (1-fRtor/rhoi) ;
1415 if(iDotxyNmax >= -2.*fRmaxTolerance)
1416 {
1418 yi*(1-fRtor/rhoi)/it,
1419 zi/it ) ;
1420 *validNorm = true ;
1421 }
1422 else
1423 {
1424 *validNorm = false ;
1425 }
1426 break ;
1427
1428 case kRMin:
1429 *validNorm = false ;
1430 break;
1431
1432 case kSPhi:
1433 if (fDPhi <= pi )
1434 {
1436 *validNorm=true;
1437 }
1438 else
1439 {
1440 *validNorm = false ;
1441 }
1442 break ;
1443
1444 case kEPhi:
1445 if (fDPhi <= pi)
1446 {
1447 *
n=
G4ThreeVector(-std::sin(fSPhi+fDPhi),std::cos(fSPhi+fDPhi),0);
1448 *validNorm=true;
1449 }
1450 else
1451 {
1452 *validNorm = false ;
1453 }
1454 break;
1455
1456 default:
1457
1458
1459
1462 std::ostringstream message;
1463 G4long oldprc = message.precision(16);
1464 message << "Undefined side for valid surface normal to solid."
1467 <<
"p.x() = " << p.
x()/mm <<
" mm" <<
G4endl
1468 <<
"p.y() = " << p.
y()/mm <<
" mm" <<
G4endl
1471 <<
"v.x() = " << v.
x() <<
G4endl
1472 <<
"v.y() = " << v.
y() <<
G4endl
1475 <<
"snxt = " << snxt/mm <<
" mm" <<
G4endl;
1476 message.precision(oldprc);
1479 break;
1480 }
1481 }
1482 if ( snxt<halfCarTolerance ) { snxt=0 ; }
1483
1484 return snxt;
1485}
CLHEP::Hep3Vector G4ThreeVector