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 #
30 ###############################################################################
31 */
32 
33 
39 #include "egs_pyramid.h"
40 #include "egs_input.h"
41 #include "egs_functions.h"
42 
43 #include <vector>
44 using std::vector;
45 
46 static EGS_PYRAMID_LOCAL string __pyrX = "EGS_PyramidX";
47 static EGS_PYRAMID_LOCAL string __pyrY = "EGS_PyramidY";
48 static EGS_PYRAMID_LOCAL string __pyrZ = "EGS_PyramidZ";
49 static EGS_PYRAMID_LOCAL string __pyr = "EGS_Pyramid";
50 
51 template<class T>
52 EGS_PyramidT<T>::EGS_PyramidT(T *P, const EGS_Vector &Xo, bool O,
53  const string &Name) : EGS_BaseGeometry(Name), p(P), xo(Xo),
54  a(p->getNormal()), open(O) {
55  nreg = 1;
56  d = p->distance(xo);
57  xop = p->getProjection(xo);
58  if (fabs(d) < boundaryTolerance) egsFatal("%s: the tip is too close to"
59  " the base (%g)\n",getType().c_str(),fabs(d));
60  if (d < 0) {
61  a *= (-1);
62  d *= (-1);
63  }
64  EGS_Vector v2 = p->getPoint(0), v1;
65  n = p->getN();
66  s = new EGS_Polygon * [n];
67  vector<EGS_2DVector> aux;
68  for (int j=0; j<p->getN(); j++) {
69  v1 = v2;
70  v2 = p->getPoint(j+1);
71  EGS_Vector aj = p->getNormal(j);
72  EGS_Projector *pro = new EGS_Projector(v1,xo,v2,"");
73  EGS_Vector n = pro->normal();
74  if (n*aj < 0) {
75  delete pro;
76  pro = new EGS_Projector(v2,xo,v1,"");
77  n = pro->normal();
78  if (n*aj < 0)
79  egsFatal("%s: n*aj < 0 for both normal orientations?\n",
80  getType().c_str());
81  }
82  aux.push_back(pro->getProjection(v1));
83  aux.push_back(pro->getProjection(xo));
84  aux.push_back(pro->getProjection(v2));
85  s[j] = new EGS_Polygon(aux,*pro,open);
86  aux.clear();
87  delete pro;
88  }
89  is_convex = p->isConvex();
90 }
91 
92 template<class T>
93 void EGS_PyramidT<T>::printInfo() const {
95 }
96 
97 extern "C" {
98 
99  EGS_PYRAMID_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) {
100 
101  if (!input) {
102  egsWarning("createGeometry(pyramid): null input?\n");
103  return 0;
104  }
105  string type;
106  int err = input->getInput("type",type);
107  if (err) {
108  egsWarning("createGeometry(pyramid): missing 'type' input\n");
109  return 0;
110  }
111  EGS_BaseGeometry *g;
112  vector<EGS_Float> p;
113  err = input->getInput("points",p);
114  if (err) {
115  egsWarning("createGeometry(pyramid): missing 'points' input\n");
116  return 0;
117  }
118  vector<EGS_Float> tip;
119  err = input->getInput("tip",tip);
120  if (err || tip.size() != 3) {
121  egsWarning("createGeometry(pyramid): wrong/missing 'tip' input\n");
122  return 0;
123  }
124  bool o = true;
125  int is_closed;
126  err = input->getInput("closed",is_closed);
127  if (!err && is_closed == 1) {
128  o = false;
129  }
130  //egsWarning("%s: open = %d\n",type.c_str(),o);
131  if (input->compare(type,__pyrX) || input->compare(type,__pyrY) ||
132  input->compare(type,__pyrZ)) {
133  int np = p.size()/2;
134  if (np < 3) {
135  egsWarning("createGeometry(pyramid): at least 3 points are "
136  "required to construct a pyramid\n");
137  return 0;
138  }
139  vector<EGS_2DVector> points;
140  for (int j=0; j<np; j++) {
141  points.push_back(EGS_2DVector(p[2*j],p[2*j+1]));
142  }
143  if (input->compare(type,__pyrX))
144  g=new EGS_PyramidX(new
145  EGS_PolygonYZ(points,EGS_XProjector(__pyrX)),
146  EGS_Vector(tip[0],tip[1],tip[2]),o);
147  else if (input->compare(type,__pyrY))
148  g=new EGS_PyramidY(new EGS_PolygonXZ(points,
149  EGS_YProjector(__pyrY)),
150  EGS_Vector(tip[0],tip[1],tip[2]),o);
151  else
152  g=new EGS_PyramidZ(new
153  EGS_PolygonXY(points,EGS_ZProjector(__pyrZ)),
154  EGS_Vector(tip[0],tip[1],tip[2]),o);
155  }
156  else {
157  int np = p.size()/3;
158  if (np < 3) {
159  egsWarning("createGeometry(pyramid): at least 3 points are required"
160  " to construct a pyramid\n");
161  return 0;
162  }
163  vector<EGS_Vector> points;
164  for (int j=0; j<np; j++) {
165  points.push_back(EGS_Vector(p[3*j],p[3*j+1],p[3*j+2]));
166  }
167  EGS_Vector aux(points[np-1]-points[0]);
168  if (aux.length2() > epsilon) {
169  points.push_back(points[0]);
170  }
171  np = points.size();
172  EGS_Projector pro(points[0],points[1],points[np-2],__pyr);
173  vector<EGS_2DVector> p2;
174  {
175  for (int j=0; j<np; j++) {
176  p2.push_back(pro.getProjection(points[j]));
177  EGS_Float d = pro.distance(points[j]);
178  if (fabs(d) > epsilon) {
179  egsWarning("createGeometry(pyramid): "
180  "points are not on a plane\n");
181  return 0;
182  }
183  }
184  }
185  g = new EGS_Pyramid(new EGS_Polygon(p2,pro),
186  EGS_Vector(tip[0],tip[1],tip[2]),o);
187  }
188  g->setName(input);
189  g->setBoundaryTolerance(input);
190  g->setMedia(input);
191  g->setLabels(input);
192  return g;
193  }
194 
195 }
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:1170
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
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:52
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:57
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.