EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_pyramid.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ pyramid geometry
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: Frederic Tessier
27 # Marc Chamberland
28 # Reid Townson
29 # Hannah Gallop
30 #
31 ###############################################################################
32 */
33 
34 
40 #include "egs_pyramid.h"
41 #include "egs_input.h"
42 #include "egs_functions.h"
43 
44 #include <vector>
45 using std::vector;
46 
47 static EGS_PYRAMID_LOCAL string __pyrX = "EGS_PyramidX";
48 static EGS_PYRAMID_LOCAL string __pyrY = "EGS_PyramidY";
49 static EGS_PYRAMID_LOCAL string __pyrZ = "EGS_PyramidZ";
50 static EGS_PYRAMID_LOCAL string __pyr = "EGS_Pyramid";
51 
52 static bool EGS_PYRAMID_LOCAL inputSet = false;
53 
54 template<class T>
55 EGS_PyramidT<T>::EGS_PyramidT(T *P, const EGS_Vector &Xo, bool O,
56  const string &Name) : EGS_BaseGeometry(Name), p(P), xo(Xo),
57  a(p->getNormal()), open(O) {
58  nreg = 1;
59  d = p->distance(xo);
60  xop = p->getProjection(xo);
61  if (fabs(d) < boundaryTolerance) egsFatal("%s: the tip is too close to"
62  " the base (%g)\n",getType().c_str(),fabs(d));
63  if (d < 0) {
64  a *= (-1);
65  d *= (-1);
66  }
67  EGS_Vector v2 = p->getPoint(0), v1;
68  n = p->getN();
69  s = new EGS_Polygon * [n];
70  vector<EGS_2DVector> aux;
71  for (int j=0; j<p->getN(); j++) {
72  v1 = v2;
73  v2 = p->getPoint(j+1);
74  EGS_Vector aj = p->getNormal(j);
75  EGS_Projector *pro = new EGS_Projector(v1,xo,v2,"");
76  EGS_Vector n = pro->normal();
77  if (n*aj < 0) {
78  delete pro;
79  pro = new EGS_Projector(v2,xo,v1,"");
80  n = pro->normal();
81  if (n*aj < 0)
82  egsFatal("%s: n*aj < 0 for both normal orientations?\n",
83  getType().c_str());
84  }
85  aux.push_back(pro->getProjection(v1));
86  aux.push_back(pro->getProjection(xo));
87  aux.push_back(pro->getProjection(v2));
88  s[j] = new EGS_Polygon(aux,*pro,open);
89  aux.clear();
90  delete pro;
91  }
92  is_convex = p->isConvex();
93 }
94 
95 template<class T>
96 void EGS_PyramidT<T>::printInfo() const {
98 }
99 
100 extern "C" {
101 
102  static void setInputs() {
103  inputSet = true;
104 
105  setBaseGeometryInputs();
106 
107  geomBlockInput->getSingleInput("library")->setValues({"egs_pyramid"});
108 
109  // Format: name, isRequired, description, vector string of allowed values
110  auto typePtr = geomBlockInput->addSingleInput("type", true, "The type of pyramid", {"EGS_PyramidX", "EGS_PyramidY", "EGS_PyramidZ", "EGS_Pyramid"});
111 
112  geomBlockInput->addSingleInput("points", true, "A list of 2D or 3D (for type=EGS_Pyramid) positions. For 3D points, they must reside on a plane. These create a polygon that define the base of the pyramid.");
113  geomBlockInput->addSingleInput("tip", true, "The 3D position of the tip of the pyramid (x, y ,z)");
114  geomBlockInput->addSingleInput("closed", false, "0 (open) or 1 (closed). When missing or set to 0, the pyramid is open, otherwise it is closed by the plane in which the pyramid base is defined.", {"0", "1"});
115  }
116 
117  EGS_PYRAMID_EXPORT string getExample() {
118  string example;
119  example = {
120  R"(
121  # Example of egs_pyramid
122 
123  # EGS_PyramidZ example
124  #:start geometry:
125  name = my_pyramid
126  library = egs_pyramid
127  type = EGS_PyramidZ
128  points = 1 1 -1 1 -1 -1 4 -1
129  tip = 0 0 7
130  closed = 0
131  :start media input:
132  media = air
133  :stop media input:
134  :stop geometry:
135 )"};
136  return example;
137  }
138 
139  EGS_PYRAMID_EXPORT shared_ptr<EGS_BlockInput> getInputs() {
140  if(!inputSet) {
141  setInputs();
142  }
143  return geomBlockInput;
144  }
145 
146  EGS_PYRAMID_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) {
147 
148  if (!input) {
149  egsWarning("createGeometry(pyramid): null input?\n");
150  return 0;
151  }
152  string type;
153  int err = input->getInput("type",type);
154  if (err) {
155  egsWarning("createGeometry(pyramid): missing 'type' input\n");
156  return 0;
157  }
158  EGS_BaseGeometry *g;
159  vector<EGS_Float> p;
160  err = input->getInput("points",p);
161  if (err) {
162  egsWarning("createGeometry(pyramid): missing 'points' input\n");
163  return 0;
164  }
165  vector<EGS_Float> tip;
166  err = input->getInput("tip",tip);
167  if (err || tip.size() != 3) {
168  egsWarning("createGeometry(pyramid): wrong/missing 'tip' input\n");
169  return 0;
170  }
171  bool o = true;
172  int is_closed;
173  err = input->getInput("closed",is_closed);
174  if (!err && is_closed == 1) {
175  o = false;
176  }
177  //egsWarning("%s: open = %d\n",type.c_str(),o);
178  if (input->compare(type,__pyrX) || input->compare(type,__pyrY) ||
179  input->compare(type,__pyrZ)) {
180  int np = p.size()/2;
181  if (np < 3) {
182  egsWarning("createGeometry(pyramid): at least 3 points are "
183  "required to construct a pyramid\n");
184  return 0;
185  }
186  vector<EGS_2DVector> points;
187  for (int j=0; j<np; j++) {
188  points.push_back(EGS_2DVector(p[2*j],p[2*j+1]));
189  }
190  if (input->compare(type,__pyrX))
191  g=new EGS_PyramidX(new
192  EGS_PolygonYZ(points,EGS_XProjector(__pyrX)),
193  EGS_Vector(tip[0],tip[1],tip[2]),o);
194  else if (input->compare(type,__pyrY))
195  g=new EGS_PyramidY(new EGS_PolygonXZ(points,
196  EGS_YProjector(__pyrY)),
197  EGS_Vector(tip[0],tip[1],tip[2]),o);
198  else
199  g=new EGS_PyramidZ(new
200  EGS_PolygonXY(points,EGS_ZProjector(__pyrZ)),
201  EGS_Vector(tip[0],tip[1],tip[2]),o);
202  }
203  else {
204  int np = p.size()/3;
205  if (np < 3) {
206  egsWarning("createGeometry(pyramid): at least 3 points are required"
207  " to construct a pyramid\n");
208  return 0;
209  }
210  vector<EGS_Vector> points;
211  for (int j=0; j<np; j++) {
212  points.push_back(EGS_Vector(p[3*j],p[3*j+1],p[3*j+2]));
213  }
214  EGS_Vector aux(points[np-1]-points[0]);
215  if (aux.length2() > epsilon) {
216  points.push_back(points[0]);
217  }
218  np = points.size();
219  EGS_Projector pro(points[0],points[1],points[np-2],__pyr);
220  vector<EGS_2DVector> p2;
221  {
222  for (int j=0; j<np; j++) {
223  p2.push_back(pro.getProjection(points[j]));
224  EGS_Float d = pro.distance(points[j]);
225  if (fabs(d) > epsilon) {
226  egsWarning("createGeometry(pyramid): "
227  "points are not on a plane\n");
228  return 0;
229  }
230  }
231  }
232  g = new EGS_Pyramid(new EGS_Polygon(p2,pro),
233  EGS_Vector(tip[0],tip[1],tip[2]),o);
234  }
235  g->setName(input);
236  g->setBoundaryTolerance(input);
237  g->setMedia(input);
238  g->setLabels(input);
239  return g;
240  }
241 
242 }
A class representing 2D vectors.
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
void setMedia(EGS_Input *inp)
Set the media in the geometry from the input pointed to by inp.
int nreg
Number of local regions in this geometry.
bool is_convex
Is this geometry convex?
EGS_Float boundaryTolerance
Boundary tolerance for geometries that need it.
void setName(EGS_Input *inp)
Set the name of the geometry from the input inp.
int setLabels(EGS_Input *input)
Set the labels from an input block.
virtual void printInfo() const
Print information about this geometry.
void setBoundaryTolerance(EGS_Input *inp)
Set the value of the boundary tolerance from the input inp.
A class for storing information in a tree-like structure of key-value pairs. This class is used throu...
Definition: egs_input.h:182
static bool compare(const string &s1, const string &s2)
Definition: egs_input.cpp:1173
int getInput(const string &key, vector< string > &values) const
Assign values to an array of strings from an input identified by key.
Definition: egs_input.cpp:341
A template class for 3D polygons.
Definition: egs_polygon.h:335
A projector into any plane.
EGS_Vector normal() const
Get the normal to the projection plane.
EGS_2DVector getProjection(const EGS_Vector &x) const
Get the 2D projection of the vector x onto the plane.
A template class for modeling pyramids.
Definition: egs_pyramid.h:129
EGS_2DVector xop
the tip projection on the base polygon
Definition: egs_pyramid.h:135
int n
number of sides
Definition: egs_pyramid.h:138
EGS_Vector xo
the tip of the pyramid
Definition: egs_pyramid.h:134
EGS_Float d
distance from tip to base polygon (always positive)
Definition: egs_pyramid.h:137
T * p
the base polygon
Definition: egs_pyramid.h:133
EGS_Polygon ** s
sides.
Definition: egs_pyramid.h:139
EGS_Vector a
the base normal vector.
Definition: egs_pyramid.h:136
bool open
is the pyramid open ?
Definition: egs_pyramid.h:140
EGS_PyramidT(T *P, const EGS_Vector &Xo, bool O=true, const string &N="")
Construct a pyramid using P as the base polygon and Xo as the position of the tip.
Definition: egs_pyramid.cpp:55
A class representing 3D vectors.
Definition: egs_vector.h:57
A projector into the x-plane.
A projector into the y-plane.
A projector into the z-plane.
Global egspp functions header file.
EGS_GLIB_EXPORT EGS_BaseGeometry * createGeometry(EGS_Input *input)
Definition: egs_glib.cpp:84
EGS_Input class header file.
EGS_PolygonT< EGS_XProjector > EGS_PolygonYZ
A 3D polygon in the x-plane.
Definition: egs_polygon.h:478
EGS_PolygonT< EGS_Projector > EGS_Polygon
A 3D polygon in any plane.
Definition: egs_polygon.h:484
EGS_PolygonT< EGS_ZProjector > EGS_PolygonXY
A 3D polygon in the z-plane.
Definition: egs_polygon.h:482
EGS_PolygonT< EGS_YProjector > EGS_PolygonXZ
A 3D polygon in the y-plane.
Definition: egs_polygon.h:480
A pyramid geometry: header.
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
const EGS_Float epsilon
The epsilon constant for floating point comparisons.
Definition: egs_functions.h:62
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.