Points&Forces (survey)
Software tools facilitating the task of surveying architecture
average.cxx
Go to the documentation of this file.
1 /*
2  Copyright 2008-2019 Pierre SMARS (smars@yuntech.edu.tw)
3  This program is free software: you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation, either version 2 of the License, or
6  (at your option) any later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 #include <iostream>
17 #include <string>
18 #include <fstream>
19 #include <sstream>
20 #include <vector>
21 
22 #include "a_point.h"
23 #include "a_segment.h"
24 #include "a_triangle.h"
25 #include "a_mat_sq.h"
26 #include "a_mat_r.h"
27 #include "a_mat_c.h"
28 #include "SimpleOpt.h"
29 
31 
32 CSimpleOpt::SOption g_rgOptions[] = {
33  { OPT_P, _T("-p"), SO_NONE },
34  { OPT_P, _T("--point"), SO_NONE },
35  { OPT_L, _T("-l"), SO_NONE },
36  { OPT_L, _T("--line"), SO_NONE },
37  { OPT_T, _T("-t"), SO_NONE },
38  { OPT_T, _T("--triangle"), SO_NONE },
39  { OPT_BOX, _T("-b"), SO_NONE },
40  { OPT_BOX, _T("--box"), SO_NONE },
41  { OPT_MASS, _T("-m"), SO_NONE },
42  { OPT_MASS, _T("--mass"), SO_NONE },
43  { OPT_VERBOSE, _T("-v"), SO_NONE },
44  { OPT_VERBOSE, _T("--verbose"), SO_NONE },
45  { OPT_COV, _T("-c"), SO_NONE },
46  { OPT_COV, _T("--covariance"), SO_NONE },
47  { OPT_SCALAR, _T("-sf"), SO_REQ_SEP },
48  { OPT_SCALAR, _T("--scalar-file"), SO_REQ_SEP },
49  { OPT_HELP, _T("-?"), SO_NONE },
50  { OPT_HELP, _T("-h"), SO_NONE },
51  { OPT_HELP, _T("--help"), SO_NONE },
52  SO_END_OF_OPTIONS
53 };
54 //*****************************************
55 int error(int val)
56 {
57 #include "average.help"
58  return val;
59 }
60 //*****************************************
61 double xmin[] = {1.e30,1.e30,1.e30};
62 double xmax[] = {-1.e30,-1.e30,-1.e30};
63 a_mat_sq x2(3);
64 //*****************************************
65 void extremes(const a_point& p)
66 {
67  for (short i=0;i<3;i++)
68  {
69  double x = p[i];
70  if (x<xmin[i]) xmin[i]=x;
71  if (x>xmax[i]) xmax[i]=x;
72  }
73 }
74 //*****************************************
75 int main( int argc, char *argv[] )
76 {
77  char code = 'p';
78  bool box = false;
79  bool verbose = false;
80  bool cov = false;
81  double mass;
82  bool with_scalars = false;
83  bool with_mass = false;
84  std::string scalar_file;
85  unsigned int n_scalars;
86  a_point average;
87  CSimpleOpt args(argc, argv, g_rgOptions);
88  while (args.Next())
89  {
90  if (args.LastError() == SO_SUCCESS)
91  {
92  if (args.OptionId() == OPT_HELP)
93  return error(0);
94  else if (args.OptionId() == OPT_P)
95  code = 'p';
96  else if (args.OptionId() == OPT_L)
97  code = 'l';
98  else if (args.OptionId() == OPT_T)
99  code = 't';
100  else if (args.OptionId() == OPT_BOX)
101  box = true;
102  else if (args.OptionId() == OPT_COV)
103  cov = true;
104  else if (args.OptionId() == OPT_SCALAR)
105  {
106  with_scalars = true;
107  scalar_file = args.OptionArg();
108  }
109  else if (args.OptionId() == OPT_MASS)
110  with_mass = true;
111  else if (args.OptionId() == OPT_VERBOSE)
112  verbose = true;
113  else
114  return error(-1);
115  // handle option, using OptionId(), OptionText() and OptionArg()
116  } else {
117  return error(args.LastError());
118  // handle error, one of: SO_OPT_INVALID, SO_OPT_MULTIPLE,
119  // SO_ARG_INVALID, SO_ARG_INVALID_TYPE, SO_ARG_MISSING
120  }
121  }
122  std::vector<double> scalars;
123  if (with_scalars)
124  {
125  std::ifstream in(scalar_file.c_str());
126  if (!in)
127  {
128  std::cerr << "Cannot open file '" << scalar_file << "'" << std::endl;
129  return error(-2);
130  }
131  in >> n_scalars;
132  for (unsigned int i=0; i<n_scalars; i++)
133  {
134  double val;
135  in >> val;
136  scalars.push_back(val);
137  }
138  in.close();
139  }
140  a_point pt;
141  switch (code) {
142  case 'p':
143  {
144  unsigned int n_pts;
145  std::cin >> n_pts;
146  if ((with_scalars)&&(n_pts!=n_scalars))
147  {
148  std::cerr << "Number of scalars does not correspond to number of points" << std::endl;
149  return error(-2);
150  }
151  for (unsigned int k = 0; k < n_pts; k++)
152  {
153  a_point p;
154  std::cin >> p;
155  if (with_scalars)
156  {
157  mass += scalars[k];
158  pt += p*scalars[k];
159  }
160  else
161  {
162  mass += 1;
163  pt += p;
164  }
165  if (box)
166  {
167  if (!with_scalars||(scalars[k]!=0))
168  extremes(p);
169  }
170  if (cov)
171  {
172  if (with_scalars)
173  x2 += p.inertia()*scalars[k];
174  else
175  x2 += p.inertia();
176  }
177  }
178  }
179  break;
180  case 'l':
181  {
182  int n_lis;
183  std::cin >> n_lis;
184  if ((with_scalars)&&(n_lis!=n_scalars))
185  {
186  std::cerr << "Number of scalars does not correspond to number of lines" << std::endl;
187  return error(-2);
188  }
189  for (unsigned int k = 0; k < n_lis; k++)
190  {
191  a_segment s;
192  std::cin >> s;
193  double l = s.length();
194  if (with_scalars)
195  l *= scalars[k];
196  mass += l;
197  a_point centre = s.c();
198  pt += centre*l;
199  if (box)
200  {
201  if (!with_scalars||(scalars[k]!=0))
202  {
203  extremes(s.p1());
204  extremes(s.p2());
205  }
206  }
207  if (cov)
208  {
209  if (with_scalars)
210  x2 += s.inertia()*scalars[k];
211  else
212  x2 += s.inertia();
213  }
214  }
215  }
216  break;
217  case 't':
218  {
219  int npts;
220  std::cin >> npts;
221  std::vector<a_point> points(npts);
222  for (unsigned int k = 0; k < npts; k++)
223  {
224  a_point p;
225  std::cin >> p;
226  if (box)
227  extremes(p);
228  points[k] = p;
229  }
230  int n_tris;
231  std::cin >> n_tris;
232  if ((with_scalars)&&(n_tris!=n_scalars))
233  {
234  std::cerr << "Number of scalars does not correspond to number of triangles" << std::endl;
235  return error(-2);
236  }
237  for (unsigned int k = 0; k < n_tris; k++)
238  {
239  int pr[3];
240  for (short l = 0; l < 3; l++)
241  std::cin >> pr[l];
242  a_triangle tri(points[pr[0]],points[pr[1]],points[pr[2]]);
243  double surface = tri.S();
244  if (with_scalars)
245  surface *= scalars[k];
246  a_point centre = tri.c();
247  mass += surface;
248  pt += centre*surface;
249  if (cov)
250  {
251  if (with_scalars)
252  x2 += tri.inertia()*scalars[k];
253  else
254  x2 += tri.inertia();
255  }
256  points.clear();
257  }
258  break;
259  }
260  }
261  average = pt/mass;
262  if (verbose)
263  std::cout << "center_of_mass: ";
264  std::cout << average << std::endl;
265  if (with_mass)
266  {
267  if (verbose)
268  std::cout << "mass: ";
269  std::cout << mass << std::endl;
270  }
271  if (cov)
272  {
273  if (verbose)
274  std::cout << "inertia: " << std::endl;
275  a_mat_sq m(3);
276  m = average.inertia();
277  m *= mass;
278  std::cout << x2-m;
279  }
280  if (box)
281  {
282  if (verbose)
283  {
284  std::cout << "bounding_box: ";
285  std::cout << std::endl << "min: ";
286  }
287  std::cout << xmin[0] << " " << xmin[1] << " " << xmin[2] << std::endl;
288  if (verbose)
289  std::cout << "max: ";
290  std::cout << xmax[0] << " " << xmax[1] << " " << xmax[2] << std::endl;
291  }
292  return 0;
293 }
a_mat_sq x2(3)
int main(int argc, char *argv[])
Definition: average.cxx:75
int error(int val)
Definition: average.cxx:55
CSimpleOpt::SOption g_rgOptions[]
Definition: average.cxx:32
@ OPT_L
Definition: average.cxx:30
@ OPT_COV
Definition: average.cxx:30
@ OPT_VERBOSE
Definition: average.cxx:30
@ OPT_MASS
Definition: average.cxx:30
@ OPT_HELP
Definition: average.cxx:30
@ OPT_P
Definition: average.cxx:30
@ OPT_T
Definition: average.cxx:30
@ OPT_SCALAR
Definition: average.cxx:30
@ OPT_BOX
Definition: average.cxx:30
double xmin[]
Definition: average.cxx:61
double xmax[]
Definition: average.cxx:62
void extremes(const a_point &p)
Definition: average.cxx:65
void tri(const uint32_t i, const uint32_t j)
Definition: generate.cxx:50
bool verbose
Definition: h_compute.cxx:40
std::istringstream in
Definition: ply2tri.cxx:32
Definition: stlb2stla.cxx:21