Points&Forces (survey)
Software tools facilitating the task of surveying architecture
a_shape_plane.cxx
Go to the documentation of this file.
1 /*
2  Copyright 2009-2020 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 "a_shape_plane.h"
17 #include <math.h>
18 #include <vnl/vnl_least_squares_function.h>
19 #include <vtkPolyData.h>
20 #include <vtkPoints.h>
21 #include <vtkCellArray.h>
22 #include <vtkHull.h>
23 #include <vtkDelaunay2D.h>
24 
26 //***************************************************************************
28 {
29  public:
31  const std::vector<a_point> & cloud) :
32  vnl_least_squares_function(4, cloud.size(), no_gradient),
33  shape_(shape),
34  cloud_(cloud) {};
35  void f(const vnl_vector<double>& x, vnl_vector<double>& fx);
36  protected:
38  const std::vector<a_point> & cloud_;
39 };
40 //---------------------------------------------------------------------------
41 void a_shape_plane_function::f(const vnl_vector<double>& x, vnl_vector<double>& fx)
42 {
43  a_point norm(x[0],x[1],x[2]);
44  double d(x[3]);
45  norm.normalise();
46  shape_.normal(norm);
47  shape_.dist(d);
48  for (int i = 0; i< fx.size(); i++)
49  fx[i] = shape_.dist_point(cloud_[i]);
50 }
51 //***************************************************************************
52 //---------------------------------------------------------------------------
53 const std::string a_shape_plane::help()
54 {
55  std::ostringstream o;
56  o << "**************" << std::endl;
57  o << "a_shape_plane:" << std::endl;
58  o << "**************" << std::endl;
59  o << "This is a 'plane' fitting class" << std::endl;
60  o << std::endl;
61  o << a_shape::help();
62  return o.str();
63 }
64 //---------------------------------------------------------------------------
65 void a_shape_plane::normal(const a_point p)
66 {
67  a_point p2=p;
68  p2.normalise();
69  para_[0] = p2.x();
70  para_[1] = p2.y();
71  para_[2] = p2.z();
72 }
73 //---------------------------------------------------------------------------
75 {
76  a_point v = this->normal();
77  v.normalise();
78  para_[0] = v.x();
79  para_[1] = v.y();
80  para_[2] = v.z();
81 }
82 //---------------------------------------------------------------------------
83 a_point a_shape_plane::origin() const
84 {
85  a_point norm = this->normal();
86  return norm*this->dist();
87 }
88 //---------------------------------------------------------------------------
89 a_point a_shape_plane::closest_point(const a_point pt) const
90 {
91  //compute the normal
92  a_point norm = this->normal();
93  //point of the plan closest to the origin
94  a_point pt0 = norm*this->dist();
95  return pt-norm*(norm*(pt-pt0));
96 }
97 //---------------------------------------------------------------------------
98 double a_shape_plane::dist_point(const a_point pt) const
99 {
100  //compute the normal
101  a_point norm = this->normal();
102  //point of the plan closest to the origin
103  a_point pt0 = norm*this->dist();
104  return fabs(norm*(pt-pt0));
105 }
106 //---------------------------------------------------------------------------
107 void a_shape_plane::p3pts(const a_point p1, const a_point p2, const a_point p3)
108 {
109  a_point d1 = p2-p1;
110  a_point d2 = p3-p1;
111  a_point dn = cross(d1,d2).normalise();
112  if (dn.norm()==0) return;
113  double d = (p1+p2+p3)*dn/3.;
114  this->normal(dn);
115  this->dist(d);
116  //std::cerr << orig_ << std::endl << dir_ << std::endl;
117 }
118 //---------------------------------------------------------------------------
119 void a_shape_plane::random_hint(const std::vector<a_point>& pts)
120 {
121  int n = pts.size();
122  int i1 = rand()%n;
123  int i2,i3;
124  do
125  {
126  i2 = rand()%n;
127  } while (i1==i2);
128  do
129  {
130  i3 = rand()%n;
131  } while ((i1==i3)||(i2==i3));
132  a_point p1 = pts[i1];
133  a_point p2 = pts[i2];
134  a_point p3 = pts[i3];
135  this->p3pts(p1,p2,p3);
136 }
137 //---------------------------------------------------------------------------
138 void a_shape_plane::fit_cloud(std::vector<a_point>& pts, short nl)
139 {
140  std::vector<a_point> pts2;
141  int cs0 = pts.size();
142  this->best_fitting_cloud(pts,pts2);
143  if (nl==1)
144  {
145  a_shape_plane_function f(*this,pts2);
146  a_shape::fit_cloud(pts2,f);
147  }
148  pts = pts2;
149 }
150 //---------------------------------------------------------------------------
152 {
153  a_point o = this->origin();
154  a_point n = this->normal();
155  int r;
156  if (n[0]<n[1]) r = 0; else r = 1;
157  if (n[r]>n[2]) r = 2;
158  //find axis farther away from n
159  a_point a;
160  switch (r)
161  {
162  case 0 : a.x(1.); break;
163  case 1 : a.y(1.); break;
164  default : a.z(1.);
165  }
166  a_point u = cross(n,a).normalise();
167  a_point v = cross(n,u).normalise();
168  std::cout << o;
169  std::cout << o+u;
170  std::cout << o+v;
171  std::cout << std::endl;
172 }
173 //---------------------------------------------------------------------------
174 void a_shape_plane::export_triangles(const std::vector<a_point>& pts) const
175 {
176  a_point x0 = this->closest_point(pts[0]);
177  double vmin, vmax;
178  double d0;
179  int i0;
180  std::vector<a_point> pts_proj;
181  pts_proj.push_back(x0);
182  for (int i=1; i< pts.size(); i++)
183  {
184  a_point x = this->closest_point(pts[i]);
185  pts_proj.push_back(x);
186  double d = (x-x0).norm();
187  if (d>d0)
188  {
189  i0 = i;
190  d0 = d;
191  }
192  }
193  a_point du = (this->closest_point(pts[i0])-x0).normalise();
194  a_point dv = cross(this->normal(),du).normalise();
195  vtkPoints * vpts = vtkPoints::New();
196  for (int i=0; i< pts.size(); i++)
197  {
198  a_point x = pts_proj[i];
199  double u = x*du;
200  double v = x*dv;
201  vpts->InsertNextPoint(u,v,0);
202  }
203  vtkCellArray * vertices = vtkCellArray::New();
204  for (vtkIdType k = 0; k < pts.size(); k++)
205  vertices->InsertNextCell(1,&k);
206  vtkPolyData * data = vtkPolyData::New();
207  data->SetPoints(vpts);
208  vpts->Delete();
209  data->SetVerts(vertices);
210  vertices->Delete();
211  vtkDelaunay2D * del = vtkDelaunay2D::New();
212  del->SetInputData(data);
213  data->Delete();
214  del->SetTolerance(0.001);
215  del->Update();
216  int n_pts = vpts->GetNumberOfPoints();
217  std::cout << n_pts << std::endl;
218  for (int k = 0; k < n_pts; k++)
219  std::cout << pts_proj[k] << std::endl;
220  vtkCellArray * triangles;
221  triangles = del->GetOutput()->GetPolys();
222  int n_tri = del->GetOutput()->GetNumberOfPolys();
223  std::cout << n_tri << std::endl;
224  triangles->InitTraversal();
225  for (int k = 0; k < n_tri; k++)
226  {
227  vtkIdType npt;
228  const vtkIdType * ref_pt = nullptr;
229  triangles->GetNextCell(npt,ref_pt);
230  std::cout << ref_pt[0] << '\t' << ref_pt[1] << '\t' << ref_pt[2] << std::endl;
231  }
232 }
plane shape solver
a_shape_plane & shape_
void f(const vnl_vector< double > &x, vnl_vector< double > &fx)
const std::vector< a_point > & cloud_
a_shape_plane_function(a_shape_plane &shape, const std::vector< a_point > &cloud)
void export_triangles(const std::vector< a_point > &pts) const
void fit_cloud(std::vector< a_point > &pts, short int=1)
void normal(const a_point p)
void p3pts(const a_point p1, const a_point p2, const a_point p3)
a_point closest_point(const a_point p) const
a_point origin() const
static const std::string help()
void export_3pts() const
a_point normal() const
Definition: a_shape_plane.h:32
void random_hint(const std::vector< a_point > &pts)
double dist_point(a_point p) const
double dist() const
Definition: a_shape_plane.h:36
vnl_vector< double > para_
Definition: a_shape.h:68
void fit_cloud(const std::vector< a_point > &pts, vnl_least_squares_function &fn)
Definition: a_shape.cxx:126
static const std::string help()
Definition: a_shape.cxx:21
int best_fitting_cloud(const std::vector< a_point > &pts, std::vector< a_point > &pts2)
Definition: a_shape.cxx:82
e_point & normalise()
Definition: e_point.cxx:67
e_point cross(e_point &a, e_point &b)
Definition: e_point.cxx:105
double v(const uint32_t step, const uint32_t n)
Definition: generate.cxx:42
uint32_t n[]
Definition: generate.cxx:34
int n_tri
Definition: ply2tri.cxx:34
Definition: stlb2stla.cxx:21