EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_roundrect_cylinders.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ roundrect cylinders 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: Manuel Stoeckl, 2016
25 #
26 # Contributors:
27 #
28 ###############################################################################
29 #
30 # A set of concentric rounded rectangle cylinders.
31 #
32 ###############################################################################
33 */
34 
35 
42 #include "egs_input.h"
43 
44 extern "C" {
45 
46  EGS_ROUNDRECT_CYLINDERS_EXPORT
48  // check for valid input
49  if (!input) {
50  egsWarning("createGeometry(round rectangular cylinders): null input?\n");
51  return 0;
52  }
53  string type;
54  int err = input->getInput("type",type);
55  if (err) {
56  egsWarning("createGeometry(round rectangular cylinders): missing type key\n");
57  return 0;
58  }
59 
60  // point on cylinder axis
61  EGS_Vector xo;
62  vector<EGS_Float> Xo;
63  err = input->getInput("midpoint",Xo);
64  if (!err && Xo.size() == 3) {
65  xo = EGS_Vector(Xo[0],Xo[1],Xo[2]);
66  }
67 
68  // cylinder radii
69  vector<EGS_Float> x_widths, y_widths, radii;
70  err = input->getInput("x-widths",x_widths);
71  if (err) {
72  egsWarning("createGeometry(round rectangular cylinders): wrong/missing "
73  "'x-widths' input\n");
74  return 0;
75  }
76  err = input->getInput("y-widths",y_widths);
77  if (err) {
78  egsWarning("createGeometry(round rectangular cylinders): wrong/missing "
79  "'y-widths' input\n");
80  return 0;
81  }
82  err = input->getInput("radii",radii);
83  if (err) {
84  egsWarning("createGeometry(round rectangular cylinders): wrong/missing "
85  "'radii' input\n");
86  return 0;
87  }
88  if (x_widths.size() != y_widths.size() || x_widths.size() != radii.size()) {
89  egsWarning("createGeometry(round rectangular cylinders): expecting the same "
90  "number of x- and y-widths and radii, your input is %d %d %d\n",
91  x_widths.size(),y_widths.size(), radii.size());
92  return 0;
93  }
94 
95  for (int i=0; i<x_widths.size(); i++) {
96  if (i >= 1) {
97  if (x_widths[i-1] > x_widths[i] || x_widths[i] <= 0 || x_widths[i-1] <= 0) {
98  egsWarning("createGeometry(round rectangular cylinders): x-widths must all be positive and in sorted order\n");
99  return 0;
100  }
101  if (y_widths[i-1] > y_widths[i] || y_widths[i] <= 0 || y_widths[i-1] <= 0) {
102  egsWarning("createGeometry(round rectangular cylinders): y-widths must all be positive and in sorted order\n");
103  return 0;
104  }
105  if (radii[i] > radii[i-1]) {
106  if (x_widths[i] - radii[i] >= x_widths[i-1] - radii[i-1]) {
107  }
108  else if (x_widths[i] - radii[i] >= x_widths[i-1] - radii[i-1]) {
109  }
110  else {
111  // We have an intersection if the furthest distance on the
112  // smaller circle away from the center of the larger is more
113  // than the larger radius
114  EGS_Float dx = (x_widths[i] - radii[i]) - (x_widths[i-1] - radii[i-1]);
115  EGS_Float dy = (y_widths[i] - radii[i]) - (y_widths[i-1] - radii[i-1]);
116  EGS_Float maxdist = sqrt(dx*dx+dy*dy);
117  if (radii[i] - radii[i-1] < maxdist) {
118  egsWarning("createGeometry(round rectangular cylinders): rounded rectangles may not intersect (but (hx,hy,r) = (%f,%f,%f) and (%f,%f,%f) do)\n",
119  x_widths[i-1], y_widths[i-1], radii[i-1],
120  x_widths[i], y_widths[i], radii[i]);
121  return 0;
122  }
123  }
124  }
125  }
126  if (radii[i] < 0) {
127  egsWarning("createGeometry(round rectangular cylinders): radii must all be positive\n");
128  return 0;
129  }
130  if (radii[i] > x_widths[i] || radii[i] > y_widths[i]) {
131  egsWarning("createGeometry(round rectangular cylinders): radii cannot be larger than half-widths\n");
132  return 0;
133  }
134  }
135 
136  // select geometry
137  EGS_BaseGeometry *g;
138  if (type == "EGS_RoundRectCylindersXY")
139  g = new EGS_RoundRectCylindersT<EGS_XProjector,EGS_YProjector>(x_widths,y_widths,radii,xo,"",
140  EGS_XProjector("X"),EGS_YProjector("Y"));
141  else if (type == "EGS_RoundRectCylindersXZ")
142  g = new EGS_RoundRectCylindersT<EGS_XProjector,EGS_ZProjector>(x_widths,y_widths,radii,xo,"",
143  EGS_XProjector("X"),EGS_ZProjector("Z"));
144  else if (type == "EGS_RoundRectCylindersYZ")
145  g = new EGS_RoundRectCylindersT<EGS_YProjector,EGS_ZProjector>(x_widths,y_widths,radii,xo,"",
146  EGS_YProjector("Y"),EGS_ZProjector("Z"));
147  else {
148  vector<EGS_Float> ax, ay;
149  err = input->getInput("x-axis",ax);
150  if (err || ax.size() != 3) {
151  egsWarning("createGeometry(round rectangular cylinders): missing/wrong "
152  "'x-axis' input\n");
153  return 0;
154  }
155  err = input->getInput("y-axis",ay);
156  if (err || ay.size() != 3) {
157  egsWarning("createGeometry(round rectangular cylinders): missing/wrong "
158  "'y-axis' input\n");
159  return 0;
160  }
161  g = new EGS_RoundRectCylindersT<EGS_Projector,EGS_Projector>(x_widths,y_widths,radii,xo,"",
162  EGS_Projector(EGS_Vector(ax[0],ax[1],ax[2]),"Any"),
163  EGS_Projector(EGS_Vector(ay[0],ay[1],ay[2]),""));
164  }
165  g->setName(input);
166  g->setLabels(input);
167  g->setMedia(input);
168  return g;
169  }
170 
171 }
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_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 setMedia(EGS_Input *inp)
Set the media in the geometry from the input pointed to by inp.
A projector into any plane.
void setName(EGS_Input *inp)
Set the name of the geometry from the input inp.
A projector into the z-plane.
A projector into the y-plane.
A projector into the x-plane.
A set of concentric rounded rectangles.
A set of concentric rounded rectangular cylinders: header.
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
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.