一、算法步骤

  1. 首先找到点集中y坐标最小的点作为初始点p0p_0p0​,若y坐标相同,选取x坐标最小的一个点作为p0p_0p0​
  2. 以p0为原点,对点集进行极角排序得到集合{p0,p1...pn}\left\{p_0,p_1...p_n\right\}{p0​,p1​...pn​}
  3. 令i=1,构建一个存储凸包边界的栈stack,栈内初始存储元素p0p_0p0​与p1p_1p1​
  4. 判断集合下一个元素pi+1p_{i+1}pi+1​在栈顶两元素构成的向量的哪一侧:
       若在左侧,则点pi+1p_{i+1}pi+1​进栈,i=i+1;i=i+1;i=i+1;重复执行步骤3,直至i>ni>ni>n
       若在右侧,则栈顶元素出栈,重复执行步骤3

二、算法示意图

三、代码

1.导入python库

from math import atan2
import math
import matplotlib.pyplot as plt
import numpy as np

2.构造工具函数

def atan(point,y,x):'''返回点(x,y)相对于point的角度'''x = x - point[0]y = y - point[1]if x==0 and y == 0:return 0point = (5,0) #表示x轴的向量,随便取cos = (point[0]*x+point[1]*y)/(math.sqrt(point[0]**2+point[1]**2)*math.sqrt(x**2+y**2))return np.arccos(cos)*(180/math.pi)
def angle_sort(p0,points):'''对点集从小到大进行极角排序'''dic = {}for point in points:angle = atan(p0,point[1],point[0])dic[point] = anglepoints = [k[0] for k in sorted(dic.items(),key=lambda x:x[1])] #,reverse=Truereturn points
def cross_product(a,b,c):'''判断点c在由点a,b构成的向量的那一侧'''result = a[0]*b[1]-a[1]*b[0] + b[0]*c[1]-b[1]*c[0] + c[0]*a[1]-c[1]*a[0]if result < 0:return False #点c在向量ab右边 返回Falseelse:return True #点c在向量ab左边  返回True

3.初始化点集

集合的高度由vertical决定,宽度由level决定

key=3
num=120
level = 10
vertical = 5
seed = np.random.RandomState(key)
seed2 = np.random.RandomState(key+1)
Z1 = seed.rand(num,1)*level #生成点集
Z2 = seed2.rand(num,1)*vertical
Z = np.concatenate([Z1,Z2],axis = 1)
points = [tuple(i) for i in Z]

三、计算凸包

#起点为y坐标最小的点
ymin = min(points,key=lambda x:x[0])[1]
start = min([i for i in points if i[1] == ymin],key = lambda x:x[0])
stack=[] #定义栈
points = angle_sort(start,points)
stack.append(points[0])
stack.append(points[1])
i=2
while len(stack)!=0 and i != len(points):if cross_product(stack[len(stack)-2],stack[len(stack)-1],points[i]):stack.append(points[i])i+=1else:stack.pop()if len(stack)<2:stack.append(points[i])i+=1continue

四、画出凸包

stack.append(stack[0])
x = [i[0] for i in points]
y = [i[1] for i in points]
x0 = [i[0] for i in stack]
y0 = [i[1] for i in stack]
plt.figure(figsize=(10,10))
plt.scatter(x,y)
plt.plot(x0,y0)plt.xlim(-1,11)
plt.ylim(-1,6)
i=0
for a,b in zip(x,y):plt.text(a, b, i)i+=1

该算法参考自算法导论第33章凸包的生成

