求多边形凸包(线性算法)--陈氏凸包算法--
http://blog.sina.com.cn/s/blog_616e189f0100qc0u.html
陈氏凸包算法—算法参考:Computing the convex hull of a simple polygon 作者:Chern-Lin Chen
陈氏算法提供了一个线性效率求凸包的算法,本文使用VS2008对算法进行了测试,论文中有很多错误的地方,大家可以参考源码进行更正。话不多说,大家请看源码,和运行效果。
本文算法更改和实现都是本人个人完成,如有转载或使用,请标明出处,并与作者取得联系,谢谢。
void draw(CClientDC & dc );//绘制凸多边形
void addPoint(const CPoint &point);//添加计算的节点
class PointAndAngle{//内部类,用于临时过程的处理(用于计算简单多边形)
bool operator < (const PointAndAngle & p1)const{//小于运算符重载,用于排序
std::vector<CPoint>::iterator findLeftPoint();//找到最左边的点
int computeS(const CPoint & p1, const CPoint &p2, const CPoint &p3)const;//计算S
void computeSimplePolygon();//计算简单多边形
void computeCovexHull();//计算凸多边形
vector<CPoint> m_points;//点集合(无序)
deque<PointAndAngle> m_pointAndAngle;//简单多边形排序后点集合(有序)
deque<CPoint> m_stack;//凸多边形点集合(有序)
void covexHull::addPoint(const CPoint &point)
inline vector<CPoint>::iterator covexHull:: findLeftPoint()
std::vector<CPoint>::iterator ret = m_points.begin();
for(std::vector<CPoint>::iterator it = m_points.begin() ; it != m_points.end() ; ++it)
void covexHull::draw(CClientDC & dc)
for(vector<CPoint>::iterator it = m_points.begin() ; it != m_points.end() ; ++it)
dc.Ellipse(it->x-3, it->y-3, it->x+3, it->y+3);
deque<PointAndAngle>::iterator it = m_pointAndAngle.begin();
if(it != m_pointAndAngle.end())//防止列表为空
dc.MoveTo(it->point.x,it->point.y);
for(; it!= m_pointAndAngle.end() ; ++it)
dc.LineTo(it->point.x,it->point.y);
if(m_pointAndAngle.size() != 0)//防止列表为空
dc.LineTo(m_pointAndAngle.begin()->point.x,m_pointAndAngle.begin()->point.y);
CPen * newPen = new CPen(PS_SOLID,1,RGB(255,0,0));//更改画笔颜色
oldPen = dc.SelectObject(newPen);
deque<CPoint>::iterator it = m_stack.begin();
for(; it!= m_stack.end() ; ++it)
dc.LineTo(m_stack.begin()->x,m_stack.begin()->y);
computeSimplePolygon();//先计算简单多边形
void covexHull::computeSimplePolygon()
vector<CPoint>::iterator it = findLeftPoint();//先找到最左侧的点
CPoint point(it->x,it->y);//将这个点保存下来
m_points.erase(it);//将最左侧的点从列表中删除(因为这个点自身求角度无意义)
for(vector<CPoint>::iterator i = m_points.begin() ; i != m_points.end() ; ++i)//计算所有点与最左侧点的角度
if(i->x - point.x == 0)//要先判断除数为的情况
paa.angle = 90.0/360.0*atan(1.0)*4;//PI = atan(1.0)*4
paa.angle = -90.0/360.0*atan(1.0)*4;
paa.angle = atan(double(double(i->y - point.y)/double(i->x - point.x)));//计算角度
m_pointAndAngle.push_back(paa);//放入简单多变行容器
std::sort(m_pointAndAngle.begin(),m_pointAndAngle.end());//按照角度从小到大排序
m_pointAndAngle.push_front(paa);//最后将最左侧的点放入集合
m_points.push_back(point);//将最左侧点放入点集合
int covexHull::computeS(const CPoint & p1, const CPoint &p2, const CPoint &p3)const
return (p3.x - p1.x)*(-p2.y + p1.y) - (-p3.y + p1.y)*(p2.x - p1.x);//计算S,注意实际坐标系与屏幕坐标系之间的转换
void covexHull::computeCovexHull()
if(m_pointAndAngle.size() < 3)//当小于个点,就不用计算了
m_stack.push_front(m_pointAndAngle.at(0).point);//先将前两个点放入栈中
m_stack.push_front(m_pointAndAngle.at(1).point);
deque<PointAndAngle>::iterator it = m_pointAndAngle.begin() + 2;//迭代器先要移动两个位置(因为那两个位置已经放入栈中了)
for(;it != m_pointAndAngle.end() ;)//迭代求解
if(computeS(m_stack.at(1),m_stack.at(0),it->point) > 0)//当S大于,此时点在直线的右侧
if(computeS(m_stack.back(),m_stack.front(),it->point) > 0)//当S大于,将点压入栈中,否则不压入(不进栈,迭代器移动,相当于reject)
m_stack.push_front(it->point);
if(m_stack.size() < 2)//栈内元素太少,将当前点直接填入栈中
转载于:https://www.cnblogs.com/kex1n/p/3305786.html
求多边形凸包(线性算法)--陈氏凸包算法--相关推荐
- matlab 凸包质心算法,求多边形凸包(线性算法)--陈氏凸包算法--Computing the convex hull of a simple polygon(源码)...
陈氏凸包算法-算法参考:Computing the convex hull of a simple polygon 作者:Chern-Lin Chen 陈氏算法提供了一个线性效率求凸包的算法,本文使用 ...
- 计算几何入门 1.6:凸包的构造——Graham Scan算法
上文简要分析出了凸包构造问题算法的下界:O(nlogn),在此就引入一种下界意义上最优的算法:Graham Scan算法.这种算法可以保证在最坏情况下时间复杂度也不超过nlogn.我们先大致了解一下算 ...
- CGAL笔记之凸包算法—3D凸包
CGAL笔记之凸包算法-3D凸包 1 介绍 2 静态凸壳结构 2.1 特性类 2.1.1 示例 2.1.2 低维结果示例 2.2 极值点 2.3 半空间交集 2.3.1 例子 2.4 凸性检查 3 动 ...
- [Poj 2187] 计算几何之凸包(二) {更高效的算法}
{ 承上一节 继续介绍点集的凸包 (下文中所有凸包 若不做特殊说明均指点集的凸包) 这一节介绍相比更高效的算法 } ========================================= ...
- Graham算法解决凸包问题
Graham算法解决凸包问题 模板题,题目来自洛谷如下. 圈奶牛[模板]二维凸包 题目简要描述 给定一些点,求凸包的周长. 输入格式 输入数据的第一行是一个整数.表示农夫约翰想要围住的放牧点的数目n. ...
- Graham-Scan算法计算凸包的Python代码实现
对于一个点集P来讲,它的凸包就是一个凸多边形Q,其中满足P中的每个点都在Q的边界上或内部.就像下图所示 凸包的计算算法有好多种,wiki和算法导论第33章中都有比较详细的介绍,比如下面是算法导论中给出 ...
- 小白算法学习 凸包 graham
一.概念: 凸包(Convex Hull)是一个计算几何(图形学)中的概念. 在一个实数向量空间V中,对于给定集合X,所有包含X的凸集的交集S被称为X的凸包. X的凸包可以用X内所有点(X1,...X ...
- Graham算法构造凸包(python)
一.算法步骤 首先找到点集中y坐标最小的点作为初始点p0p_0p0,若y坐标相同,选取x坐标最小的一个点作为p0p_0p0 以p0为原点,对点集进行极角排序得到集合{p0,p1...pn}\lef ...
- 拼题---求链式线性表的倒数第K项(两种算法的比较)
7-17 求链式线性表的倒数第K项 (20 分) 给定一系列正整数,请设计一个尽可能高效的算法,查找倒数第K个位置上的数字. 输入格式: 输入首先给出一个正整数K,随后是若干正整数,最后以一个负整数表 ...
最新文章
- 古老的SSM企业级应用
- 如何用Transformer来做目标检测?一文简述DERT及其变体
- HDU 1294 Rooted Trees Problem
- java程序中怎么保证多线程的运行安全_Java线程安全问答(草稿)
- SAP Cloud for Customer最新版本2002 RUI如何启用adaptation模式
- android 手机 与 python服务器_Python服务器与多种客户端(Python/Java/Android)之间的通信...
- Android笔记 网络源代码浏览器demo
- 【设计模式】第三章 单例模式
- 半自动驾驶大对决:特斯拉和凯迪拉克谁是真王
- 网站锁定php文件命令,PHP文件的锁定机制
- GIS中的基本概念收集
- oracle plsql存储过程中out模式参数的用法
- 校园网客户端没有linux版,Linux版校园网客户端公测中(已添加GUI输入窗口)njit-clent...
- 算法竞赛入门经典(第2版)-刘汝佳-第九章例题解题源码(C++语言)(部分)
- ios html5键盘弹出视图上移,ios 软键盘弹出, 页面整体上移问题
- 欧格教育:提升店铺流量的方法
- 轻松解决 f2pool鱼池ethermine连接失败antpool矿池连接不上的问题E池连接超时
- 深耕物料处理赛道,宏工科技助力涂料绿色自动化生产
- idea自动排版html,idea怎么格式化代码?
- 逆序输出数组,将给定数组逆序输出