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.

triangulation.cpp 3.5 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #include "geo/private/math/triangulation.h"
  2. namespace ns
  3. {
  4. namespace geo
  5. {
  6. double weightCost(const vector<PointD>& points, int i, int j, int k)
  7. {
  8. PointD p1 = points[i], p2 = points[j], p3 = points[k];
  9. double weight = p1.distance(p2) + p2.distance(p3) + p3.distance(p1);
  10. return weight;
  11. }
  12. double minWeightTriangulation(const vector<PointD>& points, const int i, const int j,
  13. std::vector<std::vector<int>>& vres)
  14. {
  15. if (j < i + 2)
  16. return 0.0;
  17. double result = basic::DOUBLE_MAX;
  18. for (int k = i + 1; k < j; k++)
  19. {
  20. double weight = minWeightTriangulation(points, i, k, vres) +
  21. minWeightTriangulation(points, k, j, vres) + weightCost(points, i, k, j);
  22. if (weight < result)
  23. {
  24. result = weight;
  25. std::vector<int> indexV = {i, k, j};
  26. vres.emplace_back(indexV);
  27. }
  28. }
  29. return result;
  30. }
  31. double mTCDP(const vector<PointD>& points, int n)
  32. {
  33. // There must be at least 3 points to form a triangle
  34. if (n < 3)
  35. return 0;
  36. // table to store results of subproblems. table[i][j] stores cost of
  37. // triangulation of points from i to j. The entry table[0][n-1] stores
  38. // the final result.
  39. double table[n][n];
  40. // Fill table using above recursive formula. Note that the table
  41. // is filled in diagonal fashion i.e., from diagonal elements to
  42. // table[0][n-1] which is the result.
  43. for (int gap = 0; gap < n; gap++)
  44. {
  45. for (int i = 0, j = gap; j < n; i++, j++)
  46. {
  47. if (j < i + 2)
  48. {
  49. table[i][j] = 0.0;
  50. }
  51. else
  52. {
  53. table[i][j] = basic::DOUBLE_MAX;
  54. for (int k = i + 1; k < j; k++)
  55. {
  56. double val = table[i][k] + table[k][j] + weightCost(points, i, j, k);
  57. if (table[i][j] > val)
  58. {
  59. table[i][j] = val;
  60. }
  61. }
  62. }
  63. }
  64. }
  65. return table[0][n - 1];
  66. }
  67. double minWeightTriangulation(const vector<PointD>& points, vector<vector<int>>& s)
  68. {
  69. int n = points.size();
  70. if (n < 3)
  71. return 0.0;
  72. s.resize(n);
  73. for (int i = 0; i < n; i++)
  74. {
  75. s[i].resize(n);
  76. }
  77. double t[n][n]; // t[i][j]表示多边形{ViVkVj}的最优权值
  78. for (int i = 0; i < n; i++)
  79. {
  80. t[i][i] = 0.;
  81. t[i][(i + 1) % n] = 0.; // t[i][i+1] =0
  82. }
  83. for (int j = 2; j < n; j++) // 至少有三个点
  84. {
  85. for (int i = 0; i < n - j; i++)
  86. {
  87. int k = i + j;
  88. int m = i + 1;
  89. t[i][k] = t[i][m] + t[m][k] + weightCost(points, i, m, k);
  90. s[i][k] = m;
  91. for (m = m + 1; m < k; m++)
  92. {
  93. int u = t[i][m] + t[m][k] + weightCost(points, i, m, j);
  94. if (u < t[i][k])
  95. {
  96. t[i][k] = u;
  97. s[i][k] = m;
  98. }
  99. }
  100. }
  101. }
  102. return t[0][n - 1];
  103. }
  104. vector<vector<int>> traceBack(const vector<vector<int>>& s, const int i, const int j,
  105. vector<vector<int>>& vres)
  106. {
  107. if (i == j || i + 1 == j)
  108. {
  109. return {};
  110. }
  111. traceBack(s, i, s[i][j], vres);
  112. traceBack(s, s[i][j], j, vres);
  113. vector<int> tempV = {i, s[i][j], j};
  114. vres.emplace_back(tempV);
  115. return vres;
  116. }
  117. } // namespace geo
  118. } // namespace ns