python学习5---实现凸包
1、暴力法
def g(A,B,P):
"""
判断点PA矢量在AB矢量的顺时针还是逆时针方向,
若在逆时针方向则返回1,同向返回0,在顺时针方向返回-1
:param A:
:param B:
:param P:
:return: 1或0或-1
"""
#使用PxQ=XpYq-XqYp,若大于0则表示Q在P的逆时针方向
result = (P[1]-A[1])*(B[0]-A[0])-(B[1]-A[1])*(P[0]-A[0])
if result<0:
return -1
elif result==0:
return 0
else:
return 1
def isInTriangle(Pi,Pj,Pk,P):
"""
判断点P是否在其他三个点组成的三角形中,是的话返回true
:param P:
:param Pi:
:param Pj:
:param Pk:
:return:
"""
if g(Pi,Pj,Pk)==0:
return 0
if g(Pi,Pj,P)*g(Pi,Pj,Pk)>=0 and g(Pj,Pk,P)*g(Pj,Pk,Pi)>=0 and g(Pk,Pi,P)*g(Pk,Pi,Pj)>=0:
return 1
return 0
def bruteForce(S):
"""
暴力方法求解凸包
:param S: 输入的顶点集合
:return: Q的凸包
"""
n=len(S)
flag=ones((n,1))
output = []
if n==3:
#以逆时针方式输出Q的点
if g(S[0], S[1], S[2])>0:
output.append(S[0])
output.append(S[1])
output.append(S[2])
elif g(S[0], S[1], S[2])<0:
output.append(S[2])
output.append(S[1])
output.append(S[0])
return output
# 若取得的三个点共线怎么办?????
for i in range(n - 3):
for j in range(i + 1, n - 2):
for k in range(j + 1, n - 1):
for p in range(k + 1, n):
# 有一个点在其他点组成的三角形里
if isInTriangle(S[i], S[j], S[k], S[p]):
# 则将该点对应的标志位置为0
flag[p] = 0
if isInTriangle(S[p], S[j], S[k], S[i]):
# 则将该点对应的标志位置为0
flag[i] = 0
if isInTriangle(S[k], S[p], S[i], S[j]):
# 则将该点对应的标志位置为0
flag[j] = 0
if isInTriangle(S[p], S[j], S[i], S[k]):
# 则将该点对应的标志位置为0
flag[k] = 0
print(flag)
sub_S = []
for i in range(n):
if flag[i][0]: # if标志不为0,将添加到sub_S:
sub_S.append(S[i]) # 则sub_S保存的是在凸包的顶点
sub_S = np.array(sub_S)
# 找到sub_S的x坐标最大点B和x坐标最小点A
sub_S_index = argsort(sub_S[:, 0])
A = sub_S[sub_S_index[0]]
B = sub_S[sub_S_index[-1]]
# 按照点在AB直线上方还是下方将sub_S分为两部分Sup,Sdown
Sup = []
Sdown = []
for i in range(len(sub_S)):
if g(A, B, sub_S[i]) > 0:
Sup.append(sub_S[i])
if g(A, B, sub_S[i]) < 0:
Sdown.append(sub_S[i])
# 将Sup按照横坐标递减排序,将Sdown按照横坐标递增排序
Sup = np.array(Sup)
Sup = Sup[argsort(-Sup[:, 0])]
Sdown = np.array(Sdown)
Sdown = Sdown[argsort(Sdown[:, 0])]
# 从B开始按照x坐标递减依次输出Sup,到达A,按照x坐标从小到大依次输出Sdown
output=[]
# for i in range(len(sub_S)):
output.append(A)
output.extend(Sdown)
output.append(B)
output.extend(Sup)
return output
2、GrahamScan
def GrahamScan(S):
"""
GrahamScan求凸包
:param S:
:return:
"""
#预处理:找到S中y坐标最小的点P0,以水平为极轴求得每个点极角
n = len(S)
P = []
S = S[argsort(S[:, 1])]
#P.append(tuple(S[0]))
P.append(list(S[0, 0:2]))
PointPolar = [] # 保存(x,y,极角)
for i in range(1, n):
polar = math.atan2(S[i][1] - S[0][1], S[i][0] - S[0][0])
polar = polar / math.pi * 180
PointPolar.append([S[i][0], S[i][1], polar])
# 将PointPolar的点按照极角从小到大排序,保存在result
result = preProcessing(PointPolar)
new_dict2 = remove_dup(result, P[0])
#P.extend(new_dict2.keys())
for key in new_dict2:
P.append(list(key))
#若m<=1返回凸包是空
m=len(P)
if m<=2:
return
# 将P[0],P[1],P[2]依次压栈Q
stack = []
stack.append(P[0])
stack.append(P[1])
stack.append(P[2])
for i in range(3, m):
while isInTriangle(P[0], P[i], stack[-2], stack[-1]):
stack.pop()
stack.append(P[i])
return stack
def preProcessing(PointPolar):
"""
当多个点的极角相同时,保留距离原点最远的点
:param dict:
:return:一个list,经预处理的P[0:m],按照极角从小到大保存要处理的点集
"""
sorted_polar=sorted(PointPolar,key=lambda d:d[2])
return sorted_polar
def remove_dup(sorted_polar,raw):
"""
:param sorted_dict:
:return:
"""
sorted_dict = {}
for d in sorted_polar:
sorted_dict[(d[0], d[1])] = d[2]
new_dict = {}
new_dict2 = {}
for k, v in sorted_dict.items():
new_dict.setdefault(v, []).append(k)
for k, v in new_dict.items():
if len(v) > 1:
d = []
for item in v:
d.append((item[0]-raw[0]) * (item[0]-raw[0]) + (item[1]-raw[1]) * (item[1]-raw[1]))
v = v[argmax(d)]
new_dict2[v] = k
else:
new_dict2[v[0]] = k
return new_dict2
结果:

