BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
BDSExtentGlobal.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 "BDSExtentGlobal.hh"
20#include "BDSTiltOffset.hh"
21#include "BDSUtilities.hh"
22
23#include "globals.hh" // geant4 types / globals
24#include "G4ThreeVector.hh"
25#include "G4Transform3D.hh"
26#include "G4TwoVector.hh"
27
28#include <algorithm>
29#include <ostream>
30#include <utility>
31#include <vector>
32
33#include "CLHEP/Geometry/Point3D.h"
34
35
37 transform(G4Transform3D()),
38 extXNegG(0.0),
39 extXPosG(0.0),
40 extYNegG(0.0),
41 extYPosG(0.0),
42 extZNegG(0.0),
43 extZPosG(0.0)
44{;}
45
47 const G4Transform3D& transformIn):
48 BDSExtent(extentIn),
49 transform(G4Transform3D(transformIn))
50{
51 const auto bps = extentIn.AllBoundaryPoints(); // local frame
52
53 // transform them to new frame
54 std::vector<G4ThreeVector> tBPS; // transformed boundary points
55 for (const auto& point : bps)
56 {tBPS.emplace_back(transform * (HepGeom::Point3D<G4double>)point);}
57
58 // must initialise to a point that definitely lies inside the extent
59 // before iterating to find extents - use one point.
60 extXNegG = tBPS[0].x();
61 extXPosG = tBPS[0].x();
62 extYNegG = tBPS[0].y();
63 extYPosG = tBPS[0].y();
64 extZNegG = tBPS[0].z();
65 extZPosG = tBPS[0].z();
66
67 // calculate new extents
68 for (const auto& point : tBPS)
69 {
70 extXNegG = std::min(extXNegG, point.x());
71 extXPosG = std::max(extXPosG, point.x());
72 extYNegG = std::min(extYNegG, point.y());
73 extYPosG = std::max(extYPosG, point.y());
74 extZNegG = std::min(extZNegG, point.z());
75 extZPosG = std::max(extZPosG, point.z());
76 }
77
78 if (extXNegG > extXPosG)
79 {std::swap(extXNegG, extXPosG);}
80 if (extYNegG > extYPosG)
81 {std::swap(extYNegG, extYPosG);}
82 if (extZNegG > extZPosG)
83 {std::swap(extZNegG, extZPosG);}
84}
85
87{;}
88
89std::vector<G4ThreeVector> BDSExtentGlobal::AllBoundaryPointsGlobal() const
90{
91 std::vector<G4ThreeVector> result;
92 result.emplace_back(extXNegG, extYNegG, extZNegG);
93 result.emplace_back(extXPosG, extYNegG, extZNegG);
94 result.emplace_back(extXPosG, extYPosG, extZNegG);
95 result.emplace_back(extXNegG, extYPosG, extZNegG);
96 result.emplace_back(extXNegG, extYNegG, extZPosG);
97 result.emplace_back(extXPosG, extYNegG, extZPosG);
98 result.emplace_back(extXPosG, extYPosG, extZPosG);
99 result.emplace_back(extXNegG, extYPosG, extZPosG);
100 return result;
101}
102
103G4bool BDSExtentGlobal::Overlaps(const BDSExtentGlobal& /*other*/) const
104{
105 return false;
106}
107
108BDSExtentGlobal BDSExtentGlobal::TranslateGlobal(G4double dx, G4double dy, G4double dz) const
109{
111 cp.extXNegG += dx;
112 cp.extXPosG += dx;
113 cp.extYNegG += dy;
114 cp.extYPosG += dy;
115 cp.extZNegG += dz;
116 cp.extZPosG += dz;
117
118 return cp;
119}
120
122{
123 BDSExtentGlobal result = BDSExtentGlobal(*this);
124 result.extXNegG = std::min(extXNegG, other.extXNegG);
125 result.extXPosG = std::max(extXPosG, other.extXPosG);
126 result.extYNegG = std::min(extYNegG, other.extYNegG);
127 result.extYPosG = std::max(extYPosG, other.extYPosG);
128 result.extZNegG = std::min(extZNegG, other.extZNegG);
129 result.extZPosG = std::max(extZPosG, other.extZPosG);
130 return result;
131}
132
133std::ostream& operator<< (std::ostream& out, BDSExtentGlobal const& ext)
134{
135 out << static_cast<const BDSExtent&>(ext);
136 out << G4endl;
137 out << "Transform: " << ext.transform.getRotation()
138 << ext.transform.getTranslation() << G4endl;
139 out << "In Global frame: " << G4endl;
140 out << ext.extXNegG << " " << ext.extXPosG << " ";
141 out << ext.extYNegG << " " << ext.extYPosG << " ";
142 out << ext.extZNegG << " " << ext.extZPosG << " mm";
143 return out;
144}
145
147{
148 std::vector<G4double> exts = {std::abs(extXNegG), extXPosG,
149 std::abs(extYNegG), extYPosG,
150 std::abs(extZNegG), extZPosG};
151 return *std::max_element(exts.begin(), exts.end());
152}
153
155 G4double y,
156 G4double z) const
157{
158 G4ThreeVector point = G4ThreeVector(x,y,z);
159
160 auto p = AllBoundaryPointsGlobal();
161
162 // construct vectors for each side
163 G4ThreeVector edge01 = p[1] - p[0];
164 G4ThreeVector edge03 = p[3] - p[0];
165 G4ThreeVector edge04 = p[4] - p[0];
166
167 // axes vectors
168 G4ThreeVector axX = edge04.cross(edge03);
169 G4ThreeVector axY = edge04.cross(edge01);
170 G4ThreeVector axZ = edge01.cross(edge03);
171
172 // projection of the point onto an axis of the rectangle must lie
173 // inside the projection of the projection of the two (origin,vertex)
174 // projections onto the same axis for the point to be inside an arbitrary
175 // 3d cuboid.
176 G4double pxp = axX.dot(point);
177 G4double pyp = axY.dot(point);
178 G4double pzp = axZ.dot(point);
179 G4bool insideX = (pxp > axX.dot(p[0])) && (pxp < axX.dot(p[1]));
180 G4bool insideY = (pyp > axY.dot(p[0])) && (pyp < axY.dot(p[3]));
181 G4bool insideZ = (pzp > axZ.dot(p[0])) && (pzp < axZ.dot(p[4]));
182
183 return insideX && insideY && insideZ;
184}
185
187{
188 G4bool insideX = (std::abs(otherExtent.ExtentXGlobal().first) < std::abs(extXNegG)) &&
189 (otherExtent.ExtentXGlobal().second < extXPosG);
190 G4bool insideY = (std::abs(otherExtent.ExtentYGlobal().first) < std::abs(extYNegG)) &&
191 (otherExtent.ExtentYGlobal().second < extYPosG);
192 G4bool insideZ = (std::abs(otherExtent.ExtentZGlobal().first) < std::abs(extZNegG)) &&
193 (otherExtent.ExtentZGlobal().second < extZPosG);
194 return insideX && insideY && insideZ;
195}
196
197G4bool BDSExtentGlobal::Encompasses(const std::vector<BDSExtentGlobal>& otherExtents)
198{
199 G4bool encompassesAllBeamlines = true;
200
201 // loop over all extents from all beam lines
202 for (const auto& ext : otherExtents)
203 {
204 if (!Encompasses(ext))
205 {encompassesAllBeamlines = false;}
206 }
207 return encompassesAllBeamlines;
208}
209
211{
212 G4ThreeVector mEA;
213 for (int i = 0; i < 3; i++)
214 {mEA[i] = std::max(std::abs(ExtentPositiveGlobal()[i]), std::abs(ExtentNegativeGlobal()[i]));}
215 return mEA;
216}
Holder for +- extents in 3 dimensions with a rotation and translation.
G4double extYNegG
Extent.
std::pair< G4double, G4double > ExtentZGlobal() const
Accessor.
G4bool EncompassesGlobal(G4double x, G4double y, G4double z) const
Return whether the extent encompasses the point. Similar, but with separate x,y,z coordinates.
std::pair< G4double, G4double > ExtentXGlobal() const
Accessor.
BDSExtentGlobal ExpandToEncompass(const BDSExtentGlobal &other) const
Return a copy of this extent but expanded to encompass another global extent.
BDSExtentGlobal TranslateGlobal(G4ThreeVector offset) const
Provide a new copy of this extent with an offset applied.
std::pair< G4double, G4double > ExtentYGlobal() const
Accessor.
G4ThreeVector GetMaximumExtentAbsolute() const
Get the maximum extent absolute in each dimension.
BDSExtentGlobal()
Default constructor gives 0 in all extents - typically unphysical.
virtual ~BDSExtentGlobal()
std::vector< G4ThreeVector > AllBoundaryPointsGlobal() const
All 8 boundary points of the bounding box.
G4double extXPosG
Extent.
G4double extXNegG
Extent.
G4double extYPosG
Extent.
G4double extZNegG
Extent.
G4double extZPosG
Extent.
G4bool Encompasses(const BDSExtentGlobal &otherExtent)
Return whether the extent encompasses another extent.
G4ThreeVector ExtentPositiveGlobal() const
Accessor.
G4ThreeVector ExtentNegativeGlobal() const
Accessor.
G4double MaximumAbsGlobal() const
Return the maximum absolute value considering all dimensions.
Holder for +- extents in 3 dimensions.
Definition: BDSExtent.hh:39
std::vector< G4ThreeVector > AllBoundaryPoints() const
All 8 boundary points of the bounding box.
Definition: BDSExtent.cc:91