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

目录

  • 一、说明
  • 二、有序顶点集
  • 三、无序顶点集
    • 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://www.hqwc.cn/news/464850.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql Day04

mysql体系结构 连接层服务层引擎层(索引)存储层 存储引擎 存储引擎是基于表建立的,默认是innoDB show create table tb; 查看当前数据库支持的存储引擎 show engines; InnoDB 特点 DML(数据增删改)遵循ACID模…

重温阿里云宝塔面板部署前后端项目

首先祝大家新年快乐啊! 回到老家,便打算趁这一段空闲时间提升一下自己,重点是学习实践一下echarts相关内容,很多公司项目都需要实现可视化,所以在bilibili上找了黑马的一个教程开始学习,不同的是&#xff…

【CTFshow】VIP题目限免 通关

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收藏…

【java基础题型】录入3位数,求每一位是?

\t 制表符,用于整到8个格子 Scanner类,导入Scanner包(1),代码里导入Scanner类写录入,调用录入的对象的方法 通用求个位数,%10即可,余数不会小于除数 package java录入3位数;import java.util.Scanner; …

CC++内存管理

1、C&C++内存分布 如上代码中各变量的存储区域。 1. 栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。 2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口 创建共享共享内存,做进程间通信。 3. 堆用于程序运行时动态…

静态时序分析:建立时间分析

静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 在静态时序分析中,建立时间检查约束了触发器时钟引脚(时钟路径)和输入数据引脚(数据路径)之间的时序关系&#x…

《21天精通IPv4 to IPv6》第3天:IPv6地址配置——如何为不同的系统配置IPv6?

博主猫头虎的技术世界 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接: 🔗 精选专栏: 《面试题大全》 — 面试准备的宝典!《IDEA开发秘籍》 — 提升你的IDEA技能!《100天精通鸿蒙》 …

实现自定义标记

实现自定义标记 问题陈述 New Tech Book的高级管理层决定在其用JSP设计的应用程序的所有页面上显示版权信息。它们还要去如何向应用程序中添加JSP页面,可以重用显示版本信息的代码。公司的软件开发人员Jerry Smith决定用自定义标记来创建应用程序的这一部分。 解决方案 要解…

2024 年 5 款适用于免费 iPhone 数据恢复的工具软件

搜索一下,你会发现许多付费或免费的iPhone数据恢复工具声称它们可以帮助你以很高的成功率找回所有丢失的数据。然而,这正是问题所在。真的很难做出选择。为了进一步帮助您解决数据丢失问题,我们在此列出了 5 款最好的免费 iPhone 恢复软件供您…

Educational Codeforces Round 135 (Rated for Div. 2)C. Digital Logarithm(思维)

文章目录 题目链接题意题解代码 题目链接 C. Digital Logarithm 题意 给两个长度位 n n n的数组 a a a、 b b b,一个操作 f f f 定义操作 f f f为, a [ i ] f ( a [ i ] ) a [ i ] a[i]f(a[i])a[i] a[i]f(a[i])a[i]的位数 求最少多少次操作可以使 …

【Linux系统学习】6.Linux系统软件安装

实战章节:在Linux上部署各类软件 前言 为什么学习各类软件在Linux上的部署 在前面,我们学习了许多的Linux命令和高级技巧,这些知识点比较零散,进行练习虽然可以基础掌握这些命令和技巧的使用,但是并没有一些具体的实…

日本的便宜服务器有哪些?

年底之际,无非是云服务器优惠的黄金时期,对于个人用户和独立开发者来说,无论你是搭建个人网站还是个人博客,现在都是行动的好时机。那么,对于这时要入手日本服务器的用户,该怎么找便宜厂商呢?这…