Working on improved interconnection strategy

This commit is contained in:
tamasmeszaros 2019-03-04 18:32:28 +01:00
parent f2f513dd3e
commit c2d5a8d03b
2 changed files with 277 additions and 108 deletions

View file

@ -347,6 +347,95 @@ PointSet normals(const PointSet& points,
return ret;
}
//template<class Vec> double distance(const Vec& p) {
// return std::sqrt(p.transpose() * p);
//}
//template<class Vec> double distance(const Vec& pp1, const Vec& pp2) {
// auto p = pp2 - pp1;
// return distance(p);
//}
// Clustering a set of points by the given criteria
ClusteredPoints cluster_nearest2d(
const sla::PointSet& points, const std::vector<unsigned>& indices,
double dist,
unsigned max_points = 0)
{
namespace bgi = boost::geometry::index;
using Index3D = bgi::rtree< SpatElement, bgi::rstar<16, 4> /* ? */ >;
// A spatial index for querying the nearest points
Index3D sindex;
// Build the index
for(unsigned idx : indices) {
Vec3d p = points.row(idx); p(Z) = 0;
sindex.insert( std::make_pair(points.row(idx), idx));
}
using Elems = std::vector<SpatElement>;
// Recursive function for visiting all the points in a given distance to
// each other
std::function<void(Elems&, Elems&)> group =
[&sindex, &group, max_points, dist](Elems& pts, Elems& cluster)
{
for(auto& p : pts) {
std::vector<SpatElement> tmp;
sindex.query(
bgi::nearest(p.first, max_points),
std::back_inserter(tmp)
);
for(auto it = tmp.begin(); it < tmp.end(); ++it)
if(distance(p.first, it->first) > dist) it = tmp.erase(it);
auto cmp = [](const SpatElement& e1, const SpatElement& e2){
return e1.second < e2.second;
};
std::sort(tmp.begin(), tmp.end(), cmp);
Elems newpts;
std::set_difference(tmp.begin(), tmp.end(),
cluster.begin(), cluster.end(),
std::back_inserter(newpts), cmp);
int c = max_points && newpts.size() + cluster.size() > max_points?
int(max_points - cluster.size()) : int(newpts.size());
cluster.insert(cluster.end(), newpts.begin(), newpts.begin() + c);
std::sort(cluster.begin(), cluster.end(), cmp);
if(!newpts.empty() && (!max_points || cluster.size() < max_points))
group(newpts, cluster);
}
};
std::vector<Elems> clusters;
for(auto it = sindex.begin(); it != sindex.end();) {
Elems cluster = {};
Elems pts = {*it};
group(pts, cluster);
for(auto& c : cluster) sindex.remove(c);
it = sindex.begin();
clusters.emplace_back(cluster);
}
ClusteredPoints result;
for(auto& cluster : clusters) {
result.emplace_back();
for(auto c : cluster) result.back().emplace_back(c.second);
}
return result;
}
// Clustering a set of points by the given criteria
ClusteredPoints cluster(
const sla::PointSet& points, const std::vector<unsigned>& indices,