69 : fIntBuffer(0), fDblBuffer(0)
94 std::lock_guard<std::mutex> guard(
fMutex);
95 std::vector<ThreadData_t *>::iterator i =
fThreadData.begin();
110 std::lock_guard<std::mutex> guard(
fMutex);
113 for (
Int_t tid = 0; tid < nthreads; tid++) {
189 Double_t rmin1, rmax1, rmin2, rmax2, dphi, dz;
193 for (ipl = 0; ipl <
fNz - 1; ipl++) {
194 dz =
fZ[ipl + 1] -
fZ[ipl];
198 rmin2 =
fRmin[ipl + 1];
199 rmax2 =
fRmax[ipl + 1];
200 capacity +=
fNedges * (tphi2 / 3.) * dz *
201 (rmax1 * rmax1 + rmax1 * rmax2 + rmax2 * rmax2 - rmin1 * rmin1 - rmin1 * rmin2 - rmin2 * rmin2);
212 for (
Int_t isec = 0; isec <
fNz - 1; isec++) {
213 if (
fZ[isec] >
fZ[isec + 1]) {
215 Fatal(
"ComputeBBox",
"Wrong section order");
222 Fatal(
"ComputeBBox",
"Shape %s at index %d: Not allowed first two or last two sections at same Z",
GetName(),
254 if (ddp < 0) ddp += 360;
255 if (ddp <= fDphi) xmax = rmax;
257 if (ddp < 0) ddp += 360;
258 if (ddp <= fDphi) ymax = rmax;
260 if (ddp < 0) ddp += 360;
261 if (ddp <= fDphi) xmin = -rmax;
263 if (ddp < 0) ddp += 360;
264 if (ddp <= fDphi) ymin = -rmax;
267 fOrigin[2] = 0.5 * (zmax + zmin);
270 fDZ = 0.5 * (zmax - zmin);
279 memset(norm, 0, 3 *
sizeof(
Double_t));
280 Double_t phi1 = 0, phi2 = 0,
c1 = 0, s1 = 0,
c2 = 0, s2 = 0;
285 if (phi1 < 0) phi1 += 360;
300 if (ipl == (
fNz - 1) || ipl < 0) {
305 Int_t iplclose = ipl;
306 if ((
fZ[ipl + 1] - point[2]) < (point[2] -
fZ[ipl])) iplclose++;
311 while (phi <
fPhi1) phi += 360.;
319 if (iplclose == 0 || iplclose == (
fNz - 1)) {
339 dz =
fZ[ipl + 1] -
fZ[ipl];
341 rmin2 =
fRmin[ipl + 1];
342 rsum = rmin1 + rmin2;
345 ta = (rmin2 - rmin1) / dz;
347 rpgon = rmin1 + (point[2] - fZ[ipl]) * ta;
351 norm[2] = -calf * ta;
355 rpgon =
fRmax[ipl] + (point[2] - fZ[ipl]) * ta;
359 norm[2] = -calf * ta;
361 if (norm[0] * dir[0] + norm[1] * dir[1] + norm[2] * dir[2] < 0) {
374 if (point[2] <
fZ[0])
return kFALSE;
379 while (phi <
fPhi1) phi += 360.0;
400 if (r < rmin)
return kFALSE;
401 if (r > rmax)
return kFALSE;
405 Double_t dzrat = (point[2] - fZ[iz]) / dz;
408 if (r < rmin)
return kFALSE;
410 if (r > rmax)
return kFALSE;
422 if (iact < 3 && safe) {
430 if (ipl ==
fNz - 1) {
431 if (dir[2] >= 0)
return 0.;
436 if (dir[2] <= 0)
return 0.;
450 if ((point[0] * dir[1] - point[1] * dir[0]) > 0) {
491 Double_t rproj = point[0] * cphi + point[1] * sphi;
494 if (rproj >
fRmin[ipln] && rproj <
fRmin[ipln + 1])
return 0.0;
495 if (rproj <
fRmax[ipln] && rproj >
fRmax[ipln + 1])
return 0.0;
498 if (rproj <
fRmin[ipln] && rproj >
fRmin[ipln + 1])
return 0.0;
499 if (rproj >
fRmax[ipln] && rproj <
fRmax[ipln + 1])
return 0.0;
522 while (phi <
fPhi1) phi += 360.;
524 if (ipsec >
fNedges - 1) ipsec = -1;
544 Double_t rdotn = point[0] * dir[0] + point[1] * dir[1];
550 sphi[0] =
TMath::Sqrt((point[0] * point[0] + point[1] * point[1]) / (1. - dir[2] * dir[2]));
552 if (sphi[0] > stepmax) {
557 while (phi <
fPhi1) phi += 360.;
559 if (istart >
fNedges - 1) istart = -1;
567 ist = (incsec > 0) ? 0 :
fNedges;
569 ist = (incsec > 0) ? (istart + 1) : istart;
575 if (istart < 0) gapdone =
kTRUE;
576 phi = phi1 + ist * divphi;
580 if (!crossing) sphi[icrossed] = stepmax;
581 iphi[icrossed++] = istart;
583 if (sphi[icrossed - 1] > stepmax) {
584 sphi[icrossed - 1] = stepmax;
588 istart = (incsec > 0) ? 0 : (
fNedges - 1);
592 istart = (
fDphi < 360.) ? (-1) : 0;
597 if (gapdone)
return icrossed;
598 ist = (incsec > 0) ? 0 :
fNedges;
600 ist = (incsec > 0) ? (istart + 1) : istart;
619 if (iphi[0] < 0 && nphi == 1)
return kFALSE;
622 if (ipl < 0 || ipl ==
fNz - 1)
return kFALSE;
635 rmin =
Rpg(point[2], ipl,
kTRUE, apg, bpg);
636 rmax =
Rpg(point[2], ipl,
kFALSE, apg, bpg);
646 memcpy(pt, point, 3 *
sizeof(
Double_t));
647 for (iphcrt = 0; iphcrt < nphi; iphcrt++) {
648 if (step > stepmax) {
652 if (iphi[iphcrt] < 0) {
657 snextphi = stepphi[iphcrt];
658 phi = phi1 + (iphi[iphcrt] + 0.5) * divphi;
661 rproj = pt[0] * cosph + pt[1] * sinph;
663 ndot = dir[0] * cosph + dir[1] * sinph;
665 dist = (ndot > 0) ? ((rmax - rproj) / ndot) : ((rmin - rproj) / ndot);
666 if (dist < 0) dist = 0.;
668 if (dist < (snextphi - step)) {
670 if (snext < stepmax)
return kTRUE;
674 for (i = 0; i < 3; i++) pt[i] = point[i] + step * dir[i];
691 if (iphi[0] < 0 && nphi == 1)
return kFALSE;
694 if (ipl < 0 || ipl ==
fNz - 1)
return kFALSE;
707 rmin =
Rpg(point[2], ipl,
kTRUE, apg, bpg);
708 rmax =
Rpg(point[2], ipl,
kFALSE, apg, bpg);
718 memcpy(pt, point, 3 *
sizeof(
Double_t));
719 for (iphcrt = 0; iphcrt < nphi; iphcrt++) {
720 if (step > stepmax)
return kFALSE;
721 snextphi = stepphi[iphcrt];
722 if (iphi[iphcrt] < 0) {
723 if (iphcrt == nphi - 1)
return kFALSE;
724 if (snextphi > stepmax)
return kFALSE;
725 for (i = 0; i < 3; i++) pt[i] = point[i] + snextphi * dir[i];
726 phi = phi1 + (iphi[iphcrt + 1] + 0.5) * divphi;
729 rproj = pt[0] * cosph + pt[1] * sinph;
730 if (rproj < rmin || rproj > rmax) {
738 phi = phi1 + (iphi[iphcrt] + 0.5) * divphi;
741 rproj = pt[0] * cosph + pt[1] * sinph;
743 ndot = dir[0] * cosph + dir[1] * sinph;
751 if (snext < stepmax)
return kTRUE;
754 for (i = 0; i < 3; i++) pt[i] = point[i] + step * dir[i];
783 Int_t incseg = (dir[2] > 0) ? 1 : -1;
785 Int_t iplstart = ipl;
788 Double_t rpg = 0, rnew = 0, znew = 0;
789 Double_t rpgin = 0, rpgout = 0, apgin = 0, apgout = 0, bpgin = 0, bpgout = 0;
794 Double_t distz = 0, distr = 0, din = 0, dout = 0;
796 memcpy(pt, point, 3 *
sizeof(
Double_t));
797 for (iphcrt = iphstart; iphcrt < nphi; iphcrt++) {
799 if (step > stepmax) {
803 if (iphi[iphcrt] < 0) {
807 snextphi = stepphi[iphcrt];
808 phi = phi1 + (iphi[iphcrt] + 0.5) * divphi;
811 Double_t rproj =
Rproj(pt[2], pt, dir, cosph, sinph, apr, bpr);
813 while (ipl >= 0 && ipl <
fNz - 1) {
816 distz = (
fZ[ipl + ((1 + incseg) >> 1)] - pt[2]) * invdir;
818 dz =
fZ[ipl + 1] -
fZ[ipl];
820 rnew = apr + bpr * fZ[ipl];
821 rpg = (rnew -
fRmin[ipl]) * (rnew -
fRmin[ipl + 1]);
822 if (rpg <= 0) din = distz;
823 rpg = (rnew -
fRmax[ipl]) * (rnew -
fRmax[ipl + 1]);
824 if (rpg <= 0) dout = distz;
827 rpgin =
Rpg(pt[2], ipl,
kTRUE, apgin, bpgin);
830 znew = (apr - apgin) / db;
831 din = (znew - pt[2]) * invdir;
833 rpgout =
Rpg(pt[2], ipl,
kFALSE, apgout, bpgout);
836 znew = (apr - apgout) / db;
837 dout = (znew - pt[2]) * invdir;
843 if (iphcrt == iphstart && ipl == iplstart) {
844 if (rproj < rpgin + 1.
E-8) {
845 Double_t ndotd = dir[0] * cosph + dir[1] * sinph + dir[2] * (
fRmin[ipl] -
fRmin[ipl + 1]) / dz;
847 snext = (din < 0) ? step : (step + din);
855 }
else if (rproj > rpgout - 1.
E-8) {
856 Double_t ndotd = dir[0] * cosph + dir[1] * sinph + dir[2] * (
fRmax[ipl] -
fRmax[ipl + 1]) / dz;
858 snext = (dout < 0) ? step : (step + dout);
870 if (snextphi < step +
TMath::Min(distz, distr)) {
871 for (i = 0; i < 3; i++) pt[i] = point[i] + snextphi * dir[i];
883 if ((ipl + incseg < 0) || (ipl + incseg >
fNz - 2)) {
906 if (iphi[0] < 0 && nphi == 1)
return kFALSE;
911 Int_t incseg = (dir[2] > 0) ? 1 : -1;
915 if (incseg < 0)
return kFALSE;
917 if (ipl ==
fNz - 1) {
919 if (incseg > 0)
return kFALSE;
923 if ((ipl + incseg) < 0 || (ipl + incseg) >
fNz - 1)
return kFALSE;
942 memcpy(pt, point, 3 *
sizeof(
Double_t));
943 for (iphcrt = 0; iphcrt < nphi; iphcrt++) {
945 if (step > stepmax)
return kFALSE;
947 snextphi = stepphi[iphcrt];
948 if (iphi[iphcrt] < 0) {
949 if (iphcrt == nphi - 1)
return kFALSE;
950 if (snextphi > stepmax)
return kFALSE;
951 for (i = 0; i < 3; i++) pt[i] = point[i] + snextphi * dir[i];
955 while (pt[2] >
fZ[ipl + 1]) {
960 while (pt[2] <
fZ[ipl]) {
962 if (ipl < 0)
return kFALSE;
966 rpgin =
Rpg(pt[2], ipl,
kTRUE, apg, bpg);
967 rpgout =
Rpg(pt[2], ipl,
kFALSE, apg, bpg);
968 phi = phi1 + (iphi[iphcrt + 1] + 0.5) * divphi;
972 rproj = pt[0] * cosph + pt[1] * sinph;
973 if (rproj < rpgin || rproj > rpgout) {
992 if (ipl < 0 || ipl >
fNz - 2)
return kFALSE;
993 if (sstart > stepmax)
return kFALSE;
995 memcpy(pt, point, 3 *
sizeof(
Double_t));
997 for (
Int_t i = 0; i < 3; i++) pt[i] += sstart * dir[i];
1000 Int_t incseg = (dir[2] > 0) ? 1 : -1;
1008 Rproj(pt[2], point, dir, cphi, sphi, apr, bpr);
1011 Int_t icrtseg = ipl;
1012 Int_t isegstart = ipl;
1013 Int_t iseglast = (incseg > 0) ? (
fNz - 1) : -1;
1014 Double_t din, dout, rdot, rnew, rpg, apg, bpg, db, znew;
1016 for (ipl = isegstart; ipl != iseglast; ipl += incseg) {
1017 step = (
fZ[ipl + 1 - ((1 + incseg) >> 1)] - pt[2]) * invdir;
1019 if (step > stepmax) {
1026 dz =
fZ[ipl + 1] -
fZ[ipl];
1032 rdot = dir[0] * cphi + dir[1] * sphi + dir[2] * (
fRmin[ipl] -
fRmin[ipl + 1]) / dz;
1037 rnew = apr + bpr * fZ[ipl];
1038 rpg = (rnew -
fRmin[ipl]) * (rnew -
fRmin[ipl + 1]);
1039 if (rpg <= 0) din = (fZ[ipl] - pt[2]) * invdir;
1041 rpg =
Rpg(pt[2], ipl,
kTRUE, apg, bpg);
1044 znew = (apr - apg) / db;
1045 if (znew > fZ[ipl] && znew < fZ[ipl + 1]) {
1046 din = (znew - pt[2]) * invdir;
1057 rdot = dir[0] * cphi + dir[1] * sphi + dir[2] * (
fRmax[ipl] -
fRmax[ipl + 1]) / dz;
1062 rnew = apr + bpr * fZ[ipl];
1063 rpg = (rnew -
fRmax[ipl]) * (rnew -
fRmax[ipl + 1]);
1064 if (rpg <= 0) dout = (fZ[ipl] - pt[2]) * invdir;
1066 rpg =
Rpg(pt[2], ipl,
kFALSE, apg, bpg);
1069 znew = (apr - apg) / db;
1070 if (znew > fZ[ipl] && znew < fZ[ipl + 1]) dout = (znew - pt[2]) * invdir;
1079 if (step > stepmax) {
1083 snext = sstart + step;
1097 if (iact < 3 && safe) {
1110 memcpy(pt, point, 3 *
sizeof(
Double_t));
1125 if (r2 > (radmax * radmax) || pt[2] <
fZ[0] || pt[2] >
fZ[
fNz - 1]) {
1126 pt[2] -= 0.5 * (
fZ[0] +
fZ[
fNz - 1]);
1132 for (i = 0; i < 3; i++) pt[i] += snext * dir[i];
1145 while (phi <
fPhi1) phi += 360.0;
1148 ipsec =
Int_t(ddp / divphi);
1151 if (rpr >= rmin && rpr <= rmax)
return snext;
1165 if (
SliceCrossingZ(pt, dir, icrossed, iph, sph, snewcross, stepmax))
return (snext + snewcross);
1172 while (ph <
fPhi1) ph += 360.;
1174 if (ipsec >
fNedges - 1) ipsec = -1;
1177 if (
fDphi < 360.0) {
1181 if (ipl < 0) ipl = 0;
1182 if (ipl ==
fNz - 1) ipl--;
1193 Double_t rproj = pt[0] * cphi + pt[1] * sphi;
1195 if (rproj <
fRmin[ipl] && rproj >
fRmin[ipl + 1] && dir[2] > 0)
return 0.0;
1196 if (rproj >
fRmin[ipl] && rproj <
fRmin[ipl + 1] && dir[2] < 0)
return 0.0;
1197 if (rproj >
fRmax[ipl] && rproj <
fRmax[ipl + 1] && dir[2] > 0)
return 0.0;
1198 if (rproj <
fRmax[ipl] && rproj >
fRmax[ipl + 1] && dir[2] < 0)
return 0.0;
1204 if (rproj < rpgout + 1.
E-8) {
1207 if (rproj > rpgin - 1.
E-8) {
1219 if (safrmin < safz && safrmin < safrmax && safrmin < safphi) {
1221 Double_t ndotd = dir[0] * cphi + dir[1] * sphi + dir[2] * (
fRmin[ipl] -
fRmin[ipl + 1]) * dzinv;
1223 if (ndotd > 0)
return snext;
1226 if (!done && safrmax < safz && safrmax < safphi) {
1227 Double_t ndotd = dir[0] * cphi + dir[1] * sphi + dir[2] * (
fRmax[ipl] -
fRmax[ipl + 1]) * dzinv;
1229 if (ndotd < 0)
return snext;
1232 if (!done && safz < safphi) {
1236 if (iplc == 0 || iplc ==
fNz - 1) {
1237 if (pt[2] * dir[2] < 0)
return snext;
1269 if (!icrossed)
return snext;
1271 if (iph[0] >= 0 && sph[0] > 1.
E-8)
return snext;
1274 if (
SliceCrossing(pt, dir, icrossed, iph, sph, snewcross, stepmax)) {
1287 const Int_t numPoints = 2 * n *
fNz;
1311 Double_t zmax = start + ndiv * step;
1316 Error(
"Divide",
"makes no sense dividing a pgon on radius");
1320 Error(
"Divide",
"ndiv should divide number of pgon edges");
1328 shape =
new TGeoPgon(-step / 2, step, nedges,
fNz);
1333 for (
id = 0;
id < ndiv;
id++) {
1340 for (ipl = 0; ipl < fNz - 1; ipl++) {
1341 if (start <
fZ[ipl])
1344 if ((start + ndiv * step) >
fZ[ipl + 1])
continue;
1348 zmax =
fZ[isect + 1];
1352 Error(
"Divide",
"cannot divide pcon on Z if divided region is not between 2 consecutive planes");
1355 finder =
new TGeoPatternZ(voldiv, ndiv, start, start + ndiv * step);
1360 for (
id = 0;
id < ndiv;
id++) {
1362 Double_t z2 = start + (
id + 1) * step;
1363 Double_t rmin1 = (
fRmin[isect] * (zmax - z1) -
fRmin[isect + 1] * (zmin - z1)) / (zmax - zmin);
1364 Double_t rmax1 = (
fRmax[isect] * (zmax - z1) -
fRmax[isect + 1] * (zmin - z1)) / (zmax - zmin);
1365 Double_t rmin2 = (
fRmin[isect] * (zmax - z2) -
fRmin[isect + 1] * (zmin - z2)) / (zmax - zmin);
1366 Double_t rmax2 = (
fRmax[isect] * (zmax - z2) -
fRmax[isect + 1] * (zmin - z2)) / (zmax - zmin);
1368 ((
TGeoPgon *)shape)->DefineSection(0, -step / 2, rmin1, rmax1);
1369 ((
TGeoPgon *)shape)->DefineSection(1, step / 2, rmin2, rmax2);
1376 default:
Error(
"Divide",
"Wrong axis type for division");
return 0;
1386 param[0] =
fRmin[0];
1387 param[1] =
fRmax[0];
1389 if (
fRmin[i] < param[0]) param[0] =
fRmin[i];
1390 if (
fRmax[i] > param[1]) param[1] =
fRmax[i];
1394 param[0] *= param[0];
1395 param[1] *= param[1];
1402 param[3] = param[2] +
fDphi;
1410 printf(
"*** Shape %s: TGeoPgon ***\n",
GetName());
1411 printf(
" Nedges = %i\n",
fNedges);
1423 if (nz < 2)
return 0;
1424 Int_t nbPnts = nz * 2 *
n;
1425 if (nbPnts <= 0)
return 0;
1429 Int_t nbSegs = 4 * (nz * n - 1 + (specialCase ==
kTRUE));
1430 Int_t nbPols = 2 * (nz * n - 1 + (specialCase ==
kTRUE));
1451 Int_t nbPnts = nz * 2 *
n;
1452 if (nbPnts <= 0)
return;
1458 Int_t indx, indx2, k;
1463 for (i = 0; i < nz * 2; i++) {
1465 for (j = 1; j <
n; j++) {
1466 buff.
fSegs[indx++] = c;
1467 buff.
fSegs[indx++] = indx2 + j - 1;
1468 buff.
fSegs[indx++] = indx2 + j;
1471 buff.
fSegs[indx++] = c;
1472 buff.
fSegs[indx++] = indx2 + j - 1;
1473 buff.
fSegs[indx++] = indx2;
1478 for (i = 0; i < 2; i++) {
1479 indx2 = i * (nz - 1) * 2 * n;
1480 for (j = 0; j <
n; j++) {
1481 buff.
fSegs[indx++] = c;
1482 buff.
fSegs[indx++] = indx2 + j;
1483 buff.
fSegs[indx++] = indx2 + n + j;
1488 for (i = 0; i < (nz - 1); i++) {
1491 for (j = 0; j <
n; j++) {
1492 buff.
fSegs[indx++] = c + 2;
1493 buff.
fSegs[indx++] = indx2 + j;
1494 buff.
fSegs[indx++] = indx2 + n * 2 + j;
1497 indx2 = i * n * 2 +
n;
1498 for (j = 0; j <
n; j++) {
1499 buff.
fSegs[indx++] = c + 3;
1500 buff.
fSegs[indx++] = indx2 + j;
1501 buff.
fSegs[indx++] = indx2 + n * 2 + j;
1508 for (i = 1; i < (nz - 1); i++) {
1509 for (j = 0; j < 2; j++) {
1510 buff.
fSegs[indx++] = c;
1511 buff.
fSegs[indx++] = 2 * i * n + j * (n - 1);
1512 buff.
fSegs[indx++] = (2 * i + 1) * n + j * (n - 1);
1523 for (j = 0; j < n - 1; j++) {
1524 buff.
fPols[indx++] = c + 3;
1525 buff.
fPols[indx++] = 4;
1526 buff.
fPols[indx++] = 2 * nz * m + i * n + j;
1527 buff.
fPols[indx++] = i * (nz * 2 - 2) * m + m + j;
1528 buff.
fPols[indx++] = 2 * nz * m + i * n + j + 1;
1529 buff.
fPols[indx++] = i * (nz * 2 - 2) * m + j;
1532 buff.
fPols[indx++] = c + 3;
1533 buff.
fPols[indx++] = 4;
1534 buff.
fPols[indx++] = 2 * nz * m + i * n + j;
1535 buff.
fPols[indx++] = i * (nz * 2 - 2) * m + m + j;
1536 buff.
fPols[indx++] = 2 * nz * m + i *
n;
1537 buff.
fPols[indx++] = i * (nz * 2 - 2) * m + j;
1540 for (j = 0; j < n - 1; j++) {
1541 buff.
fPols[indx++] = c + 3;
1542 buff.
fPols[indx++] = 4;
1543 buff.
fPols[indx++] = i * (nz * 2 - 2) * m + j;
1544 buff.
fPols[indx++] = 2 * nz * m + i * n + j + 1;
1545 buff.
fPols[indx++] = i * (nz * 2 - 2) * m + m + j;
1546 buff.
fPols[indx++] = 2 * nz * m + i * n + j;
1549 buff.
fPols[indx++] = c + 3;
1550 buff.
fPols[indx++] = 4;
1551 buff.
fPols[indx++] = i * (nz * 2 - 2) * m + j;
1552 buff.
fPols[indx++] = 2 * nz * m + i *
n;
1553 buff.
fPols[indx++] = i * (nz * 2 - 2) * m + m + j;
1554 buff.
fPols[indx++] = 2 * nz * m + i * n + j;
1558 for (k = 0; k < (nz - 1); k++) {
1560 for (j = 0; j < n - 1; j++) {
1561 buff.
fPols[indx++] = c + i;
1562 buff.
fPols[indx++] = 4;
1563 buff.
fPols[indx++] = nz * 2 * m + (2 * k + i * 1 + 2) * n + j + 1;
1564 buff.
fPols[indx++] = (2 * k + i * 1 + 2) * m + j;
1565 buff.
fPols[indx++] = nz * 2 * m + (2 * k + i * 1 + 2) * n + j;
1566 buff.
fPols[indx++] = (2 * k + i * 1) * m + j;
1569 buff.
fPols[indx++] = c + i;
1570 buff.
fPols[indx++] = 4;
1571 buff.
fPols[indx++] = nz * 2 * m + (2 * k + i * 1 + 2) * n;
1572 buff.
fPols[indx++] = (2 * k + i * 1 + 2) * m + j;
1573 buff.
fPols[indx++] = nz * 2 * m + (2 * k + i * 1 + 2) * n + j;
1574 buff.
fPols[indx++] = (2 * k + i * 1) * m + j;
1577 for (j = 0; j < n - 1; j++) {
1578 buff.
fPols[indx++] = c + i;
1579 buff.
fPols[indx++] = 4;
1580 buff.
fPols[indx++] = (2 * k + i * 1) * m + j;
1581 buff.
fPols[indx++] = nz * 2 * m + (2 * k + i * 1 + 2) * n + j;
1582 buff.
fPols[indx++] = (2 * k + i * 1 + 2) * m + j;
1583 buff.
fPols[indx++] = nz * 2 * m + (2 * k + i * 1 + 2) * n + j + 1;
1586 buff.
fPols[indx++] = c + i;
1587 buff.
fPols[indx++] = 4;
1588 buff.
fPols[indx++] = (2 * k + i * 1) * m + j;
1589 buff.
fPols[indx++] = nz * 2 * m + (2 * k + i * 1 + 2) * n + j;
1590 buff.
fPols[indx++] = (2 * k + i * 1 + 2) * m + j;
1591 buff.
fPols[indx++] = nz * 2 * m + (2 * k + i * 1 + 2) * n;
1598 indx2 = nz * 2 * (n - 1);
1599 for (k = 0; k < (nz - 1); k++) {
1600 buff.
fPols[indx++] = c + 2;
1601 buff.
fPols[indx++] = 4;
1602 buff.
fPols[indx++] = k == 0 ? indx2 : indx2 + 2 * nz * n + 2 * (k - 1);
1603 buff.
fPols[indx++] = indx2 + 2 * (k + 1) * n;
1604 buff.
fPols[indx++] = indx2 + 2 * nz * n + 2 * k;
1605 buff.
fPols[indx++] = indx2 + (2 * k + 3) * n;
1607 buff.
fPols[indx++] = c + 2;
1608 buff.
fPols[indx++] = 4;
1609 buff.
fPols[indx++] = k == 0 ? indx2 + n - 1 : indx2 + 2 * nz * n + 2 * (k - 1) + 1;
1610 buff.
fPols[indx++] = indx2 + (2 * k + 3) * n + n - 1;
1611 buff.
fPols[indx++] = indx2 + 2 * nz * n + 2 * k + 1;
1612 buff.
fPols[indx++] = indx2 + 2 * (k + 1) * n + n - 1;
1614 buff.
fPols[indx - 8] = indx2 +
n;
1615 buff.
fPols[indx - 2] = indx2 + 2 * n - 1;
1629 if (ipl < 0 || ipl >
fNz - 2) {
1630 Fatal(
"Rpg",
"Plane index parameter ipl=%i out of range\n", ipl);
1650 a = (r1 * fZ[ipl + 1] -
r2 * fZ[ipl]) * dzinv;
1651 b = (
r2 -
r1) * dzinv;
1668 a = ((point[0] * dir[2] - point[2] * dir[0]) * cphi + (point[1] * dir[2] - point[2] * dir[1]) * sphi) * invdirz;
1669 b = (dir[0] * cphi + dir[1] * sphi) * invdirz;
1683 if (ipl < 0 || ipl >
fNz - 2)
return (safmin + 1.);
1686 if (dz < 1
E-9)
return 1E9;
1687 Double_t znew = point[2] - 0.5 * (fZ[ipl] + fZ[ipl + 1]);
1699 r =
TMath::Sqrt(point[0] * point[0] + point[1] * point[1]);
1700 Double_t ro1 = 0.5 * (rmin1 + rmin2);
1701 Double_t tg1 = (rmin2 - rmin1) / dz;
1703 Double_t ro2 = 0.5 * (rmax1 + rmax2);
1704 Double_t tg2 = (rmax2 - rmax1) / dz;
1709 saf[2] = (rout -
r) * cr2;
1710 for (i = 0; i < 3; i++) saf[i] = -saf[i];
1713 if (safe < 0) safe = 0;
1718 if (rmin1 + rmin2 > 1
E-10) {
1719 ta = (rmin2 - rmin1) / dz;
1721 rpgon = rmin1 + (point[2] - fZ[ipl]) * ta;
1722 saf[1] = (r - rpgon) * calf;
1726 ta = (rmax2 - rmax1) / dz;
1728 rpgon = rmax1 + (point[2] - fZ[ipl]) * ta;
1729 saf[2] = (rpgon -
r) * calf;
1734 for (i = 0; i < 3; i++) saf[i] = -saf[i];
1738 if (safe < 0) safe = 0;
1750 Int_t ipl, iplane, iphi;
1756 if (ipl == (
fNz - 1))
return 0;
1757 if (ipl < 0)
return 0;
1758 dz = 0.5 * (
fZ[ipl + 1] -
fZ[ipl]);
1759 if (dz < 1
E-8)
return 0;
1762 if (safmin > 1E10) {
1770 while ((iplane <
fNz - 1) && saftmp < 1E10) {
1772 if (saftmp < safmin) safmin = saftmp;
1778 while ((iplane >= 0) && saftmp < 1E10) {
1780 if (saftmp < safmin) safmin = saftmp;
1789 else if (ipl ==
fNz - 1)
1791 dz = 0.5 * (
fZ[ipl + 1] -
fZ[ipl]);
1794 if (ipl >
fNz - 2)
return 0.;
1795 dz = 0.5 * (
fZ[ipl + 1] -
fZ[ipl]);
1804 while ((iplane <
fNz - 1) && saftmp < 1E10) {
1806 if (saftmp < safmin) safmin = saftmp;
1812 while ((iplane >= 0) && saftmp < 1E10) {
1814 if (saftmp < safmin) safmin = saftmp;
1826 out <<
" // Shape: " <<
GetName() <<
" type: " <<
ClassName() << std::endl;
1827 out <<
" phi1 = " <<
fPhi1 <<
";" << std::endl;
1828 out <<
" dphi = " <<
fDphi <<
";" << std::endl;
1829 out <<
" nedges = " <<
fNedges <<
";" << std::endl;
1830 out <<
" nz = " <<
fNz <<
";" << std::endl;
1831 out <<
" TGeoPgon *pgon = new TGeoPgon(\"" <<
GetName() <<
"\",phi1,dphi,nedges,nz);" << std::endl;
1833 out <<
" z = " <<
fZ[i] <<
";" << std::endl;
1834 out <<
" rmin = " <<
fRmin[i] <<
";" << std::endl;
1835 out <<
" rmax = " <<
fRmax[i] <<
";" << std::endl;
1836 out <<
" pgon->DefineSection(" << i <<
", z,rmin,rmax);" << std::endl;
1838 out <<
" TGeoShape *" <<
GetPointerName() <<
" = pgon;" << std::endl;
1852 Error(
"SetDimensions",
"Pgon %s: Number of Z sections must be > 2",
GetName());
1857 if (
fZ)
delete[]
fZ;
1864 for (
Int_t i = 0; i <
fNz; i++)
DefineSection(i, param[4 + 3 * i], param[5 + 3 * i], param[6 + 3 * i]);
1874 dphi =
fDphi / (n - 1);
1880 for (i = 0; i <
fNz; i++) {
1881 for (j = 0; j <
n; j++) {
1885 points[indx++] =
fZ[i];
1887 for (j = 0; j <
n; j++) {
1891 points[indx++] =
fZ[i];
1904 dphi =
fDphi / (n - 1);
1910 for (i = 0; i <
fNz; i++) {
1911 for (j = 0; j <
n; j++) {
1915 points[indx++] =
fZ[i];
1917 for (j = 0; j <
n; j++) {
1921 points[indx++] =
fZ[i];
1936 nsegs = 4 * (nz * n - 1 + (specialCase ==
kTRUE));
1937 npols = 2 * (nz * n - 1 + (specialCase ==
kTRUE));
1969 Int_t nbPnts = nz * 2 *
n;
1970 if (nz >= 2 && nbPnts > 0) {
1972 Int_t nbSegs = 4 * (nz * n - 1 + (specialCase ==
kTRUE));
1973 Int_t nbPols = 2 * (nz * n - 1 + (specialCase ==
kTRUE));
1974 if (buffer.
SetRawSizes(nbPnts, 3 * nbPnts, nbSegs, 3 * nbSegs, nbPols, 6 * nbPols)) {
2001 for (
Int_t i = 0; i < vecsize; i++) inside[i] =
Contains(&points[3 * i]);
2011 for (
Int_t i = 0; i < vecsize; i++)
ComputeNormal(&points[3 * i], &dirs[3 * i], &norms[3 * i]);
2020 for (
Int_t i = 0; i < vecsize; i++) dists[i] =
DistFromInside(&points[3 * i], &dirs[3 * i], 3, step[i]);
2029 for (
Int_t i = 0; i < vecsize; i++) dists[i] =
DistFromOutside(&points[3 * i], &dirs[3 * i], 3, step[i]);
2039 for (
Int_t i = 0; i < vecsize; i++) safe[i] =
Safety(&points[3 * i], inside[i]);
TGeoVolumeMulti * MakeVolumeMulti(const char *name, TGeoMedium *medium)
Make a TGeoVolumeMulti handling a list of volumes.
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 void SetPoints(Double_t *points) const
create polygone mesh points
virtual void GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
Returns numbers of vertices, segments and polygons composing the shape mesh.
double dist(Rotation3D const &r1, Rotation3D const &r2)
#define snext(osub1, osub2)
Long64_t LocMax(Long64_t n, const T *a)
void SetFinder(TGeoPatternFinder *finder)
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 SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
virtual void Sizeof3D() const
fill size of this 3-D object
void AddNodeOffset(TGeoVolume *vol, Int_t copy_no, Double_t offset=0, Option_t *option="")
Add a division node to the list of nodes.
void ClearThreadData() const
virtual Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const
compute distance from inside point to surface of the polygone first find out in which Z section the p...
virtual ~TGeoPgon()
destructor
virtual void GetBoundingCylinder(Double_t *param) const
Fill vector param[4] with the bounding cylinder parameters.
Bool_t TestBit(UInt_t f) const
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Double_t * fDblBuffer
[fNedges+4] temporary int buffer array
virtual void InspectShape() const
Inspect the PGON parameters.
Short_t Min(Short_t a, Short_t b)
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 Safety(const Double_t *point, Bool_t in=kTRUE) const
computes the closest distance from given point to this shape, according to option.
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...
virtual Int_t GetNsegments() const
Returns number of segments on each mesh circle segment.
void LocatePhi(const Double_t *point, Int_t &ipsec) const
Locates index IPSEC of the phi sector containing POINT.
TObject * At(Int_t idx) const
Int_t fThreadSize
Navigation data per thread.
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.
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.
~ThreadData_t()
Destructor.
virtual Bool_t Contains(const Double_t *point) const
test if point is inside this shape check total z range
static Bool_t IsSameWithinTolerance(Double_t a, Double_t b)
Check if two numbers differ with less than a tolerance.
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
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...
static Double_t Tolerance()
Int_t GetNdaughters() const
std::vector< ThreadData_t * > fThreadData
virtual const char * ClassName() const
Returns name of class to which the object belongs.
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...
void AddVolume(TGeoVolume *vol)
Add a volume with valid shape to the list of volumes.
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, from start position with the given step.
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.
constexpr Double_t DegToRad()
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
Fills a static 3D buffer and returns a reference.
TGeoMedium * GetMedium() const
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 void ComputeBBox()
compute bounding box for a polygone Check if the sections are in increasing Z order ...
Double_t ATan2(Double_t, Double_t)
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.
void SetSectionsValid(UInt_t mask)
const char * GetPointerName() const
Provide a pointer name containing uid.
virtual void InspectShape() const
print shape parameters
Base finder class for patterns.
virtual const char * GetName() const
Get the shape name.
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const
Compute distance from outside point to surface of the polygone.
Int_t ShapeDistancetoPrimitive(Int_t numpoints, Int_t px, Int_t py) const
Returns distance to shape primitive mesh.
Bool_t SectionsValid(UInt_t mask) const
Base abstract class for all shapes.
unsigned int r1[N_CITIES]
TObjArray * GetListOfShapes() const
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.
void TransformPoints(Double_t *points, UInt_t NbPoints) const
Tranform a set of points (LocalToMaster)
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
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.
Generic 3D primitive description class.
void CreateThreadData(Int_t nthreads)
Create thread data for n threads max.
void SetDivIndex(Int_t index)
ThreadData_t()
[fNedges+4] temporary double buffer array
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.
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,s2.
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.
R__EXTERN TGeoManager * gGeoManager
virtual Double_t Capacity() const
Computes capacity of the shape in [length^3].
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const
Compute distance from outside point to surface of the box.
ThreadData_t & GetThreadData() const
Int_t IndexOf(const TObject *obj) const
Node containing an offset.
void SetShapeBit(UInt_t f, Bool_t set)
Equivalent of TObject::SetBit.
you should not use this method at all Int_t Int_t z
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...
constexpr Double_t RadToDeg()
virtual void SetDimensions(Double_t *param)
Set PGON dimensions starting from an array.
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
compute closest distance from point px,py to each corner
static Int_t ThreadId()
Translates the current thread id to an ordinal number.
virtual void SetSegsAndPols(TBuffer3D &buff) const
Fill TBuffer3D structure for segments and polygons.
Short_t Max(Short_t a, Short_t b)
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...
virtual Int_t GetNmeshVertices() const
Return number of vertices of the mesh representation.
virtual TBuffer3D * MakeBuffer3D() const
Creates a TBuffer3D describing this shape.
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
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.
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.
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...
Double_t Sqrt(Double_t x)
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
std::mutex fMutex
Size for the navigation data array.
Long64_t LocMin(Long64_t n, const T *a)
double norm(double *x, double *p)
Int_t GetBasicColor() const
Get the basic color (0-7).
Long64_t BinarySearch(Long64_t n, const T *array, T value)
unsigned int r2[N_CITIES]
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. ...
const char * Data() const