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