14 #include <range/v3/view/enumerate.hpp>
15 #include <range/v3/view/sliding.hpp>
23 inputFeatures(
std::move(features)), chainApproximationParams(chainApproximationParams)
29 inputFeatures(features), chainApproximationParams(chainApproximationParams)
36 ARMARX_DEBUG <<
"Starting merge of " << inputFeatures.size() <<
" features";
39 for (
const auto [i, f] : ranges::views::enumerate(inputFeatures))
41 std::optional<std::size_t> lastFeature = std::nullopt;
42 for (
const auto& p : f.points)
44 if (
auto res = checkPoint(p, i, lastFeature); res)
46 uf.unite(i, res.value());
47 lastFeature = res.value();
52 for (
const auto [i, f] : ranges::views::enumerate(inputFeatures))
54 std::size_t representative = uf.find(i);
55 if (i != representative)
57 ARMARX_DEBUG <<
"add feature " << i <<
" to feature " << representative;
58 addToFeature(inputFeatures[representative], f);
62 std::vector<Features> merged;
63 for (
const auto [i, f] : ranges::views::enumerate(inputFeatures))
72 recalculateFeatures(merged);
74 ARMARX_DEBUG <<
"Merged " << inputFeatures.size() <<
" features into " << merged.size();
80 const std::vector<Eigen::Vector2f>& vertices)
85 const auto signum = [](
float x)
89 return x > 0 ? 1 : -1;
92 const auto checkSide = [&](
const Eigen::Vector2f&
a,
const Eigen::Vector2f& b)
93 {
return signum((p.x() -
a.x()) * (b.y() -
a.y()) - (p.y() -
a.y()) * (b.x() -
a.x())); };
95 float previousSide = 0;
96 for (
const auto edge : vertices | ranges::views::sliding(2))
98 int d = checkSide(edge[0], edge[1]);
102 if (previousSide != 0 && d != previousSide)
108 int d = checkSide(vertices.back(), vertices.front());
111 return d == previousSide;
114 std::optional<std::size_t>
115 FeatureMerger::checkPoint(
const Eigen::Vector2f p,
117 const std::optional<std::size_t> checkFirst)
122 if (
insideConvexPoly(p, inputFeatures[checkFirst.value()].convexHull->vertices))
124 return checkFirst.value();
128 for (
const auto [i, f] : ranges::views::enumerate(inputFeatures))
130 if (i == ignore || (checkFirst && i == checkFirst.value()))
144 f.points.insert(f.points.end(), toAdd.points.begin(), toAdd.points.end());
146 f.convexHull = std::nullopt;
147 f.circle = std::nullopt;
148 f.ellipsoid = std::nullopt;
149 f.chain = std::nullopt;
153 FeatureMerger::recalculateFeatures(std::vector<Features>& features)
155 for (
auto& f : features)
175 f.points, f.convexHull, chainApproximationParams);