实现思路非常简单和直观,本方法针对与二维平面上的凸多边形。多边形顶点坐标数据结构咱就以opencv举例

现有一组凸多边形二维平面坐标数组//base on opencv

std::vector<:point2f> polygonstep1 计算凸多边形的质心

计算质心的方法非常简单,就是分区计算x、y坐标的平均值cv::Point2f centroid = {0.0f, 0.0f};

for(const auto& pt: polygon)

{

centroid.x += pt.x;

centroid.y += pt.y;

}

auto count = polygon.size();

centroid.x = centroid.x / count;

centroid.y = centroid.y / count;step2: 将质心作为坐标系原点建立坐标系

以质心坐标作为参考基准,多边形顶点减去质心坐标,就可以将多边形转换为以质心作为原点的坐标表示for(auto& pt: polygon)

{

auto offset_pt = pt - centroid;

//...下一步处理

}step3: 计算每个顶点与质心连线的角度,并基于角度排序

到这一步就很直观了,质心在凸多边形内部,作为坐标系原点。根据顶点的角度排序后,坐标数组自然是成顺时针或逆时针排序的。计算角度的方法我们采用opencv的反三角计算函数cv::fastAtan2(pt.y, pt.x); //返回值为0-360度的角度值

至于排序,比较方便的方法是基于c++11的lambda表达式特性,写一个匿名函数就可以丢进sort函数里面进行排序,关于根据lambda表达式更多介绍可以参考我这篇笔记使用lambda表达式对自定义对象数组进行排序。下面直接给出代码auto cmp_angle = [&](cv::Point2f& a, cv::Point2f& b)

{

//将转换坐标系写进匿名函数

auto a_offset = a - centroid;

auto b_offset = b - centroid;

//按角度升序排序(顺时针),若需要逆时针将小于号改为大于号即可

//opencv图像坐标系为如下图,角度升序对应顺时针

//(0,0)----------------------x+-------->

// .

// .

// y+

// .

// V

return cv::fastAtan2(a_offset.y, a_offset.x) < cv::fastAtan2(b_offset.y, b_offset.x);

};

std::sort(polygon.begin(), polygon.end(), cmp_angle);

最后,完整的代码如下#include "opencv2/opencv.hpp"

//base on opencv

std::vector<:point2f> polygon;

//step1

cv::Point2f centroid = {0.0f, 0.0f};

for(const auto& pt: polygon)

{

centroid.x += pt.x;

centroid.y += pt.y;

}

auto count = polygon.size();

centroid.x = centroid.x / count;

centroid.y = centroid.y / count;

auto cmp_angle = [&](cv::Point2f& a, cv::Point2f& b)

{

//step2

//将转换坐标系写进匿名函数

auto a_offset = a - centroid;

auto b_offset = b - centroid;

//按角度升序排序(顺时针),若需要逆时针将小于号改为大于号即可

//opencv图像坐标系为如下图,角度升序对应顺时针

//(0,0)----------------------x+-------->

// .

// .

// y+

// .

// V

//step3

return cv::fastAtan2(a_offset.y, a_offset.x) < cv::fastAtan2(b_offset.y, b_offset.x);

};

std::sort(polygon.begin(), polygon.end(), cmp_angle);

我们简单测试一下,将以下顺时针数据打乱后输入排序//顺时针 {12.0, 3.0} { 12.0, 20.0} {0.0, 13.0} {-11.0, 12.0} {-12.0, 0。0} {-11.0, -12.0} {0.0, -15.0}

std::vector<:point2f> polygon;

polygon.push_back({ 12.0f, 20.0f });

polygon.push_back({ 12.0f, 3.0f });

polygon.push_back({ -11.0f, 12.0f });

polygon.push_back({ 0.0f, 13.0f });

polygon.push_back({ 0.0f, -15.0f });

polygon.push_back({ -11.0f, -12.0f });

polygon.push_back({ -12.0f, 0.0f });

测试代码如下:// polygon vertices sort by angle

// @mango

#include "opencv2/opencv.hpp"

//base on opencv

int main()

{

//顺时针 {12.0, 3.0} { 12.0, 20.0} {0.0, 13.0} {-11.0, 12.0} {-12.0, 0。0} {-11.0, -12.0} {0.0, -15.0}

std::vector<:point2f> polygon;

polygon.push_back({ 12.0f, 20.0f });

polygon.push_back({ 12.0f, 3.0f });

polygon.push_back({ -11.0f, 12.0f });

polygon.push_back({ 0.0f, 13.0f });

polygon.push_back({ 0.0f, -15.0f });

polygon.push_back({ -11.0f, -12.0f });

polygon.push_back({ -12.0f, 0.0f });

//step1

cv::Point2f centroid = { 0.0f, 0.0f };

for (const auto& pt : polygon)

{

centroid.x += pt.x;

centroid.y += pt.y;

}

auto count = polygon.size();

centroid.x = centroid.x / count;

centroid.y = centroid.y / count;

auto cmp_angle = [&](cv::Point2f& a, cv::Point2f& b)

{

//step2

//将转换坐标系写进匿名函数

auto a_offset = a - centroid;

auto b_offset = b - centroid;

//按角度升序排序(顺时针),若需要逆时针将小于号改为大于号即可

//opencv图像坐标系为如下图,角度升序对应顺时针

//(0,0)----------------------x+-------->

// .

// .

// y+

// .

// V

//step3

return cv::fastAtan2(a_offset.y, a_offset.x) < cv::fastAtan2(b_offset.y, b_offset.x);

};

std::sort(polygon.begin(), polygon.end(), cmp_angle);

for (auto& pt : polygon)

{

std::cout << pt << std::endl;

}

return 0;

}

