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 #
28 ###############################################################################
29 */
30 
31 
37 #include "egs_pyramid.h"
38 #include "egs_input.h"
39 #include "egs_functions.h"
40 
41 #include <vector>
42 using std::vector;
43 
44 static EGS_PYRAMID_LOCAL string __pyrX = "EGS_PyramidX";
45 static EGS_PYRAMID_LOCAL string __pyrY = "EGS_PyramidY";
46 static EGS_PYRAMID_LOCAL string __pyrZ = "EGS_PyramidZ";
47 static EGS_PYRAMID_LOCAL string __pyr = "EGS_Pyramid";
48 
49 template<class T>
50 EGS_PyramidT<T>::EGS_PyramidT(T *P, const EGS_Vector &Xo, bool O,
51  const string &Name) : EGS_BaseGeometry(Name), p(P), xo(Xo),
52  a(p->getNormal()), open(O) {
53  nreg = 1;
54  d = p->distance(xo);
55  xop = p->getProjection(xo);
56  if (fabs(d) < boundaryTolerance) egsFatal("%s: the tip is too close to"
57  " the base (%g)\n",getType().c_str(),fabs(d));
58  if (d < 0) {
59  a *= (-1);
60  d *= (-1);
61  }
62  EGS_Vector v2 = p->getPoint(0), v1;
63  n = p->getN();
64  s = new EGS_Polygon * [n];
65  vector<EGS_2DVector> aux;
66  for (int j=0; j<p->getN(); j++) {
67  v1 = v2;
68  v2 = p->getPoint(j+1);
69  EGS_Vector aj = p->getNormal(j);
70  EGS_Projector *pro = new EGS_Projector(v1,xo,v2,"");
71  EGS_Vector n = pro->normal();
72  if (n*aj < 0) {
73  delete pro;
74  pro = new EGS_Projector(v2,xo,v1,"");
75  n = pro->normal();
76  if (n*aj < 0)
77  egsFatal("%s: n*aj < 0 for both normal orientations?\n",
78  getType().c_str());
79  }
80  aux.push_back(pro->getProjection(v1));
81  aux.push_back(pro->getProjection(xo));
82  aux.push_back(pro->getProjection(v2));
83  s[j] = new EGS_Polygon(aux,*pro,open);
84  aux.clear();
85  delete pro;
86  }
87  is_convex = p->isConvex();
88 }
89 
90 template<class T>
91 void EGS_PyramidT<T>::printInfo() const {
93 }
94 
95 extern "C" {
96 
97  EGS_PYRAMID_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) {
98 
99  if (!input) {
100  egsWarning("createGeometry(pyramid): null input?\n");
101  return 0;
102  }
103  string type;
104  int err = input->getInput("type",type);
105  if (err) {
106  egsWarning("createGeometry(pyramid): missing 'type' input\n");
107  return 0;
108  }
109  EGS_BaseGeometry *g;
110  vector<EGS_Float> p;
111  err = input->getInput("points",p);
112  if (err) {
113  egsWarning("createGeometry(pyramid): missing 'points' input\n");
114  return 0;
115  }
116  vector<EGS_Float> tip;
117  err = input->getInput("tip",tip);
118  if (err || tip.size() != 3) {
119  egsWarning("createGeometry(pyramid): wrong/missing 'tip' input\n");
120  return 0;
121  }
122  bool o = true;
123  int is_closed;
124  err = input->getInput("closed",is_closed);
125  if (!err && is_closed == 1) {
126  o = false;
127  }
128  //egsWarning("%s: open = %d\n",type.c_str(),o);
129  if (input->compare(type,__pyrX) || input->compare(type,__pyrY) ||
130  input->compare(type,__pyrZ)) {
131  int np = p.size()/2;
132  if (np < 3) {
133  egsWarning("createGeometry(pyramid): at least 3 points are "
134  "required to construct a pyramid\n");
135  return 0;
136  }
137  vector<EGS_2DVector> points;
138  for (int j=0; j<np; j++) {
139  points.push_back(EGS_2DVector(p[2*j],p[2*j+1]));
140  }
141  if (input->compare(type,__pyrX))
142  g=new EGS_PyramidX(new
143  EGS_PolygonYZ(points,EGS_XProjector(__pyrX)),
144  EGS_Vector(tip[0],tip[1],tip[2]),o);
145  else if (input->compare(type,__pyrY))
146  g=new EGS_PyramidY(new EGS_PolygonXZ(points,
147  EGS_YProjector(__pyrY)),
148  EGS_Vector(tip[0],tip[1],tip[2]),o);
149  else
150  g=new EGS_PyramidZ(new
151  EGS_PolygonXY(points,EGS_ZProjector(__pyrZ)),
152  EGS_Vector(tip[0],tip[1],tip[2]),o);
153  }
154  else {
155  int np = p.size()/3;
156  if (np < 3) {
157  egsWarning("createGeometry(pyramid): at least 3 points are required"
158  " to construct a pyramid\n");
159  return 0;
160  }
161  vector<EGS_Vector> points;
162  for (int j=0; j<np; j++) {
163  points.push_back(EGS_Vector(p[3*j],p[3*j+1],p[3*j+2]));
164  }
165  EGS_Vector aux(points[np-1]-points[0]);
166  if (aux.length2() > epsilon) {
167  points.push_back(points[0]);
168  }
169  np = points.size();
170  EGS_Projector pro(points[0],points[1],points[np-2],__pyr);
171  vector<EGS_2DVector> p2;
172  {
173  for (int j=0; j<np; j++) {
174  p2.push_back(pro.getProjection(points[j]));
175  EGS_Float d = pro.distance(points[j]);
176  if (fabs(d) > epsilon) {
177  egsWarning("createGeometry(pyramid): "
178  "points are not on a plane\n");
179  return 0;
180  }
181  }
182  }
183  g = new EGS_Pyramid(new EGS_Polygon(p2,pro),
184  EGS_Vector(tip[0],tip[1],tip[2]),o);
185  }
186  g->setName(input);
187  g->setBoundaryTolerance(input);
188  g->setMedia(input);
189  g->setLabels(input);
190  return g;
191  }
192 
193 }
A pyramid geometry: header.
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.
EGS_Input class header file.
A class representing 3D vectors.
Definition: egs_vector.h:56
int setLabels(EGS_Input *input)
Set the labels from an input block.
EGS_Vector normal() const
Get the normal to the projection plane.
Global egspp functions header file.
EGS_Vector a
the base normal vector.
Definition: egs_pyramid.h:136
T * p
the base polygon
Definition: egs_pyramid.h:133
EGS_GLIB_EXPORT EGS_BaseGeometry * createGeometry(EGS_Input *input)
Definition: egs_glib.cpp:57
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
void setBoundaryTolerance(EGS_Input *inp)
Set the value of the boundary tolerance from the input inp.
EGS_PolygonT< EGS_XProjector > EGS_PolygonYZ
A 3D polygon in the x-plane.
Definition: egs_polygon.h:478
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
EGS_PolygonT< EGS_Projector > EGS_Polygon
A 3D polygon in any plane.
Definition: egs_polygon.h:484
void setMedia(EGS_Input *inp)
Set the media in the geometry from the input pointed to by inp.
bool is_convex
Is this geometry convex?
A projector into any plane.
EGS_2DVector getProjection(const EGS_Vector &x) const
Get the 2D projection of the vector x onto the plane.
void setName(EGS_Input *inp)
Set the name of the geometry from the input inp.
EGS_Float boundaryTolerance
Boundary tolerance for geometries that need it.
A projector into the z-plane.
EGS_2DVector xop
the tip projection on the base polygon
Definition: egs_pyramid.h:135
A projector into the y-plane.
A template class for 3D polygons.
Definition: egs_polygon.h:335
EGS_PolygonT< EGS_ZProjector > EGS_PolygonXY
A 3D polygon in the z-plane.
Definition: egs_polygon.h:482
A projector into the x-plane.
const EGS_Float epsilon
The epsilon constant for floating point comparisons.
Definition: egs_functions.h:61
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:1170
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
int nreg
Number of local regions in this geometry.
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:50
EGS_PolygonT< EGS_YProjector > EGS_PolygonXZ
A 3D polygon in the y-plane.
Definition: egs_polygon.h:480
EGS_Vector xo
the tip of the pyramid
Definition: egs_pyramid.h:134
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:338
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.