【计算几何】给定一组点的多边形面积

目录

  • 一、说明
  • 二、有序顶点集
  • 三、无序顶点集
    • 3.1 凸多边形
    • 3.2 非凸多边形
  • 四、结论

一、说明

   计算多边形面积的方法有很多种。众所周知的多边形(如三角形、矩形、正方形、梯形等)的面积可以使用简单的数学公式计算。在这篇文章中,我将讨论如何计算给定顶点集的多边形面积。这里讨论的方法适用于大多数没有孔的多边形。

二、有序顶点集

   如果多边形的顶点按顺时针或逆时针方向排列,则可以使用鞋带算法计算面积。该公式可以用表达式表示


A = 1 2 ∣ ∑ i = 1 n − 1 x i y i + 1 + x n y 1 − ∑ i = 1 n − 1 x i + 1 y i − x 1 y n ∣ A = \frac{1}{2}\left|\sum_{i = 1}^{n-1}x_iy_{i+1}+x_ny_1 - \sum_{i = 1}^{n - 1}x_{i + 1}y_i - x_1y_n\right| A=21 i=1n1xiyi+1+xny1i=1n1xi+1yix1yn

   使用此公式的唯一条件是顶点必须按顺时针或逆时针方向排序,否则面积将不正确。这是该算法的Python实现。

# Shoelace formula to calculate the area of a polygon
# the points must be sorted anticlockwise (or clockwise)def polygon_area(vertices):psum = 0nsum = 0for i in range(len(vertices)):sindex = (i + 1) % len(vertices)prod = vertices[i].x * vertices[sindex].ypsum += prodfor i in range(len(vertices)):sindex = (i + 1) % len(vertices)prod = vertices[sindex].x * vertices[i].ynsum += prodreturn abs(1/2*(psum - nsum))

   列表顶点包含 Point 类型的对象列表。点是表示 2D 平面中的点的数据结构。表示一个点的Python代码是

class Point:def __init__(self, x, y):self.x = xself.y = ydef __str__(self):return '(' + str(self.x) + ', ' + str(self.y) + ')'

   下面的代码片段测试了上面的代码。

if __name__ == '__main__':points = [Point(0, 0), Point(5, 0), Point(5, 5), Point(0, 5)]print polygon_area(points) # prints 25

三、无序顶点集

   如果顶点不是顺时针或逆时针排列的,那么计算面积可能会有点棘手。这意味着,在调用 之前,我们需要按顺时针或逆时针polygon_area(points)排序。points为了对顶点进行排序,我们需要一个完全位于多边形内部的参考点。有了参考点后,我们计算参考点与每个顶点之间的角度,并按升序或降序对它们进行排序。现在的问题是,我们如何找到参考点呢?答案很简单“这取决于多边形的类型”。

3.1 凸多边形

   如果多边形是凸多边形,即所有内角都小于或等于的多边形18001800,多边形内的任何点都可以是给出完全相同面积的参考点,即无论参考点位于多边形内的哪个位置,面积在所有情况下都是相同的。这是因为参考点的选择不会改变凸多边形的形状。在这种情况下,我们可以简单地平均X 和y 坐标来找到参考点。这可以很容易地计算出来,如下面的代码所示。

# returns the average x and y coordinates of all the points
def average_point_inside(points):x = 0y = 0for point in points:x += point.xy += point.yreturn Point(x / len(points), y / len(points))

3.2 非凸多边形

   对于非凸多边形,参考点的选择会改变多边形的形状,因此不同的参考点可能会得到不同的面积。因此,如果多边形不是凸多边形,那么在顶点未排序的情况下求面积没有任何意义。

   一旦我们有了参考点(仅对凸多边形有意义),我们就可以根据参考点与每个顶点与 x 轴逆时针方向连接的线段所成的角度对所有顶点进行排序如下图所示,下面的代码计算参考点和顶点与x轴的连线之间的角度(以弧度为单位)。
在这里插入图片描述

