使用该算法的初衷是想找到一个二维点集的有序边界,调用到CGAL中的Alpha_shape2。但是CGAL中的Alpha_shape2获取到的segment是随机的,也就是各个端点是无序的,如下图:
而我们需要的是有序边界,如下图所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
typedef K::FT FT; typedef K::Point_2 Point2f; typedef K::Segment_2 Segment2f; typedef CGAL::Alpha_shape_2<Triangulation_2> Alpha_shape_2;
std::list<Point2f> points;
... Alpha_shape_2 A(points.begin(), points.end(), FTA(10000), Alpha_shape_2::GENERAL); std::vector<Segment2f> segments; alpha_edges(A, std::back_inserter(segments)); std::cout << "Alpha Shape computed" << std::endl; std::cout << segments.size() << " alpha shape edges" << std::endl; std::cout << "Optimal alpha: " << *A.find_optimal_alpha(1) << std::endl;
std::vector<Point2f> points_in_segment; float sumX,sumY = 0.f; for (auto& seg : segments) { Point2f p1 (seg.vertex(0).x(),seg.vertex(0).y()); points_in_segment.push_back(p1); sumX = seg.vertex(0).x() + sumX; sumY = seg.vertex(0).y() + sumY; }
Point2f barycenter(sumX/points_in_segment.size(), sumY/points_in_segment.size());
std::vector<float> aBary; std::vector<int> aBaryIndex; aBary.clear(); aBaryIndex.clear(); for (int j = 0; j < points_in_segment.size(); ++j) { aBary.push_back(atan2(points_in_segment[j].y() - barycenter.y(), points_in_segment[j].x() - barycenter.x())); aBaryIndex.push_back(j); }
aBaryIndex = Utility::sort_indexes_decline(aBary);
std::vector<Point2f> polygon; for (int j = 0; j < aBaryIndex.size(); ++j) { polygon.push_back(points_in_segment[aBaryIndex[j]]); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
std::vector<int> sort_indexes_decline(const std::vector<float> &v) { std::vector<int> idx(v.size()); std::iota(idx.begin(), idx.end(), 0); sort(idx.begin(), idx.end(), [&v](int i1, int i2) {return v[i1] > v[i2]; }); return idx; }
|