Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
SolidRidge.cc
Go to the documentation of this file.
1#include <cmath>
2#include <iostream>
3
5#include "Garfield/Polygon.hh"
7
8namespace Garfield {
9
10SolidRidge::SolidRidge(const double cx, const double cy, const double cz,
11 const double lx, const double ly, const double hz,
12 const double hx)
13 : Solid(cx, cy, cz, "SolidRidge"),
14 m_lX(lx),
15 m_lY(ly),
16 m_hz(hz),
17 m_hx(hx) {}
18
19SolidRidge::SolidRidge(const double cx, const double cy, const double cz,
20 const double lx, const double ly, const double hz,
21 const double hx,
22 const double dx, const double dy, const double dz)
23 : SolidRidge(cx, cy, cz, lx, ly, hz, hx) {
24 SetDirection(dx, dy, dz);
25}
26
27bool SolidRidge::IsInside(const double x, const double y, const double z,
28 const bool /*tesselated*/) const {
29 // Transform the point to local coordinates.
30 double u = x, v = y, w = z;
31 ToLocal(x, y, z, u, v, w);
32
33 bool inside = true;
34 if (fabs(u) > m_lX || fabs(v) > m_lY || w < 0. || w > m_hz) {
35 inside = false;
36 } else if (u >= m_hx && m_hz * u + (m_lX - m_hx) * v > m_hz * m_lX) {
37 inside = false;
38 } else if (u <= m_hx && -m_hz * u + (m_lX + m_hx) * v > m_hz * m_lX) {
39 inside = false;
40 }
41 return inside;
42}
43
44bool SolidRidge::GetBoundingBox(double& xmin, double& ymin, double& zmin,
45 double& xmax, double& ymax, double& zmax) const {
46 if (m_cTheta == 1. && m_cPhi == 1.) {
47 xmin = m_cX - m_lX;
48 xmax = m_cX + m_lX;
49 ymin = m_cY - m_lY;
50 ymax = m_cY + m_lY;
51 zmin = m_cZ;
52 zmax = m_cZ + m_hz;
53 return true;
54 }
55
56 const double dd = sqrt(m_lX * m_lX + m_lY * m_lY + m_hz * m_hz);
57 xmin = m_cX - dd;
58 xmax = m_cX + dd;
59 ymin = m_cY - dd;
60 ymax = m_cY + dd;
61 zmin = m_cZ - dd;
62 zmax = m_cZ + dd;
63 return true;
64}
65
66void SolidRidge::SetHalfLengthX(const double lx) {
67 if (lx <= 0.) {
68 std::cerr << "SolidRidge::SetHalfLengthX: Half-length must be > 0.\n";
69 return;
70 }
71 m_lX = lx;
72}
73
74void SolidRidge::SetHalfLengthY(const double ly) {
75 if (ly <= 0.) {
76 std::cerr << "SolidRidge::SetHalfLengthY: Half-length must be > 0.\n";
77 return;
78 }
79 m_lY = ly;
80}
81
82void SolidRidge::SetRidgeHeight(const double hz) {
83 if (hz <= 0.) {
84 std::cerr << "SolidRidge::SetRidgeHeight: Height must be > 0.\n";
85 return;
86 }
87 m_hz = hz;
88}
89
90bool SolidRidge::SolidPanels(std::vector<Panel>& panels) {
91 const auto id = GetId();
92 const unsigned int nPanels = panels.size();
93 // Direction vector.
94 const double fnorm = sqrt(m_dX * m_dX + m_dY * m_dY + m_dZ * m_dZ);
95 if (fnorm <= 0) {
96 std::cerr << "SolidRidge::SolidPanels:\n"
97 << " Zero norm direction vector; no panels generated.\n";
98 return false;
99 }
100 double xv0, yv0, zv0;
101 double xv1, yv1, zv1;
102 double xv2, yv2, zv2;
103 double xv3, yv3, zv3;
104
105 // Draw the 5 sides of the ridge, start with the floor.
106 ToGlobal(-m_lX, -m_lY, 0, xv0, yv0, zv0);
107 ToGlobal(-m_lX, +m_lY, 0, xv1, yv1, zv1);
108 ToGlobal(+m_lX, +m_lY, 0, xv2, yv2, zv2);
109 ToGlobal(+m_lX, -m_lY, 0, xv3, yv3, zv3);
110
111 Panel base;
112 base.a = -m_cPhi * m_sTheta;
113 base.b = -m_sPhi * m_sTheta;
114 base.c = -m_cTheta;
115 base.xv = {xv0, xv1, xv2, xv3};
116 base.yv = {yv0, yv1, yv2, yv3};
117 base.zv = {zv0, zv1, zv2, zv3};
118 base.colour = m_colour;
119 base.volume = id;
120 panels.push_back(std::move(base));
121
122 // Side triangles at y=ymin and y=ymax.
123 for (unsigned int i = 0; i < 2; ++i) {
124 const double y = i == 0 ? -m_lY : +m_lY;
125 ToGlobal(-m_lX, y, 0, xv0, yv0, zv0);
126 ToGlobal(+m_lX, y, 0, xv1, yv1, zv1);
127 ToGlobal(m_hx, y, m_hz, xv2, yv2, zv2);
128
129 const double a = i == 0 ? +m_sPhi : -m_sPhi;
130 const double b = i == 0 ? -m_cPhi : +m_cPhi;
131 Panel side;
132 side.a = a;
133 side.b = b;
134 side.c = 0.;
135 side.xv = {xv0, xv1, xv2};
136 side.yv = {yv0, yv1, yv2};
137 side.zv = {zv0, zv1, zv2};
138 side.colour = m_colour;
139 side.volume = id;
140 panels.push_back(std::move(side));
141 }
142
143 // The roof, parts at +x and -x.
144 for (unsigned int i = 0; i < 2; ++i) {
145 const double x = i == 0 ? +m_lX : -m_lX;
146 ToGlobal(x, -m_lY, 0, xv0, yv0, zv0);
147 ToGlobal(x, +m_lY, 0, xv1, yv1, zv1);
148 ToGlobal(m_hx, +m_lY, m_hz, xv2, yv2, zv2);
149 ToGlobal(m_hx, -m_lY, m_hz, xv3, yv3, zv3);
150 const double dx = i == 0 ? m_lX - m_hx : m_lX + m_hx;
151 const double s = sqrt(m_hz * m_hz + dx * dx);
152 const double xroof = i == 0 ? m_hz / s : -m_hz / s;
153 const double zroof = dx / s;
154
155 Panel roof;
156 roof.a = m_cPhi * m_cTheta * xroof + m_cPhi * m_sTheta * zroof;
157 roof.b = m_sPhi * m_cTheta * xroof + m_sPhi * m_sTheta * zroof;
158 roof.c = -m_sTheta * xroof + m_cTheta * zroof;
159 roof.xv = {xv0, xv1, xv2, xv3};
160 roof.yv = {yv0, yv1, yv2, yv3};
161 roof.zv = {zv0, zv1, zv2, zv3};
162 roof.colour = m_colour;
163 roof.volume = id;
164 panels.push_back(std::move(roof));
165 }
166 std::cout << "SolidRidge::SolidPanels: " << panels.size() - nPanels
167 << " panels.\n";
168 return true;
169}
170
172
173 // Transform the normal vector to local coordinates.
174 double u = 0., v = 0., w = 0.;
175 VectorToLocal(panel.a, panel.b, panel.c, u, v, w);
176 // Identify the vector.
177 if (v > std::max(std::abs(u), std::abs(w))) {
178 return m_dis[2];
179 } else if (v < -std::max(std::abs(u), std::abs(w))) {
180 return m_dis[3];
181 } else if (w < -std::max(std::abs(u), std::abs(v))) {
182 return m_dis[4];
183 } else if (u > 0) {
184 return m_dis[0];
185 } else if (u < 0) {
186 return m_dis[1];
187 }
188 if (m_debug) {
189 std::cout << m_className << "::GetDiscretisationLevel:\n"
190 << " Found no match for the panel; return first value.\n";
191 }
192 return m_dis[0];
193}
194
195void SolidRidge::Cut(const double x0, const double y0, const double z0,
196 const double xn, const double yn, const double zn,
197 std::vector<Panel>& panels) {
198
199 //-----------------------------------------------------------------------
200 // PLATBC - Cuts ridge with a plane.
201 //-----------------------------------------------------------------------
202
203 std::vector<double> xv;
204 std::vector<double> yv;
205 std::vector<double> zv;
206 // Draw all 9 lines and cut.
207 // The line (xmin,ymin,0) to (xmax,ymin,0).
208 double x1, y1, z1;
209 ToGlobal(-m_lX, -m_lY, 0., x1, y1, z1);
210 double x2, y2, z2;
211 ToGlobal(+m_lX, -m_lY, 0., x2, y2, z2);
212 double xc, yc, zc;
213 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
214 xv.push_back(xc);
215 yv.push_back(yc);
216 zv.push_back(zc);
217 }
218 // ... to (xmin,ymax,0).
219 ToGlobal(-m_lX, +m_lY, 0., x2, y2, z2);
220 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
221 xv.push_back(xc);
222 yv.push_back(yc);
223 zv.push_back(zc);
224 }
225 // ... to (xh,ymin,zh).
226 ToGlobal(m_hx, -m_lY, m_hz, x2, y2, z2);
227 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
228 xv.push_back(xc);
229 yv.push_back(yc);
230 zv.push_back(zc);
231 }
232
233 // The line (xmax,ymax,0) to (xmin,ymax,0).
234 ToGlobal(+m_lX, +m_lY, 0., x1, y1, z1);
235 ToGlobal(-m_lX, +m_lY, 0., x2, y2, z2);
236 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
237 xv.push_back(xc);
238 yv.push_back(yc);
239 zv.push_back(zc);
240 }
241
242 // ... to (xmax,ymin,0).
243 ToGlobal(+m_lX, -m_lY, 0., x2, y2, z2);
244 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
245 xv.push_back(xc);
246 yv.push_back(yc);
247 zv.push_back(zc);
248 }
249
250 // ... to (xh,ymax,zh).
251 ToGlobal(m_hx, +m_lY, m_hz, x2, y2, z2);
252 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
253 xv.push_back(xc);
254 yv.push_back(yc);
255 zv.push_back(zc);
256 }
257
258 // The line (xmin,ymax,0) to (xh,ymax,zh).
259 ToGlobal(-m_lX, +m_lY, 0., x1, y1, z1);
260 ToGlobal(m_hx, +m_lY, m_hz, x2, y2, z2);
261 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
262 xv.push_back(xc);
263 yv.push_back(yc);
264 zv.push_back(zc);
265 }
266
267 // The line (xh,ymax,zh) to (xh,ymin,zh)
268 ToGlobal(m_hx, +m_lY, m_hz, x1, y1, z1);
269 ToGlobal(m_hx, -m_lY, m_hz, x2, y2, z2);
270 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
271 xv.push_back(xc);
272 yv.push_back(yc);
273 zv.push_back(zc);
274 }
275
276 // The line (xh,ymin,zh) to (xmax,ymin,0)
277 ToGlobal(m_hx, -m_lY, m_hz, x1, y1, z1);
278 ToGlobal(+m_lX, -m_lY, 0., x2, y2, z2);
279 if (Intersect(x1, y1, z1, x2, y2, z2, x0, y0, z0, xn, yn, zn, xc, yc, zc)) {
280 xv.push_back(xc);
281 yv.push_back(yc);
282 zv.push_back(zc);
283 }
284
285 // Get rid of butterflies.
287 if (xv.size() >= 3) {
288 Panel panel;
289 panel.a = xn;
290 panel.b = yn;
291 panel.c = zn;
292 panel.xv = xv;
293 panel.yv = yv;
294 panel.zv = zv;
295 panel.colour = m_colour;
296 panel.volume = GetId();
297 panels.push_back(std::move(panel));
298 }
299
300}
301
302}
Triangular prism (Toblerone bar).
Definition: SolidRidge.hh:10
SolidRidge(const double cx, const double cy, const double cz, const double lx, const double ly, const double hz, const double offsetx)
Constructor from centre, half-lengths, height and x-offset.
Definition: SolidRidge.cc:10
bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) const override
Return the bounding box of the solid.
Definition: SolidRidge.cc:44
void SetRidgeHeight(const double hz)
Set the height of the ridge.
Definition: SolidRidge.cc:82
double GetDiscretisationLevel(const Panel &panel) override
Retrieve the discretisation level of a panel.
Definition: SolidRidge.cc:171
bool IsInside(const double x, const double y, const double z, const bool tesselated) const override
Definition: SolidRidge.cc:27
void SetHalfLengthX(const double lx)
Set the half-length along x.
Definition: SolidRidge.cc:66
bool SolidPanels(std::vector< Panel > &panels) override
Retrieve the surface panels of the solid.
Definition: SolidRidge.cc:90
void Cut(const double x0, const double y0, const double z0, const double xn, const double yn, const double zn, std::vector< Panel > &panels) override
Definition: SolidRidge.cc:195
void SetHalfLengthY(const double ly)
Set the half-length along y.
Definition: SolidRidge.cc:74
Abstract base class for solids.
Definition: Solid.hh:28
double m_dZ
Definition: Solid.hh:205
double m_cZ
Definition: Solid.hh:202
void VectorToLocal(const double x, const double y, const double z, double &u, double &v, double &w)
Transform a vector from global to local coordinates.
Definition: Solid.hh:253
double m_cTheta
Polar angle.
Definition: Solid.hh:209
static bool Intersect(const double x1, const double y1, const double z1, const double x2, const double y2, const double z2, const double x0, const double y0, const double z0, const double a, const double b, const double c, double &xc, double &yc, double &zc)
Definition: Solid.cc:52
double m_dX
Direction vector.
Definition: Solid.hh:205
unsigned int GetId() const
Get the ID of the solid.
Definition: Solid.hh:137
void ToLocal(const double x, const double y, const double z, double &u, double &v, double &w) const
Definition: Solid.hh:234
void SetDirection(const double dx, const double dy, const double dz)
Definition: Solid.cc:12
int m_colour
Colour.
Definition: Solid.hh:230
double m_sPhi
Definition: Solid.hh:207
void ToGlobal(const double u, const double v, const double w, double &x, double &y, double &z) const
Definition: Solid.hh:246
double m_sTheta
Definition: Solid.hh:209
double m_cY
Definition: Solid.hh:202
bool m_debug
Debug flag.
Definition: Solid.hh:218
double m_dY
Definition: Solid.hh:205
double m_cX
Centre of the solid.
Definition: Solid.hh:202
double m_cPhi
Azimuthal angle.
Definition: Solid.hh:207
std::string m_className
Class name.
Definition: Solid.hh:212
void EliminateButterflies(std::vector< double > &xp, std::vector< double > &yp, std::vector< double > &zp)
Definition: Polygon.cc:355
Surface panel.
Definition: Solid.hh:11
std::vector< double > zv
Z-coordinates of vertices.
Definition: Solid.hh:19
int volume
Reference to solid to which the panel belongs.
Definition: Solid.hh:23
double a
Perpendicular vector.
Definition: Solid.hh:13
double c
Definition: Solid.hh:13
double b
Definition: Solid.hh:13
std::vector< double > xv
X-coordinates of vertices.
Definition: Solid.hh:15
std::vector< double > yv
Y-coordinates of vertices.
Definition: Solid.hh:17
int colour
Colour index.
Definition: Solid.hh:21