BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSExtent.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) BDSIM Collaboration, 2001 - 2026.
3
4This file is part of BDSIM.
5
6BDSIM is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published
8by the Free Software Foundation version 3 of the License.
9
10BDSIM is distributed in the hope that it will be useful, but
11WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
17*/
18#include "BDSExtent.hh"
19#include "BDSParticleCoords.hh"
20#include "BDSTiltOffset.hh"
21#include "BDSUtilities.hh"
22
23#include "globals.hh" // geant4 types / globals
24#include "G4ThreeVector.hh"
25#include "G4TwoVector.hh"
26
27#include <algorithm>
28#include <cmath>
29#include <ostream>
30#include <utility>
31#include <vector>
32
34 extXNeg(0.0),
35 extXPos(0.0),
36 extYNeg(0.0),
37 extYPos(0.0),
38 extZNeg(0.0),
39 extZPos(0.0)
40{;}
41
42BDSExtent::BDSExtent(const std::pair<G4double, G4double>& extXIn,
43 const std::pair<G4double, G4double>& extYIn,
44 const std::pair<G4double, G4double>& extZIn):
45 extXNeg(extXIn.first),
46 extXPos(extXIn.second),
47 extYNeg(extYIn.first),
48 extYPos(extYIn.second),
49 extZNeg(extZIn.first),
50 extZPos(extZIn.second)
51{;}
52
53BDSExtent::BDSExtent(G4double extXNegIn, G4double extXPosIn,
54 G4double extYNegIn, G4double extYPosIn,
55 G4double extZNegIn, G4double extZPosIn):
56 extXNeg(extXNegIn),
57 extXPos(extXPosIn),
58 extYNeg(extYNegIn),
59 extYPos(extYPosIn),
60 extZNeg(extZNegIn),
61 extZPos(extZPosIn)
62{;}
63
64BDSExtent::BDSExtent(G4double extXIn, G4double extYIn, G4double extZIn):
65 extXNeg(-std::abs(extXIn)),
66 extXPos( std::abs(extXIn)),
67 extYNeg(-std::abs(extYIn)),
68 extYPos( std::abs(extYIn)),
69 extZNeg(-std::abs(extZIn)),
70 extZPos( std::abs(extZIn))
71{;}
72
73BDSExtent::BDSExtent(G4ThreeVector extIn):
74 BDSExtent(extIn.x(), extIn.y(), extIn.z())
75{;}
76
77BDSExtent::BDSExtent(G4ThreeVector extInNeg,
78 G4ThreeVector extInPos):
79 extXNeg(extInNeg.x()),
80 extXPos(extInPos.x()),
81 extYNeg(extInNeg.y()),
82 extYPos(extInPos.y()),
83 extZNeg(extInNeg.z()),
84 extZPos(extInPos.z())
85{;}
86
87BDSExtent::~BDSExtent()
88{;}
89
90std::vector<G4ThreeVector> BDSExtent::AllBoundaryPoints() const
91{
92 std::vector<G4ThreeVector> result;
93 result.emplace_back(extXNeg, extYNeg, extZNeg);
94 result.emplace_back(extXNeg, extYPos, extZNeg);
95 result.emplace_back(extXPos, extYNeg, extZNeg);
96 result.emplace_back(extXPos, extYPos, extZNeg);
97 result.emplace_back(extXNeg, extYNeg, extZPos);
98 result.emplace_back(extXNeg, extYPos, extZPos);
99 result.emplace_back(extXPos, extYNeg, extZPos);
100 result.emplace_back(extXPos, extYPos, extZPos);
101 return result;
102}
103
105{
106 if (!tiltOffset)
107 {return BDSExtent(*this);}
108 BDSExtent tilted = Tilted(tiltOffset->GetTilt());
109 BDSExtent offset = tilted.Translate(tiltOffset->GetOffset());
110 return offset;
111}
112
113BDSExtent BDSExtent::Translate(G4double dx, G4double dy, G4double dz) const
114{
115 return BDSExtent(extXNeg + dx, extXPos + dx,
116 extYNeg + dy, extYPos + dy,
117 extZNeg + dz, extZPos + dz);
118}
119
120BDSExtent BDSExtent::Tilted(G4double angle) const
121{
122 if (!BDS::IsFinite(angle))
123 {return BDSExtent(*this);}
124
125 // rotate each vector (from origin to each corner) by angle
126 // and check - safer than checking based on +ve / -ve angle
127 G4TwoVector topRight = G4TwoVector(extXPos, extYPos);
128 G4TwoVector botRight = G4TwoVector(extXPos, extYNeg);
129 G4TwoVector botLeft = G4TwoVector(extXNeg, extYNeg);
130 G4TwoVector topLeft = G4TwoVector(extXNeg, extYPos);
131
132 topRight.rotate(angle);
133 botRight.rotate(angle);
134 botLeft.rotate(angle);
135 topLeft.rotate(angle);
136
137 G4double xMin = std::min({botRight.x(), botLeft.x(), topLeft.x(), topRight.x()});
138 G4double xMax = std::max({botRight.x(), botLeft.x(), topLeft.x(), topRight.x()});
139 G4double yMin = std::min({botRight.y(), botLeft.y(), topLeft.y(), topRight.y()});
140 G4double yMax = std::max({botRight.y(), botLeft.y(), topLeft.y(), topRight.y()});
141
142 BDSExtent result = BDSExtent(xMin, xMax,
143 yMin, yMax,
145 return result;
146}
147
148std::ostream& operator<< (std::ostream& out, BDSExtent const& ext)
149{
150 out << "X- " << ext.extXNeg << ", X+ " << ext.extXPos << " mm\n";
151 out << "Y- " << ext.extYNeg << ", Y+ " << ext.extYPos << " mm\n";
152 out << "Z- " << ext.extZNeg << ", Z+ " << ext.extZPos << " mm";
153 return out;
154}
155
156G4double BDSExtent::MaximumAbs() const
157{
158 return std::max({std::abs(extXNeg), extXPos,
159 std::abs(extYNeg), extYPos,
160 std::abs(extZNeg), extZPos});
161}
162
163G4double BDSExtent::MinimumAbs() const
164{
165 return std::min({std::abs(extXNeg), extXPos,
166 std::abs(extYNeg), extYPos,
167 std::abs(extZNeg), extZPos});
168}
169
171{
172 return std::max({std::abs(extXNeg), extXPos,
173 std::abs(extYNeg), extYPos});
174}
175
177{
178 return std::min({std::abs(extXNeg), extXPos,
179 std::abs(extYNeg), extYPos});
180}
181
183{
184 G4double x = std::max(std::abs(extXNeg), std::abs(extXPos));
185 G4double y = std::max(std::abs(extYNeg), std::abs(extYPos));
186 return std::hypot(x, y);
187}
188
189G4bool BDSExtent::Encompasses(const G4ThreeVector& point) const
190{
191 G4bool xOK = (point.x() >= extXNeg) && (point.x() <= extXPos);
192 G4bool yOK = (point.y() >= extYNeg) && (point.y() <= extYPos);
193 G4bool zOK = (point.z() >= extZNeg) && (point.z() <= extZPos);
194 return xOK && yOK && zOK;
195}
196
197G4bool BDSExtent::Encompasses(const BDSExtent& other) const
198{
199 std::vector<G4ThreeVector> otherPoints = other.AllBoundaryPoints();
200 G4bool result = false;
201 for (const auto& p : otherPoints)
202 {result = result || !Encompasses(p);}
203 return !result;
204}
205
206G4bool BDSExtent::Encompasses(const BDSParticleCoords& coords) const
207{
208 G4ThreeVector point(coords.x, coords.y, coords.z);
209 return Encompasses(point);
210}
211
212BDSExtent BDSExtent::ExpandBy(G4double margin) const
213{
214 margin = std::abs(margin);
215 BDSExtent result(*this);
216 result.extXNeg -= margin;
217 result.extXPos += margin;
218 result.extYNeg -= margin;
219 result.extYPos += margin;
220 result.extZNeg -= margin;
221 result.extZPos += margin;
222 return result;
223}
224
226{
227 BDSExtent result(*this);
228 result.extXNeg -= margin;
229 result.extXPos += margin;
230 result.extYNeg -= margin;
231 result.extYPos += margin;
232 return result;
233}
234
236{
237 BDSExtent result = BDSExtent(*this);
238 result.extXNeg = std::min(extXNeg, other.extXNeg);
239 result.extYNeg = std::min(extYNeg, other.extYNeg);
240 result.extZNeg = std::min(extZNeg, other.extZNeg);
241 result.extXPos = std::max(extXPos, other.extXPos);
242 result.extYPos = std::max(extYPos, other.extYPos);
243 result.extZPos = std::max(extZPos, other.extZPos);
244}
245namespace BDS
246{
248 const BDSExtent& second)
249 {
250 return BDSExtent(std::min(first.XNeg(), second.XNeg()),
251 std::max(first.XPos(), second.XPos()),
252 std::min(first.YNeg(), second.YNeg()),
253 std::max(first.YPos(), second.YPos()),
254 std::min(first.ZNeg(), second.ZNeg()),
255 std::max(first.ZPos(), second.ZPos()));
256 }
257}
Holder for +- extents in 3 dimensions.
Definition BDSExtent.hh:38
G4double XPos() const
Accessor.
Definition BDSExtent.hh:65
BDSExtent Tilted(G4double angle) const
Provide a new copy of this extent but rotated along Z by a given tilt angle.
Definition BDSExtent.cc:120
BDSExtent Translate(const G4ThreeVector &offset) const
Provide a new copy of this extent with an offset applied.
Definition BDSExtent.hh:124
std::vector< G4ThreeVector > AllBoundaryPoints() const
All 8 boundary points of the bounding box.
Definition BDSExtent.cc:90
G4double extZNeg
Extent.
Definition BDSExtent.hh:169
BDSExtent()
Default constructor gives 0 in all extents - typically unphysical.
Definition BDSExtent.cc:33
G4double extZPos
Extent.
Definition BDSExtent.hh:170
G4double ZPos() const
Accessor.
Definition BDSExtent.hh:69
G4double MaximumAbsTransverse() const
Return the maximum absolute value considering only x,y.
Definition BDSExtent.cc:170
BDSExtent ExpandBy(G4double margin) const
Return a copy expanded in all dimensions by the given margin.
Definition BDSExtent.cc:212
G4bool Encompasses(const G4ThreeVector &point) const
Return whether the extent encompasses the point. True if point lies inside the extent.
Definition BDSExtent.cc:189
G4double MaximumAbs() const
Return the maximum absolute value considering all dimensions.
Definition BDSExtent.cc:156
void ExpandToEncompass(const BDSExtent &other)
Definition BDSExtent.cc:235
G4double XNeg() const
Accessor.
Definition BDSExtent.hh:64
G4double extYNeg
Extent.
Definition BDSExtent.hh:167
G4double extYPos
Extent.
Definition BDSExtent.hh:168
G4double YNeg() const
Accessor.
Definition BDSExtent.hh:66
BDSExtent TiltOffset(const BDSTiltOffset *tiltOffset) const
Provide a new copy of this extent with both a tilt and an offset applied.
Definition BDSExtent.cc:104
G4double extXPos
Extent.
Definition BDSExtent.hh:166
G4double MinimumAbsTransverse() const
Return the minimum absolute value considering only x,y.
Definition BDSExtent.cc:176
G4double MinimumAbs() const
Return the minimum absolute value considering all dimensions.
Definition BDSExtent.cc:163
BDSExtent ExpandTransverselyBy(G4double margin) const
Return a copy expanded in x and y by the given margin.
Definition BDSExtent.cc:225
G4double YPos() const
Accessor.
Definition BDSExtent.hh:67
G4double extXNeg
Extent.
Definition BDSExtent.hh:165
G4double ZNeg() const
Accessor.
Definition BDSExtent.hh:68
G4double TransverseBoundingRadius() const
Return a radius that would encompass the maximum x,y extent.
Definition BDSExtent.cc:182
A set of particle coordinates.
A holder for any placement offsets and rotations for a BDSAcceleratorComponent.
G4double GetTilt() const
Accessor.
G4ThreeVector GetOffset() const
More advance accessor for offset - only in x,y.
Return either G4Tubs or G4CutTubs depending on flat face.
BDSExtent MaximumCombinedExtent(const BDSExtent &first, const BDSExtent &second)
Returns the extent which is the greatest extent in all six directions.
Definition BDSExtent.cc:247
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())
STL namespace.