首页 > 编程语言 >python 实现凸多边形的凸包问题算法

python 实现凸多边形的凸包问题算法

时间:2024-10-14 09:22:37浏览次数:7  
标签:return point python hull bottommost 凸多边形 凸包 points

凸多边形的凸包问题算法介绍

凸多边形的凸包问题本身有点自相矛盾,因为凸多边形本身就是其所有顶点的凸包。凸包(Convex Hull)的定义是对于一个点集,包含所有点的最小凸多边形。对于已经是凸多边形的点集,这个多边形就是它自己的凸包。

然而,如果你的问题是关于如何找到一个点集的凸包(这些点不一定构成一个凸多边形),那么有多种算法可以用来解决这个问题。以下是一些常用的算法:

Graham扫描算法(Graham’s Scan Algorithm):

首先,找出点集中Y坐标最小的点,如果有多个点Y坐标相同,则取X坐标最小的点,记为P0。这个点是凸包上的一个顶点。
以P0为基准,将所有点按照它们与P0的连线与X轴的夹角(极角)进行排序。如果夹角相同,则距离P0较远的点排在前面。
使用一个栈来保存凸包上的点。将P0和极角最小的点压入栈中。
遍历排序后的点集(从第三个点开始),对于每个点,进行如下判断:
如果栈顶的两个点(记为P1和P2)与当前点(记为P3)构成的向量是顺时针的,则弹出栈顶元素(P2),并继续检查新的栈顶元素和P3的向量方向,直到栈为空或者向量方向为逆时针。
将当前点P3压入栈中。
栈中的点(除了最初的P0)就是凸包的顶点,按照栈的顺序连接这些点即可得到凸包。

Andrew’s Monotone Chain Algorithm:

类似于Graham扫描算法,但更侧重于处理效率。
它首先按照X坐标对点进行排序(如果X坐标相同,则按Y坐标排序)。
然后,它分别从上到下和从下到上找到两个凸链(凸多边形的一边),最后将这两个凸链合并以形成完整的凸包。

QuickHull 算法:

是一种基于分而治之的算法,适用于大数据集。
它首先找到一个点作为“初始点”,然后从这个点出发,找到距离它最远的点,这两个点之间的连线将点集分为两部分。
接着,在每一部分中递归地找到最远点,并继续分割,直到满足停止条件(如,子集中的点足够少,可以直接计算凸包)。
最后,将所有子集的凸包合并,形成完整的凸包。

每种算法都有其特点和适用场景,你可以根据具体的应用场景和数据规模来选择合适的算法。

凸多边形的凸包问题算法python实现样例

凸多边形的凸包问题可以通过Graham扫描算法来解决。下面是用Python实现的凸包问题算法:

import math

# 计算两个点的极角
def polar_angle(p, q):
    dx = q[0] - p[0]
    dy = q[1] - p[1]
    return math.atan2(dy, dx)

# 计算两个点的距离
def distance(p, q):
    dx = q[0] - p[0]
    dy = q[1] - p[1]
    return math.sqrt(dx**2 + dy**2)

# 判断三个点的转向关系
def orientation(p, q, r):
    val = (q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1])
    if val == 0:
        return 0  # p, q, r共线
    elif val > 0:
        return 1  # 逆时针
    else:
        return 2  # 顺时针

# 找到最下方的点
def find_bottommost(points):
    bottommost = points[0]
    for point in points[1:]:
        if point[1] < bottommost[1]:
            bottommost = point
        elif point[1] == bottommost[1] and point[0] < bottommost[0]:
            bottommost = point
    return bottommost

# 通过极角和距离排序
def sort_points(points, origin):
    def compare(p1, p2):
        angle1 = polar_angle(origin, p1)
        angle2 = polar_angle(origin, p2)
        if angle1 < angle2:
            return -1
        elif angle1 > angle2:
            return 1
        else:
            dist1 = distance(origin, p1)
            dist2 = distance(origin, p2)
            if dist1 < dist2:
                return -1
            elif dist1 > dist2:
                return 1
            else:
                return 0
    
    sorted_points = sorted(points, key=lambda p: (p[0], p[1]))  # 先按x坐标排序
    return sorted(sorted_points, key=lambda p: polar_angle(origin, p), cmp=compare)

# 计算凸包
def convex_hull(points):
    if len(points) < 3:
        return None
    
    bottommost = find_bottommost(points)
    sorted_points = sort_points(points, bottommost)
    
    hull = [sorted_points[0], sorted_points[1]]
    for point in sorted_points[2:]:
        while len(hull) > 1 and orientation(hull[-2], hull[-1], point) != 1:
            hull.pop()
        hull.append(point)
    
    return hull


