gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
hausdorffDistance.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 /*
7  compute the hausdorff distance between two polygonal curves
8  in n*m time where n and m are the nb of points of the
9  polygonal curves
10 */
11 
12 #include "SVector3.h"
13 #include "hausdorffDistance.h"
14 
15 static double intersect(SPoint3 &q, SVector3 &n, // a plane
16  SPoint3 &p1, SPoint3 &p2, // a segment
17  SPoint3 &result)
18 {
19  // n * (x-q) = 0
20  // x = p1 + t (p2-p1)
21  // n *(p1 + t (p2-p1) - q) = 0
22  // t = n*(q-p1) / n*(p2-p1)
23 
24  const double t = dot(n, q - p1) / dot(n, p2 - p1);
25  result = p1 * (1. - t) + p2 * t;
26  return t;
27 }
28 
29 static double projection(SPoint3 &p1, SPoint3 &p2, SPoint3 &q, SPoint3 &result)
30 {
31  // x = p1 + t (p2 - p1)
32  // (x - q) * (p2 - p1) = 0
33  // (p1 + t (p2 - p1) - q) (p2 - p1) = 0
34  // t = (q-p1) * (p2-p1) / (p2-p1)^2
35  SVector3 p21 = p2 - p1;
36  const double t = dot(q - p1, p21) / dot(p21, p21);
37  result = p1 * (1. - t) + p2 * t;
38  return t;
39 }
40 
42 {
43  double result;
44  const double t = projection(p1, p2, q, result);
45  if(t >= 0.0 && t <= 1.0) return result;
46  if(t < 0) return p1;
47  return p2;
48 }
49 
50 double closestPoint(const std::vector<SPoint3> &P, const SPoint3 &p,
51  SPoint3 &result)
52 {
53  double closestDistance = 1.e22;
54  for(std::size_t i = 1; i < P.size(); i++) {
55  SPoint3 q = closestPoint(P[i - 1], P[i], p);
56  const double pq = p.distance(q);
57  if(pq < closestDistance) {
58  closestDistance = pq;
59  result = q;
60  }
61  }
62  return closestDistance;
63 }
64 
65 // we test all points of P plus all points that are the intersections
66 // of angle bissectors of Q with P
67 double oneSidedHausdorffDistance(const std::vector<SPoint3> &P,
68  const std::vector<SPoint3> &Q, SPoint3 &p1,
69  SPoint3 &p2)
70 {
71  const double hausdorffDistance = 0.0;
72 
73  // first test the points
74  for(std::size_t i = 0; i < P.size(); i++) {
75  SPoint3 result;
76  double d = closestPoint(Q, P[i], result);
77  if(d > hausdorffDistance) {
79  p1 = P[i];
80  p2 = result;
81  }
82  }
83  // compute angle bissectors intersections
84  std::vector<SPoint3> intersections;
85  for(std::size_t i = 1; i < Q.size() - 1; i++) {
86  SPoint3 a = Q[i - 1];
87  SPoint3 b = Q[i];
88  SPoint3 c = Q[i + 1];
89  SVector3 ba = b - a;
90  SVector3 ca = c - a;
91  SVector3 bissector = (ba + ca);
92  SVector3 n; // normal to the bissector plane
93  if(bissector.norm == 0) {
94  ba.normalize();
95  n = ba;
96  }
97  else {
98  SVector3 b = crossprod(bissector, ba);
99  n = crossprod(b, bissector);
100  n.normalize();
101  }
102  for(std::size_t i = 1; i < P.size(); i++) {
103  SPoint3 result;
104  const double t = intersect(b, n, P[i - 1], P[i], result);
105  if(t >= 0 && t <= 1) intersections.push_back(result);
106  }
107  }
108 
109  for(std::size_t i = 0; i < intersections.size(); i++) {
110  SPoint3 result;
111  double d = closestPoint(Q, intersections[i], result);
112  if(d > hausdorffDistance) {
113  hausdorffDistance = d;
114  p1 = P[i];
115  p2 = result;
116  }
117  }
118  return hausdorffDistance;
119 }
120 
121 double hausdorffDistance(const std::vector<SPoint3> &P,
122  const std::vector<SPoint3> &Q)
123 {
124  return std::max(oneSidedHausdorffDistance(P, Q),
126 }
crossprod
SVector3 crossprod(const SVector3 &a, const SVector3 &b)
Definition: SVector3.h:150
dot
double dot(const SVector3 &a, const SMetric3 &m, const SVector3 &b)
Definition: STensor3.h:71
c
static double c(int i, int j, fullMatrix< double > &CA, const std::vector< SPoint3 > &P, const std::vector< SPoint3 > &Q)
Definition: discreteFrechetDistance.cpp:15
SPoint3
Definition: SPoint3.h:14
SVector3
Definition: SVector3.h:16
projection
static double projection(SPoint3 &p1, SPoint3 &p2, SPoint3 &q, SPoint3 &result)
Definition: hausdorffDistance.cpp:29
SVector3.h
oneSidedHausdorffDistance
double oneSidedHausdorffDistance(const std::vector< SPoint3 > &P, const std::vector< SPoint3 > &Q, SPoint3 &p1, SPoint3 &p2)
Definition: hausdorffDistance.cpp:67
SVector3::norm
double norm() const
Definition: SVector3.h:33
hausdorffDistance.h
SPoint3::distance
double distance(const SPoint3 &p) const
Definition: SPoint3.h:176
intersect
static double intersect(SPoint3 &q, SVector3 &n, SPoint3 &p1, SPoint3 &p2, SPoint3 &result)
Definition: hausdorffDistance.cpp:15
hausdorffDistance
double hausdorffDistance(const std::vector< SPoint3 > &P, const std::vector< SPoint3 > &Q)
Definition: hausdorffDistance.cpp:121
closestPoint
static SPoint3 closestPoint(SPoint3 &p1, SPoint3 &p2, SPoint3 &q)
Definition: hausdorffDistance.cpp:41
SVector3::normalize
double normalize()
Definition: SVector3.h:38