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