• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    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()

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

    您可能感兴趣的文章:
    • python 生成任意形状的凸包图代码
    • 基于python 凸包问题的解决
    • Python求凸包及多边形面积教程
    上一篇:Django与数据库交互的实现
    下一篇:实例讲解Python中sys.argv[]的用法
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

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