EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_polygon_shape.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ polygon shape
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: Randle Taylor
27 # Reid Townson
28 #
29 ###############################################################################
30 */
31 
32 
38 #include "egs_polygon_shape.h"
39 #include "egs_polygon.h"
40 #include "egs_input.h"
41 #include "egs_functions.h"
42 #include "egs_math.h"
43 
44 EGS_TriangleShape::EGS_TriangleShape(const vector<EGS_Float> &points,
45  const string &Name, EGS_ObjectFactory *f) : EGS_SurfaceShape(Name,f) {
46  xo = points[0];
47  yo = points[1];
48  ax = points[2] - xo;
49  ay = points[3] - yo;
50  bx = points[4] - xo;
51  by = points[5] - yo;
52  A = 0.5*fabs(ax*by-ay*bx);
53 }
54 
55 EGS_TriangleShape::EGS_TriangleShape(const EGS_Float *points,
56  const string &Name, EGS_ObjectFactory *f) : EGS_SurfaceShape(Name,f) {
57  xo = points[0];
58  yo = points[1];
59  ax = points[2] - xo;
60  ay = points[3] - yo;
61  bx = points[4] - xo;
62  by = points[5] - yo;
63  A = 0.5*fabs(ax*by-ay*bx);
64 }
65 
66 EGS_PolygonShape::EGS_PolygonShape(const vector<EGS_Float> &points,
67  const string &Name, EGS_ObjectFactory *f) : EGS_SurfaceShape(Name,f) {
68  int np = points.size();
69  n = np/2;
70  EGS_Float auxx = points[np-2] - points[0];
71  EGS_Float auxy = points[np-1] - points[1];
72  EGS_Float *xc, *yc;
73  if (auxx*auxx + auxy*auxy > epsilon) {
74  n++;
75  }
76  xc = new EGS_Float [n];
77  yc = new EGS_Float [n];
78  vector<EGS_2DVector> p1;
79  for (int j=0; j<np/2; j++) {
80  xc[j] = points[2*j];
81  yc[j] = points[2*j+1];
82  p1.push_back(EGS_2DVector(xc[j],yc[j]));
83  }
84  if (n > np/2) {
85  xc[n-1] = points[0];
86  yc[n-1] = points[1];
87  p1.push_back(EGS_2DVector(xc[n-1],yc[n-1]));
88  }
89  EGS_2DPolygon pol(p1);
90  int ntr = 0;
91  triangle = new EGS_TriangleShape* [n-2];
92  np = n;
93  EGS_Float p_tmp[6];
94  while (np > 3) {
95  for (int i=0; i<np-2; i++) {
96  EGS_2DVector aux(0.5*(xc[i+2]+xc[i]),0.5*(yc[i+2]+yc[i]));
97  if (pol.isInside(aux)) {
98  bool is_ok = true;
99  vector<EGS_2DVector> p2;
100  for (int k=0; k<3; k++) {
101  p_tmp[2*k] = xc[i+k];
102  p_tmp[2*k+1] = yc[i+k];
103  p2.push_back(EGS_2DVector(xc[i+k],yc[i+k]));
104  }
105  EGS_2DPolygon tri(p2);
106  for (int j=0; j<np-1; j++) {
107  if (j < i || j > i+2) {
108  EGS_2DVector tmp(xc[j],yc[j]);
109  if (tri.isInside(tmp)) {
110  is_ok = false;
111  break;
112  }
113  }
114  }
115  if (is_ok) {
116  EGS_TriangleShape *t = new EGS_TriangleShape(p_tmp);
117  triangle[ntr++] = t;
118  for (int j=i+1; j<np-1; j++) {
119  xc[j] = xc[j+1];
120  yc[j] = yc[j+1];
121  }
122  }
123  np--;
124  }
125  }
126  }
127  for (int k=0; k<3; k++) {
128  p_tmp[2*k] = xc[k];
129  p_tmp[2*k+1] = yc[k];
130  }
131  triangle[ntr++] = new EGS_TriangleShape(p_tmp);
132  A = 0;
133  for (int i=0; i<ntr; i++) {
134  yc[i] = triangle[i]->area();
135  A += yc[i];
136  }
137  table = new EGS_AliasTable(ntr,xc,yc,0);
138  delete [] xc;
139  delete [] yc;
140 }
141 
142 extern "C" {
143 
144  EGS_POLYGON_SHAPE_EXPORT EGS_BaseShape *createShape(EGS_Input *input,
145  EGS_ObjectFactory *f) {
146  if (!input) {
147  egsWarning("createShape(polygon): null input?\n");
148  return 0;
149  }
150  vector<EGS_Float> points;
151  int err = input->getInput("points",points);
152  if (err) {
153  egsWarning("createShape(polygon): no 'points' input\n");
154  return 0;
155  }
156  int np = points.size();
157  if ((np%2) != 0) {
158  egsWarning("createShape(polygon): you must input an even number of"
159  " floating numbers\n");
160  return 0;
161  }
162  if (np < 6) {
163  egsWarning("createShape(polygon): you must input at least 3 2D points"
164  " to form a polygon\n");
165  return 0;
166  }
167  EGS_BaseShape *shape;
168  if (np == 6) {
169  shape = new EGS_TriangleShape(points,"",f);
170  }
171  else {
172  shape = new EGS_PolygonShape(points,"",f);
173  }
174  shape->setName(input);
175  shape->setTransformation(input);
176  return shape;
177  }
178 
179 }
A class to represent a polygon in a plane (a 2D polygon).
Definition: egs_polygon.h:59
A class representing 2D vectors.
A class for sampling random values from a given probability distribution using the alias table techni...
Base shape class. All shapes in the EGSnrc C++ class library are derived from EGS_BaseShape.
Definition: egs_shapes.h:114
void setTransformation(EGS_Input *inp)
Set the transformation attached to this shape.
Definition: egs_shapes.cpp:69
A class for storing information in a tree-like structure of key-value pairs. This class is used throu...
Definition: egs_input.h:182
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
An object factory.
void setName(EGS_Input *inp)
Set the name of the object from the information provided by inp.
A polygon shape.
A surface shape.
Definition: egs_shapes.h:266
A triangular shape.
Global egspp functions header file.
EGS_Input class header file.
Attempts to fix broken math header files.
EGS_2DPolygon and EGS_PolygonT class header file.
A polygon shape.
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.