EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_pyramid.h
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ pyramid 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: Blake Walters
27 # Reid Townson
28 #
29 ###############################################################################
30 */
31 
32 
38 #ifndef EGS_PYRAMID_
39 #define EGS_PYRAMID_
40 
41 #include "egs_base_geometry.h"
42 #include "egs_polygon.h"
43 
44 #ifdef WIN32
45 
46  #ifdef BUILD_PYRAMID_DLL
47  #define EGS_PYRAMID_EXPORT __declspec(dllexport)
48  #else
49  #define EGS_PYRAMID_EXPORT __declspec(dllimport)
50  #endif
51  #define EGS_PYRAMID_LOCAL
52 
53 #else
54 
55  #ifdef HAVE_VISIBILITY
56  #define EGS_PYRAMID_EXPORT __attribute__ ((visibility ("default")))
57  #define EGS_PYRAMID_LOCAL __attribute__ ((visibility ("hidden")))
58  #else
59  #define EGS_PYRAMID_EXPORT
60  #define EGS_PYRAMID_LOCAL
61  #endif
62 
63 #endif
64 
128 template <class T>
129 class EGS_PYRAMID_EXPORT EGS_PyramidT : public EGS_BaseGeometry {
130 
131 protected:
132 
133  T *p;
137  EGS_Float d;
138  int n;
140  bool open;
141 
142 public:
143 
151  EGS_PyramidT(T *P, const EGS_Vector &Xo, bool O=true, const string &N="");
152 
153  ~EGS_PyramidT() {
154  delete p;
155  for (int j=0; j<n; j++) {
156  delete s[j];
157  }
158  delete [] s;
159  };
160 
161  bool isInside(const EGS_Vector &x) {
162  EGS_Vector xp(x-xo);
163  EGS_Float axp = a*xp;
164  if (axp > 0) {
165  return false;
166  }
167  //if( axp > -1e-10 ) return true;
168  if (!open && d + axp < 0) {
169  return false;
170  }
171  EGS_Float t = -d/axp;
172  //return p->isInside2D(xop+p->getProjection(xp)*t);
173  return p->isInside2D(p->getProjection(xo + t*xp));
174  };
175 
176  int isWhere(const EGS_Vector &x) {
177  if (isInside(x)) {
178  return 0;
179  }
180  else {
181  return -1;
182  }
183  };
184  int inside(const EGS_Vector &x) {
185  return isWhere(x);
186  };
187 
188  int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u,
189  EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) {
190  int jhit=-1;
191  if (ireg == 0) {
192  int convex = p->isConvex();
193  for (int j=0; j<n; j++) {
194  if (convex || s[j]->isInside2D(x)) {
195  if (s[j]->isInside(x))
196  if (s[j]->howfar(true,x,u,t)) {
197  jhit = j;
198  }
199  }
200  }
201  if (!open) {
202  if (p->howfar(true,x,u,t)) {
203  jhit = n;
204  }
205  }
206  if (jhit < 0) {
207  return ireg;
208  }
209  if (newmed) {
210  *newmed = -1;
211  }
212  if (normal) *normal = jhit < n ? s[jhit]->getNormal() :
213  p->getNormal();
214  return -1;
215  }
216  for (int j=0; j<n; j++) {
217  //bool in = s[j]->isInside(x) && s[j]->isInside2D(x);
218  EGS_Float up = u*s[j]->getNormal(), xp = s[j]->distance(x);
219  if (up > 0 && xp < 0) {
220  EGS_Float tt = -xp/up;
221  if (tt <= t+boundaryTolerance && s[j]->isInside2D(x+u*tt)) {
222  t = tt;
223  jhit = j;
224  }
225  }
226  }
227  if (!open) {
228  EGS_Float up = u*p->getNormal(), xp = p->distance(x);
229  if (up > 0 && xp < 0) {
230  EGS_Float tt = -xp/up;
231  if (tt <= t+boundaryTolerance && p->isInside2D(x+u*tt)) {
232  t = tt;
233  jhit = n;
234  }
235  }
236  }
237  if (jhit < 0) {
238  return ireg;
239  }
240  if (newmed) {
241  *newmed = med;
242  }
243  if (normal) *normal = jhit < n ? s[jhit]->getNormal()*(-1) :
244  p->getNormal()*(-1);
245  return 0;
246  };
247 
248  // TODO: optimize. this implementation is waaaay too slow.
249  EGS_Float hownear(int ireg, const EGS_Vector &x) {
250  EGS_Float tperp = veryFar;
251  for (int j=0; j<n; j++) {
252  EGS_Float t = s[j]->hownear(true,x);
253  if (t < tperp) {
254  if (t <= 0) {
255  return 0;
256  }
257  tperp = t;
258  }
259  }
260  if (!open) {
261  EGS_Float t = p->hownear(true,x);
262  if (t < tperp) {
263  tperp = t;
264  }
265  }
266  return tperp;
267  };
268 
269  const string &getType() const {
270  return p->getType();
271  };
272 
273  void printInfo() const;
274 
275 };
276 
281 
282 #endif
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?
bool open
is the pyramid open ?
Definition: egs_pyramid.h:140
virtual void printInfo() const
Print information about this geometry.
EGS_Polygon ** s
sides.
Definition: egs_pyramid.h:139
A class representing 2D vectors.
A class representing 3D vectors.
Definition: egs_vector.h:56
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.
EGS_Vector a
the base normal vector.
Definition: egs_pyramid.h:136
int med
Medium index.
T * p
the base polygon
Definition: egs_pyramid.h:133
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
EGS_2DPolygon and EGS_PolygonT class header file.
virtual int inside(const EGS_Vector &x)=0
Returns the region index, if inside, or -1 if outside (obsolete)
virtual EGS_Float hownear(int ireg, const EGS_Vector &x)=0
Calculate the distance to a boundary for position x in any direction.
EGS_2DVector xop
the tip projection on the base polygon
Definition: egs_pyramid.h:135
A template class for 3D polygons.
Definition: egs_polygon.h:335
EGS_Float d
distance from tip to base polygon (always positive)
Definition: egs_pyramid.h:137
A template class for modeling pyramids.
Definition: egs_pyramid.h:129
int n
number of sides
Definition: egs_pyramid.h:138
EGS_BaseGeometry class header file.
EGS_Vector xo
the tip of the pyramid
Definition: egs_pyramid.h:134