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 ...
随机推荐
- java运行时内存分配详解
一. 基本概念 每运行一个java程序会产生一个java进程,每个java进程可能包含一个或者多个线程,每一个Java进程对应唯一一个JVM实例,每一个JVM实例唯一对应一个堆,每一个线程有一个自己私 ...
- css3动画怎样能从下往上慢慢升上去
<!DOCTYPE html><html><head> <style> div { width:100px; height:100px; backgro ...
- Jeecg
姓名:黄于霞 班级:软件151 1.第一步将Jeecg引包到javaEE中,如图下图所示: 2.第二步改jeecg_config.properties中的用户名和密码改成和数据库中一 ...
- CPU的系统总线
主频:时钟频率,用来表示CPU的运算速度.主频=外频*倍频. 外频:基准频率,系统总线的工作频率,外频是CPU与主板之间同步运行的速度,大部分电脑系统中外频也是内存与主板之间同步运行的速度,在这种方式 ...
- 201671010142 2017-2 《java第十二十三章学习感悟》
Swing编程第一步,需要导入Swing相关包,即javax.swing.*. 接下里需要设置界面外观风格,使用到UIManager类. 设置完外观之后一定要调用 SwingUtilities.upd ...
- pip install beautifulsoup4.失败
在学习python爬虫时,用到bs4解析网页,开始遇到安装bs出错 Collecting beautifulsoup4Exception:Traceback (most recent call las ...
- java算法01 - 链表
1.链表 在Java中实现链表,每个节点都有一个值,然后把它链接到下一个节点.下面来看一下节点的实现 class Node<E> { private E e; private Node&l ...
- 【转】Linux的nm查看动态库和静态库的符号
转自https://blog.csdn.net/qq_16683355/article/details/52297884 功能 列出.o..a..so中的符号信息,包括符号的值,符号类型及符号名称等. ...
- 用几句话说一说CMake add_dependencies & target_link_libraries的使用区别
简单说一说前两天学习使用CMake解决链接问题时遇到的一个问题. 对于编译时遇到的依赖问题,很多时候我们只需要一句target_link_libraries就可以搞定. 但是CMake还有另外一个co ...
- Excel--------实用功能(数据对比)
--excel数据在sql中查询展示出来 SELECT * FROM (SELECT '101001' as code ,'上海宝山站' as name union allSELECT '102083 ...