distance.h
Go to the documentation of this file.
1 #pragma once
2 // std
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <vector>
7 #include <list>
8 #include <set>
9 // eigen
10 #include <Eigen/Dense>
11 // other headers
12 #include "global.h"
13 #include "geodesic/Xin_Wang.h"
14 
15 // todo: organize distance funcs.
16 
18 {
19 public:
20 
23 
25  {
26  m_geodesic_domain = new CRichModel(cdt_obj_path);
27  }
29  {
30  delete m_geodesic_domain;
31  }
32 
33  // euclidean distance
34  double get_euclidean_distance(Point_2 p1, Point_2 p2);
35  // euclidean distance
36  double get_euclidean_distance(cv::Point p1, cv::Point p2);
37  // euclidean distance
38  double get_euclidean_distance(Point_2 p1, Point_2 p2, vector<Point_2> & path);
39 
40  // getGeodesicDistances
41  vector<double> GeodesicDistances(Eigen::Vector2d source, vector<Eigen::Vector2d> targets);
42  // getGeodesicDistances
43  vector<double> getGeodesicDistances(Point_2 source, vector<Point_2> targets);
44  // get_geodesic_distance_fast initialization.
46  // geodesic distance fast, need initialization.
48  // geodesic distance
49  double get_geodesic_distance(Point_2 p0, Point_2 p1, vector<Point_2> & path);
50 };
51 
52 // euclidean distance
53 double DistanceMetric::get_euclidean_distance(cv::Point p1, cv::Point p2)
54 {
55  Eigen::Vector2d v1(p1.x, p1.y);
56  Eigen::Vector2d v2(p2.x, p2.y);
57  return (v1 - v2).norm();
58 }
59 
60 // euclidean distance
62 {
63  Eigen::Vector2d v1(p1.x(), p1.y());
64  Eigen::Vector2d v2(p2.x(), p2.y());
65  return (v1 - v2).norm();
66 }
67 
68 // euclidean distance
69 double DistanceMetric::get_euclidean_distance(Point_2 p1, Point_2 p2, vector<Point_2> & path)
70 {
71  Eigen::Vector2d v1(p1.x(), p1.y());
72  Eigen::Vector2d v2(p2.x(), p2.y());
73  path.clear();
74  path.push_back(p1);
75  path.push_back(p2);
76  return (v1 - v2).norm();
77 }
78 
79 // geodesic distance
80 double DistanceMetric::get_geodesic_distance(Point_2 p0, Point_2 p1, vector<Point_2> & path)
81 {
82  // load model
83  CRichModel m_model(cdt_obj_path);
84  m_model.LoadModel();
85  // find source index in model
86  Point_2 source(p0.x(), p0.y()); // source point := p0
87  int source_index = -1;
88  // find source point id
89  for (int i = 0; i < m_model.GetNumOfVerts(); i++)
90  {
91  if (ceil(m_model.m_Verts[i].x) == ceil(source.x()) && ceil(m_model.m_Verts[i].y) == ceil(source.y())){
92  source_index = i;
93  break;
94  }
95  }
96  if (source_index == -1){
97  double min_dis = DBL_MAX;
98  int min_index = -1;
99  for (int i = 0; i < m_model.GetNumOfVerts(); i++)// find the closet point instead
100  {
101  double crt_dis = get_euclidean_distance(Point_2(m_model.m_Verts[i].x, m_model.m_Verts[i].y), source);
102  if (crt_dis < min_dis){
103  min_dis = crt_dis;
104  min_index = i;
105  }
106  }
107  source_index = min_index;
108  }
109  if (source_index == -1){
110  cout << "source point: " << source.x() << " " << source.y() << endl;
111  cout << "error in " << __FUNCTION__ << ", source index cant find, input to exit" << endl;
112  getchar(); getchar(); getchar(); // dsy
113  exit(-1);
114  }
115  // geodesic algorithm
116  CXin_Wang alg(m_model, source_index);
117  alg.Execute();
118  auto distanceField = alg.GetDistanceField();
119  // find target index in model
120  Point_2 target(p1.x(), p1.y()); // target point := p1
121  int target_index = -1;
122  // find task point id
123  for (int i = 0; i < m_model.GetNumOfVerts(); i++)
124  {
125  if (ceil(m_model.m_Verts[i].x) == ceil(target.x()) && ceil(m_model.m_Verts[i].y) == ceil(target.y())){
126  target_index = i;
127  break;
128  }
129  }
130  if (target_index == -1){
131  double min_dis = DBL_MAX;
132  int min_index = -1;
133  for (int i = 0; i < m_model.GetNumOfVerts(); i++)// find the closet point instead
134  {
135  double crt_dis = get_euclidean_distance(Point_2(m_model.m_Verts[i].x, m_model.m_Verts[i].y), target);
136  if (crt_dis < min_dis){
137  min_dis = crt_dis;
138  min_index = i;
139  }
140  }
141  target_index = min_index;
142  }
143  if (target_index == -1){
144  cout << "task point: " << target.x() << " " << target.y() << endl;
145  cout << "error in " << __FUNCTION__ << ", task index cant find, input to exit" << endl;
146  getchar(); getchar(); getchar(); // dsy
147  exit(-1);
148  }
149  // distance result
150  double distance_result = distanceField[target_index];
151  // distance path
152  path.clear();
153  auto path_result = alg.BacktraceShortestPath(target_index);
154  for (int i = 0; i < path_result.size(); i++)
155  path.push_back(Point_2(path_result[i].Get3DPoint(m_model).x, path_result[i].Get3DPoint(m_model).y));
156  if (ceil(path.front().x()) != ceil(p0.x()) || ceil(path.front().y()) != ceil(p0.y()))
157  path.front() = p0;
158  if (ceil(path.back().x()) != ceil(p1.x()) || ceil(path.back().y()) != ceil(p1.y()))
159  path.back() = p1;
160  return distance_result;
161 }
162 
163 // GeodesicDistances
164 vector<double> DistanceMetric::GeodesicDistances(Eigen::Vector2d source, vector<Eigen::Vector2d> targets)
165 {
166  Point_2 s(source.x(), source.y());
167  vector<Point_2> t(targets.size());
168  for (int idx = 0; idx < targets.size(); idx++)
169  t[idx] = Point_2(targets[idx].x(), targets[idx].y());
170  return getGeodesicDistances(s, t);
171 }
172 
173 // getGeodesicDistances
174 vector<double> DistanceMetric::getGeodesicDistances(Point_2 source, vector<Point_2> targets)
175 {
176  // timing
177  double t1 = clock();
178 
179  // set up
180  vector<double> stDistances;
181  for (int tid = 0; tid < targets.size(); tid++)
182  stDistances.push_back(0);
183 
184  // load model
185  CRichModel m_model(cdt_obj_path);
186  m_model.LoadModel();
187 
188  // find source index in model
189  int source_index = -1;
190  // find source point id
191  for (int i = 0; i < m_model.GetNumOfVerts(); i++)
192  {
193  if (ceil(m_model.m_Verts[i].x) == ceil(source.x()) && ceil(m_model.m_Verts[i].y) == ceil(source.y())){
194  source_index = i;
195  break;
196  }
197  }
198  if (source_index == -1){
199  double min_dis = DBL_MAX;
200  int min_index = -1;
201  for (int i = 0; i < m_model.GetNumOfVerts(); i++)// find the closet point instead
202  {
203  double crt_dis = get_euclidean_distance(Point_2(m_model.m_Verts[i].x, m_model.m_Verts[i].y), source);
204  if (crt_dis < min_dis){
205  min_dis = crt_dis;
206  min_index = i;
207  }
208  }
209  source_index = min_index;
210  }
211  if (source_index == -1)
212  {
213  cerr << "source point: " << source.x() << " " << source.y() << endl;
214  cerr << "error in " << __FUNCTION__ << ", source index cant find, input to exit" << endl;
215  getchar(); getchar(); getchar(); // dsy
216  exit(-1);
217  }
218 
219  // geodesic algorithm
220  CXin_Wang alg(m_model, source_index);
221  alg.Execute();
222  auto distanceField = alg.GetDistanceField();
223 
224  // retrival distances
225  for (int tid = 0; tid < targets.size(); tid++)
226  {
227  // find target index in model
228  Point_2 target(targets[tid].x(), targets[tid].y()); // target point
229  int target_index = -1;
230  // find task point id
231  for (int i = 0; i < m_model.GetNumOfVerts(); i++)
232  {
233  if (ceil(m_model.m_Verts[i].x) == ceil(target.x()) && ceil(m_model.m_Verts[i].y) == ceil(target.y())){
234  target_index = i;
235  break;
236  }
237  }
238  if (target_index == -1){
239  double min_dis = DBL_MAX;
240  int min_index = -1;
241  for (int i = 0; i < m_model.GetNumOfVerts(); i++)// find the closet point instead
242  {
243  double crt_dis = get_euclidean_distance(Point_2(m_model.m_Verts[i].x, m_model.m_Verts[i].y), target);
244  if (crt_dis < min_dis){
245  min_dis = crt_dis;
246  min_index = i;
247  }
248  }
249  target_index = min_index;
250  }
251  if (target_index == -1)
252  {
253  cerr << "task point: " << target.x() << " " << target.y() << endl;
254  cerr << "error in " << __FUNCTION__ << ", target index can't find, input to exit" << endl;
255  getchar(); getchar(); getchar(); // dsy
256  exit(-1);
257  }
258  // distance result
259  stDistances[tid] = distanceField[target_index];
260  }
261 
262  // timing
263  double t2 = clock();
264  //cerr << "geodesic timing " << t2 - t1 << " ms" << endl;
265 
266  return stDistances;
267 }
268 
269 // get_geodesic_distance_fast initialization
271 {
272  // load model
275  //m_geodesic_domain_version = exe_count; // todo.
276  return;
277 }
278 
279 // geodesic distance fast, need initialization.
281 {
282  // find source index in model
283  Point_2 source(p0.x(), p0.y()); // source point := p0
284  int source_index = -1;
285  // find source point id
286  for (int i = 0; i < m_geodesic_domain->GetNumOfVerts(); i++)
287  {
288  if (ceil(m_geodesic_domain->m_Verts[i].x) == ceil(source.x()) && ceil(m_geodesic_domain->m_Verts[i].y) == ceil(source.y())){
289  source_index = i;
290  break;
291  }
292  }
293  if (source_index == -1){
294  double min_dis = DBL_MAX;
295  int min_index = -1;
296  for (int i = 0; i < m_geodesic_domain->GetNumOfVerts(); i++)// find the closet point instead
297  {
298  double crt_dis = get_euclidean_distance(Point_2(m_geodesic_domain->m_Verts[i].x, m_geodesic_domain->m_Verts[i].y), source);
299  if (crt_dis < min_dis){
300  min_dis = crt_dis;
301  min_index = i;
302  }
303  }
304  source_index = min_index;
305  }
306  if (source_index == -1){
307  cout << "source point: " << source.x() << " " << source.y() << endl;
308  cout << "error in " << __FUNCTION__ << ", source index cant find, input to exit" << endl;
309  getchar(); getchar(); getchar(); // dsy
310  exit(-1);
311  }
312  // geodesic algorithm
313  CXin_Wang alg(*m_geodesic_domain, source_index);
314  alg.Execute();
315  auto distanceField = alg.GetDistanceField();
316  // find target index in model
317  Point_2 target(p1.x(), p1.y()); // target point := p1
318  int target_index = -1;
319  // find task point id
320  for (int i = 0; i < m_geodesic_domain->GetNumOfVerts(); i++)
321  {
322  if (ceil(m_geodesic_domain->m_Verts[i].x) == ceil(target.x()) && ceil(m_geodesic_domain->m_Verts[i].y) == ceil(target.y())){
323  target_index = i;
324  break;
325  }
326  }
327  if (target_index == -1){
328  double min_dis = DBL_MAX;
329  int min_index = -1;
330  for (int i = 0; i < m_geodesic_domain->GetNumOfVerts(); i++)// find the closet point instead
331  {
332  double crt_dis = get_euclidean_distance(Point_2(m_geodesic_domain->m_Verts[i].x, m_geodesic_domain->m_Verts[i].y), target);
333  if (crt_dis < min_dis){
334  min_dis = crt_dis;
335  min_index = i;
336  }
337  }
338  target_index = min_index;
339  }
340  if (target_index == -1){
341  cout << "task point: " << target.x() << " " << target.y() << endl;
342  cout << "error in " << __FUNCTION__ << ", task index cant find, input to exit" << endl;
343  getchar(); getchar(); getchar(); // dsy
344  exit(-1);
345  }
346  // distance result
347  double distance_result = distanceField[target_index];
348  return distance_result;
349 }
K::Point_2 Point_2
Definition: global.h:32
vector< CPoint3D > m_Verts
Definition: BaseModel.h:38
void get_geodesic_distance_fast_initialization()
Definition: distance.h:270
XmlRpcServer s
vector< double > GeodesicDistances(Eigen::Vector2d source, vector< Eigen::Vector2d > targets)
Definition: distance.h:164
void LoadModel()
Definition: RichModel.cpp:276
const std::string cdt_obj_path
Definition: global.h:10
double distanceField[map_rows][map_cols]
double get_euclidean_distance(Point_2 p1, Point_2 p2)
Definition: distance.h:61
const vector< double > & GetDistanceField() const
virtual void Execute()
CRichModel * m_geodesic_domain
Definition: distance.h:21
int m_geodesic_domain_version
Definition: distance.h:22
double get_geodesic_distance(Point_2 p0, Point_2 p1, vector< Point_2 > &path)
Definition: distance.h:80
virtual vector< EdgePoint > BacktraceShortestPath(int end) const
int GetNumOfVerts() const
Definition: BaseModel.h:80
double get_geodesic_distance_fast(Point_2 p0, Point_2 p1)
Definition: distance.h:280
vector< double > getGeodesicDistances(Point_2 source, vector< Point_2 > targets)
Definition: distance.h:174
EIGEN_DEVICE_FUNC const CeilReturnType ceil() const


co_scan
Author(s):
autogenerated on Mon Feb 28 2022 23:00:41