# returns the angle made by a line segment
# connecting p1 and p2 with x-axis in the anticlockwise direction
def angle(p1, p2):k = (p2.y - p1.y) / distance(p1, p2)x2 = p2.xx1 = p1.xif k >= 0:if x2 >= x1: # First Quadrantreturn (2.0 * math.pi - math.asin(k))else: # Second Quadrantreturn (math.pi + math.asin(k))else:if x2 >= x1: # Fourth Quadrantreturn math.asin(-k)else: # Third Quadrantreturn (math.pi - math.asin(-k))

   sorted我们可以使用标准Python库的方法对顶点进行排序。这里的技巧是我们传递根据角度比较点的比较器。

# angularly sort the points anticlockwise
def sort_angular(points, reference_point):return sorted(points, key = lambda point: -angle(point, reference_point))

   现在我们完成了。我们将排序后的点传递到polygon_area给出正确面积的函数中。下面的代码片段测试了上面的代码。

if __name__ == '__main__':points = [Point(0,3), Point(2, 4), Point(3,1), Point(4,3), Point(3, 5), Point(1, 1)]reference_point = average_point_inside(points)spoints =  sort_angular(points, reference_point)print polygon_area(spoints) # prints 9

四、结论

   在这篇文章中,我讨论了如何计算给定一组顶点的面积。如果顶点是有序的,则可以使用鞋带公式计算面积。如果顶点没有排序,则将顶点排序后即可计算面积,只有多边形是凸多边形时才是准确的。如果多边形不是凸的,则该方法可能有效,也可能无效。最后,提供了实现所讨论的所有方法的 python 代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2780197.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

