Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
SolidHole.cc
Go to the documentation of this file.
1#include <cmath>
2#include <iostream>
3
5#include "Garfield/Polygon.hh"
7
8namespace {
9
10void CutBox(const std::array<double, 8>& xbox,
11 const std::array<double, 8>& ybox,
12 const std::array<double, 8>& zbox,
13 std::vector<double>& xcut,
14 std::vector<double>& ycut,
15 std::vector<double>& zcut,
16 const double x0, const double y0, const double z0,
17 const double a, const double b, const double c) {
18
19 //-----------------------------------------------------------------------
20 // PLABOX - Crossings between a box and a plane.
21 //-----------------------------------------------------------------------
22 xcut.clear();
23 ycut.clear();
24 zcut.clear();
25 // Compute the, at most 6, crossings between plane and box.
26 for (unsigned int i = 0; i < 8; ++i) {
27 double xc, yc, zc;
28 unsigned int j = i + 1;
29 if (i == 3) {
30 j = 0;
31 } else if (i == 7) {
32 j = 4;
33 }
34 if (Garfield::Solid::Intersect(xbox[i], ybox[i], zbox[i],
35 xbox[j], ybox[j], zbox[j],
36 x0, y0, z0, a, b, c, xc, yc, zc)) {
37 xcut.push_back(xc);
38 ycut.push_back(yc);
39 zcut.push_back(zc);
40 }
41 }
42 for (unsigned int i = 0; i < 4; ++i) {
43 double xc, yc, zc;
44 const unsigned int j = i + 4;
45 if (Garfield::Solid::Intersect(xbox[i], ybox[i], zbox[i],
46 xbox[j], ybox[j], zbox[j],
47 x0, y0, z0, a, b, c, xc, yc, zc)) {
48 xcut.push_back(xc);
49 ycut.push_back(yc);
50 zcut.push_back(zc);
51 }
52 }
53
54 // Eliminate the butterflies.
56}
57
58}
59
60namespace Garfield {
61
62SolidHole::SolidHole(const double cx, const double cy, const double cz,
63 const double rup, const double rlow,
64 const double lx, const double ly, const double lz)
65 : Solid(cx, cy, cz, "SolidHole"),
66 m_rUp(rup),
67 m_rLow(rlow),
68 m_lX(lx),
69 m_lY(ly),
70 m_lZ(lz) {
71 Update();
72}
73
74SolidHole::SolidHole(const double cx, const double cy, const double cz,
75 const double rup, const double rlow,
76 const double lx, const double ly, const double lz,
77 const double dx, const double dy, const double dz)
78 : SolidHole(cx, cy, cz, rup, rlow, lx, ly, lz) {
79 SetDirection(dx, dy, dz);
80}
81
82void SolidHole::Update() {
83 std::lock_guard<std::mutex> guard(m_mutex);
84 const double alpha = Pi / (4. * (m_n - 1.));
85 if (m_average) {
86 m_fp = 2. / (1. + asinh(tan(alpha)) * cos(alpha) / tan(alpha));
87 } else {
88 m_fp = 1.;
89 }
90 m_fi = cos(alpha);
91}
92
93bool SolidHole::IsInside(const double x, const double y, const double z,
94 const bool tesselated) const {
95 // Transform the point to local coordinates.
96 double u = x, v = y, w = z;
97 ToLocal(x, y, z, u, v, w);
98
99 if (fabs(u) > m_lX || fabs(v) > m_lY || fabs(w) > m_lZ) {
100 return false;
101 }
102
103 double r = m_rLow + (w + m_lZ) * (m_rUp - m_rLow) / (2 * m_lZ);
104 if (!tesselated) return (u * u + v * v >= r * r);
105 const double rho = sqrt(u * u + v * v);
106 if (m_average) r *= m_fp;
107 if (rho > r) return true;
108 if (rho < r * m_fi) return false;
109
110 std::vector<double> xp;
111 std::vector<double> yp;
112 const double phi0 = -0.5 * HalfPi;
113 const double dphi = HalfPi / double(m_n - 1);
114 const unsigned int nP = 4 * (m_n - 1);
115 for (unsigned int i = 0; i < nP; ++i) {
116 // Bottom and top of the line along the axis of the cylinder.
117 const double phi = phi0 + dphi * i;
118 xp.push_back(r * cos(phi));
119 yp.push_back(r * sin(phi));
120 }
121 bool inside = false;
122 bool edge = false;
123 Polygon::Inside(xp, yp, u, v, inside, edge);
124 return !inside;
125}
126
127bool SolidHole::GetBoundingBox(double& xmin, double& ymin, double& zmin,
128 double& xmax, double& ymax, double& zmax) const {
129 if (m_cTheta == 1. && m_cPhi == 1.) {
130 xmin = m_cX - m_lX;
131 xmax = m_cX + m_lX;
132 ymin = m_cY - m_lY;
133 ymax = m_cY + m_lY;
134 zmin = m_cZ - m_lZ;
135 zmax = m_cZ + m_lZ;
136 return true;
137 }
138
139 const double dd = sqrt(m_lX * m_lX + m_lY * m_lY + m_lZ * m_lZ);
140 xmin = m_cX - dd;
141 xmax = m_cX + dd;
142 ymin = m_cY - dd;
143 ymax = m_cY + dd;
144 zmin = m_cZ - dd;
145 zmax = m_cZ + dd;
146 return true;
147}
148
149void SolidHole::SetUpperRadius(const double r) {
150 if (r <= 0.) {
151 std::cerr << "SolidHole::SetUpperRadius: Radius must be > 0.\n";
152 return;
153 }
154 m_rUp = r;
155}
156
157void SolidHole::SetLowerRadius(const double r) {
158 if (r <= 0.) {
159 std::cerr << "SolidHole::SetLowerRadius: Radius must be > 0.\n";
160 return;
161 }
162 m_rLow = r;
163}
164
165void SolidHole::SetHalfLengthX(const double lx) {
166 if (lx <= 0.) {
167 std::cerr << "SolidHole::SetHalfLengthX: Half-length must be > 0.\n";
168 return;
169 }
170 m_lX = lx;
171}
172
173void SolidHole::SetHalfLengthY(const double ly) {
174 if (ly <= 0.) {
175 std::cerr << "SolidHole::SetHalfLengthY: Half-length must be > 0.\n";
176 return;
177 }
178 m_lY = ly;
179}
180
181void SolidHole::SetHalfLengthZ(const double lz) {
182 if (lz <= 0.) {
183 std::cerr << "SolidHole::SetHalfLengthZ: Half-length must be > 0.\n";
184 return;
185 }
186 m_lZ = lz;
187}
188
189void SolidHole::SetSectors(const unsigned int n) {
190 if (n < 1) {
191 std::cerr << "SolidHole::SetSectors: Number must be > 0.\n";
192 return;
193 }
194 m_n = n;
195 Update();
196}
197
198bool SolidHole::SolidPanels(std::vector<Panel>& panels) {
199 const auto id = GetId();
200 const auto nPanels = panels.size();
201 // Direction vector.
202 const double fnorm = sqrt(m_dX * m_dX + m_dY * m_dY + m_dZ * m_dZ);
203 if (fnorm <= 0) {
204 std::cerr << "SolidHole::SolidPanels:\n"
205 << " Zero norm direction vector; no panels generated.\n";
206 return false;
207 }
208
209 // Set the mean or the outer radius.
210 double r1 = m_rLow;
211 double r2 = m_rUp;
212 if (m_average) {
213 r1 *= m_fp;
214 r2 *= m_fp;
215 }
216
217 double xv0, yv0, zv0;
218 double xv1, yv1, zv1;
219 double xv2, yv2, zv2;
220 double xv3, yv3, zv3;
221 // Draw the 6 sides of the box, start with the x=xmin face.
222 if (m_lY > 0 && m_lZ > 0) {
223 ToGlobal(-m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
224 ToGlobal(-m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
225 ToGlobal(-m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
226 ToGlobal(-m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
227 Panel panel;
228 panel.a = -m_cPhi * m_cTheta;
229 panel.b = -m_sPhi * m_cTheta;
230 panel.c = +m_sTheta;
231 panel.xv = {xv0, xv1, xv2, xv3};
232 panel.yv = {yv0, yv1, yv2, yv3};
233 panel.zv = {zv0, zv1, zv2, zv3};
234 panel.colour = m_colour;
235 panel.volume = id;
236 panels.push_back(std::move(panel));
237 }
238 // The x=xmax face.
239 if (m_lX > 0 && m_lY > 0 && m_lZ > 0) {
240 ToGlobal(+m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
241 ToGlobal(+m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
242 ToGlobal(+m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
243 ToGlobal(+m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
244 Panel panel;
245 panel.a = m_cPhi * m_cTheta;
246 panel.b = m_sPhi * m_cTheta;
247 panel.c = -m_sTheta;
248 panel.xv = {xv0, xv1, xv2, xv3};
249 panel.yv = {yv0, yv1, yv2, yv3};
250 panel.zv = {zv0, zv1, zv2, zv3};
251 panel.colour = m_colour;
252 panel.volume = id;
253 panels.push_back(std::move(panel));
254 }
255 // The y=ymin face.
256 if (m_lX > 0 && m_lZ > 0) {
257 ToGlobal(-m_lX, -m_lY, -m_lZ, xv0, yv0, zv0);
258 ToGlobal(+m_lX, -m_lY, -m_lZ, xv1, yv1, zv1);
259 ToGlobal(+m_lX, -m_lY, +m_lZ, xv2, yv2, zv2);
260 ToGlobal(-m_lX, -m_lY, +m_lZ, xv3, yv3, zv3);
261 Panel panel;
262 panel.a = m_sPhi;
263 panel.b = -m_cPhi;
264 panel.c = 0;
265 panel.xv = {xv0, xv1, xv2, xv3};
266 panel.yv = {yv0, yv1, yv2, yv3};
267 panel.zv = {zv0, zv1, zv2, zv3};
268 panel.colour = m_colour;
269 panel.volume = id;
270 panels.push_back(std::move(panel));
271 }
272 // The y=ymax face.
273 if (m_lX > 0 && m_lY > 0 && m_lZ > 0) {
274 ToGlobal(-m_lX, +m_lY, -m_lZ, xv0, yv0, zv0);
275 ToGlobal(+m_lX, +m_lY, -m_lZ, xv1, yv1, zv1);
276 ToGlobal(+m_lX, +m_lY, +m_lZ, xv2, yv2, zv2);
277 ToGlobal(-m_lX, +m_lY, +m_lZ, xv3, yv3, zv3);
278 Panel panel;
279 panel.a = -m_sPhi;
280 panel.b = m_cPhi;
281 panel.c = 0;
282 panel.xv = {xv0, xv1, xv2, xv3};
283 panel.yv = {yv0, yv1, yv2, yv3};
284 panel.zv = {zv0, zv1, zv2, zv3};
285 panel.colour = m_colour;
286 panel.volume = id;
287 panels.push_back(std::move(panel));
288 }
289 const double phi0 = -0.5 * HalfPi;
290 const double dphi = HalfPi / double(m_n - 1);
291 // The faces at constant z have a hole, and are drawn in parts.
292 for (int iside = -1; iside <= 1; iside += 2) {
293 const double r = iside == -1 ? r1 : r2;
294 const double w = m_lZ * iside;
295 Panel panel;
296 panel.a = iside * m_cPhi * m_sTheta;
297 panel.b = iside * m_sPhi * m_sTheta;
298 panel.c = iside * m_cTheta;
299 panel.colour = m_colour;
300 panel.volume = id;
301 // Loop over the panels.
302 for (unsigned int i = 0; i < m_n - 1; ++i) {
303 // The panels for x=xmax.
304 const double phi1 = phi0 + dphi * i;
305 const double phi2 = phi1 + dphi;
306 const double t1 = tan(phi1);
307 const double t2 = tan(phi2);
308 ToGlobal(r * cos(phi1), r * sin(phi1), w, xv0, yv0, zv0);
309 ToGlobal(r * cos(phi2), r * sin(phi2), w, xv3, yv3, zv3);
310 ToGlobal(m_lX, m_lY * t1, w, xv1, yv1, zv1);
311 ToGlobal(m_lX, m_lY * t2, w, xv2, yv2, zv2);
312 panel.xv = {xv0, xv1, xv2, xv3};
313 panel.yv = {yv0, yv1, yv2, yv3};
314 panel.zv = {zv0, zv1, zv2, zv3};
315 panels.push_back(panel);
316 // The panels for y=ymax.
317 const double phi3 = phi1 + HalfPi;
318 const double phi4 = phi3 + dphi;
319 ToGlobal(r * cos(phi3), r * sin(phi3), w, xv0, yv0, zv0);
320 ToGlobal(r * cos(phi4), r * sin(phi4), w, xv3, yv3, zv3);
321 ToGlobal(-m_lX * t1, m_lY, w, xv1, yv1, zv1);
322 ToGlobal(-m_lX * t2, m_lY, w, xv2, yv2, zv2);
323 panel.xv = {xv0, xv1, xv2, xv3};
324 panel.yv = {yv0, yv1, yv2, yv3};
325 panel.zv = {zv0, zv1, zv2, zv3};
326 panels.push_back(panel);
327 // The panels for x=xmin.
328 const double phi5 = phi3 + HalfPi;
329 const double phi6 = phi5 + dphi;
330 ToGlobal(r * cos(phi5), r * sin(phi5), w, xv0, yv0, zv0);
331 ToGlobal(r * cos(phi6), r * sin(phi6), w, xv3, yv3, zv3);
332 ToGlobal(-m_lX, -m_lY * t1, w, xv1, yv1, zv1);
333 ToGlobal(-m_lX, -m_lY * t2, w, xv2, yv2, zv2);
334 panel.xv = {xv0, xv1, xv2, xv3};
335 panel.yv = {yv0, yv1, yv2, yv3};
336 panel.zv = {zv0, zv1, zv2, zv3};
337 panels.push_back(panel);
338 // The panels for y=ymin.
339 const double phi7 = phi5 + HalfPi;
340 const double phi8 = phi7 + dphi;
341 ToGlobal(r * cos(phi7), r * sin(phi7), w, xv0, yv0, zv0);
342 ToGlobal(r * cos(phi8), r * sin(phi8), w, xv3, yv3, zv3);
343 ToGlobal(m_lX * t1, -m_lY, w, xv1, yv1, zv1);
344 ToGlobal(m_lX * t2, -m_lY, w, xv2, yv2, zv2);
345 panel.xv = {xv0, xv1, xv2, xv3};
346 panel.yv = {yv0, yv1, yv2, yv3};
347 panel.zv = {zv0, zv1, zv2, zv3};
348 panels.push_back(panel);
349 }
350 }
351 // The panels of the central cylinder, compute the projection angles.
352 const double alpha = atan2((r1 - r2) * cos(Pi / (4 * (m_n - 1))),
353 2 * m_lZ);
354 const double ci = cos(alpha);
355 const double si = sin(alpha);
356 // Initialise loop.
357 ToGlobal(r1 * cos(phi0), r1 * sin(phi0), -m_lZ, xv0, yv0, zv0);
358 ToGlobal(r2 * cos(phi0), r2 * sin(phi0), +m_lZ, xv1, yv1, zv1);
359 // Go around the cylinder.
360 const unsigned int nPoints = 4 * m_n - 3;
361 for (unsigned int i = 1; i < nPoints; ++i) {
362 // Bottom and top of the line along the axis of the cylinder.
363 const double phi = phi0 + dphi * i;
364 ToGlobal(r2 * cos(phi), r2 * sin(phi), +m_lZ, xv2, yv2, zv2);
365 ToGlobal(r1 * cos(phi), r1 * sin(phi), -m_lZ, xv3, yv3, zv3);
366 // Store the plane.
367 Panel panel;
368 const double phim = phi0 + dphi * (i - 0.5);
369 const double cm = cos(phim);
370 const double sm = sin(phim);
371 panel.a = -m_cPhi * m_cTheta * cm * ci +
372 m_sPhi * sm * ci -
373 m_cPhi * m_sTheta * si;
374 panel.b = -m_sPhi * m_cTheta * cm * ci -
375 m_cPhi * sm * ci -
376 m_sPhi * m_sTheta * si;
377 panel.c = m_sTheta * cm * ci - m_cTheta * si;
378 panel.xv = {xv0, xv1, xv2, xv3};
379 panel.yv = {yv0, yv1, yv2, yv3};
380 panel.zv = {zv0, zv1, zv2, zv3};
381 panel.colour = m_colour;
382 panel.volume = id;
383 panels.push_back(std::move(panel));
384 // Shift the points.
385 xv0 = xv3;
386 yv0 = yv3;
387 zv0 = zv3;
388 xv1 = xv2;
389 yv1 = yv2;
390 zv1 = zv2;
391 }
392 std::cout << "SolidHole::SolidPanels: " << panels.size() - nPanels
393 << " panels.\n";
394 return true;
395}
396
398
399 // Transform the normal vector to local coordinates.
400 double un = 0., vn = 0., wn = 0.;
401 VectorToLocal(panel.a, panel.b, panel.c, un, vn, wn);
402 // Transform one of the points (first).
403 double u1 = 0., v1 = 0., w1 = 0.;
404 ToLocal(panel.xv[0], panel.yv[0], panel.zv[0], u1, v1, w1);
405 // Identify the vector.
406 if (wn > std::max(std::abs(un), std::abs(vn))) {
407 return m_dis[0];
408 } else if (wn < -std::max(std::abs(un), std::abs(vn))) {
409 return m_dis[1];
410 } else if (un * u1 + vn * v1 + wn * w1 < 0) {
411 return m_dis[2];
412 } else if (un > std::max(std::abs(vn), std::abs(wn))) {
413 return m_dis[3];
414 } else if (un < -std::max(std::abs(vn), std::abs(wn))) {
415 return m_dis[4];
416 } else if (vn > std::max(std::abs(un), std::abs(wn))) {
417 return m_dis[5];
418 } else if (vn < -std::max(std::abs(un), std::abs(wn))) {
419 return m_dis[6];
420 }
421 if (m_debug) {
422 std::cout << m_className << "::GetDiscretisationLevel:\n"
423 << " Found no match for the panel; returning first value.\n";
424 }
425 return m_dis[0];
426}
427
428void SolidHole::Cut(const double x0, const double y0, const double z0,
429 const double xn, const double yn, const double zn,
430 std::vector<Panel>& panels) {
431
432 //-----------------------------------------------------------------------
433 // PLACHC - Cuts a cylindrical hole with a plane.
434 //-----------------------------------------------------------------------
435
436 // Adjust the mean radii if requested.
437 double r1 = m_rLow;
438 double r2 = m_rUp;
439 if (m_average) {
440 r1 *= m_fp;
441 r2 *= m_fp;
442 }
443 std::array<double, 8> xbox;
444 std::array<double, 8> ybox;
445 std::array<double, 8> zbox;
446 // Loop over the boxes that make up the hole.
447 const double dphi = HalfPi / (m_n - 1.);
448 for (unsigned int i = 1; i <= m_n - 1; ++i) {
449 const double phi1 = dphi * (i - 1.);
450 const double phi2 = dphi * i;
451 const double t1 = tan(-0.5 * HalfPi + phi1);
452 const double t2 = tan(-0.5 * HalfPi + phi2);
453 // The boxes ending at x=xmax.
454 for (int iside : {-1, 1}) {
455 const double r = iside < 0 ? r1 : r2;
456 const double w = iside * m_lZ;
457 const unsigned int k = iside < 0 ? 0 : 4;
458 const double phi0 = -0.5 * HalfPi;
459 ToGlobal(r * cos(phi0 + phi1), r * sin(phi0 + phi1), w,
460 xbox[k], ybox[k], zbox[k]);
461 ToGlobal(r * cos(phi0 + phi2), r * sin(phi0 + phi2), w,
462 xbox[k + 3], ybox[k + 3], zbox[k + 3]);
463 ToGlobal(m_lX, m_lY * t1, w, xbox[k + 1], ybox[k + 1], zbox[k + 1]);
464 ToGlobal(m_lX, m_lY * t2, w, xbox[k + 2], ybox[k + 2], zbox[k + 2]);
465 }
466 std::vector<double> xv;
467 std::vector<double> yv;
468 std::vector<double> zv;
469 CutBox(xbox, ybox, zbox, xv, yv, zv, x0, y0, z0, xn, yn, zn);
470 if (xv.size() >= 3) {
471 Panel panel;
472 panel.a = xn;
473 panel.b = yn;
474 panel.c = zn;
475 panel.xv = xv;
476 panel.yv = yv;
477 panel.zv = zv;
478 panel.colour = m_colour;
479 panel.volume = GetId();
480 panels.push_back(std::move(panel));
481 }
482 xv.clear();
483 yv.clear();
484 zv.clear();
485 // The panels for y=ymax.
486 for (int iside : {-1, 1}) {
487 const double r = iside < 0 ? r1 : r2;
488 const double w = iside * m_lZ;
489 const unsigned int k = iside < 0 ? 0 : 4;
490 const double phi0 = 0.5 * HalfPi;
491 ToGlobal(r * cos(phi0 + phi1), r * sin(phi0 + phi1), w,
492 xbox[k], ybox[k], zbox[k]);
493 ToGlobal(r * cos(phi0 + phi2), r * sin(phi0 + phi2), w,
494 xbox[k + 3], ybox[k + 3], zbox[k + 3]);
495 ToGlobal(-m_lX * t1, m_lY, w, xbox[k + 1], ybox[k + 1], zbox[k + 1]);
496 ToGlobal(-m_lX * t2, m_lY, w, xbox[k + 2], ybox[k + 2], zbox[k + 2]);
497 }
498 CutBox(xbox, ybox, zbox, xv, yv, zv, x0, y0, z0, xn, yn, zn);
499 if (xv.size() >= 3) {
500 Panel panel;
501 panel.a = xn;
502 panel.b = yn;
503 panel.c = zn;
504 panel.xv = xv;
505 panel.yv = yv;
506 panel.zv = zv;
507 panel.colour = m_colour;
508 panel.volume = GetId();
509 panels.push_back(std::move(panel));
510 }
511 xv.clear();
512 yv.clear();
513 zv.clear();
514 // The panels for x=xmin.
515 for (int iside : {-1, 1}) {
516 const double r = iside < 0 ? r1 : r2;
517 const double w = iside * m_lZ;
518 const unsigned int k = iside < 0 ? 0 : 4;
519 const double phi0 = 1.5 * HalfPi;
520 ToGlobal(r * cos(phi0 + phi1), r * sin(phi0 + phi1), w,
521 xbox[k], ybox[k], zbox[k]);
522 ToGlobal(r * cos(phi0 + phi2), r * sin(phi0 + phi2), w,
523 xbox[k + 3], ybox[k + 3], zbox[k + 3]);
524 ToGlobal(-m_lX, -m_lY * t1, w, xbox[k + 1], ybox[k + 1], zbox[k + 1]);
525 ToGlobal(-m_lX, -m_lY * t2, w, xbox[k + 2], ybox[k + 2], zbox[k + 2]);
526 }
527 CutBox(xbox, ybox, zbox, xv, yv, zv, x0, y0, z0, xn, yn, zn);
528 if (xv.size() >= 3) {
529 Panel panel;
530 panel.a = xn;
531 panel.b = yn;
532 panel.c = zn;
533 panel.xv = xv;
534 panel.yv = yv;
535 panel.zv = zv;
536 panel.colour = m_colour;
537 panel.volume = GetId();
538 panels.push_back(std::move(panel));
539 }
540 xv.clear();
541 yv.clear();
542 zv.clear();
543 // The panels for y=ymin.
544 for (int iside : {-1, 1}) {
545 const double r = iside < 0 ? r1 : r2;
546 const double w = iside * m_lZ;
547 const unsigned int k = iside < 0 ? 0 : 4;
548 const double phi0 = -1.5 * HalfPi;
549 ToGlobal(r * cos(phi0 + phi1), r * sin(phi0 + phi1), w,
550 xbox[k], ybox[k], zbox[k]);
551 ToGlobal(r * cos(phi0 + phi2), r * sin(phi0 + phi2), w,
552 xbox[k + 3], ybox[k + 3], zbox[k + 3]);
553 ToGlobal(m_lX * t1, -m_lY, w, xbox[k + 1], ybox[k + 1], zbox[k + 1]);
554 ToGlobal(m_lX * t2, -m_lY, w, xbox[k + 2], ybox[k + 2], zbox[k + 2]);
555
556 }
557 CutBox(xbox, ybox, zbox, xv, yv, zv, x0, y0, z0, xn, yn, zn);
558 if (xv.size() >= 3) {
559 Panel panel;
560 panel.a = xn;
561 panel.b = yn;
562 panel.c = zn;
563 panel.xv = xv;
564 panel.yv = yv;
565 panel.zv = zv;
566 panel.colour = m_colour;
567 panel.volume = GetId();
568 panels.push_back(std::move(panel));
569 }
570 }
571}
572
573}
Box with a cylindrical hole.
Definition: SolidHole.hh:12
void SetHalfLengthY(const double ly)
Set the half-length of the box along y.
Definition: SolidHole.cc:173
bool GetBoundingBox(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax) const override
Return the bounding box of the solid.
Definition: SolidHole.cc:127
double GetDiscretisationLevel(const Panel &panel) override
Retrieve the discretisation level of a panel.
Definition: SolidHole.cc:397
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: SolidHole.cc:428
void SetSectors(const unsigned int n)
Definition: SolidHole.cc:189
void SetHalfLengthX(const double lx)
Set the half-length of the box along x.
Definition: SolidHole.cc:165
void SetLowerRadius(const double r)
Set the radius at z = -lz.
Definition: SolidHole.cc:157
bool IsInside(const double x, const double y, const double z, const bool tesselated) const override
Definition: SolidHole.cc:93
bool SolidPanels(std::vector< Panel > &panels) override
Retrieve the surface panels of the solid.
Definition: SolidHole.cc:198
void SetHalfLengthZ(const double lz)
Set the half-length of the box along z.
Definition: SolidHole.cc:181
void SetUpperRadius(const double r)
Set the radius at z = +lz.
Definition: SolidHole.cc:149
SolidHole(const double cx, const double cy, const double cz, const double rup, const double rlow, const double lx, const double ly, const double lz)
Constructor from centre, upper/lower radii, half-lengths of the box.
Definition: SolidHole.cc:62
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
void Inside(const std::vector< double > &xpl, const std::vector< double > &ypl, const double x, const double y, bool &inside, bool &edge)
Definition: Polygon.cc:187
DoubleAc cos(const DoubleAc &f)
Definition: DoubleAc.cpp:432
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