Points&Forces (survey)
Software tools facilitating the task of surveying architecture
a_shape_line.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_line.h"
17 #include <math.h>
18 #include <time.h>
19 #include <vnl/vnl_least_squares_function.h>
20 
23 {
24  public:
26  const std::vector<a_point> & cloud) :
27  vnl_least_squares_function(6, cloud.size(), no_gradient),
28  shape_(shape),
29  cloud_(cloud) {};
30  void f(const vnl_vector<double>& x, vnl_vector<double>& fx);
31  protected:
33  const std::vector<a_point> & cloud_;
34 };
35 //***************************************************************************
36 //---------------------------------------------------------------------------
37 void a_shape_line_function::f(const vnl_vector<double>& x, vnl_vector<double>& fx)
38 {
39  a_point dir(x[0],x[1],x[2]);
40  a_point orig(x[3],x[4],x[5]);
41  dir.normalise();
42  shape_.dir(dir);
43  shape_.orig(orig-(dir*orig)*dir);
44  for (int i = 0; i< fx.size(); i++)
45  fx[i] = shape_.dist_point(cloud_[i]);
46 }
47 //***************************************************************************
48 //---------------------------------------------------------------------------
49 const std::string a_shape_line::help()
50 {
51  std::ostringstream o;
52  o << "*************" << std::endl;
53  o << "a_shape_line:" << std::endl;
54  o << "*************" << std::endl;
55  o << "This is a 'line' fitting class" << std::endl;
56  o << std::endl;
57  o << a_shape::help();
58  return o.str();
59 }
60 //---------------------------------------------------------------------------
61 void a_shape_line::p2pts(const a_point p1, const a_point p2)
62 {
63  a_point dir = p2-p1;
64  if (dir.norm()==0) return;
65  this->dir(dir.normalise());
66  this->orig(p1-(p1*this->dir())*this->dir());
67  //std::cerr << orig_ << std::endl << dir_ << std::endl;
68 }
69 //---------------------------------------------------------------------------
70 a_point a_shape_line::closest_point(const a_point pt) const
71 {
72  a_point d = this->orig()-pt;
73  a_point dist = (this->dir()*d)*this->dir()-d;
74  return pt-dist;
75 }
76 //---------------------------------------------------------------------------
77 double a_shape_line::dist_point(const a_point pt) const
78 {
79  a_point d = this->orig()-pt;
80  a_point dist = (this->dir()*d)*this->dir()-d;
81  return dist.norm();
82 }
83 //---------------------------------------------------------------------------
84 void a_shape_line::random_hint(const std::vector<a_point>& pts)
85 {
86  //srand(time(NULL));
87  int n = pts.size();
88  int i1 = rand()%n;
89  int i2;
90  do
91  {
92  i2 = rand()%n;
93  } while (i1==i2);
94  a_point p1 = pts[i1];
95  a_point p2 = pts[i2];
96  this->p2pts(p1,p2);
97 }
98 //---------------------------------------------------------------------------
99 void a_shape_line::fit_cloud(std::vector<a_point>& pts, short nl)
100 {
101  std::vector<a_point> pts2;
102  int cs0 = pts.size();
103  this->best_fitting_cloud(pts,pts2);
104  if (nl==1)
105  {
106  a_shape_line_function f(*this,pts2);
107  a_shape::fit_cloud(pts2,f);
108  }
109  pts = pts2;
110 }
111 //---------------------------------------------------------------------------
112 void a_shape_line::export_line(const std::vector<a_point>& pts) const
113 {
114  a_point x0 = this->closest_point(pts[0]);
115  double vmin, vmax;
116  for (int i=1; i< pts.size(); i++)
117  {
118  a_point x = this->closest_point(pts[i]);
119  double v = this->dir()*(x-x0);
120  if (v<vmin) vmin=v;
121  if (v>vmax) vmax=v;
122  }
123  std::cout << "1" << std::endl;
124  std::cout << x0+vmin*this->dir() << " " << x0+vmax*this->dir() << std::endl;
125 }
line shape solver
const std::vector< a_point > & cloud_
void f(const vnl_vector< double > &x, vnl_vector< double > &fx)
a_shape_line_function(a_shape_line &shape, const std::vector< a_point > &cloud)
a_shape_line & shape_
line shape
Definition: a_shape_line.h:26
void export_line(const std::vector< a_point > &pts) const
static const std::string help()
void p2pts(const a_point p1, const a_point p2)
a_point orig() const
Definition: a_shape_line.h:35
void random_hint(const std::vector< a_point > &pts)
a_point dir() const
Definition: a_shape_line.h:34
a_point closest_point(const a_point p) const
void fit_cloud(std::vector< a_point > &pts, short nl=1)
double dist_point(const a_point p) const
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
double v(const uint32_t step, const uint32_t n)
Definition: generate.cxx:42
uint32_t n[]
Definition: generate.cxx:34
a_point dir(int i, int l)
Definition: rib0.cxx:60
Definition: stlb2stla.cxx:21