diff --git a/src/Classic/AbsBeamline/ElementBase.cpp b/src/Classic/AbsBeamline/ElementBase.cpp index fe4fde06cbca89180158da48edcb40f116a25ef7..727d1e621ca3108b0d64b147186693b922f30373 100644 --- a/src/Classic/AbsBeamline/ElementBase.cpp +++ b/src/Classic/AbsBeamline/ElementBase.cpp @@ -304,4 +304,64 @@ void ElementBase::setCurrentSCoordinate(double s) { elementEdge_m = actionRange_m.front().first; } } +} + +bool ElementBase::isInsideTransverse(const Vector_t &r) const +{ + double x = aperture_m.second[0]; + double y = aperture_m.second[1]; + double f = 1.0; + if (aperture_m.first == CONIC_RECTANGULAR || + aperture_m.first == CONIC_ELLIPTIC) { + Vector_t rRelativeToBegin = getEdgeToBegin().transformTo(r); + double fractionLength = rRelativeToBegin(2) / getElementLength(); + f = fractionLength * aperture_m.second[2]; + } + + switch(aperture_m.first) { + case RECTANGULAR: + return (std::abs(r[0]) < aperture_m.second[0] && std::abs(r[1]) < aperture_m.second[1]); + case ELLIPTICAL: + return (std::pow(r[0] / aperture_m.second[0], 2) + std::pow(r[1] / aperture_m.second[1], 2) < 1.0); + case CONIC_RECTANGULAR: + return (std::abs(r[0]) < f * aperture_m.second[0] && std::abs(r[1]) < f * aperture_m.second[1]); + case CONIC_ELLIPTICAL: + return (std::pow(r[0] / (f * aperture_m.second[0]), 2) + std::pow(r[1] / (f * aperture_m.second[1]), 2) < 1.0); + default: + return false; + } +} + +BoundaryBox getBoundaryBoxInLabCoords() const { + CoordinateSystemTrafo toBegin = getEdgeToBegin() * csTrafoGlobal2Local_m; + CoordinateSystemTrafo toEnd = getEdgeToEnd() * csTrafoGlobal2Local_m; + + double &x = aperture_m.second[0]; + double &y = aperture_m.second[1]; + double &f = aperture_m.second[2]; + + std::vector<Vector_t> corners(8); + for (int i = -1; i < 2; i += 2) { + for (int j = -1; j < 2; j += 2) { + unsigned int idx = (i + 1)/2 + (j + 1); + corners[idx] = toBegin.transformFrom(Vector_t(i * x, j * y, 0.0)); + corners[idx + 4] = toEnd.transformFrom(Vector_t(i * f * x, j * f * y, 0.0)); + } + } + + BoundingBox bb; + bb.lowerLeftCorner = bb.upperRightCorner = corners[0]; + + for (unsigned int i = 1; i < 8u; ++ i) { + for (unsigned int d; d < 3u; ++ d) { + if (bb.lowerLeftCorner(d) > corners[i](d)) { + bb.lowerLeftCorner(d) = corners[i](d); + } + if (bb.upperLeftCorner(d) < corners[i](d)) { + bb.upperLeftCorner(d) = corners[i](d); + } + } + } + + return bb; } \ No newline at end of file diff --git a/src/Classic/AbsBeamline/ElementBase.h b/src/Classic/AbsBeamline/ElementBase.h index deaf6872c37886ac7c299bebadd9ab8943004a78..aaa2fd5a4bcd07f3c33cf7d02c59fffa2f431e46 100644 --- a/src/Classic/AbsBeamline/ElementBase.h +++ b/src/Classic/AbsBeamline/ElementBase.h @@ -79,6 +79,12 @@ class BoundaryGeometry; class Channel; class ConstChannel; class ElementImage; + +struct BoundaryBox { + Vector_t lowerLeftEdge; + Vector_t upperRightEdge; +}; + class ParticleMatterInteractionHandler; class WakeFunction; @@ -353,6 +359,8 @@ public: void setRotationAboutZ(double rotation); double getRotationAboutZ() const; + virtual BoundaryBox getBoundaryBoxInLabCoords() const; + protected: bool isInsideTransverse(const Vector_t &r, double f = 1) const; @@ -525,24 +533,7 @@ inline bool ElementBase::isInside(const Vector_t &r) const { const double length = getElementLength(); - return isInsideTransverse(r, r(2) / length * aperture_m.second[2]) && r(2) >= 0.0 && r(2) < length; -} - -inline -bool ElementBase::isInsideTransverse(const Vector_t &r, double f) const -{ - switch(aperture_m.first) { - case RECTANGULAR: - return (std::abs(r[0]) < aperture_m.second[0] && std::abs(r[1]) < aperture_m.second[1]); - case ELLIPTICAL: - return (std::pow(r[0] / aperture_m.second[0], 2) + std::pow(r[1] / aperture_m.second[1], 2) < 1.0); - case CONIC_RECTANGULAR: - return (std::abs(r[0]) < f * aperture_m.second[0] && std::abs(r[1]) < f * aperture_m.second[1]); - case CONIC_ELLIPTICAL: - return (std::pow(r[0] / (f * aperture_m.second[0]), 2) + std::pow(r[1] / (f * aperture_m.second[1]), 2) < 1.0); - default: - return false; - } + return r(2) >= 0.0 && r(2) < length && isInsideTransverse(r); } inline @@ -611,5 +602,4 @@ inline bool ElementBase::isElementPositionSet() const { return elemedgeSet_m; } - -#endif // CLASSIC_ElementBase_HH \ No newline at end of file +#endif // CLASSIC_ElementBase_HH diff --git a/src/Classic/AbsBeamline/RFCavity.h b/src/Classic/AbsBeamline/RFCavity.h index 5b60b027f1b383037fc704beedfb2cbd073d7844..3b553a60f557d70bbb0ca1a0b2a3af271ca72420 100644 --- a/src/Classic/AbsBeamline/RFCavity.h +++ b/src/Classic/AbsBeamline/RFCavity.h @@ -513,4 +513,4 @@ CoordinateSystemTrafo RFCavity::getEdgeToEnd() const { return ret; } -#endif // CLASSIC_RFCavity_HH \ No newline at end of file +#endif // CLASSIC_RFCavity_HH