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