76 : fIntBuffer(0), fDblBuffer(0)
101 std::lock_guard<std::mutex> guard(
fMutex);
102 std::vector<ThreadData_t *>::iterator i =
fThreadData.begin();
117 std::lock_guard<std::mutex> guard(
fMutex);
120 for (
Int_t tid = 0; tid < nthreads; tid++) {
196 Double_t rmin1, rmax1, rmin2, rmax2, dphi, dz;
200 for (ipl = 0; ipl <
fNz - 1; ipl++) {
201 dz =
fZ[ipl + 1] -
fZ[ipl];
205 rmin2 =
fRmin[ipl + 1];
206 rmax2 =
fRmax[ipl + 1];
207 capacity +=
fNedges * (tphi2 / 3.) * dz *
208 (rmax1 * rmax1 + rmax1 * rmax2 + rmax2 * rmax2 - rmin1 * rmin1 - rmin1 * rmin2 - rmin2 * rmin2);
219 for (
Int_t isec = 0; isec <
fNz - 1; isec++) {
220 if (
fZ[isec] >
fZ[isec + 1]) {
222 Fatal(
"ComputeBBox",
"Wrong section order");
229 Fatal(
"ComputeBBox",
"Shape %s at index %d: Not allowed first two or last two sections at same Z",
GetName(),
261 if (ddp < 0) ddp += 360;
264 if (ddp < 0) ddp += 360;
267 if (ddp < 0) ddp += 360;
270 if (ddp < 0) ddp += 360;
274 fOrigin[2] = 0.5 * (zmax + zmin);
277 fDZ = 0.5 * (zmax - zmin);
286 memset(norm, 0, 3 *
sizeof(
Double_t));
292 if (phi1 < 0) phi1 += 360;
307 if (ipl == (
fNz - 1) || ipl < 0) {
312 Int_t iplclose = ipl;
313 if ((
fZ[ipl + 1] - point[2]) < (point[2] -
fZ[ipl])) iplclose++;
318 while (phi <
fPhi1) phi += 360.;
326 if (iplclose == 0 || iplclose == (
fNz - 1)) {
346 dz =
fZ[ipl + 1] -
fZ[ipl];
348 rmin2 =
fRmin[ipl + 1];
349 rsum = rmin1 + rmin2;
352 ta = (rmin2 - rmin1) / dz;
354 rpgon = rmin1 + (point[2] -
fZ[ipl]) * ta;
358 norm[2] = -calf * ta;
362 rpgon =
fRmax[ipl] + (point[2] -
fZ[ipl]) * ta;
366 norm[2] = -calf * ta;
368 if (norm[0] * dir[0] + norm[1] * dir[1] + norm[2] * dir[2] < 0) {
381 if (point[2] <
fZ[0])
return kFALSE;
386 while (phi <
fPhi1) phi += 360.0;
429 if (iact < 3 && safe) {
437 if (ipl ==
fNz - 1) {
438 if (dir[2] >= 0)
return 0.;
443 if (dir[2] <= 0)
return 0.;
457 if ((point[0] * dir[1] - point[1] * dir[0]) > 0) {
498 Double_t rproj = point[0] * cphi + point[1] * sphi;
501 if (rproj >
fRmin[ipln] && rproj <
fRmin[ipln + 1])
return 0.0;
502 if (rproj <
fRmax[ipln] && rproj >
fRmax[ipln + 1])
return 0.0;
505 if (rproj <
fRmin[ipln] && rproj >
fRmin[ipln + 1])
return 0.0;
506 if (rproj >
fRmax[ipln] && rproj <
fRmax[ipln + 1])
return 0.0;
529 while (phi <
fPhi1) phi += 360.;
531 if (ipsec >
fNedges - 1) ipsec = -1;
551 Double_t rdotn = point[0] * dir[0] + point[1] * dir[1];
557 sphi[0] =
TMath::Sqrt((point[0] * point[0] + point[1] * point[1]) / (1. - dir[2] * dir[2]));
559 if (sphi[0] > stepmax) {
564 while (phi <
fPhi1) phi += 360.;
566 if (istart >
fNedges - 1) istart = -1;
574 ist = (incsec > 0) ? 0 :
fNedges;
576 ist = (incsec > 0) ? (istart + 1) : istart;
582 if (istart < 0) gapdone =
kTRUE;
583 phi = phi1 + ist * divphi;
587 if (!crossing) sphi[icrossed] = stepmax;
588 iphi[icrossed++] = istart;
590 if (sphi[icrossed - 1] > stepmax) {
591 sphi[icrossed - 1] = stepmax;
595 istart = (incsec > 0) ? 0 : (
fNedges - 1);
599 istart = (
fDphi < 360.) ? (-1) : 0;
604 if (gapdone)
return icrossed;
605 ist = (incsec > 0) ? 0 :
fNedges;
607 ist = (incsec > 0) ? (istart + 1) : istart;
626 if (iphi[0] < 0 && nphi == 1)
return kFALSE;
629 if (ipl < 0 || ipl ==
fNz - 1)
return kFALSE;
642 rmin =
Rpg(point[2], ipl,
kTRUE, apg, bpg);
643 rmax =
Rpg(point[2], ipl,
kFALSE, apg, bpg);
654 for (iphcrt = 0; iphcrt < nphi; iphcrt++) {
655 if (step > stepmax) {
659 if (iphi[iphcrt] < 0) {
664 snextphi = stepphi[iphcrt];
665 phi = phi1 + (iphi[iphcrt] + 0.5) * divphi;
668 rproj =
pt[0] * cosph +
pt[1] * sinph;
670 ndot = dir[0] * cosph + dir[1] * sinph;
672 dist = (ndot > 0) ? ((rmax - rproj) / ndot) : ((rmin - rproj) / ndot);
673 if (dist < 0) dist = 0.;
675 if (dist < (snextphi - step)) {
681 for (i = 0; i < 3; i++)
pt[i] = point[i] + step * dir[i];
698 if (iphi[0] < 0 && nphi == 1)
return kFALSE;
701 if (ipl < 0 || ipl ==
fNz - 1)
return kFALSE;
714 rmin =
Rpg(point[2], ipl,
kTRUE, apg, bpg);
715 rmax =
Rpg(point[2], ipl,
kFALSE, apg, bpg);
726 for (iphcrt = 0; iphcrt < nphi; iphcrt++) {
727 if (step > stepmax)
return kFALSE;
728 snextphi = stepphi[iphcrt];
729 if (iphi[iphcrt] < 0) {
730 if (iphcrt == nphi - 1)
return kFALSE;
731 if (snextphi > stepmax)
return kFALSE;
732 for (i = 0; i < 3; i++)
pt[i] = point[i] + snextphi * dir[i];
733 phi = phi1 + (iphi[iphcrt + 1] + 0.5) * divphi;
736 rproj =
pt[0] * cosph +
pt[1] * sinph;
737 if (rproj < rmin || rproj > rmax) {
745 phi = phi1 + (iphi[iphcrt] + 0.5) * divphi;
748 rproj =
pt[0] * cosph +
pt[1] * sinph;
750 ndot = dir[0] * cosph + dir[1] * sinph;
761 for (i = 0; i < 3; i++)
pt[i] = point[i] + step * dir[i];
790 Int_t incseg = (dir[2] > 0) ? 1 : -1;
792 Int_t iplstart = ipl;
795 Double_t rpg = 0, rnew = 0, znew = 0;
796 Double_t rpgin = 0, rpgout = 0, apgin = 0, apgout = 0, bpgin = 0, bpgout = 0;
801 Double_t distz = 0, distr = 0, din = 0, dout = 0;
804 for (iphcrt = iphstart; iphcrt < nphi; iphcrt++) {
806 if (step > stepmax) {
810 if (iphi[iphcrt] < 0) {
814 snextphi = stepphi[iphcrt];
815 phi = phi1 + (iphi[iphcrt] + 0.5) * divphi;
820 while (ipl >= 0 && ipl <
fNz - 1) {
823 distz = (
fZ[ipl + ((1 + incseg) >> 1)] -
pt[2]) * invdir;
825 dz =
fZ[ipl + 1] -
fZ[ipl];
827 rnew = apr + bpr *
fZ[ipl];
828 rpg = (rnew -
fRmin[ipl]) * (rnew -
fRmin[ipl + 1]);
829 if (rpg <= 0) din = distz;
830 rpg = (rnew -
fRmax[ipl]) * (rnew -
fRmax[ipl + 1]);
831 if (rpg <= 0) dout = distz;
837 znew = (apr - apgin) / db;
838 din = (znew -
pt[2]) * invdir;
843 znew = (apr - apgout) / db;
844 dout = (znew -
pt[2]) * invdir;
850 if (iphcrt == iphstart && ipl == iplstart) {
851 if (rproj < rpgin + 1.E-8) {
852 Double_t ndotd = dir[0] * cosph + dir[1] * sinph + dir[2] * (
fRmin[ipl] -
fRmin[ipl + 1]) / dz;
854 snext = (din < 0) ? step : (step + din);
862 }
else if (rproj > rpgout - 1.E-8) {
863 Double_t ndotd = dir[0] * cosph + dir[1] * sinph + dir[2] * (
fRmax[ipl] -
fRmax[ipl + 1]) / dz;
865 snext = (dout < 0) ? step : (step + dout);
877 if (snextphi < step +
TMath::Min(distz, distr)) {
878 for (i = 0; i < 3; i++)
pt[i] = point[i] + snextphi * dir[i];
890 if ((ipl + incseg < 0) || (ipl + incseg >
fNz - 2)) {
913 if (iphi[0] < 0 && nphi == 1)
return kFALSE;
918 Int_t incseg = (dir[2] > 0) ? 1 : -1;
922 if (incseg < 0)
return kFALSE;
924 if (ipl ==
fNz - 1) {
926 if (incseg > 0)
return kFALSE;
930 if ((ipl + incseg) < 0 || (ipl + incseg) >
fNz - 1)
return kFALSE;
950 for (iphcrt = 0; iphcrt < nphi; iphcrt++) {
952 if (step > stepmax)
return kFALSE;
954 snextphi = stepphi[iphcrt];
955 if (iphi[iphcrt] < 0) {
956 if (iphcrt == nphi - 1)
return kFALSE;
957 if (snextphi > stepmax)
return kFALSE;
958 for (i = 0; i < 3; i++)
pt[i] = point[i] + snextphi * dir[i];
962 while (
pt[2] >
fZ[ipl + 1]) {
967 while (
pt[2] <
fZ[ipl]) {
969 if (ipl < 0)
return kFALSE;
975 phi = phi1 + (iphi[iphcrt + 1] + 0.5) * divphi;
979 rproj =
pt[0] * cosph +
pt[1] * sinph;
980 if (rproj < rpgin || rproj > rpgout) {
999 if (ipl < 0 || ipl >
fNz - 2)
return kFALSE;
1000 if (sstart > stepmax)
return kFALSE;
1004 for (
Int_t i = 0; i < 3; i++)
pt[i] += sstart * dir[i];
1007 Int_t incseg = (dir[2] > 0) ? 1 : -1;
1015 Rproj(
pt[2], point, dir, cphi, sphi, apr, bpr);
1018 Int_t icrtseg = ipl;
1019 Int_t isegstart = ipl;
1020 Int_t iseglast = (incseg > 0) ? (
fNz - 1) : -1;
1021 Double_t din, dout, rdot, rnew, apg, bpg, db, znew;
1023 for (ipl = isegstart; ipl != iseglast; ipl += incseg) {
1024 step = (
fZ[ipl + 1 - ((1 + incseg) >> 1)] -
pt[2]) * invdir;
1026 if (step > stepmax) {
1033 dz =
fZ[ipl + 1] -
fZ[ipl];
1039 rdot = dir[0] * cphi + dir[1] * sphi + dir[2] * (
fRmin[ipl] -
fRmin[ipl + 1]) / dz;
1044 rnew = apr + bpr *
fZ[ipl];
1046 if (rpg <= 0) din = (
fZ[ipl] -
pt[2]) * invdir;
1051 znew = (apr - apg) / db;
1052 if (znew >
fZ[ipl] && znew <
fZ[ipl + 1]) {
1053 din = (znew -
pt[2]) * invdir;
1064 rdot = dir[0] * cphi + dir[1] * sphi + dir[2] * (
fRmax[ipl] -
fRmax[ipl + 1]) / dz;
1069 rnew = apr + bpr *
fZ[ipl];
1071 if (rpg <= 0) dout = (
fZ[ipl] -
pt[2]) * invdir;
1076 znew = (apr - apg) / db;
1077 if (znew >
fZ[ipl] && znew <
fZ[ipl + 1]) dout = (znew -
pt[2]) * invdir;
1086 if (step > stepmax) {
1090 snext = sstart + step;
1104 if (iact < 3 && safe) {
1132 if (r2 > (radmax * radmax) ||
pt[2] <
fZ[0] ||
pt[2] >
fZ[
fNz - 1]) {
1139 for (i = 0; i < 3; i++)
pt[i] +=
snext * dir[i];
1152 while (phi <
fPhi1) phi += 360.0;
1155 ipsec =
Int_t(ddp / divphi);
1158 if (rpr >= rmin && rpr <= rmax)
return snext;
1179 while (ph <
fPhi1) ph += 360.;
1181 if (ipsec >
fNedges - 1) ipsec = -1;
1184 if (
fDphi < 360.0) {
1188 if (ipl < 0) ipl = 0;
1189 if (ipl ==
fNz - 1) ipl--;
1202 if (rproj <
fRmin[ipl] && rproj >
fRmin[ipl + 1] && dir[2] > 0)
return 0.0;
1203 if (rproj >
fRmin[ipl] && rproj <
fRmin[ipl + 1] && dir[2] < 0)
return 0.0;
1204 if (rproj >
fRmax[ipl] && rproj <
fRmax[ipl + 1] && dir[2] > 0)
return 0.0;
1205 if (rproj <
fRmax[ipl] && rproj >
fRmax[ipl + 1] && dir[2] < 0)
return 0.0;
1211 if (rproj < rpgout + 1.E-8) {
1214 if (rproj > rpgin - 1.E-8) {
1226 if (safrmin < safz && safrmin < safrmax && safrmin < safphi) {
1228 Double_t ndotd = dir[0] * cphi + dir[1] * sphi + dir[2] * (
fRmin[ipl] -
fRmin[ipl + 1]) * dzinv;
1230 if (ndotd > 0)
return snext;
1233 if (!done && safrmax < safz && safrmax < safphi) {
1234 Double_t ndotd = dir[0] * cphi + dir[1] * sphi + dir[2] * (
fRmax[ipl] -
fRmax[ipl + 1]) * dzinv;
1236 if (ndotd < 0)
return snext;
1239 if (!done && safz < safphi) {
1243 if (iplc == 0 || iplc ==
fNz - 1) {
1244 if (
pt[2] * dir[2] < 0)
return snext;
1276 if (!icrossed)
return snext;
1278 if (iph[0] >= 0 && sph[0] > 1.E-8)
return snext;
1318 Double_t zmax = start + ndiv * step;
1323 Error(
"Divide",
"makes no sense dividing a pgon on radius");
1327 Error(
"Divide",
"ndiv should divide number of pgon edges");
1335 shape =
new TGeoPgon(-step / 2, step, nedges,
fNz);
1340 for (
id = 0;
id < ndiv;
id++) {
1347 for (ipl = 0; ipl <
fNz - 1; ipl++) {
1348 if (start <
fZ[ipl])
1351 if ((start + ndiv * step) >
fZ[ipl + 1])
continue;
1355 zmax =
fZ[isect + 1];
1359 Error(
"Divide",
"cannot divide pcon on Z if divided region is not between 2 consecutive planes");
1362 finder =
new TGeoPatternZ(voldiv, ndiv, start, start + ndiv * step);
1367 for (
id = 0;
id < ndiv;
id++) {
1369 Double_t z2 = start + (
id + 1) * step;
1370 Double_t rmin1 = (
fRmin[isect] * (zmax - z1) -
fRmin[isect + 1] * (zmin - z1)) / (zmax - zmin);
1371 Double_t rmax1 = (
fRmax[isect] * (zmax - z1) -
fRmax[isect + 1] * (zmin - z1)) / (zmax - zmin);
1372 Double_t rmin2 = (
fRmin[isect] * (zmax - z2) -
fRmin[isect + 1] * (zmin - z2)) / (zmax - zmin);
1373 Double_t rmax2 = (
fRmax[isect] * (zmax - z2) -
fRmax[isect + 1] * (zmin - z2)) / (zmax - zmin);
1375 ((
TGeoPgon *)shape)->DefineSection(0, -step / 2, rmin1, rmax1);
1376 ((
TGeoPgon *)shape)->DefineSection(1, step / 2, rmin2, rmax2);
1383 default:
Error(
"Divide",
"Wrong axis type for division");
return 0;
1393 param[0] =
fRmin[0];
1394 param[1] =
fRmax[0];
1396 if (
fRmin[i] < param[0]) param[0] =
fRmin[i];
1397 if (
fRmax[i] > param[1]) param[1] =
fRmax[i];
1401 param[0] *= param[0];
1402 param[1] *= param[1];
1409 param[3] = param[2] +
fDphi;
1417 printf(
"*** Shape %s: TGeoPgon ***\n",
GetName());
1418 printf(
" Nedges = %i\n",
fNedges);
1428 Int_t nbPnts, nbSegs, nbPols;
1458 Int_t nbPnts = nz * 2 *
n;
1459 if (nbPnts <= 0)
return;
1465 Int_t indx = 0, indx2, k;
1469 for (i = 0; i < nz * 2; i++) {
1471 for (j = 1; j <
n; j++) {
1473 buff.
fSegs[indx++] = indx2 + j - 1;
1474 buff.
fSegs[indx++] = indx2 + j;
1478 buff.
fSegs[indx++] = indx2 + j - 1;
1479 buff.
fSegs[indx++] = indx2;
1484 for (i = 0; i < 2; i++) {
1485 indx2 = i * (nz - 1) * 2 *
n;
1486 for (j = 0; j <
n; j++) {
1488 buff.
fSegs[indx++] = indx2 + j;
1489 buff.
fSegs[indx++] = indx2 +
n + j;
1494 for (i = 0; i < (nz - 1); i++) {
1497 for (j = 0; j <
n; j++) {
1498 buff.
fSegs[indx++] =
c + 2;
1499 buff.
fSegs[indx++] = indx2 + j;
1500 buff.
fSegs[indx++] = indx2 +
n * 2 + j;
1503 indx2 = i *
n * 2 +
n;
1504 for (j = 0; j <
n; j++) {
1505 buff.
fSegs[indx++] =
c + 3;
1506 buff.
fSegs[indx++] = indx2 + j;
1507 buff.
fSegs[indx++] = indx2 +
n * 2 + j;
1514 for (i = 1; i < (nz - 1); i++) {
1515 for (j = 0; j < 2; j++) {
1517 buff.
fSegs[indx++] = 2 * i *
n + j * (
n - 1);
1518 buff.
fSegs[indx++] = (2 * i + 1) *
n + j * (
n - 1);
1523 Int_t m =
n - 1 + (specialCase ? 1 : 0);
1529 for (j = 0; j <
n - 1; j++) {
1530 buff.
fPols[indx++] =
c + 3;
1531 buff.
fPols[indx++] = 4;
1532 buff.
fPols[indx++] = 2 * nz *
m + i *
n + j;
1533 buff.
fPols[indx++] = i * (nz * 2 - 2) *
m +
m + j;
1534 buff.
fPols[indx++] = 2 * nz *
m + i *
n + j + 1;
1535 buff.
fPols[indx++] = i * (nz * 2 - 2) *
m + j;
1538 buff.
fPols[indx++] =
c + 3;
1539 buff.
fPols[indx++] = 4;
1540 buff.
fPols[indx++] = 2 * nz *
m + i *
n + j;
1541 buff.
fPols[indx++] = i * (nz * 2 - 2) *
m +
m + j;
1542 buff.
fPols[indx++] = 2 * nz *
m + i *
n;
1543 buff.
fPols[indx++] = i * (nz * 2 - 2) *
m + j;
1546 for (j = 0; j <
n - 1; j++) {
1547 buff.
fPols[indx++] =
c + 3;
1548 buff.
fPols[indx++] = 4;
1549 buff.
fPols[indx++] = i * (nz * 2 - 2) *
m + j;
1550 buff.
fPols[indx++] = 2 * nz *
m + i *
n + j + 1;
1551 buff.
fPols[indx++] = i * (nz * 2 - 2) *
m +
m + j;
1552 buff.
fPols[indx++] = 2 * nz *
m + i *
n + j;
1555 buff.
fPols[indx++] =
c + 3;
1556 buff.
fPols[indx++] = 4;
1557 buff.
fPols[indx++] = i * (nz * 2 - 2) *
m + j;
1558 buff.
fPols[indx++] = 2 * nz *
m + i *
n;
1559 buff.
fPols[indx++] = i * (nz * 2 - 2) *
m +
m + j;
1560 buff.
fPols[indx++] = 2 * nz *
m + i *
n + j;
1564 for (k = 0; k < (nz - 1); k++) {
1566 for (j = 0; j <
n - 1; j++) {
1567 buff.
fPols[indx++] =
c + i;
1568 buff.
fPols[indx++] = 4;
1569 buff.
fPols[indx++] = nz * 2 *
m + (2 * k + i * 1 + 2) *
n + j + 1;
1570 buff.
fPols[indx++] = (2 * k + i * 1 + 2) *
m + j;
1571 buff.
fPols[indx++] = nz * 2 *
m + (2 * k + i * 1 + 2) *
n + j;
1572 buff.
fPols[indx++] = (2 * k + i * 1) *
m + j;
1575 buff.
fPols[indx++] =
c + i;
1576 buff.
fPols[indx++] = 4;
1577 buff.
fPols[indx++] = nz * 2 *
m + (2 * k + i * 1 + 2) *
n;
1578 buff.
fPols[indx++] = (2 * k + i * 1 + 2) *
m + j;
1579 buff.
fPols[indx++] = nz * 2 *
m + (2 * k + i * 1 + 2) *
n + j;
1580 buff.
fPols[indx++] = (2 * k + i * 1) *
m + j;
1583 for (j = 0; j <
n - 1; j++) {
1584 buff.
fPols[indx++] =
c + i;
1585 buff.
fPols[indx++] = 4;
1586 buff.
fPols[indx++] = (2 * k + i * 1) *
m + j;
1587 buff.
fPols[indx++] = nz * 2 *
m + (2 * k + i * 1 + 2) *
n + j;
1588 buff.
fPols[indx++] = (2 * k + i * 1 + 2) *
m + j;
1589 buff.
fPols[indx++] = nz * 2 *
m + (2 * k + i * 1 + 2) *
n + j + 1;
1592 buff.
fPols[indx++] =
c + i;
1593 buff.
fPols[indx++] = 4;
1594 buff.
fPols[indx++] = (2 * k + i * 1) *
m + j;
1595 buff.
fPols[indx++] = nz * 2 *
m + (2 * k + i * 1 + 2) *
n + j;
1596 buff.
fPols[indx++] = (2 * k + i * 1 + 2) *
m + j;
1597 buff.
fPols[indx++] = nz * 2 *
m + (2 * k + i * 1 + 2) *
n;
1604 indx2 = nz * 2 * (
n - 1);
1605 for (k = 0; k < (nz - 1); k++) {
1606 buff.
fPols[indx++] =
c + 2;
1607 buff.
fPols[indx++] = 4;
1608 buff.
fPols[indx++] = k == 0 ? indx2 : indx2 + 2 * nz *
n + 2 * (k - 1);
1609 buff.
fPols[indx++] = indx2 + 2 * (k + 1) *
n;
1610 buff.
fPols[indx++] = indx2 + 2 * nz *
n + 2 * k;
1611 buff.
fPols[indx++] = indx2 + (2 * k + 3) *
n;
1613 buff.
fPols[indx++] =
c + 2;
1614 buff.
fPols[indx++] = 4;
1615 buff.
fPols[indx++] = k == 0 ? indx2 +
n - 1 : indx2 + 2 * nz *
n + 2 * (k - 1) + 1;
1616 buff.
fPols[indx++] = indx2 + (2 * k + 3) *
n +
n - 1;
1617 buff.
fPols[indx++] = indx2 + 2 * nz *
n + 2 * k + 1;
1618 buff.
fPols[indx++] = indx2 + 2 * (k + 1) *
n +
n - 1;
1620 buff.
fPols[indx - 8] = indx2 +
n;
1621 buff.
fPols[indx - 2] = indx2 + 2 *
n - 1;
1633 const Int_t nbPnts = nz *
n + 2;
1635 if ((nz < 2) || (nbPnts <= 0) || (
n < 2))
return;
1639 Int_t indx = 0, indx1 = 0, indx2 = 0, i, j;
1642 for (i = 0; i < nz; i++) {
1644 for (j = 1; j <
n; j++) {
1646 buff.
fSegs[indx++] = indx2 + j - 1;
1647 buff.
fSegs[indx++] = indx2 + j % (
n-1);
1653 for (j = 0; j <
n; j++) {
1655 buff.
fSegs[indx++] = indx2 + j % (
n-1);
1656 buff.
fSegs[indx++] = nbPnts - 2;
1661 for (j = 0; j <
n; j++) {
1663 buff.
fSegs[indx++] = indx2 + j % (
n-1);
1664 buff.
fSegs[indx++] = nbPnts - 1;
1668 for (i = 0; i < (nz - 1); i++) {
1671 for (j = 0; j <
n; j++) {
1673 buff.
fSegs[indx++] = indx2 + j % (
n-1);
1674 buff.
fSegs[indx++] = indx2 +
n + j % (
n-1);
1683 for (j = 0; j <
n - 1; j++) {
1685 buff.
fPols[indx++] = 3;
1686 buff.
fPols[indx++] = indx1 + j;
1687 buff.
fPols[indx++] = indx2 + (j+1)%(
n-1);
1688 buff.
fPols[indx++] = indx2 + j;
1692 indx1 = (nz-1)*(
n-1);
1693 indx2 = nz*(
n-1) +
n;
1694 for (j = 0; j <
n - 1; j++) {
1696 buff.
fPols[indx++] = 3;
1697 buff.
fPols[indx++] = indx1 + j;
1698 buff.
fPols[indx++] = indx2 + j;
1699 buff.
fPols[indx++] = indx2 + (j+1)%(
n-1);
1703 for (
Int_t k = 0; k < (nz - 1); k++) {
1705 indx2 = nz*(
n-1) +
n*2 + k*
n;
1706 for (j = 0; j <
n-1; j++) {
1708 buff.
fPols[indx++] = 4;
1709 buff.
fPols[indx++] = indx1 + j;
1710 buff.
fPols[indx++] = indx2 + j;
1711 buff.
fPols[indx++] = indx1 + j + (
n-1);
1712 buff.
fPols[indx++] = indx2 + (j+1)%(
n-1);
1728 if (ipl < 0 || ipl >
fNz - 2) {
1729 Fatal(
"Rpg",
"Plane index parameter ipl=%i out of range\n", ipl);
1743 r2 =
fRmin[ipl + 1];
1746 r2 =
fRmax[ipl + 1];
1749 a = (r1 *
fZ[ipl + 1] - r2 *
fZ[ipl]) * dzinv;
1750 b = (r2 - r1) * dzinv;
1767 a = ((point[0] * dir[2] - point[2] * dir[0]) * cphi + (point[1] * dir[2] - point[2] * dir[1]) * sphi) * invdirz;
1768 b = (dir[0] * cphi + dir[1] * sphi) * invdirz;
1782 if (ipl < 0 || ipl >
fNz - 2)
return (safmin + 1.);
1785 if (dz < 1E-9)
return 1E9;
1786 Double_t znew = point[2] - 0.5 * (
fZ[ipl] +
fZ[ipl + 1]);
1798 r =
TMath::Sqrt(point[0] * point[0] + point[1] * point[1]);
1799 Double_t ro1 = 0.5 * (rmin1 + rmin2);
1800 Double_t tg1 = (rmin2 - rmin1) / dz;
1802 Double_t ro2 = 0.5 * (rmax1 + rmax2);
1803 Double_t tg2 = (rmax2 - rmax1) / dz;
1808 saf[2] = (rout -
r) * cr2;
1809 for (i = 0; i < 3; i++) saf[i] = -saf[i];
1812 if (safe < 0) safe = 0;
1817 if (rmin1 + rmin2 > 1E-10) {
1818 ta = (rmin2 - rmin1) / dz;
1820 rpgon = rmin1 + (point[2] -
fZ[ipl]) * ta;
1821 saf[1] = (
r - rpgon) * calf;
1825 ta = (rmax2 - rmax1) / dz;
1827 rpgon = rmax1 + (point[2] -
fZ[ipl]) * ta;
1828 saf[2] = (rpgon -
r) * calf;
1833 for (i = 0; i < 3; i++) saf[i] = -saf[i];
1837 if (safe < 0) safe = 0;
1849 Int_t ipl, iplane, iphi;
1855 if (ipl == (
fNz - 1))
return 0;
1856 if (ipl < 0)
return 0;
1857 dz = 0.5 * (
fZ[ipl + 1] -
fZ[ipl]);
1858 if (dz < 1E-8)
return 0;
1861 if (safmin > 1E10) {
1865 if (safmin < 1E-6)
return TMath::Abs(safmin);
1869 while ((iplane <
fNz - 1) && saftmp < 1E10) {
1871 if (saftmp < safmin) safmin = saftmp;
1877 while ((iplane >= 0) && saftmp < 1E10) {
1879 if (saftmp < safmin) safmin = saftmp;
1888 else if (ipl ==
fNz - 1)
1890 dz = 0.5 * (
fZ[ipl + 1] -
fZ[ipl]);
1893 if (ipl >
fNz - 2)
return 0.;
1894 dz = 0.5 * (
fZ[ipl + 1] -
fZ[ipl]);
1898 if (safmin < 1E-6)
return TMath::Abs(safmin);
1902 while ((iplane <
fNz - 1) && saftmp < 1E10) {
1904 if (saftmp < safmin) safmin = saftmp;
1910 while ((iplane >= 0) && saftmp < 1E10) {
1912 if (saftmp < safmin) safmin = saftmp;
1924 out <<
" // Shape: " <<
GetName() <<
" type: " <<
ClassName() << std::endl;
1925 out <<
" phi1 = " <<
fPhi1 <<
";" << std::endl;
1926 out <<
" dphi = " <<
fDphi <<
";" << std::endl;
1927 out <<
" nedges = " <<
fNedges <<
";" << std::endl;
1928 out <<
" nz = " <<
fNz <<
";" << std::endl;
1929 out <<
" auto " <<
GetPointerName() <<
" = new TGeoPgon(\"" <<
GetName() <<
"\", phi1, dphi, nedges, nz);" << std::endl;
1931 out <<
" z = " <<
fZ[i] <<
";" << std::endl;
1932 out <<
" rmin = " <<
fRmin[i] <<
";" << std::endl;
1933 out <<
" rmax = " <<
fRmax[i] <<
";" << std::endl;
1934 out <<
" " <<
GetPointerName() <<
"->DefineSection(" << i <<
", z, rmin, rmax);" << std::endl;
1949 Error(
"SetDimensions",
"Pgon %s: Number of Z sections must be > 2",
GetName());
1954 if (
fZ)
delete[]
fZ;
1961 for (
Int_t i = 0; i <
fNz; i++)
DefineSection(i, param[4 + 3 * i], param[5 + 3 * i], param[6 + 3 * i]);
1979 for (i = 0; i <
GetNz(); i++) {
1981 for (j = 0; j <
n; j++) {
1987 for (j = 0; j <
n; j++) {
2022 for (i = 0; i <
fNz; i++) {
2024 for (j = 0; j <
n; j++) {
2030 for (j = 0; j <
n; j++) {
2055 nvert = nsegs = npols = 0;
2065 nsegs = 4 * (nz *
n - 1 + (specialCase ? 1 : 0));
2066 npols = 2 * (nz *
n - 1 + (specialCase ? 1 : 0));
2069 nsegs = nz * (
n - 1) +
n * 2 + (nz - 1) *
n;
2070 npols = 2 * (
n - 1) + (nz - 1) * (
n - 1);
2079 Int_t nvert, nsegs, npols;
2103 Int_t nbPnts, nbSegs, nbPols;
2106 if (buffer.
SetRawSizes(nbPnts, 3 * nbPnts, nbSegs, 3 * nbSegs, nbPols, 6 * nbPols)) {
2171 for (
Int_t i = 0; i < vecsize; i++) safe[i] =
Safety(&
points[3 * i], inside[i]);
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t points
R__EXTERN TGeoManager * gGeoManager
Generic 3D primitive description class.
Bool_t SectionsValid(UInt_t mask) const
void SetSectionsValid(UInt_t mask)
Bool_t SetRawSizes(UInt_t reqPnts, UInt_t reqPntsCapacity, UInt_t reqSegs, UInt_t reqSegsCapacity, UInt_t reqPols, UInt_t reqPolsCapacity)
Set kRaw tessellation section of buffer with supplied sizes.
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const
Compute distance from outside point to surface of the box.
virtual void FillBuffer3D(TBuffer3D &buffer, Int_t reqSections, Bool_t localFrame) const
Fills the supplied buffer, with sections in desired frame See TBuffer3D.h for explanation of sections...
TGeoVolumeMulti * MakeVolumeMulti(const char *name, TGeoMedium *medium)
Make a TGeoVolumeMulti handling a list of volumes.
TObjArray * GetListOfShapes() const
static Int_t ThreadId()
Translates the current thread id to an ordinal number.
Node containing an offset.
Base finder class for patterns.
void SetDivIndex(Int_t index)
A polycone is represented by a sequence of tubes/cones, glued together at defined Z planes.
virtual void DefineSection(Int_t snum, Double_t z, Double_t rmin, Double_t rmax)
Defines z position of a section plane, rmin and rmax at this z.
virtual void InspectShape() const
print shape parameters
Bool_t HasInsideSurface() const
Returns true when pgon has internal surface It will be only disabled when all Rmin values are 0.
Polygons are defined in the same way as polycones, the difference being just that the segments betwee...
virtual Bool_t Contains(const Double_t *point) const
test if point is inside this shape check total z range
virtual void DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const
Compute distance from array of input points having directions specified by dirs. Store output in dist...
Bool_t SliceCrossingInZ(const Double_t *point, const Double_t *dir, Int_t nphi, Int_t *iphi, Double_t *sphi, Double_t &snext, Double_t stepmax) const
Performs ray propagation between Z segments.
void CreateThreadData(Int_t nthreads)
Create thread data for n threads max.
Bool_t SliceCrossing(const Double_t *point, const Double_t *dir, Int_t nphi, Int_t *iphi, Double_t *sphi, Double_t &snext, Double_t stepmax) const
Check boundary crossing inside phi slices.
virtual Double_t Capacity() const
Computes capacity of the shape in [length^3].
virtual void SetDimensions(Double_t *param)
Set PGON dimensions starting from an array.
virtual TGeoVolume * Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step)
Divide this polygone shape belonging to volume "voldiv" into ndiv volumes called divname,...
virtual void ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize)
Compute the normal for an array o points so that norm.dot.dir is positive Input: Arrays of point coor...
virtual void ComputeBBox()
compute bounding box for a polygone Check if the sections are in increasing Z order
virtual void DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const
Compute distance from array of input points having directions specified by dirs. Store output in dist...
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const
computes the closest distance from given point to this shape, according to option.
virtual TBuffer3D * MakeBuffer3D() const
Creates a TBuffer3D describing this shape.
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const
Compute distance from outside point to surface of the polygone.
Bool_t SliceCrossingZ(const Double_t *point, const Double_t *dir, Int_t nphi, Int_t *iphi, Double_t *sphi, Double_t &snext, Double_t stepmax) const
Performs ray propagation between Z segments.
void LocatePhi(const Double_t *point, Int_t &ipsec) const
Locates index IPSEC of the phi sector containing POINT.
std::mutex fMutex
Size for the navigation data array.
virtual void Sizeof3D() const
fill size of this 3-D object
virtual void GetBoundingCylinder(Double_t *param) const
Fill vector param[4] with the bounding cylinder parameters.
virtual void GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
Returns numbers of vertices, segments and polygons composing the shape mesh.
ThreadData_t & GetThreadData() const
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
virtual void SetSegsAndPols(TBuffer3D &buff) const
Fill TBuffer3D structure for segments and polygons.
virtual void Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const
Check the inside status for each of the points in the array.
virtual Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const
compute distance from inside point to surface of the polygone first find out in which Z section the p...
Double_t SafetyToSegment(const Double_t *point, Int_t ipl, Int_t iphi, Bool_t in, Double_t safphi, Double_t safmin=TGeoShape::Big()) const
Compute safety from POINT to segment between planes ipl, ipl+1 within safmin.
virtual void SetPoints(Double_t *points) const
create polygone mesh points
Double_t Rpg(Double_t z, Int_t ipl, Bool_t inner, Double_t &a, Double_t &b) const
Computes projected pgon radius (inner or outer) corresponding to a given Z value.
void SetSegsAndPolsNoInside(TBuffer3D &buff) const
Fill TBuffer3D structure for segments and polygons, when no inner surface exists.
Bool_t SliceCrossingIn(const Double_t *point, const Double_t *dir, Int_t ipl, Int_t nphi, Int_t *iphi, Double_t *sphi, Double_t &snext, Double_t stepmax) const
Check boundary crossing inside phi slices.
virtual void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm)
Compute normal to closest surface from POINT.
virtual Int_t GetNmeshVertices() const
Return number of vertices of the mesh representation.
std::vector< ThreadData_t * > fThreadData
Int_t fThreadSize
Navigation data per thread.
void ClearThreadData() const
Double_t Rproj(Double_t z, const Double_t *point, const Double_t *dir, Double_t cphi, Double_t sphi, Double_t &a, Double_t &b) const
Computes projected distance at a given Z for a given ray inside a given sector and fills coefficients...
Bool_t IsCrossingSlice(const Double_t *point, const Double_t *dir, Int_t iphi, Double_t sstart, Int_t &ipl, Double_t &snext, Double_t stepmax) const
Check crossing of a given pgon slice, from a starting point inside the slice.
Int_t GetPhiCrossList(const Double_t *point, const Double_t *dir, Int_t istart, Double_t *sphi, Int_t *iphi, Double_t stepmax=TGeoShape::Big()) const
Mutex for thread data.
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
Fills a static 3D buffer and returns a reference.
virtual void Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
Compute safe distance from each of the points in the input array.
virtual ~TGeoPgon()
destructor
virtual void InspectShape() const
Inspect the PGON parameters.
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
compute closest distance from point px,py to each corner
Base abstract class for all shapes.
Int_t GetBasicColor() const
Get the basic color (0-7).
void TransformPoints(Double_t *points, UInt_t NbPoints) const
Tranform a set of points (LocalToMaster)
void SetShapeBit(UInt_t f, Bool_t set)
Equivalent of TObject::SetBit.
static Double_t SafetyPhi(const Double_t *point, Bool_t in, Double_t phi1, Double_t phi2)
Static method to compute safety w.r.t a phi corner defined by cosines/sines of the angles phi1,...
static Bool_t IsSameWithinTolerance(Double_t a, Double_t b)
Check if two numbers differ with less than a tolerance.
const char * GetPointerName() const
Provide a pointer name containing uid.
Int_t ShapeDistancetoPrimitive(Int_t numpoints, Int_t px, Int_t py) const
Returns distance to shape primitive mesh.
virtual const char * GetName() const
Get the shape name.
static void NormalPhi(const Double_t *point, const Double_t *dir, Double_t *norm, Double_t c1, Double_t s1, Double_t c2, Double_t s2)
Static method to compute normal to phi planes.
static Bool_t IsCrossingSemiplane(const Double_t *point, const Double_t *dir, Double_t cphi, Double_t sphi, Double_t &snext, Double_t &rxy)
Compute distance from POINT to semiplane defined by PHI angle along DIR.
static Double_t Tolerance()
static Bool_t IsCloseToPhi(Double_t epsil, const Double_t *point, Double_t c1, Double_t s1, Double_t c2, Double_t s2)
True if point is closer than epsil to one of the phi planes defined by c1,s1 or c2,...
static Double_t DistFromOutsideS(const Double_t *point, const Double_t *dir, Double_t rmin, Double_t rmax, Double_t dz)
Static method to compute distance from outside point to a tube with given parameters Boundary safe al...
void AddVolume(TGeoVolume *vol)
Add a volume with valid shape to the list of volumes.
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
void AddNodeOffset(TGeoVolume *vol, Int_t copy_no, Double_t offset=0, Option_t *option="")
Add a division node to the list of nodes.
TGeoMedium * GetMedium() const
void SetFinder(TGeoPatternFinder *finder)
Int_t GetNdaughters() const
Int_t IndexOf(const TObject *obj) const override
TObject * At(Int_t idx) const override
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
virtual const char * ClassName() const
Returns name of class to which the object belongs.
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
const char * Data() const
Long64_t LocMin(Long64_t n, const T *a)
Returns index of array with the minimum element.
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
T1 Sign(T1 a, T2 b)
Returns a value with the magnitude of a and the sign of b.
Double_t ATan2(Double_t y, Double_t x)
Returns the principal value of the arc tangent of y/x, expressed in radians.
Long64_t LocMax(Long64_t n, const T *a)
Returns index of array with the maximum element.
constexpr Double_t DegToRad()
Conversion from degree to radian: .
Double_t Sqrt(Double_t x)
Returns the square root of x.
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Double_t Tan(Double_t)
Returns the tangent of an angle of x radians.
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
constexpr Double_t RadToDeg()
Conversion from radian to degree: .
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Double_t * fDblBuffer
[fNedges+4] temporary int buffer array
ThreadData_t()
[fNedges+4] temporary double buffer array
~ThreadData_t()
Destructor.
#define snext(osub1, osub2)