|
- #include "geo/private/math/triangulation.h"
-
- namespace ns
- {
- namespace geo
- {
-
- double weightCost(const vector<PointD>& points, int i, int j, int k)
- {
- PointD p1 = points[i], p2 = points[j], p3 = points[k];
- double weight = p1.distance(p2) + p2.distance(p3) + p3.distance(p1);
- return weight;
- }
-
- double minWeightTriangulation(const vector<PointD>& points, const int i, const int j,
- std::vector<std::vector<int>>& vres)
- {
- if (j < i + 2)
- return 0.0;
-
- double result = basic::DOUBLE_MAX;
- for (int k = i + 1; k < j; k++)
- {
- double weight = minWeightTriangulation(points, i, k, vres) +
- minWeightTriangulation(points, k, j, vres) + weightCost(points, i, k, j);
-
- if (weight < result)
- {
- result = weight;
- std::vector<int> indexV = {i, k, j};
- vres.emplace_back(indexV);
- }
- }
- return result;
- }
-
- double mTCDP(const vector<PointD>& points, int n)
- {
- // There must be at least 3 points to form a triangle
- if (n < 3)
- return 0;
-
- // table to store results of subproblems. table[i][j] stores cost of
- // triangulation of points from i to j. The entry table[0][n-1] stores
- // the final result.
- double table[n][n];
-
- // Fill table using above recursive formula. Note that the table
- // is filled in diagonal fashion i.e., from diagonal elements to
- // table[0][n-1] which is the result.
- for (int gap = 0; gap < n; gap++)
- {
- for (int i = 0, j = gap; j < n; i++, j++)
- {
- if (j < i + 2)
- {
- table[i][j] = 0.0;
- }
- else
- {
- table[i][j] = basic::DOUBLE_MAX;
- for (int k = i + 1; k < j; k++)
- {
- double val = table[i][k] + table[k][j] + weightCost(points, i, j, k);
- if (table[i][j] > val)
- {
- table[i][j] = val;
- }
- }
- }
- }
- }
- return table[0][n - 1];
- }
-
- double minWeightTriangulation(const vector<PointD>& points, vector<vector<int>>& s)
- {
- int n = points.size();
- if (n < 3)
- return 0.0;
- s.resize(n);
- for (int i = 0; i < n; i++)
- {
- s[i].resize(n);
- }
- double t[n][n]; // t[i][j]表示多边形{ViVkVj}的最优权值
- for (int i = 0; i < n; i++)
- {
- t[i][i] = 0.;
- t[i][(i + 1) % n] = 0.; // t[i][i+1] =0
- }
- for (int j = 2; j < n; j++) // 至少有三个点
- {
- for (int i = 0; i < n - j; i++)
- {
- int k = i + j;
- int m = i + 1;
- t[i][k] = t[i][m] + t[m][k] + weightCost(points, i, m, k);
- s[i][k] = m;
- for (m = m + 1; m < k; m++)
- {
- int u = t[i][m] + t[m][k] + weightCost(points, i, m, j);
- if (u < t[i][k])
- {
- t[i][k] = u;
- s[i][k] = m;
- }
- }
- }
- }
- return t[0][n - 1];
- }
-
- vector<vector<int>> traceBack(const vector<vector<int>>& s, const int i, const int j,
- vector<vector<int>>& vres)
- {
- if (i == j || i + 1 == j)
- {
- return {};
- }
- traceBack(s, i, s[i][j], vres);
- traceBack(s, s[i][j], j, vres);
- vector<int> tempV = {i, s[i][j], j};
- vres.emplace_back(tempV);
- return vres;
- }
-
- } // namespace geo
- } // namespace ns
|