这是我的函数,它可以按左上方的顺序对四边形的顶点进行排序 - >右上角 - >右下角 - >左下角:
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());
我需要一个优雅的解决方案(可能是此解决方案的递归版本),适用于任意数量的四边形。这意味着如果有两个四边形,它们应按类似的顺序排序。
答案 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, [¢er](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
。此时,您可以从左到右稳定排序第一个,从右到左稳定第二个。
所以考虑像:
这样的多边形
并为算法提供点矢量:
(1,1)(6,1)(9,6)(3,6)
你会收到:
(3,6)(9,6)(6,1)(1,1)
这当然也适用于其他多边形,如:
被视为:
(9,8)(3,6)(2,3)(6,8)(6,1)(10,4)
会产生:
(3,6)(6,8)(9,8)(10,4)(6,1)(2,3)
*如果需要,您当然可以根据情况进行调整:)
注意:图片来自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
请注意,我通过更改以下内容使您的代码更像是惯用的C ++:P:
<algorithm>
用于名称<numeric>
标题4 + 5 + 6 + 40 + 50 + 50 + 60 + 40 + 60 + 400 + 400
+ 500 + 500 + 600 + 600 = 3315
标题