6 #include <Eigen/Geometry>
15 points(points), params(params)
18 indices.resize(points.size());
19 std::iota(indices.begin(), indices.end(), 0);
27 const auto maxIterConditionReached = [&]()
40 if (maxIterConditionReached())
45 .iterations = iterations};
48 if (not approximateStep())
53 .iterations = iterations,
54 .reductionFactor = 1.F -
static_cast<float>(indices.size()) /
55 static_cast<float>(points.size())};
62 ChainApproximation::Triplets ChainApproximation::getTriplets()
const
64 const int nIndices =
static_cast<int>(indices.size());
72 triplets.reserve(indices.size());
79 triplets.emplace_back(indices.back(), indices.front(), indices.at(1));
82 for (
int i = 1; i < (nIndices - 1); i++)
84 triplets.emplace_back(indices.at(i - 1), indices.at(i), indices.at(i + 1));
88 triplets.emplace_back(indices.back(), indices.front(), indices.at(1));
94 ChainApproximation::computeDistances(
const ChainApproximation::Triplets& triplets)
96 std::vector<float> distances;
97 distances.reserve(triplets.size());
101 std::back_inserter(distances),
102 [&](
const auto & triplet)
104 return computeDistance(triplet);
109 float ChainApproximation::computeDistance(
const ChainApproximation::Triplet& triplet)
const
111 using Line = Eigen::ParametrizedLine<float, 2>;
113 const Eigen::Vector2f& ptBefore = points.at(triplet.a);
114 const Eigen::Vector2f& ptPivot = points.at(triplet.b);
115 const Eigen::Vector2f& ptAfter = points.at(triplet.c);
117 const auto line = Line::Through(ptBefore, ptAfter);
118 return line.distance(ptPivot);
121 bool ChainApproximation::approximateStep()
123 const size_t nIndices = indices.size();
129 const Triplets triplets = getTriplets();
130 const std::vector<float> distances = computeDistances(triplets);
133 const int n =
static_cast<int>(triplets.size());
135 std::vector<int> indicesToBeRemoved;
138 for (
int i = 1; i < n - 1; i++)
140 const auto&
distance = distances.at(i);
151 indicesToBeRemoved.emplace_back(triplets.at(i).b);
156 if (indicesToBeRemoved.empty())
161 const auto isMatch = [&](
const int& idx) ->
bool
163 return std::find(indicesToBeRemoved.begin(), indicesToBeRemoved.end(), idx) !=
164 indicesToBeRemoved.end();
167 indices.erase(std::remove_if(indices.begin(), indices.end(), isMatch), indices.end());
174 extractedPoints.reserve(indices.size());
178 std::back_inserter(extractedPoints),
179 [&](
const auto & idx)
181 return points.at(idx);
184 return extractedPoints;
191 const std::string condStr = [&res]() -> std::string
197 case TerminationCondition::Converged:
200 case TerminationCondition::IterationLimit:
201 repr =
"IterationLimit";
207 str <<
"ApproximationResult: ["
208 <<
"condition: " << condStr <<
" | "