You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

frechet_dist.cpp 3.8 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include <cmath>
  2. #include "geo/private/math/frechet_dist.h"
  3. namespace ns
  4. {
  5. namespace geo
  6. {
  7. namespace
  8. {
  9. typedef struct _sPoint
  10. {
  11. double x;
  12. double y;
  13. } sPoint;
  14. #define max(a, b) (((a) > (b)) ? (a) : (b))
  15. double dis(sPoint* p1, sPoint* p2, int i, int j)
  16. {
  17. return sqrt(pow(p1[i].x - p2[j].x, 2) + pow(p1[i].y - p2[j].y, 2));
  18. }
  19. double min3(double f1, double f2, double f3)
  20. {
  21. double minf = (f1 < f2) ? f1 : f2;
  22. minf = (minf < f3) ? minf : f3;
  23. return minf;
  24. }
  25. double Cal(sPoint* p1, sPoint* p2, double** ca, int i, int j)
  26. {
  27. if (ca[i][j] > -1.0)
  28. {
  29. return ca[i][j];
  30. }
  31. else if (i == 0 && j == 0)
  32. {
  33. ca[i][j] = dis(p1, p2, 0, 0);
  34. }
  35. else if (i > 0 && j == 0)
  36. {
  37. ca[i][j] = max(Cal(p1, p2, ca, i - 1, 0), dis(p1, p2, i, 0));
  38. }
  39. else if (i == 0 && j > 0)
  40. {
  41. ca[i][j] = max(Cal(p1, p2, ca, 0, j - 1), dis(p1, p2, 0, j));
  42. }
  43. else if (i > 0 && j > 0)
  44. {
  45. ca[i][j] = max(min3(Cal(p1, p2, ca, i - 1, j), Cal(p1, p2, ca, i - 1, j - 1),
  46. Cal(p1, p2, ca, i, j - 1)),
  47. dis(p1, p2, i, j));
  48. }
  49. else
  50. {
  51. ca[i][j] = 0xFFFFFFFF;
  52. }
  53. return ca[i][j];
  54. }
  55. double calcFrechet(sPoint* p1, int p, sPoint* p2, int q)
  56. {
  57. // init ca[p][q]
  58. double** ca = new double*[p];
  59. for (int i = 0; i < p; i++)
  60. {
  61. ca[i] = new double[q];
  62. }
  63. for (int i = 0; i < p; i++)
  64. {
  65. for (int j = 0; j < q; j++)
  66. {
  67. ca[i][j] = -1.0;
  68. }
  69. }
  70. double r = Cal(p1, p2, ca, p - 1, q - 1);
  71. // for (int i = 0; i < p; i++)
  72. // {
  73. // for (int j = 0; j < q; j++)
  74. // {
  75. // printf("%f ", ca[i][j]);
  76. // }
  77. // printf("\n");
  78. // }
  79. for (int i = 0; i < p; i++)
  80. delete[] ca[i];
  81. delete[] ca;
  82. return r;
  83. }
  84. double calcFrechetBottomUp(sPoint* p1, int p, sPoint* p2, int q)
  85. {
  86. double** ca = new double*[p];
  87. for (int i = 0; i < p; i++)
  88. {
  89. ca[i] = new double[q];
  90. }
  91. for (int i = 0; i < p; i++)
  92. {
  93. for (int j = 0; j < q; j++)
  94. {
  95. ca[i][j] = -1.0;
  96. }
  97. }
  98. ca[0][0] = dis(p1, p2, 0, 0);
  99. for (int i = 1; i < p; i++)
  100. ca[i][0] = max(ca[i - 1][0], dis(p1, p2, i, 0));
  101. for (int i = 1; i < p; i++)
  102. ca[0][i] = max(ca[0][i - 1], dis(p1, p2, 0, i));
  103. for (int i = 1; i < p; i++)
  104. {
  105. for (int j = 1; j < q; j++)
  106. {
  107. ca[i][j] = max(min3(ca[i - 1][j], ca[i - 1][j - 1], ca[i][j - 1]), dis(p1, p2, i, j));
  108. }
  109. }
  110. double r = ca[p - 1][q - 1];
  111. for (int i = 0; i < p; i++)
  112. delete[] ca[i];
  113. delete[] ca;
  114. return r;
  115. }
  116. } // namespace
  117. double Frechet::calcFrechetDistance(const std::vector<PointD>& line1,
  118. const std::vector<PointD>& line2)
  119. {
  120. double dis = 0;
  121. sPoint* p1 = new sPoint[line1.size()];
  122. for (size_t i = 0; i < line1.size(); i++)
  123. {
  124. p1[i].x = line1[i].x;
  125. p1[i].y = line1[i].y;
  126. }
  127. sPoint* p2 = new sPoint[line2.size()];
  128. for (size_t i = 0; i < line2.size(); i++)
  129. {
  130. p2[i].x = line2[i].x;
  131. p2[i].y = line2[i].y;
  132. }
  133. dis = calcFrechet(p1, static_cast<int>(line1.size()), p2, static_cast<int>(line2.size()));
  134. delete[] p2;
  135. delete[] p1;
  136. // sPoint p1[5] = {{1.0,2.0},{2.0,3.0},{3.0,4.0},{4.0,5.0},{5.0,6.0}};
  137. // sPoint p2[7] = {{1.0,-2.0},{2.0,-3.0},{3.0,-4.0},{4.0,-5.0},{5.0,-6.0},{6.0,-7.0},{7.0,-8.0}};
  138. // sPoint p3[7] = {{7.0,-8.0},{6.0,-7.0},{5.0,-6.0},{4.0,-5.0},{3.0,-4.0},{2.0,-3.0},{1.0,-2.0}};
  139. // dis = calcFrechet(p1, 5, p2, 7);
  140. // dis = calcFrechet(p1, 5, p3, 7);
  141. return dis;
  142. }
  143. } // namespace geo
  144. } // namespace ns