python Graham求凸包问题并画图操作

 更新时间:2021年06月03日 14:11:06   作者:sunnyorrainy  
这篇文章主要介绍了python Graham求凸包问题并画图操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

python Graham求凸包并画图

python写Graham没有c++那么好写,但是python画图简单。只需要用matplotlib里的pyplot,c++画图太难了。

Graham算法写起来比较简单,只需要想办法对最小点和其他的点所连成的直线,与x轴正半轴的夹角进行排序,然后其他的就直接套用Graham算法模板就好了,因为c++可以重载排序函数sort,不用计算角度(用其他的数学方法),但是python不行(也许是我不知道而已,菜)。

python必须要在结构体里面加上角度这个变量,然后才能按照角度排序。排好序后就变得容易了,用stack栈存放答案,算完答案后,用scatter(散点图)画出点,用plt(折线图)画边界就好了。

import matplotlib.pyplot as plt
import math
import numpy as np  
class Node:
    def __init__(self):
        self.x = 0
        self.y = 0
        self.angel = 0
        #和最左下的点连成的直线,与x轴正半轴的夹角大小 
 
#按照角度从小到大排序
def cmp(x):
    return x.angel  
def bottom_point(points):
    min_index = 0
    n = len(points)
    #先判断y坐标,找出y坐标最小的点,x坐标最小的点
    for i in range(1, n):
        if points[i].y < points[min_index].y or (points[i].y == points[min_index].y and
           points[i].x < points[min_index].x):
            min_index = i
    return min_index 
 
#计算角度
def calc_angel(vec):
    norm = math.sqrt(vec[0] * vec[0] + vec[1] * vec[1])
    if norm == 0:
        return 0
    angel = math.acos(vec[0]/norm)
    if vec[1] >= 0:
        return angel
    else:
        return math.pi * 2 - angel 
 
def multi(v1, v2):
    return v1[0] * v2[1] - v1[1] * v2[0] 
 
point = []
n = 30
#生成30个点的坐标,n可以修改
for i in range(n):
    temp = Node()
    temp.x = np.random.randint(1, 100)
    temp.y = np.random.randint(1, 100)
    point.append(temp)
index = bottom_point(point)
for i in range(n):
    if i == index:
        continue
    #计算每个点和point[index]所连成的直线与x轴正半轴的夹角
    vector = [point[i].x - point[index].x, point[i].y - point[index].y]
    #vector是向量
    point[i].angel = calc_angel(vector)
#排序
point.sort(key=cmp)
#答案存入栈中
stack = []
stack.append(point[0])
stack.append(point[1])
#for循环更新答案
for i in range(2, n):
    L = len(stack)
    top = stack[L - 1]
    next_top = stack[L - 2]
    vec1 = [point[i].x - next_top.x, point[i].y - next_top.y]
    vec2 = [top.x - next_top.x, top.y - next_top.y]
    #一定要大于等于零,因为可能在一条直线上
    while multi(vec1, vec2) >= 0:
        stack.pop()
        L = len(stack)
        top = stack[L - 1]
        next_top = stack[L - 2]
        vec1 = [point[i].x - next_top.x, point[i].y - next_top.y]
        vec2 = [top.x - next_top.x, top.y - next_top.y]
    stack.append(point[i])
#画出图像
for p in point:
    plt.scatter(p.x, p.y, marker='o', c='g')
L = len(stack)
for i in range(L-1):
    plt.plot([stack[i].x, stack[i+1].x], [stack[i].y, stack[i+1].y], c='r')
plt.plot([stack[0].x, stack[L-1].x], [stack[0].y, stack[L-1].y], c='r')
plt.show()

Python 找到凸包 Convex hulls

图形学可以说经常遇到这东西了,这里给出一个库函数的实现

from scipy.spatial import ConvexHull
points = np.random.rand(10, 2) # 30 random points in 2-D
hull = ConvexHull(points)
import matplotlib.pyplot as plt
plt.plot(points[:,0], points[:,1], 'o')
for simplex in hull.simplices:
 plt.plot(points[simplex,0], points[simplex,1], 'k-')
plt.show()

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 在cmd中运行.py文件: python的操作步骤

    在cmd中运行.py文件: python的操作步骤

    今天小编就为大家分享一篇在cmd中运行.py文件: python的操作步骤,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • python 解决tqdm模块不能单行显示的问题

    python 解决tqdm模块不能单行显示的问题

    这篇文章主要介绍了python 解决tqdm模块不能单行显示的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-02-02
  • python实现三维拟合的方法

    python实现三维拟合的方法

    今天小编就为大家分享一篇python实现三维拟合的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • Python 矩阵转置的几种方法小结

    Python 矩阵转置的几种方法小结

    今天小编就为大家分享一篇Python 矩阵转置的几种方法小结,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • Python中实现输入超时及如何通过变量获取变量名

    Python中实现输入超时及如何通过变量获取变量名

    这篇文章主要介绍了Python中实现输入超时以及通过变量获取变量的名字,本文给大家分享了解决思路主要是通过多线程法实现,需要的朋友可以参考下
    2020-01-01
  • Python实现矩阵转置的几种方法详解

    Python实现矩阵转置的几种方法详解

    这篇文章主要介绍了Python实现矩阵转置的几种方法详解,zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象,这样做的好处是节约了不少的内存,需要的朋友可以参考下
    2023-08-08
  • Python绘制心形曲线完整代码实现

    Python绘制心形曲线完整代码实现

    这篇文章主要介绍了Python绘制心形曲线的相关资料,通过numpy和matplotlib库计算坐标并绘图,代码包含导入库、定义函数、生成参数、计算坐标、绘图和显示图形等步骤,展示了数学与编程的结合美感,需要的朋友可以参考下
    2024-10-10
  • python基础之并发编程(一)

    python基础之并发编程(一)

    这篇文章主要介绍了详解python的并发编程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-10-10
  • Python学习笔记之open()函数打开文件路径报错问题

    Python学习笔记之open()函数打开文件路径报错问题

    这篇文章主要介绍了Python学习笔记之open()函数打开文件路径报错问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • TensorFlow车牌识别完整版代码(含车牌数据集)

    TensorFlow车牌识别完整版代码(含车牌数据集)

    这篇文章主要介绍了TensorFlow车牌识别完整版代码(含车牌数据集),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08

最新评论