# 测试
points = [(0, 3), (1, 1), (2, 2), (4, 4), (0, 0), (1, 2), (3, 1), (3, 3)]
hull = convex_hull(points)
print("凸包点集:")
for point in hull:
    print(point)

该算法首先找到最下方的点作为基准点,然后对其余点按照极角和距离进行排序,接下来采用扫描线的方式找到凸包。最后输出凸包的点集。

标签:return,point,python,hull,bottommost,凸多边形,凸包,points
From: https://blog.csdn.net/u010634139/article/details/142909558

相关文章

  • 【Python开发技术之PyQt5精品教学】第36课--PyQt5 拖放功能
    PyQt5拖放功能拖放功能对用户来说非常直观。它被应用于许多桌面应用程序,用户可以将对象从一个窗口复制或移动到另一个窗口。基于MIME的拖放数据传输是基于QDrag类实现的。QMimeData对象将数据与对应的MIME类型关联起来。数据被存储在剪贴板中,然后在拖放过程中使用。以下QMi......
  • 【Python开发技术之PyQt5精品教学】第32课--PyQt5 QDialog类
    PyQt5QDialog类QDialog 是一个顶层窗口小部件,主要用于收集用户的响应。它可以配置为 模态 (它会阻塞其父窗口)或 非模态 (对话框窗口可以被绕过)。PyQt API有许多预配置的对话框小部件,例如InputDialog,FileDialog,FontDialog等。示例在下面的示例中,对话框窗口的 WindowMo......
  • 【Python开发技术之PyQt5精品教学】第24课--PyQt5 QTab小部件
    PyQt5QTab小部件如果一个表单具有太多字段无法同时显示,则可以将它们安排在选项卡窗口小部件的每个选项卡下的不同页面中。提供了一个选项卡栏和一个页面区域。第一个选项卡下的页面会显示,其他页面会隐藏。用户可以通过点击所需的选项卡来查看任何页面。以下是QTabWidget类的......
  • 【Python开发技术之PyQt5精品教学】第31课--PyQt5 QCalendar小工具
    PyQt5QCalendar小工具QCalendar小工具是一个有用的日期选择器控件。它提供了基于月份的视图。用户可以通过鼠标或键盘选择日期,默认为今天的日期。还可以指定日历的日期范围。以下是这个类的一些实用方法:序号方法和描述1setDateRange() :设置可选择的较低和较高日期。2setFi......
  • 烟尘监测识别系统 Python
    烟尘监测识别系统基于先进的AI机器视觉技术,烟尘监测识别系统通过现场已有的监控摄像头对可能发生露天焚烧的重点区域进行实时监测。一旦监测到烟尘,系统将立即触发告警,提醒相关人员及时处理。这一系统的应用,可以有效预防严重的火灾事件,降低火灾事故发生的概率,保护人民生命财产安......
  • Python知识点:基于Python工具,如何使用Web3.py进行以太坊智能合约开发
    开篇,先说一个好消息,截止到2025年1月1日前,翻到文末找到我,赠送定制版的开题报告和任务书,先到先得!过期不候!基于Python工具Web3.py进行以太坊智能合约开发简介智能合约是区块链技术的核心应用之一,它允许在没有中介的情况下,通过代码自动执行合同条款。以太坊是目前最流行的智......
  • Python知识点:基于Python工具,如何使用Brownie进行智能合约测试
    开篇,先说一个好消息,截止到2025年1月1日前,翻到文末找到我,赠送定制版的开题报告和任务书,先到先得!过期不候!如何使用Brownie进行智能合约测试在以太坊智能合约开发中,测试是至关重要的一环。Brownie是一个基于Python的智能合约开发和测试框架,它提供了一套完整的工具来帮助开发......
  • 基于Python的自然语言处理系列(26):Get to the Point Summarization
            在本篇文章中,我们将实现经典的"GettothePoint"模型,该模型最初发表于GettothePoint:SummarizationwithPointer-GeneratorNetworks。这是当时最著名的摘要生成模型之一,至今仍有很多人使用其Pointer-Generator架构作为他们模型的一部分。1.模型简介......
  • python基础知识(十一)面向过程,面向对象,对象属性,魔法方法,继承,私有权限
    目录面向过程是什么什么是面向对象?面向对象的三大特性:继承多态类对象self关键字对象属性类外面访问属性类内部获取属性魔法方法无参init()方法有参init()方法str()方法del()方法继承基础什么是继承单继承多继承继承进阶方法重写调用父类方法多层继承......
  • Python 禅道测试用例助手
    程序及源码下载地址:https://gitee.com/ishouke/zen-tao-testcase-helper实现功能禅道测试用例助手。实现xmind用例导入禅道,支持自动创建产品,模块,删除用例,此外,支持禅道导出的excel用例转xmind用例之后,再导入禅道,实现禅道用例管理闭环使用要求适配xmind版本:xmind8update9(XM......