1192{
1193 ESide side = kNull, sidephi = kNull ;
1194 G4double snxt = kInfinity, sphi, sd[4] ;
1195
1197 static const G4double halfAngTolerance = 0.5*kAngTolerance;
1198
1199
1200
1201 G4double sinSPhi, cosSPhi, ePhi, sinEPhi, cosEPhi;
1203 G4double pDistS, compS, pDistE, compE, sphi2, xi, yi, zi, vphi ;
1204
1205
1206
1207
1208
1209#if 1
1210
1211
1212
1213
1214
1217
1218 G4double pt2 = rho2 + p.
z()*p.
z() + fRtor * (fRtor - 2.0*rho);
1219
1220
1221 if( pt2 < 0.0)
1222 {
1223 pt2= std::fabs( pt2 );
1224 }
1225
1227
1229
1230 G4double tolRMax = fRmax - fRmaxTolerance ;
1231
1232 G4double vDotNmax = pDotV - fRtor*(v.
x()*p.
x() + v.
y()*p.
y())/rho ;
1233 G4double pDotxyNmax = (1 - fRtor/rho) ;
1234
1235 if( (pt2 > tolRMax*tolRMax) && (vDotNmax >= 0) )
1236 {
1237
1238
1239
1240
1241 if ( calcNorm && (pDotxyNmax >= -2.*fRmaxTolerance) )
1242 {
1244 p.
y()*(1 - fRtor/rho)/pt,
1246 *validNorm = true ;
1247 }
1248
1249 return snxt = 0 ;
1250 }
1251
1252 snxt = SolveNumericJT(p,v,fRmax,false);
1253 side = kRMax ;
1254
1255
1256
1257 if ( fRmin )
1258 {
1259 G4double tolRMin = fRmin + fRminTolerance ;
1260
1261 if ( (pt2 < tolRMin*tolRMin) && (vDotNmax < 0) )
1262 {
1263 if (calcNorm) { *validNorm = false ; }
1264 return snxt = 0 ;
1265 }
1266
1267 sd[0] = SolveNumericJT(p,v,fRmin,false);
1268 if ( sd[0] < snxt )
1269 {
1270 snxt = sd[0] ;
1271 side = kRMin ;
1272 }
1273 }
1274
1275#else
1276
1277
1278
1279
1280 snxt = SolveNumericJT(p,v,fRmax,false);
1281 side = kRMax ;
1282
1283 if ( fRmin )
1284 {
1285 sd[0] = SolveNumericJT(p,v,fRmin,false);
1286 if ( sd[0] < snxt )
1287 {
1288 snxt = sd[0] ;
1289 side = kRMin ;
1290 }
1291 }
1292
1293 if ( calcNorm && (snxt == 0.0) )
1294 {
1295 *validNorm = false ;
1296 return snxt ;
1297 }
1298
1299#endif
1300
1301 if (fDPhi < twopi)
1302 {
1303 sinSPhi = std::sin(fSPhi) ;
1304 cosSPhi = std::cos(fSPhi) ;
1305 ePhi = fSPhi + fDPhi ;
1306 sinEPhi = std::sin(ePhi) ;
1307 cosEPhi = std::cos(ePhi) ;
1308 cPhi = fSPhi + fDPhi*0.5 ;
1309 sinCPhi = std::sin(cPhi) ;
1310 cosCPhi = std::cos(cPhi) ;
1311
1312
1313
1314
1315 vphi = std::atan2(v.
y(),v.
x()) ;
1316
1317 if ( vphi < fSPhi - halfAngTolerance ) { vphi += twopi; }
1318 else if ( vphi > ePhi + halfAngTolerance ) { vphi -= twopi; }
1319
1320 if ( p.
x() || p.
y() )
1321 {
1322 pDistS = p.
x()*sinSPhi - p.
y()*cosSPhi ;
1323 pDistE = -p.
x()*sinEPhi + p.
y()*cosEPhi ;
1324
1325
1326
1327 compS = -sinSPhi*v.
x() + cosSPhi*v.
y() ;
1328 compE = sinEPhi*v.
x() - cosEPhi*v.
y() ;
1329 sidephi = kNull ;
1330
1331 if( ( (fDPhi <= pi) && ( (pDistS <= halfCarTolerance)
1332 && (pDistE <= halfCarTolerance) ) )
1333 || ( (fDPhi > pi) && !((pDistS > halfCarTolerance)
1334 && (pDistE > halfCarTolerance) ) ) )
1335 {
1336
1337
1338 if ( compS < 0 )
1339 {
1340 sphi = pDistS/compS ;
1341
1342 if (sphi >= -halfCarTolerance)
1343 {
1344 xi = p.
x() + sphi*v.
x() ;
1345 yi = p.
y() + sphi*v.
y() ;
1346
1347
1348
1349
1352 {
1353 sidephi = kSPhi;
1354 if ( ((fSPhi-halfAngTolerance)<=vphi)
1355 && ((ePhi+halfAngTolerance)>=vphi) )
1356 {
1357 sphi = kInfinity;
1358 }
1359 }
1360 else if ( yi*cosCPhi-xi*sinCPhi >=0 )
1361 {
1362 sphi = kInfinity ;
1363 }
1364 else
1365 {
1366 sidephi = kSPhi ;
1367 }
1368 }
1369 else
1370 {
1371 sphi = kInfinity ;
1372 }
1373 }
1374 else
1375 {
1376 sphi = kInfinity ;
1377 }
1378
1379 if ( compE < 0 )
1380 {
1381 sphi2 = pDistE/compE ;
1382
1383
1384
1386 {
1387 xi = p.
x() + sphi2*v.
x() ;
1388 yi = p.
y() + sphi2*v.
y() ;
1389
1392 {
1393
1394
1395 if( !( (fSPhi-halfAngTolerance <= vphi)
1396 && (ePhi+halfAngTolerance >= vphi) ) )
1397 {
1398 sidephi = kEPhi ;
1399 sphi = sphi2;
1400 }
1401 }
1402 else
1403 {
1404 if ( (yi*cosCPhi-xi*sinCPhi) >= 0)
1405 {
1406
1407
1408 sidephi = kEPhi ;
1409 sphi = sphi2;
1410
1411 }
1412 }
1413 }
1414 }
1415 }
1416 else
1417 {
1418 sphi = kInfinity ;
1419 }
1420 }
1421 else
1422 {
1423
1424
1425
1426 vphi = std::atan2(v.
y(),v.
x());
1427
1428 if ( ( fSPhi-halfAngTolerance <= vphi ) &&
1429 ( vphi <= ( ePhi+halfAngTolerance ) ) )
1430 {
1431 sphi = kInfinity;
1432 }
1433 else
1434 {
1435 sidephi = kSPhi ;
1436 sphi=0;
1437 }
1438 }
1439
1440
1441
1442 if (sphi<snxt)
1443 {
1444 snxt=sphi;
1445 side=sidephi;
1446 }
1447 }
1448
1449 G4double rhoi2,rhoi,it2,it,iDotxyNmax ;
1450
1451
1452
1453 if (calcNorm)
1454 {
1455 switch(side)
1456 {
1457 case kRMax:
1458 xi = p.
x() + snxt*v.
x() ;
1459 yi =p.
y() + snxt*v.
y() ;
1460 zi = p.
z() + snxt*v.
z() ;
1461 rhoi2 = xi*xi + yi*yi ;
1462 rhoi = std::sqrt(rhoi2) ;
1463 it2 = std::fabs(rhoi2 + zi*zi + fRtor*fRtor - 2*fRtor*rhoi) ;
1464 it = std::sqrt(it2) ;
1465 iDotxyNmax = (1-fRtor/rhoi) ;
1466 if(iDotxyNmax >= -2.*fRmaxTolerance)
1467 {
1469 yi*(1-fRtor/rhoi)/it,
1470 zi/it ) ;
1471 *validNorm = true ;
1472 }
1473 else
1474 {
1475 *validNorm = false ;
1476 }
1477 break ;
1478
1479 case kRMin:
1480 *validNorm = false ;
1481 break;
1482
1483 case kSPhi:
1484 if (fDPhi <= pi )
1485 {
1487 *validNorm=true;
1488 }
1489 else
1490 {
1491 *validNorm = false ;
1492 }
1493 break ;
1494
1495 case kEPhi:
1496 if (fDPhi <= pi)
1497 {
1498 *
n=
G4ThreeVector(-std::sin(fSPhi+fDPhi),std::cos(fSPhi+fDPhi),0);
1499 *validNorm=true;
1500 }
1501 else
1502 {
1503 *validNorm = false ;
1504 }
1505 break;
1506
1507 default:
1508
1509
1510
1513 std::ostringstream message;
1514 G4int oldprc = message.precision(16);
1515 message << "Undefined side for valid surface normal to solid."
1518 <<
"p.x() = " << p.
x()/mm <<
" mm" <<
G4endl
1519 <<
"p.y() = " << p.
y()/mm <<
" mm" <<
G4endl
1522 <<
"v.x() = " << v.
x() <<
G4endl
1523 <<
"v.y() = " << v.
y() <<
G4endl
1526 <<
"snxt = " << snxt/mm <<
" mm" <<
G4endl;
1527 message.precision(oldprc);
1530 break;
1531 }
1532 }
1533 if ( snxt<halfCarTolerance ) { snxt=0 ; }
1534
1535 return snxt;
1536}
CLHEP::Hep3Vector G4ThreeVector