对多个四边形的顶点进行排序

时间:2015-07-11 17:58:29

标签: c++ sorting

enter image description here

这是我的函数,它可以按左上方的顺序对四边形的顶点进行排序 - >右上角 - >右下角 - >左下角:

void sortCornors(Point center, vector<Point> LEDPoints,        vector<Point2f> &newLEDPoints)
{
    vector<Point2f> top;
    vector<Point2f> bottom;

    for (int i = 0; i < LEDPoints.size(); ++i)
    {
        if (LEDPoints[i].y < center.y)
            top.push_back(LEDPoints[i]);
        else
            bottom.push_back(LEDPoints[i]);
    }

    Point2f tl = top[0].x > top[1].x ? top[1] : top[0];
    Point2f tr = top[0].x > top[1].x ? top[0] : top[1];
    Point2f bl = bottom[0].x > bottom[1].x ? bottom[1] : bottom[0];
    Point2f br = bottom[0].x > bottom[1].x ? bottom[0] : bottom[1];

    newLEDPoints.push_back(tl);
    newLEDPoints.push_back(tr);
    newLEDPoints.push_back(br);
    newLEDPoints.push_back(bl);
}

中心计算如下(对于四个顶点):

for (int i = 0; i < LEDPoints.size(); ++i)
{
    center += LEDPoints[i];
}

center *= (1.0 / LEDPoints.size());

我需要一个优雅的解决方案(可能是此解决方案的递归版本),适用于任意数量的四边形。这意味着如果有两个四边形,它们应按类似的顺序排序。

1 个答案:

答案 0 :(得分:2)

使用n个顶点

对多边形进行排序

假设一个坐标系统,x指向右,y指向*,一种方法就是这样:

template<typename It>
void sort_vertices(It begin, It end, typename It::value_type const& center) {
    using point_type = typename It::value_type;

    auto top_down = [](point_type const& a, point_type const& b) { return a.y > b.y; };
    std::sort(begin, end, top_down);
    auto middle = std::find_if(begin, end, [&center](point_type const& a) { return a.y <= center.y; });

    auto left_right = [](point_type const& a, point_type const& b) { return a.x < b.x; };
    auto right_left = [](point_type const& a, point_type const& b) { return a.x > b.x; };
    std::stable_sort(begin, middle, left_right);
    std::stable_sort(middle, end, right_left);
}

即,从顶部到底部对顶点进行排序,然后选择[begin, middle)范围内中心上方的顶点。剩余的[middle, end)是底部的n。此时,您可以从左到右稳定排序第一个,从右到左稳定第二个。

所以考虑像:

这样的多边形

A polygon with vertices: (1, 1) (6, 1) (9, 6) (3, 6)

并为算法提供点矢量:

  

(1,1)(6,1)(9,6)(3,6)

你会收到:

  

(3,6)(9,6)(6,1)(1,1)

Live demo

这当然也适用于其他多边形,如:

enter image description here

被视为:

  

(9,8)(3,6)(2,3)(6,8)(6,1)(10,4)

会产生:

  

(3,6)(6,8)(9,8)(10,4)(6,1)(2,3)

Live demo

*如果需要,您当然可以根据情况进行调整:)

注意:图片来自Wolfram|Alpha

计算template<typename It> typename It::value_type polygon_center(It begin, It end) { using point_type = typename It::value_type; auto sum = std::accumulate(begin, end, point_type()); return sum / std::distance(begin, end); } 顶点

的多边形的中心

假设我们使用与“中心”相同的概念,您可以计算累积所有点的中心并将它们除以点数:

sort_vertices

这样就可以定义一个只占用开始和结束迭代器的template<typename It> void sort_vertices(It begin, It end) { sort_vertices(begin, end, polygon_center(begin, end)); } 函数:

m

排序n多边形

给定这个用于排序任意数量顶点的定义,我们可以使用一个简单的算法来迭代n个顶点组(template<typename It> void sort_polygons(It begin, It end, std::size_t m) { for (It cur_begin = begin; cur_begin != end; std::advance(cur_begin, m)) sort_vertices(cur_begin, std::next(cur_begin, m)); } 在你的情况下将是4)并执行这个转换: / p>

snake_case

Live demo

走向更惯用的C ++

请注意,我通过更改以下内容使您的代码更像是惯用的C ++:P:

  • <algorithm>用于名称
  • 使用模板和迭代器
  • 使用<numeric>标题
  • 使用4 + 5 + 6 + 40 + 50 + 50 + 60 + 40 + 60 + 400 + 400 + 500 + 500 + 600 + 600 = 3315 标题