计算多边形(polygon)面积的算法原理和python实现

计算多边形(polygon)的面积其实很简单,假设是n边形,分割为n-2个三角形,积分别计算每个三角形面积后累加得多边形面积。

如下图所示:

那么如何计算三角形的面积呢?

 △ABC的面积是“向量AB”和“向量AC”两个向量叉乘的绝对值的一半。其正负表示三角形顶点是在右手系还是左手系。

代码如下:

import math
import re
VERTICES_FILE = "vertices.txt"

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def move(self, x, y):
        self.x = x
        self.y = y

    def reset(self):
        self.x = 0
        self.y = 0

    def calculate_distance(self, other_point):
        """计算两点间距离"""
        distance = math.sqrt((self.x - other_point.x) ** 2 + (self.y - other_point.y) ** 2)
        return distance

    def __str__(self):
        return "({},{})".format(self.x, self.y)


class Polygon:
    def __init__(self):
        self.vertices = []
        self.points2vertices()

    def points2vertices(self):
        """读取坐标文件,并转换为顶点对象"""
        with open(VERTICES_FILE, "r", encoding="utf-8") as fr:
            # 定义一个用于切割字符串的正则
            seq = re.compile(",")
            for d in fr.readlines():
                # 读取出来的数据d为字符串,需切割后拼接为列表
                point = seq.split(d.strip())
                # 将列表转为坐标元组,测绘坐标与绘图坐标x,y互换
                point = (float(point[1]), float(point[0]))
                if isinstance(point, tuple):
                    point = Point(*point)
                    self.vertices.append(point)
    
    def perimeter(self):
        perimeter = 0
        points = self.vertices + [self.vertices[0]]
        for i in range(len(self.vertices)):
            perimeter += points[i].calculate_distance(points[i + 1])
        return perimeter

    def area(self):
        """给出任意一个多边形,其顶点坐标依次为(x0,y0),(x1,y1),(x2,y2),...,(xn,yn)(其中n=2,3,4,…),
        则其面积可表示为:

                     |Xi      Yi     |
        AREA = sigma |               | /2
        (i= 0,...n)  |X(i+1)  Y(i+1) |

        """
        n = len(self.vertices)
        if n < 3:
            return 0
        area = 0
        for i in range(n-2):
            # 以第一个坐标点为原点,将多边形分割为n-2个三角形,分别计算每个三角形面积后累加得多边形面积
            area += self.calculate_triangle_area(self.vertices[0], self.vertices[i+1], self.vertices[i+2])
        return abs(area)

    @staticmethod
    def calculate_triangle_area(point_a, point_b, point_c):
        """向量叉乘法计算三角形面积"""
        triangle_area = 0.5*((point_b.x - point_a.x)*(point_c.y - point_a.y) -
                             (point_b.y - point_a.y)*(point_c.x - point_a.x))
        return triangle_area


if __name__ == "__main__":
    polygon1 = Polygon()
    print("面积:{:.3f},周长:{:.3f}".format(polygon1.area(), polygon1.perimeter()))

测试文件1:

975.750000,82.720001
973.500000,82.080002
973.500000,91.360001
975.750000,91.360001
973.500000,91.360001
973.500000,82.080002

测试文件2:

18453.751,114760.926
18449.551,114777.988
18441.985,114777.334
18442.764,114768.321
18444.064,114766.257
18444.309,114766.273
18445.070,114756.212
18448.973,114758.467

 

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EnjoyCodingAndGame

愿我的知识,成为您的财富!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值