Graham算法构造凸包(python)相关推荐

  1. Graham算法解决凸包问题

    Graham算法解决凸包问题 模板题,题目来自洛谷如下. 圈奶牛[模板]二维凸包 题目简要描述 给定一些点,求凸包的周长. 输入格式 输入数据的第一行是一个整数.表示农夫约翰想要围住的放牧点的数目n. ...

  2. 使用ID3算法构造决策树——python

    任务描述 本关任务:补充python代码,完成DecisionTree类中的fit和predict函数. 相关知识 为了完成本关任务,你需要掌握: ID3算法构造决策树的流程 如何使用构造好的决策树进 ...

  3. graham算法 java_凸包Graham Scan算法实现

    凸包算法实现点集合中搜索凸包顶点的功能,可以处理共线情况,可以输出共线点也可以不输出而只输出凸包顶点.经典的Graham Scan算法,点排序使用极角排序方式,并对共线情况做特殊处理.一般算法是将共线 ...

  4. HDUOJ 1392凸包graham算法

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

  5. Graham-Scan算法计算凸包的Python代码实现

    对于一个点集P来讲,它的凸包就是一个凸多边形Q,其中满足P中的每个点都在Q的边界上或内部.就像下图所示 凸包的计算算法有好多种,wiki和算法导论第33章中都有比较详细的介绍,比如下面是算法导论中给出 ...

  6. 凸包模板(Graham算法)

    因为某些原因被迫学习几何知识..先从网上拿个模板来用用 用处: 可以按照极角排序,依次找出凸包边界的点 const int N=10;int n=4,tot;struct node {double x ...

  7. 凸包问题-Graham 算法

    这里我只是想记录一下凸包问题,我发现如果要把他讲解非常清楚,需要画比较复杂的集合图形,而我不会.所以,这篇文章可能只能帮你梳理一下算法步骤或者参考一下代码. 什么是凸包问题 找一条线,能够将二维平面上 ...

  8. 【计算几何】凸包之graham算法(适合小白)

    计算几何–凸包(graham算法实现) 题目链接:LeetCode587 https://leetcode-cn.com/problemset/all/ 题目描述 在一个二维的花园中,有一些用 (x, ...

  9. 凸包Graham算法

    在学习Graham算法前,需要先了解二维叉乘这个概念. 叉乘的拓展 在一般的常识或者教科书中规定叉乘只有3d才拥有,其实2d也可以拓展出来一个叉乘形式,而且非常有用. 拓展方式:假设有两个2d向量a, ...

最新文章

  1. 【Android 异步操作】AsyncTask 异步任务 ( 参数简介 | 方法简介 | 使用方法 | AsyncTask 源码分析 )
  2. python的tell和seek_python文件对象的seek和tell
  3. ubuntu Gitolite管理git server代码库权限
  4. tyvj1194 划分大理石
  5. Deep Learning with PyTorch 必看教程集(4本)
  6. 2.Rails程序框架
  7. 解决github网站打开慢的问题
  8. 为什么会存在乱码?什么是编解码?为什么会有这么多字符集?
  9. 三极管共射放大电路静态工作点怎么设计
  10. 家里两个路由器,Wifi名相同密码相同,请问手机会自动选择信号强的路由器连接吗?
  11. 传腾讯计划出售美团全部股权,知情人士辟谣;苹果证实iOS 16要大量推送广告;Linux 6.0-rc1 发布|极客头条
  12. android多媒体视频,android多媒体(视频播放器)
  13. 被人民日报点名的马保国,一年能挣多少钱?
  14. 分享Python采集99个VB源码,总有一款适合您
  15. 动画 | 大学四年结束之前必须透彻的排序算法
  16. html盒子浮动效果,有关CSS盒子浮动的方法详解
  17. HINSTANCE初了解
  18. java 点阵打印机_Java打印文字点阵信息
  19. chrome 如何清理 dns
  20. MySQL 07、脏页的处理及更新频率 跟 数据库表的空间正确回收

热门文章

  1. 用pygame做一个简单的python小游戏---贪吃蛇
  2. 小米路由器3有信号无网络连接到服务器,小米路由器3上不了网(不能上网)怎么办?...
  3. matplotlib系列-plt.axis
  4. Cameralink转VGA接口转换模块
  5. 电脑操作手机scrcpy软件
  6. Redis+Lua+Java
  7. 上海伯俊软件科技有限公司面试题
  8. 如图标黄的是什么意思?
  9. win10新建菜单只有文件夹怎么办?
  10. 码云最火爆开源项目 TOP 50,你都用过哪些?