EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_prism.h
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ prism geometry headers
5 # Copyright (C) 2015 National Research Council Canada
6 #
7 # This file is part of EGSnrc.
8 #
9 # EGSnrc is free software: you can redistribute it and/or modify it under
10 # the terms of the GNU Affero General Public License as published by the
11 # Free Software Foundation, either version 3 of the License, or (at your
12 # option) any later version.
13 #
14 # EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
17 # more details.
18 #
19 # You should have received a copy of the GNU Affero General Public License
20 # along with EGSnrc. If not, see <http://www.gnu.org/licenses/>.
21 #
22 ###############################################################################
23 #
24 # Author: Iwan Kawrakow, 2005
25 #
26 # Contributors: Reid Townson
27 #
28 ###############################################################################
29 */
30 
31 
37 #ifndef EGS_PRISM_
38 #define EGS_PRISM_
39 
40 #include "egs_base_geometry.h"
41 #include "egs_polygon.h"
42 #include "egs_functions.h"
43 
44 #ifdef WIN32
45 
46  #ifdef BUILD_PRISM_DLL
47  #define EGS_PRISM_EXPORT __declspec(dllexport)
48  #else
49  #define EGS_PRISM_EXPORT __declspec(dllimport)
50  #endif
51  #define EGS_PRISM_LOCAL
52 
53 #else
54 
55  #ifdef HAVE_VISIBILITY
56  #define EGS_PRISM_EXPORT __attribute__ ((visibility ("default")))
57  #define EGS_PRISM_LOCAL __attribute__ ((visibility ("hidden")))
58  #else
59  #define EGS_PRISM_EXPORT
60  #define EGS_PRISM_LOCAL
61  #endif
62 
63 #endif
64 
123 template <class T>
124 class EGS_PRISM_EXPORT EGS_PrismT : public EGS_BaseGeometry {
125 
126 protected:
127 
128  T *p;
130  EGS_Float
131  d1,
132  d2;
133 
134  bool open;
135 
136 public:
137 
143  EGS_PrismT(T *P, const string &Name="") :
144  EGS_BaseGeometry(Name), p(P), a(p->getNormal()), open(true) {
145  is_convex = p->isConvex();
146  nreg = 1;
147  };
148 
155  EGS_PrismT(T *P, EGS_Float D1, EGS_Float D2, const string &Name="") :
156  EGS_BaseGeometry(Name), p(P), a(p->getNormal()),
157  d1(D1), d2(D2), open(false) {
158  if (d1 > d2) {
159  d1 = D2;
160  d2 = D1;
161  }
162  is_convex = p->isConvex();
163  nreg = 1;
164  };
165 
168  delete p;
169  };
170 
171  bool isInside(const EGS_Vector &x) {
172  if (!open) {
173  EGS_Float d = p->distance(x);
174  if (d < d1 || d > d2) {
175  return false;
176  }
177  }
178  return p->isInside2D(x);
179  };
180 
181  int isWhere(const EGS_Vector &x) {
182  if (isInside(x)) {
183  return 0;
184  }
185  else {
186  return -1;
187  }
188  };
189  int inside(const EGS_Vector &x) {
190  return isWhere(x);
191  };
192 
193  int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u,
194  EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) {
195  EGS_2DVector v;
196  EGS_2DVector *pv = normal ? &v : 0;
197  if (open) {
198  bool hit = p->howfar2D(ireg == 0 ? true : false,x,u,t,pv);
199  if (!hit) {
200  return ireg;
201  }
202  if (newmed) {
203  *newmed = !ireg ? -1 : med;
204  }
205  if (normal) {
206  *normal = p->getNormal(v);
207  }
208  return !ireg ? -1 : 0;
209  }
210  EGS_Float up = a*u, d = p->distance(x);
211  if (!ireg) { // inside
212  EGS_Float tt = veryFar;
213  int inew = ireg;
214  if (up > boundaryTolerance) {
215  tt = (d2 - d)/up;
216  }
217  else if (up < -boundaryTolerance) {
218  tt = (d1 - d)/up;
219  }
220  else {
221  tt = 0;
222  }
223  if (tt <= t) {
224  if (tt > 0) {
225  t = tt+boundaryTolerance;
226  }
227  else {
228  t = tt;
229  }
230  inew = -1;
231  if (normal) {
232  *normal = up>0 ? a*(-1) : a;
233  }
234  if (newmed) {
235  *newmed = -1;
236  }
237  }
238  bool hit = p->howfar2D(true,x,u,t,pv);
239  if (!hit) {
240  return inew;
241  }
242  if (newmed) {
243  *newmed = -1;
244  }
245  if (normal) {
246  *normal = p->getNormal(v);
247  }
248  return -1;
249  }
250  if (d < d1 || d > d2) {
251  EGS_Float tt = veryFar;
252  if (d < d1 && up > boundaryTolerance) {
253  tt = (d1 - d)/up;
254  }
255  else if (d > d2 && up < -boundaryTolerance) {
256  tt = (d2 - d)/up;
257  }
258  if (tt < t) {
259  EGS_Vector xp(x + u*tt);
260  if (p->isInside2D(xp)) {
261  t = tt;
262  if (newmed) {
263  *newmed = med;
264  }
265  if (normal) {
266  *normal = up>0 ? a*(-1) : a;
267  }
268  return 0;
269  }
270  }
271  }
272  EGS_Float tt = t;
273  bool hit = p->howfar2D(false,x,u,tt,pv);
274  if (!hit) {
275  return ireg;
276  }
277  d = p->distance(x+u*tt);
278  if (d >= d1 && d <= d2) {
279  t = tt;
280  if (newmed) {
281  *newmed = med;
282  }
283  if (normal) {
284  *normal = p->getNormal(v);
285  }
286  return 0;
287  }
288  return ireg;
289  };
290 
291  EGS_Float hownear(int ireg, const EGS_Vector &x) {
292  EGS_Float tperp = p->hownear2D(ireg == 0 ? true : false,x);
293  if (open) {
294  return tperp;
295  }
296  EGS_Float d = p->distance(x);
297  if (!ireg) { // inside
298  EGS_Float t = d2 - d;
299  if (t < tperp) {
300  tperp = t;
301  }
302  t = d - d1;
303  if (t < tperp) {
304  tperp = t;
305  }
306  }
307  else {
308  EGS_Float t;
309  if (d < d1) {
310  t = d1 - d;
311  }
312  else if (d > d2) {
313  t = d - d2;
314  }
315  else {
316  return tperp;
317  }
318  if (p->isInside2D(x)) {
319  tperp = t;
320  }
321  else {
322  tperp = sqrt(tperp*tperp + t*t);
323  }
324  }
325  return tperp;
326  };
327 
328  //const string &getType() const { return type; };
329  const string &getType() const {
330  return p->getType();
331  };
332 
333  void printInfo() const {
335  if (open) {
336  egsInformation(" open\n");
337  }
338  else {
339  egsInformation(" closed with planes at %g and %g\n",d1,d2);
340  }
341  egsInformation("===================================================\n");
342  };
343 
344 };
345 
354 
355 #endif
EGS_PrismT(T *P, const string &Name="")
Construct an open prism using P as the base polygon.
Definition: egs_prism.h:143
virtual const string & getType() const =0
Get the geometry type.
virtual bool isInside(const EGS_Vector &x)=0
Is the position x inside the geometry?
virtual void printInfo() const
Print information about this geometry.
EGS_PrismT(T *P, EGS_Float D1, EGS_Float D2, const string &Name="")
Construct a closed prism using P as the base polygon.
Definition: egs_prism.h:155
A class representing 2D vectors.
A class representing 3D vectors.
Definition: egs_vector.h:56
bool open
Is the prism open ?
Definition: egs_prism.h:134
Global egspp functions header file.
virtual int isWhere(const EGS_Vector &x)=0
In which region is poisition x?
virtual int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, EGS_Float &t, int *newmed=0, EGS_Vector *normal=0)=0
Calculate the distance to a boundary from x along the direction u.
const EGS_Float veryFar
A very large float.
int med
Medium index.
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
EGS_Vector a
The normal vector to the base plane.
Definition: egs_prism.h:129
EGS_2DPolygon and EGS_PolygonT class header file.
A class for modeling prisms.
Definition: egs_prism.h:124
bool isConvex() const
Is the geometry convex?
EGS_PrismT< EGS_PolygonYZ > EGS_PrismX
A prism with base in the X-plane.
Definition: egs_prism.h:347
virtual int inside(const EGS_Vector &x)=0
Returns the region index, if inside, or -1 if outside (obsolete)
EGS_InfoFunction EGS_EXPORT egsInformation
Always use this function for reporting the progress of a simulation and any other type of information...
EGS_PrismT< EGS_PolygonXZ > EGS_PrismY
A prism with base in the Y-plane.
Definition: egs_prism.h:349
virtual EGS_Float hownear(int ireg, const EGS_Vector &x)=0
Calculate the distance to a boundary for position x in any direction.
EGS_Float boundaryTolerance
Boundary tolerance for geometries that need it.
EGS_PrismT< EGS_PolygonXY > EGS_PrismZ
A prism with base in the Z-plane.
Definition: egs_prism.h:351
EGS_PrismT< EGS_Polygon > EGS_Prism
A prism with base in an arbitrary plane.
Definition: egs_prism.h:353
~EGS_PrismT()
Desctructor, deletes the base polygon.
Definition: egs_prism.h:167
EGS_BaseGeometry class header file.
EGS_Float d2
Distance of the bottom plane to the base (for closed prisms)
Definition: egs_prism.h:131
T * p
The base polygon.
Definition: egs_prism.h:128