测试结果[12, 3]

[12, 20]

[0, 13]

[-11, 12]

[-12, 0]

[-11, -12]

[0, -15]

平面凸多边形顶点排序MATLAB,凸多边形顶点顺逆时针排序相关推荐

  1. matlab 按字母排序,matlab命令大全(按字母排序) 总汇详解最新发布完整珍藏版

    matlab命令大全(按字母排序) 总汇详解最新发布完整珍藏版 abs 绝对值.模.字符的ASCII码值 acos 反余弦 acosh 反双曲余弦 acot 反余切 acoth 反双曲余切 acsc ...

  2. matlab 根据顶点坐标绘制三维立方体(当部分边有权值时)

    matlab 根据顶点坐标绘制三维立方体棱线(当部分边有权值时,有更多的边时方法是类似的) a25=load('xx0.25');%顶点x坐标,大立方体外表面棱边权值为0.25的边的两顶点x坐标,第一 ...

  3. 五边形顶点坐标_足球顶点坐标的计算

    &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp 预备知识 解三棱锥顶角,空间旋转矩阵 图 1:足球透视图 足 ...

  4. opengles 顶点数组 android,OpenGLES顶点属性、顶点数组和缓冲区对象

    顶点属性数据可以用一个顶点数组对每个顶点指定,也可以将一个常量值用于一个图元的所有顶点 OpenGLES支持最少16个顶点属性.准确查询顶点数量方法如下: GLint maxVertexAttribs ...

  5. 怎么找到一抛物线数组的顶点_抛物线与顶点坐标的关系如何确定抛物线开口是向上还是向下?知道抛物线的定点坐标,和x轴的交点或y轴的交点,怎么求抛物线的解析式?抛物线的顶点坐标与抛物线还有什么关系?...

    我想这个你应该有用一.理解二次函数的内涵及本质 . 二次函数 y=ax2 + bx + c ( a ≠ 0 , a . b . c 是常数)中含有两个变量 x . y ,我们只要先确定其中一个变量,就 ...

  6. matlab数组元素的比较大小排序,MATLAB数组元素的排序

    MATLAB sort() 函数用来对数组元素进行排序,它有以下几种常见的用法: B = sort(A)  %使用默认规则对数组排序 B = sort(A, dim)  %dim指定排序的维度 B = ...

  7. MATLAB程序采用非支配排序遗传算法(NSGA2)求解分布式电源选址定容问题

    MATLAB程序采用非支配排序遗传算法(NSGA2)求解分布式电源选址定容问题,可作为一个有用的参考,程序注释明确,算法原理可以自己搜. 现有:6920651507678049浪迹天涯

  8. MATLAB程序采用非支配排序遗传算法(NSGA2)求解分布式电源选址定容问题,可作为一个有用的参考,程序注释明确,算法原理可以自己搜。

    MATLAB程序采用非支配排序遗传算法(NSGA2)求解分布式电源选址定容问题,可作为一个有用的参考,程序注释明确,算法原理可以自己搜. :8620651507678049浪迹天涯

  9. Dijkstra算法实现求有向图中一顶点到其余各个顶点的最短路径

    一.文章说明: C++语言实现: 有向图的存储结构为: 邻接矩阵: 这篇文章的代码是我根据B站UP主懒猫老师所写的,能成功运行,VS里面显示有很多警告.而且还可能存在有未调试出的BUG,请多多指教. ...

最新文章

  1. rocketmq怎么保证消息一致性_RocketMQ为什么要保证订阅关系的一致性?
  2. mvc3中正确处理ajax访问需要登录的页面
  3. 一道关于宏的面试题及解答
  4. 计算机一级应用考试题,办公软件应用计算机一级考试试题
  5. JLOI2015 解题报告
  6. ln创建、删除软/硬链接
  7. post方法就返回了一个string字符串前台怎么接_LoadRunner脚本编写教程Getamp;Post
  8. 点击area不出现黑框_一切小黑屋,都能被黑框玻璃门治愈 | 附安装法则
  9. 10投屏后没有声音_10年后,学区房有没有可能成为“负资产”?这位专家说了实话...
  10. 基于逻辑回归的评分卡模型简单概述
  11. 回答阿里云实名认证常见问题
  12. JS实现将数字金额转换为大写人民币汉字的方法
  13. RAM汇编指令DMB、DSB、ISB、SEV等
  14. java实现can通信_[MicroPython]TPYBoard v102 CAN总线通信
  15. 小米笔记本 air 12.5寸 支持硬盘参数
  16. 【ThreeJs】(2)照相机 | 正交投影照相机 | 透视投影照相机
  17. 接口测试 | 接口测试入门
  18. 前世界银行经济学家质疑华为财报
  19. 服务器端程序的演进过程
  20. HTML/CSS 知识点解析

热门文章

  1. React 设计思想
  2. matlab中 feof(fp),feof和ferror函数,C语言feof和ferror函数详解
  3. 别不信,程序员永远也摆脱不了这 7 个噩梦
  4. jQuery实现倒计时效果
  5. 函数周期表丨时间智能丨表丨DATESINPERIOD
  6. 使用JQuery的turn.js库来实现翻书效果
  7. JVM核心知识体系(转http://www.cnblogs.com/wxdlut/p/10670871.html)
  8. QSFP28光模块工作原理
  9. 砼匠LED显示屏排队配置文件-LED.ini 屏大小:288-176,生产线横显示
  10. (5)微信UI自动化-实现静默鼠标点击(C#)