凸包之Jarvis步进法
Jarvis步进法:
概述:也可称为卷包裹法,思路是先找到一个在凸包上的点,然后卷过去,由于每次确定凸包上的一个点需要遍历所有的点,因此时间复杂度为O(N*H),其中N为全部点的数目,H为凸包上的点数目;
适用性:从时间复杂度可以看出此方法适用点的数目不易过多,建议适用Graham扫描法;
方法和步骤:(下述采用固定两点的方式)
(1)找到位于最低最左边的点p0,最高最右边的点pk,则此两点必为凸包上的点;
(2)对逆时针方向排列的顶点序列按p0pk构造右链,左链;
(3)右链构造:设定一个栈,先将p0入栈,对其他的点依据相对于栈顶元素的最小极角,并距离最远的点入栈,左链同理;
(4)核心:如何求相对于栈顶元素的最小极角?
设pk为最高点,p0位栈顶元素;
只要栈顶元素不是pk,循环做以下工作:
{
pm=pk;
for(int i=0;i<n;i++)//依次考查其他的点p[i],是否有相对于p[top]的最小极角
{
if((p[top]p[i]×p[top]pm>0)||(p[top]p[i]与P[top]pm共线)&&(|p[top]p[i]|>|p[top]pm|)
{
pm=p[i];
}
}
经过上述一次遍历,得到的pm为相对于当前p[top]的具有最小极角的顶点,即右链中连接p[top]的下一个凸包的顶点;
}
左链同上述操作同理;
代码:(&&优先级高于||)
#include <stdio.h>
#include <algorithm>
using namespace std;struct POINT
{int x,y;
};
POINT point[100],pk;
int n,top,k,Stack[100];int det(POINT a,POINT b,POINT c){return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}int dis(POINT a,POINT b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}void Jarvis(int n,int flag)
{int m,tmp;POINT pm;Stack[0]=0;//p0进栈top=0;while(m!=k){pm=pk;m=k;for(int i=1;i<n;i++){tmp=det(point[Stack[top]],point[i],pm);if((tmp>0&&flag==1)||(tmp<0&&flag==0)||(tmp==0)&&(dis(point[Stack[top]],point[i])>dis(point[Stack[top]],pm))){pm=point[i];m=i;}}top++;Stack[top]=m;}if(flag==1){for(int i=0;i<=top;i++)printf("(%d,%d)",point[Stack[i]].x,point[Stack[i]].y);}if(flag==0){for(int i=top-1;i>0;i--)printf("(%d,%d)",point[Stack[i]].x,point[Stack[i]].y);printf("\n");}
}int main()
{scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d%d",&(point[i].x),&(point[i].y));if(point[i].y<point[0].y||point[i].y==point[0].y&&point[i].x<point[0].x)//最左最低点 swap(point[0],point[i]);if(i==0){pk=point[0];k=0;}if(point[i].y>pk.y||point[i].y==pk.y&&point[i].x>pk.x)//最右最高点 {pk=point[i];k=i;} }Jarvis(n,1);//右链 Jarvis(n,0);//左链 return 0;
}
凸包之Jarvis步进法相关推荐
- Java实现算法导论中凸包问题Jarvis步进法
对于凸包的理解,参考http://www.cnblogs.com/Booble/archive/2011/02/28/1967179.html,说的还是比较深入浅出. 凸包问题的Jarvis步进法,其 ...
- 【opencv学习笔记】030 之 凸包之Graham扫描法与Jarvis步进法详解
目录 一.前言 二.凸包 1.概念 2.凸包查找算法 1.Graham扫描法 2.Jarvis步进法 3.凸包API 4.代码展示 5.执行结果 一.前言 继续更新有关于opencv的基础博客,即将更 ...
- HDU 1348 Wall ( 凸包周长 )
链接:传送门 题意:给出二维坐标轴上 n 个点,这 n 个点构成了一个城堡,国王想建一堵墙,城墙与城堡之间的距离总不小于一个数 L ,求城墙的最小长度,答案四舍五入 思路:城墙与城堡直线长度是相等的, ...
- 计算几何-经典算法-凸包
在学习了一些有关计算机几何的基础知识和一些基本工具之后要快速的解决一些简单的几何问题,如两点之间的距离.两线段的交点个数等等是可以轻松应付的,但是对于复杂点的几何问题,我们还是要有更好的算法,这样才可 ...
- 分治算法-02凸包问题
几何问题之凸包 简介 简单地说,凸包是正好包含所有点的凸多边形,可以将它想象为一个包围点几何的橡皮筋.之所以叫凸包是因为这个凸多边形包围所有点.本案例主要讲解分治法解决凸包问题,常见的还有Graham ...
- python计算多边形面积_Python求凸包及多边形面积教程
一般有两种算法来计算平面上给定n个点的凸包:Graham扫描法(Graham's scan),时间复杂度为O(nlgn):Jarvis步进法(Jarvis march),时间复杂度为O(nh),其中h ...
- 凸包 初学 Andrew 和 Melkman (模板) 旋转卡(qia)壳(ke)
凸包初学 定义: 给你n个散落的点,让你求出最小的凸多边形将所有的点包括起来,或者点在边上. 稳定凸包,不能再扩充,每条边都用3个点 必备知识: 会用叉积判断点与直线的关系(这里指 点在线的那一边, ...
- 凸包(Graham扫描法构建)
凸包(Graham扫描法构建) PS:我的妈呀,心态爆炸,好像也不太难,看各种模板看的云里雾里的,真的还是自己动手敲来的好,几乎没多久就懂的差不多了.... 一个本该寒假就该掌握的知识,居然熬了我几个 ...
- 凸包算法-------Graham扫描法
在网络上关于凸包解法多种多样,讲的也非常的不错,可以参考一下这篇博客,但是还是想用自己的话去描述一遍,以加深一下印象. 常见的解法有: 穷举法(蛮力法) 分治法 Jarvis步进法 Graham扫描法 ...
最新文章
- 为什么不记录慢速查询?
- RiboFR-Seq:将16S rRNA与宏基因组连接的方法
- vsts~CI/CD实现自动化编译
- 1087 有多少不同的值 (20 分)
- 工作281:时间戳转换问题
- 201521123059 《Java程序设计》第八周学习总结
- Java里a和b哪个大_Java中 a+=b和a=a+b有什么区别?
- Redis之List类型操作
- 干支纪年法简便算法_@谢氏宗亲:可知道我国为何放弃黄帝纪年,而选择耶稣诞辰纪年法...
- 滴滴定制网约车D1即将登陆长沙 市民12月中可叫到
- Linux安装软件包时的“依赖关系树”算法(C#)
- 拿到offer怕查学历不敢去_《令人心动的offer》— 我们法庭见
- webpack 打包第三方库_webpack提取第三方库的正确姿势
- 网络拓扑图js插件——jTopo应用
- Windows Mobile 6.5开发环境搭建
- python充电时刻
- 大众点评评论反爬解决方案
- Android四大组件生命周期
- java刘备猜拳游戏类_基于java实现人机猜拳游戏
- 支付宝常用接口统一封装,可直接支付参数使用(适用于H5、PC、APP)