计算几何 : 凸包学习笔记 --- Graham 扫描法

凸包

(只针对二维平面内的凸包)

一、定义

简单的说,在一个二维平面内有n个点的集合S,现在要你选择一个点集C,C中的点构成一个凸多边形G,使得S集合的所有点要么在G内,要么在G上,并且保证这个凸多边形的面积最小,我们要求的就是这个C集合。

二、算法

求凸包的算法很多,常用的有两种:

1.  Graham扫描法,运行时间为O(nlgn)。

2.  Jarvis步进法,运行时间为O(nh),h为凸包中的顶点数。

这里主要讨论第一种算法:Graham扫描法

Graham扫描法:

基本思想:使用一个栈来对所有点逐一判断,把不符合条件的点筛出去。

操作:输入集合Q中的每一个点都被压入栈一次,非CH(Q)(表示Q的凸包)中的顶点的点最终将被弹出堆栈,当算法终止时,堆栈S中仅包含CH(Q)中的顶点,其顺序为个各顶点在边界上出现的逆时针方向排列的顺序。

首先,找一个凸包上的点,把这个点放到第一个点的位置P0。然后把P1~Pm 按照P0Pi的方向排序,可以用矢量积(叉积)判定。

判定过程:

做好了预处理后开始对堆栈中的点<p3,p4,...,pm>中的每一个点进行迭代,在第7到8行的while循环把发现不是凸包中的顶点的点从堆栈中移去。(原理:沿逆时针方向通过凸包时,在每个顶点处应该向左转。因此,while循环每次发现在一个顶点处没有向左转时,就把该顶点从堆栈中弹出。)当算法向点pi推进、在已经弹出所有非左转的顶点后,就把pi压入堆栈中。

整个算法过程如图所示:

计算几何 : 凸包学习笔记 --- Graham 扫描法

时间: 2024-12-28 08:01:19

计算几何 : 凸包学习笔记 --- Graham 扫描法的相关文章

[hdu contest 2019-07-29] Azshara&#39;s deep sea 计算几何 动态规划 区间dp 凸包 graham扫描法

今天hdu的比赛的第一题,凸包+区间dp. 给出n个点m个圆,n<400,m<100,要求找出凸包然后给凸包上的点连线,连线的两个点不能(在凸包上)相邻,连线不能与圆相交或相切,连线不能相交但是可以有公共端点. 首先找出凸包,然后把n*n条边和m个圆算点到直线距离验证一下边是否与圆相交存到e[n][n]里. 然后显然是一个dp,但是我开始看错题目了以为不能有公共端点,能有公共端点的情况考虑一下像一个找三角形的过程,就是区间dp. 区间dp有一点妙的地方是最大区间范围是凸包点数而不用+1,因为连

[笔记] 计算几何-凸包 POJ-3348 Cows

题目:http://poj.org/problem?id=3348 求凸包面积 算法:先对点的横坐标排序,从左到右先计算下凸边,再从右到左计算上凸边.复杂度比Graham Scan法稍稍要高(两次遍历点集),但实现较容易 #include <stdio.h> #include <algorithm> using namespace std; struct point{ double x,y; }; point a[10005]; point res[10005]; bool cmp

【笔记篇】最良心的计算几何学习笔记(六)

半平面交 github传送门 简介 Emmmm学完旋转卡壳感觉自己已经是个废人了.. 修整了一个周末, 回来接着跟计算几何势力硬干... (这个周末是不是有点长?) 今天就讲讲半平面交吧. 请自己回顾必修五 线性规划相关知识... 什么是半平面? 就是一条直线一侧的点构成的集合.. 用解析几何的观点来看就是满足\(Ax+By+C<0\)这个不等式的点的集合. 那么半平面交自然就是许多这样的集合的交集咯~ 最后就很像线性规划做出来的可行域一样... 半平面交可以长这样 这样 甚至这样 也就是说,

poj1113Wall 求凸包周长 Graham扫描法

#include<iostream> #include<algorithm> #include<cmath> using namespace std; typedef pair<int ,int > ll; ll num,dot[1010]; int i; const double pi=3.1415926535898; ll operator -(ll a,ll b) { return make_pair(a.first-b.first,a.second-

【算法学习笔记】36.凸包 求最大两点距离 SJTU OJ 1244 Date A Live

Description 某助教有好多好多妹纸,其中不乏来自五道口与东川路等男子职业技术学校的.然而,遥远的距离让他不得不花费大量的时间奔波于众多城市之间.为了更好地安排自己的约会计划,他想知道最远的两只妹纸之间的距离是多少. Input Format 第一行有一个整数n,表示妹纸的数量. 接下来n行,每行两个实数x,y,表示妹纸的坐标(假定在一个平面直角坐标系上). 对于80%的数据,n<=2000 对于90%的数据,n<=10000 对于100%的数据,n<=100000 Output

凸包-Graham扫描法

RT,Graham扫描法求凸包分为3步: 1.找到y最小的点 2.以y最小的点O为原点,求其余所有点相对O的极角并按极角从小到大排序 3.对于排序后的点集,配合栈,完成Graham扫描. ConvexHull.py #coding=utf-8 import math import numpy import pylab as pl #画原始图 def drawGraph(x,y): pl.title("The Convex Hull") pl.xlabel("x axis&qu

【笔记篇】最良心的计算几何学习笔记(七)

动态凸包 本文的github传送门在这里~ ====================================================================== 不会凸包的赶紧去学一下哦~ ====================================================================== 好的我们已经会求凸包了. 那我们来看这样一道题. 题目大意(英文题必须要有的翻译过程OvO): 写一个程序支持一下两种操作: 1 x y 添加一

(模板)poj1113(graham扫描法求凸包)

题目链接:https://vjudge.net/problem/POJ-1113 题意:简化下题意即求凸包的周长+2×PI×r. 思路:用graham求凸包,模板是kuangbin的. AC code: #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int maxn=1005; const double PI=

计算几何 --- 凸包 模板

//Memory Time // 1347K 0MS // by : Snarl_jsb #include<algorithm> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<vector> #include<queue> #include<stack> #include<map> #