Estimation of the geometrical volume span.
428 const CuboidVolumeBounds* box =
429 dynamic_cast<const CuboidVolumeBounds*
>(&volBounds);
430 const TrapezoidVolumeBounds* trd =
431 dynamic_cast<const TrapezoidVolumeBounds*
>(&volBounds);
432 const DoubleTrapezoidVolumeBounds* dtrd =
433 dynamic_cast<const DoubleTrapezoidVolumeBounds*
>(&volBounds);
434 const BevelledCylinderVolumeBounds* bcyl =
435 dynamic_cast<const BevelledCylinderVolumeBounds*
>(&volBounds);
436 const CylinderVolumeBounds* cyl =
437 dynamic_cast<const CylinderVolumeBounds*
>(&volBounds);
438 const SubtractedVolumeBounds* sub =
439 dynamic_cast<const SubtractedVolumeBounds*
>(&volBounds);
440 const CombinedVolumeBounds* comb =
441 dynamic_cast<const CombinedVolumeBounds*
>(&volBounds);
442 const SimplePolygonBrepVolumeBounds* spb =
443 dynamic_cast<const SimplePolygonBrepVolumeBounds*
>(&volBounds);
444 const PrismVolumeBounds* prism =
445 dynamic_cast<const PrismVolumeBounds*
>(&volBounds);
451 transform * sub->outer()->transform(), zTol,
457 comb->first()->volumeBounds(),
458 transform * comb->first()->transform(), zTol, phiTol);
460 comb->second()->volumeBounds(),
461 transform * comb->second()->transform(), zTol, phiTol);
464 scomb.rMin =
std::min((*s1).rMin, (*s2).rMin);
465 scomb.rMax =
std::max((*s1).rMax, (*s2).rMax);
466 scomb.xMin =
std::min((*s1).xMin, (*s2).xMin);
467 scomb.xMax =
std::max((*s1).xMax, (*s2).xMax);
468 scomb.yMin =
std::min((*s1).yMin, (*s2).yMin);
469 scomb.yMax =
std::max((*s1).yMax, (*s2).yMax);
470 scomb.zMin =
std::min((*s1).zMin, (*s2).zMin);
471 scomb.zMax =
std::max((*s1).zMax, (*s2).zMax);
472 if ((*s1).phiMin < (*s1).phiMax && (*s2).phiMin < (*s2).phiMax) {
473 scomb.phiMin =
std::min((*s1).phiMin, (*s2).phiMin);
474 scomb.phiMax =
std::max((*s1).phiMax, (*s2).phiMax);
475 }
else if ((*s1).phiMin < (*s1).phiMax && (*s2).phiMin > (*s2).phiMax) {
476 if ((*s1).phiMin > (*s2).phiMax) {
477 scomb.phiMin =
std::min((*s1).phiMin, (*s2).phiMin);
478 scomb.phiMax = (*s2).phiMax;
479 }
else if ((*s1).phiMax < (*s2).phiMin) {
480 scomb.phiMin = (*s2).phiMin;
481 scomb.phiMax =
std::max((*s1).phiMax, (*s2).phiMax);
484 scomb.phiMax = 2 *
M_PI;
486 }
else if ((*s1).phiMin > (*s1).phiMax && (*s2).phiMin < (*s2).phiMax) {
487 if ((*s2).phiMin > (*s1).phiMax) {
488 scomb.phiMin =
std::min((*s1).phiMin, (*s2).phiMin);
489 scomb.phiMax = (*s1).phiMax;
490 }
else if ((*s2).phiMax < (*s1).phiMin) {
491 scomb.phiMin = (*s1).phiMin;
492 scomb.phiMax =
std::max((*s1).phiMax, (*s2).phiMax);
495 scomb.phiMax = 2 *
M_PI;
498 scomb.phiMin =
std::min((*s1).phiMin, (*s2).phiMin);
499 scomb.phiMax =
std::max((*s1).phiMax, (*s2).phiMax);
501 return std::make_unique<VolumeSpan>(scomb);
505 double minZ{1.e6}, maxZ{-1.e6}, minPhi{2 *
M_PI}, maxPhi{0.}, minR{1.e6},
506 maxR{0.}, minX{1.e6}, maxX{-1.e6}, minY{1.e6}, maxY{-1.e6};
509 std::vector<Amg::Vector3D> vtx;
510 std::vector<std::pair<int, int>> edges;
514 vtx.emplace_back(box->halflengthX(), box->halflengthY(),
516 vtx.emplace_back(-box->halflengthX(), box->halflengthY(),
518 vtx.emplace_back(box->halflengthX(), -box->halflengthY(),
520 vtx.emplace_back(-box->halflengthX(), -box->halflengthY(),
522 vtx.emplace_back(box->halflengthX(), box->halflengthY(),
523 -box->halflengthZ());
524 vtx.emplace_back(-box->halflengthX(), box->halflengthY(),
525 -box->halflengthZ());
526 vtx.emplace_back(box->halflengthX(), -box->halflengthY(),
527 -box->halflengthZ());
528 vtx.emplace_back(-box->halflengthX(), -box->halflengthY(),
529 -box->halflengthZ());
530 edges.emplace_back(0, 1);
531 edges.emplace_back(0, 2);
532 edges.emplace_back(1, 3);
533 edges.emplace_back(2, 3);
534 edges.emplace_back(4, 5);
535 edges.emplace_back(4, 6);
536 edges.emplace_back(5, 7);
537 edges.emplace_back(6, 7);
538 edges.emplace_back(0, 4);
539 edges.emplace_back(1, 5);
540 edges.emplace_back(2, 6);
541 edges.emplace_back(3, 7);
544 vtx.emplace_back(trd->maxHalflengthX(), trd->halflengthY(),
546 vtx.emplace_back(-trd->maxHalflengthX(), trd->halflengthY(),
548 vtx.emplace_back(trd->minHalflengthX(), -trd->halflengthY(),
550 vtx.emplace_back(-trd->minHalflengthX(), -trd->halflengthY(),
552 vtx.emplace_back(trd->maxHalflengthX(), trd->halflengthY(),
553 -trd->halflengthZ());
554 vtx.emplace_back(-trd->maxHalflengthX(), trd->halflengthY(),
555 -trd->halflengthZ());
556 vtx.emplace_back(trd->minHalflengthX(), -trd->halflengthY(),
557 -trd->halflengthZ());
558 vtx.emplace_back(-trd->minHalflengthX(), -trd->halflengthY(),
559 -trd->halflengthZ());
560 edges.emplace_back(0, 1);
561 edges.emplace_back(0, 2);
562 edges.emplace_back(1, 3);
563 edges.emplace_back(2, 3);
564 edges.emplace_back(4, 5);
565 edges.emplace_back(4, 6);
566 edges.emplace_back(5, 7);
567 edges.emplace_back(6, 7);
568 edges.emplace_back(0, 4);
569 edges.emplace_back(1, 5);
570 edges.emplace_back(2, 6);
571 edges.emplace_back(3, 7);
574 vtx.emplace_back(dtrd->maxHalflengthX(), 2 * dtrd->halflengthY2(),
575 dtrd->halflengthZ());
576 vtx.emplace_back(-dtrd->maxHalflengthX(), 2 * dtrd->halflengthY2(),
577 dtrd->halflengthZ());
578 vtx.emplace_back(dtrd->medHalflengthX(), 0., dtrd->halflengthZ());
579 vtx.emplace_back(-dtrd->medHalflengthX(), 0., dtrd->halflengthZ());
580 vtx.emplace_back(dtrd->minHalflengthX(), -2 * dtrd->halflengthY1(),
581 dtrd->halflengthZ());
582 vtx.emplace_back(-dtrd->minHalflengthX(), -2 * dtrd->halflengthY1(),
583 dtrd->halflengthZ());
584 vtx.emplace_back(dtrd->maxHalflengthX(), 2 * dtrd->halflengthY2(),
585 -dtrd->halflengthZ());
586 vtx.emplace_back(-dtrd->maxHalflengthX(), 2 * dtrd->halflengthY2(),
587 -dtrd->halflengthZ());
588 vtx.emplace_back(dtrd->medHalflengthX(), 0., -dtrd->halflengthZ());
589 vtx.emplace_back(-dtrd->medHalflengthX(), 0., -dtrd->halflengthZ());
590 vtx.emplace_back(dtrd->minHalflengthX(), -2 * dtrd->halflengthY1(),
591 -dtrd->halflengthZ());
592 vtx.emplace_back(-dtrd->minHalflengthX(), -2 * dtrd->halflengthY1(),
593 -dtrd->halflengthZ());
594 edges.emplace_back(0, 1);
595 edges.emplace_back(0, 2);
596 edges.emplace_back(1, 3);
597 edges.emplace_back(2, 4);
598 edges.emplace_back(3, 5);
599 edges.emplace_back(4, 5);
600 edges.emplace_back(6, 7);
601 edges.emplace_back(6, 8);
602 edges.emplace_back(7, 9);
603 edges.emplace_back(8, 10);
604 edges.emplace_back(9, 11);
605 edges.emplace_back(10, 11);
606 edges.emplace_back(0, 6);
607 edges.emplace_back(1, 7);
608 edges.emplace_back(2, 8);
609 edges.emplace_back(3, 9);
610 edges.emplace_back(4, 10);
611 edges.emplace_back(5, 11);
614 dPhi = bcyl->halfPhiSector();
615 vtx.emplace_back(0., 0., bcyl->halflengthZ());
616 vtx.emplace_back(0., 0., -bcyl->halflengthZ());
617 edges.emplace_back(0, 1);
621 vtx.emplace_back(bcyl->outerRadius() * cosDphi,
622 bcyl->outerRadius() * sinDphi,
623 bcyl->halflengthZ());
624 vtx.emplace_back(bcyl->innerRadius() * cosDphi,
625 bcyl->innerRadius() * sinDphi,
626 bcyl->halflengthZ());
627 vtx.emplace_back(bcyl->outerRadius() * cosDphi,
628 -bcyl->outerRadius() * sinDphi,
629 bcyl->halflengthZ());
630 vtx.emplace_back(bcyl->innerRadius() * cosDphi,
631 -bcyl->innerRadius() * sinDphi,
632 bcyl->halflengthZ());
633 vtx.emplace_back(bcyl->outerRadius() * cosDphi,
634 bcyl->outerRadius() * sinDphi,
635 -bcyl->halflengthZ());
636 vtx.emplace_back(bcyl->innerRadius() * cosDphi,
637 bcyl->innerRadius() * sinDphi,
638 -bcyl->halflengthZ());
639 vtx.emplace_back(bcyl->outerRadius() * cosDphi,
640 -bcyl->outerRadius() * sinDphi,
641 -bcyl->halflengthZ());
642 vtx.emplace_back(bcyl->innerRadius() * cosDphi,
643 -bcyl->innerRadius() * sinDphi,
644 -bcyl->halflengthZ());
645 vtx.emplace_back(bcyl->outerRadius(), 0.,
648 edges.emplace_back(2, 3);
649 edges.emplace_back(4, 5);
650 edges.emplace_back(6, 7);
651 edges.emplace_back(8, 9);
652 if (bcyl->type() == 1 || bcyl->type() == 3) {
653 edges.emplace_back(3, 5);
654 edges.emplace_back(7, 9);
656 if (bcyl->type() == 2 || bcyl->type() == 3) {
657 edges.emplace_back(2, 4);
658 edges.emplace_back(6, 8);
663 dPhi = cyl->halfPhiSector();
664 vtx.emplace_back(0., 0., cyl->halflengthZ());
665 vtx.emplace_back(0., 0., -cyl->halflengthZ());
666 edges.emplace_back(0, 1);
670 vtx.emplace_back(cyl->outerRadius() * cosDphi,
671 cyl->outerRadius() * sinDphi, cyl->halflengthZ());
672 vtx.emplace_back(cyl->innerRadius() * cosDphi,
673 cyl->innerRadius() * sinDphi, cyl->halflengthZ());
674 vtx.emplace_back(cyl->outerRadius() * cosDphi,
675 -cyl->outerRadius() * sinDphi, cyl->halflengthZ());
676 vtx.emplace_back(cyl->outerRadius() * cosDphi,
677 -cyl->outerRadius() * sinDphi, cyl->halflengthZ());
678 vtx.emplace_back(cyl->outerRadius() * cosDphi,
679 cyl->outerRadius() * sinDphi, -cyl->halflengthZ());
680 vtx.emplace_back(cyl->innerRadius() * cosDphi,
681 cyl->innerRadius() * sinDphi, -cyl->halflengthZ());
682 vtx.emplace_back(cyl->outerRadius() * cosDphi,
683 -cyl->outerRadius() * sinDphi,
684 -cyl->halflengthZ());
685 vtx.emplace_back(cyl->outerRadius() * cosDphi,
686 -cyl->outerRadius() * sinDphi,
687 -cyl->halflengthZ());
688 vtx.emplace_back(cyl->outerRadius(), 0.,
691 edges.emplace_back(2, 3);
692 edges.emplace_back(4, 5);
693 edges.emplace_back(6, 7);
694 edges.emplace_back(8, 9);
699 const std::vector<std::pair<double, double>> vtcs = spb->xyVertices();
700 for (
const auto& vtc : vtcs) {
701 vtx.emplace_back(vtc.first, vtc.second, spb->halflengthZ());
702 vtx.emplace_back(vtc.first, vtc.second, -spb->halflengthZ());
703 edges.emplace_back(vtx.size() - 2, vtx.size() - 1);
704 if (vtx.size() > 2) {
706 vtx.size() - 4, vtx.size() - 2);
708 vtx.size() - 3, vtx.size() - 1);
710 if (vtx.size() > 4) {
711 edges.emplace_back(vtx.size() - 2, 1);
712 edges.emplace_back(vtx.size() - 1, 0);
715 edges.emplace_back(0, vtx.size() - 2);
716 edges.emplace_back(1, vtx.size() - 1);
720 const std::vector<std::pair<double, double>> vtcs = prism->xyVertices();
721 for (
const auto& vtc : vtcs) {
722 vtx.emplace_back(vtc.first, vtc.second, prism->halflengthZ());
723 vtx.emplace_back(vtc.first, vtc.second, -prism->halflengthZ());
724 edges.emplace_back(vtx.size() - 2, vtx.size() - 1);
725 if (vtx.size() > 2) {
727 vtx.size() - 4, vtx.size() - 2);
729 vtx.size() - 3, vtx.size() - 1);
732 edges.emplace_back(0, vtx.size() - 2);
733 edges.emplace_back(1, vtx.size() - 1);
736 std::vector<Amg::Vector3D> vtxt;
738 for (
unsigned int ie = 0;
ie < vtx.size();
ie++) {
743 double rad = gp.perp();
760 double ro = cyl ? cyl->outerRadius() : bcyl->outerRadius();
761 double ri = cyl ? cyl->innerRadius() : bcyl->innerRadius();
764 (vtxt[edges[0].first] - vtxt[edges[0].second]).
unit();
765 maxZ += ro *
sin(
dir.theta());
766 minZ += -ro *
sin(
dir.theta());
771 Intersection closest = peri.straightLineIntersection(vtxt[1],
dir);
772 double le = (vtxt[0] - vtxt[1]).
norm();
773 if ((closest.position - vtxt[0]).norm() < le &&
774 (closest.position - vtxt[1]).
norm() < le) {
775 if (minR > closest.position.perp() - ro)
776 minR =
std::max(0., closest.position.perp() - ro);
778 double phiClosest = closest.position.phi() +
M_PI;
779 if (phiClosest < minPhi || phiClosest > maxPhi) {
780 double phiTmp = minPhi;
785 minR =
std::max(0., minR - ro * std::abs(
dir.z()));
787 const double aTan = std::atan2(ro, minR);
792 if (maxPhi > 2 *
M_PI)
795 maxR += ro * std::abs(
cos(
dir.theta()));
806 for (
unsigned int ie = 0;
ie < edges.size();
ie++) {
808 (vtxt[edges[
ie].first] - vtxt[edges[
ie].second]).
unit();
809 Intersection closest =
810 peri.straightLineIntersection(vtxt[edges[
ie].
second],
dir);
812 (vtxt[edges[
ie].first] - vtxt[edges[
ie].second]).
norm();
813 if ((closest.position - vtxt[edges[
ie].first]).norm() < le &&
814 (closest.position - vtxt[edges[
ie].second]).
norm() < le)
815 if (minR > closest.position.perp())
816 minR = closest.position.perp();
819 if (vtxt.size() > 10) {
840 if (vtxt[10].
phi() +
M_PI < minPhi ||
841 vtxt[10].
phi() +
M_PI > maxPhi) {
845 for (
unsigned int iv = 2; iv < vtxt.size(); iv++) {
846 phiTmp = vtxt[iv].phi() +
M_PI;
849 minPhi = phiTmp < minPhi ? phiTmp : minPhi;
850 maxPhi = phiTmp > maxPhi ? phiTmp : maxPhi;
852 if (minPhi > 2 *
M_PI)
854 if (maxPhi > 2 *
M_PI)
862 if (minPhi >= maxPhi && (minPhi - maxPhi) <
M_PI) {
872 for (
unsigned int ie = 0;
ie < edges.size();
ie++) {
874 (vtxt[edges[
ie].first] - vtxt[edges[
ie].second]).
unit();
875 Intersection closest =
876 peri.straightLineIntersection(vtxt[edges[
ie].
second],
dir);
877 double le = (vtxt[edges[
ie].first] - vtxt[edges[
ie].second]).
norm();
878 if ((closest.position - vtxt[edges[
ie].first]).norm() < le &&
879 (closest.position - vtxt[edges[
ie].second]).
norm() < le)
880 if (minR > closest.position.perp())
881 minR = closest.position.perp();
884 if (std::abs(maxPhi - minPhi) >
M_PI) {
885 double phiTmp = minPhi;
888 for (
unsigned int iv = 0; iv < vtxt.size(); iv++) {
889 phiTmp = vtxt[iv].phi() +
M_PI;
892 minPhi = phiTmp < minPhi ? phiTmp : minPhi;
893 maxPhi = phiTmp > maxPhi ? phiTmp : maxPhi;
895 if (minPhi > 2 *
M_PI)
897 if (maxPhi > 2 *
M_PI)
899 if (minPhi >= maxPhi && (minPhi - maxPhi) <
M_PI) {
906 if (cyl || bcyl || box || trd || dtrd || spb || prism) {
907 span.zMin = minZ - zTol;
908 span.zMax = maxZ - +zTol;
909 minPhi = (minPhi - phiTol) < 0 ? minPhi - phiTol + 2 *
M_PI
911 span.phiMin = minPhi;
912 maxPhi = (maxPhi + phiTol) > 2 *
M_PI ? maxPhi + phiTol - 2 *
M_PI
914 span.phiMax = maxPhi;
916 span.rMax = maxR + zTol;
917 span.xMin = minX - zTol;
918 span.xMax = maxX - +zTol;
919 span.yMin = minY - zTol;
920 span.yMax = maxY - +zTol;
924 return std::make_unique<VolumeSpan>(
span);