python学习5---实现凸包的更多相关文章
- Python学习--04条件控制与循环结构
Python学习--04条件控制与循环结构 条件控制 在Python程序中,用if语句实现条件控制. 语法格式: if <条件判断1>: <执行1> elif <条件判断 ...
- Python学习--01入门
Python学习--01入门 Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.和PHP一样,它是后端开发语言. 如果有C语言.PHP语言.JAVA语言等其中一种语言的基础,学习Py ...
- Python 学习小结
python 学习小结 python 简明教程 1.python 文件 #!/etc/bin/python #coding=utf-8 2.main()函数 if __name__ == '__mai ...
- Python学习路径及练手项目合集
Python学习路径及练手项目合集 https://zhuanlan.zhihu.com/p/23561159
- python学习笔记-python程序运行
小白初学python,写下自己的一些想法.大神请忽略. 安装python编辑器,并配置环境(见http://www.cnblogs.com/lynn-li/p/5885001.html中 python ...
- Python学习记录day6
title: Python学习记录day6 tags: python author: Chinge Yang date: 2016-12-03 --- Python学习记录day6 @(学习)[pyt ...
- Python学习记录day5
title: Python学习记录day5 tags: python author: Chinge Yang date: 2016-11-26 --- 1.多层装饰器 多层装饰器的原理是,装饰器装饰函 ...
- [Python] 学习资料汇总
Python是一种面向对象的解释性的计算机程序设计语言,也是一种功能强大且完善的通用型语言,已经有十多年的发展历史,成熟且稳定.Python 具有脚本语言中最丰富和强大的类库,足以支持绝大多数日常应用 ...
- Python学习之路【目录】
本系列博文包含 Python基础.前端开发.Web框架.缓存以及队列等,希望可以给正在学习编程的童鞋提供一点帮助!!! 目录: Python学习[第一篇]python简介 Python学习[第二篇]p ...
随机推荐
- 我是如何通过学习拿到年薪80w
本人做了5年Java,如今还是一个码农,天天写业务代码,直到2018年10月中旬遇到一位技术大牛,他给我一套技术思维导图让我又看到了希望!今天分享给各位想要提升.升职.加薪的你. 普通Java程序员与 ...
- Android 音视频深入 十九 使用ijkplayer做个视频播放器(附源码下载)
项目地址https://github.com/979451341/Myijkplayer 前段时候我觉得FFmpeg做个视频播放器好难,虽然播放上没问题,但暂停还有通过拖动进度条来设置播放进度,这些都 ...
- 华为S5700设置vlan,并绑定电脑的IP地址与mac地址。
要求是设置两个vlan,10和20.交换机下的10网段和20网段的电脑在两个vlan当中.20网段的ip地址与mac地址绑定,从而实现下面的电脑更改ip地址或者不明来源的电脑不能连接到交换机. 1.s ...
- git切换用户踩坑
1)配置用户信息 git config --global user.name "username" git config --global user.email "**@ ...
- 历史命令与实时记录(redhat6.8)
历史命令与实时记录(redhat6.8) linuxshell 2018年02月13日 10时58分53秒 参数 HISTTIMEFORMAT HISTSIZE HISTFILESIZE HISTFI ...
- 使用java命令出现Error: A JNI error has occurred, please check your installation and try again的错误
运行Java程序,javac运行.java文件没有报错,但java运行的时候报错 仔细看一下报错 Exception in thread "main" java.lang. ...
- R语言的精度和时间效率比较(简单版)
R语言的最大数值 在R语言里面,所能计算的最大数值可以用下面的方法获得: ###R可计算最大数值 .Machine 在编程的时候注意不要超过这个数值.当然,普通情况下也不可能超过的. R语言的最大精度 ...
- Python随笔--爬虫(下载妹子图片)
- 前端车牌识别SDK算法提取
同行业中,别人标配有的产品我有,别人没有的产品我们也有,如此才能增强竞争力,通过优化创新,前端车牌识别SDK功能,性能上,都是行业NO.1的水平.车牌识别sdk这个用于越来越多人集成了,汽车保有量日益 ...
- js问题解决——cannot read property style of undefind
当遇到cannot read property style of undefine的问题如下: 那就说明你设定的这个变量名为空 比如我在文档里写的属性名为list_box 但是我获取的属性名称写错了 ...