《UE5_C++多人TPS完整教程》学习笔记2 ——《P3 多人游戏概念(Multiplayer Concept)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P3 多人游戏概念(Multiplayer Concept)》 的学习笔记,该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版,UP主(也是译…

图灵日记--MapSet字符串常量池反射枚举Lambda表达式泛型

目录 搜索树概念实现性能分析和 java 类集的关系 搜索概念及场景模型 Map的使用Map常用方法 Set的说明常见方法说明 哈希表冲突-避免-负载因子调节冲突-解决-闭散列冲突-解决-开散列/哈希桶冲突严重时的解决办法 实现和 java 类集的关系 字符串常量池String对象创建intern方法 …

SpringCloud-Eureka服务注册中心测试实践

5. Eureka服务注册中心 5.1 什么是Eureka Netflix在涉及Eureka时,遵循的就是API原则.Eureka是Netflix的有个子模块,也是核心模块之一。Eureka是基于REST的服务,用于定位服务,以实现云端中间件层服务发现和故障转移,服…

Junit5基础教程

文章目录 一,导入依赖二,基本功能一、常用断言二、执行顺序和常用注解1、通过BeforeAll类的注解来保证顺序2、通过order注解来保证执行顺序 三、依赖测试四、参数化测试五、测试套件SelectPackages、IncludePackages、SelectClasses、IncludeTags等注解的…

C语言printf函数详解..

1.printf函数解析 前面我们有讲过printf函数的格式为: printf(“占位1 占位2 占位3……”, 替代1, 替代2, 替代3……); 今天我们进一步深入的解析一下这个函数 2.printf函数的特点 1.printf函数是一个变参函数(即参数的数量和类型都不确定) 2.printf函数的第一个…

【MySQL】——数值函数的学习

🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​💫个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-Z1fAnfrxGD7I5gqp {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

bugku 1

Flask_FileUpload 文件上传 先随便传个一句话木马 看看回显 果然不符合规定 而且发现改成图片什么的都不行 查看页面源代码,发现提示 那应该就要用python命令才行 试试ls 类型要改成图片 cat /flag 好像需要密码 bp爆破 根据提示,我们先抓包 爆破 …

ChatGPT高效提问—prompt常见用法(续篇九)

ChatGPT高效提问—prompt常见用法(续篇九) ​ 如何准确地向大型语言模型提出问题,使其更好地理解我们的意图,从而得到期望的答案呢?编写有效的prompt的技巧,精心设计的prompt,获得期望的的答案。 1.1 增加条件 ​ 在各种prompt技巧中,增加条件是最常用的。在prompt中…

MOMENTUM: 1

攻击机 192.168.223.128 目标机 192.168.223.146 主机发现 nmap -sP 192.168.223.0/24 端口扫描 nmap -sV -p- -A 192.168.223.146 开启了22 80端口 看一下web界面 随便打开看看 发现这里有个参数id,sql尝试无果,发现写入什么,网页显示…

【数据结构】11 堆栈(顺序存储和链式存储)

定义 可认为是具有一定约束的线性表,插入和删除操作都在一个称为栈顶的端点位置。也叫后入先出表(LIFO) 类型名称:堆栈(STACK) 数据对象集: 一个有0个或者多个元素的有穷线性表。 操作集&#…

Obsidian Publish的开源替代品Perlite

前几天就有网友跟我说,freenom 的免费域名不可用了,10 号的时候老苏进后台看了一下,还有一半的域名显示为 ACTIVE,似乎是以 2024年6月 为限。但到 11 号,老苏发现博客 (https://laosu.cf) 已经访问不了了,这…

【Linux】信号保存与信号捕捉处理

信号保存与信号捕捉 一、信号保存1. 信号的发送2. 理解信号保存(1)信号保存原因(2)信号保存概念 3. 信号保存系统接口(1)sigset_t(2)sigprocmask()(3)sigpend…

GraphicsMagick 的 OpenCL 开发记录(三十七)

文章目录 如何写ScaleImage()的硬件加速函数&#xff08;十一&#xff09; <2022-05-06 周五> 如何写ScaleImage()的硬件加速函数&#xff08;十一&#xff09; “如何写ScaleImage()的硬件加速函数&#xff08;十&#xff09;”这里的代码写得比较随意&#xff0c;其中…

vscode远程连接失败

目录 解决方案尝试1解决方案尝试2 解决方案尝试1 最近通过vscode一直使用腾讯云的服务器作为远程开发环境&#xff0c;以前一直很好用。 直到最近重装了系统之后&#xff0c;发现vscode没法对云服务器进行连接了&#xff0c;即使在远程主机添加了本地的公钥也不行。直接报错:…

python-自动化篇-终极工具-用GUI自动控制键盘和鼠标-pyautogui

文章目录 用GUI自动控制键盘和鼠标pyautogui 模块鼠标屏幕位置——移动地图——pyautogui.size鼠标位置——自身定位——pyautogui.position()移动鼠标——pyautogui.moveTo拖动鼠标滚动鼠标 键盘按下键盘释放键盘 开始与结束通过注销关闭所有程序 用GUI自动控制键盘和鼠标 在…

springboot178智能学习平台系统

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

正则可视化工具:学习和编写正则表达式的利器

引言 正则表达式是一种强大的文本匹配和处理工具&#xff0c;但对于初学者和非专业开发者来说&#xff0c;编写和理解正则表达式可能是一项具有挑战性的任务。为了帮助人们更好地学习和编写正则表达式&#xff0c;正则可视化工具应运而生。本文将探讨正则可视化工具的优点&…

Infuse通过Alist添加115网盘资源

说明 通过Alist代理管理115网盘&#xff0c;Infuse再添加Alist代理的115网盘的WebDAV 准备一台Linux服务器安装Alist 我这里用的华为云CentOS7&#xff0c;使用Docker容器 安装Alist docker run -d --restartalways -v /etc/alist:/opt/alist/data -p 5244:5244 -e PUID0 …

Javaweb之SpringBootWeb案例之事务进阶的详细解析

1.3 事务进阶 前面我们通过spring事务管理注解Transactional已经控制了业务层方法的事务。接下来我们要来详细的介绍一下Transactional事务管理注解的使用细节。我们这里主要介绍Transactional注解当中的两个常见的属性&#xff1a; 异常回滚的属性&#xff1a;rollbackFor 事…

Days28 ElfBoard 板]修改开机动画

1.可能需要安装的库 elfubuntu:~/work/psplash$ sudo apt-get install build-essential libncurses5-dev elfubuntu:~/work/psplash$ sudo apt-get install libtool elfubuntu:~/work/psplash$ sudo apt-get install gettext elfubuntu:~/work/psplash$ sudo apt-get install l…