我们通常会使用多个点序列来表示一个多边形。这些点都是按照一定的顺序(顺时针或者逆时针)来排列的。那么,已知这么一个多边形,怎么计算这个多边形的面积呢?
如下图:
我们首先需要计算绿色部分的面积,绿色部分的面积可以看成 4 个直角梯形的面积之和,按照梯形的面积公式,最左边的那个直角梯形面积为:
其余 3 个的面积也是这么算的,即绿色部分的面积为:
但是,这个绿色部分的面积并不是我们最终需要的面积,我们还得减掉下面的面积,如图,红色部分的面积需要减掉:
和上面的计算方法一样,红色部分的面积就是 3 个红色的梯形的面积之和。我们添加第八个点,它和第一个点的坐标一样,这样,我们就可以应用计算公式如下:
最终,我们需要计算的面积就是绿色的面积减去红色的面积。即:
我们发现,绿色面积和红色面积的公式就差 x 上的一个符号,我们可以交换下符号,保持公式的一致,即:
此时,公式就很简洁了,对于任意多边形,其面积为:
注意,这个计算结果根据你给的点的顺序(顺时针还是逆时针)是有关系的,所以,如果顺序不一致(上面的公式是按照顺时针推导的),就会出现结果为负数的情况,所以,最终的计算中还需要取一下绝对值。
下面,贴上 Python 的实现代码:
def calculate_area(pts: list[Point]) -> float:
"""
计算多边形的面积,无论凸凹。
注意,传入的坐标默认单位 1 米,如果是经纬度请自行转换。
"""
area = 0
# 计算面积的点必须至少 3 个
if len(pts) < 3:
raise RuntimeError('pts length should be at least 3')
# 点序列要求首尾连接,如果最后一个点不是第一个点,需要补齐
if pts[-1] != pts[0]:
pts.append(pts[0])
for i in range(0, len(pts) - 1):
x0, y0 = pts[i].x, pts[i].y
x1, y1 = pts[i+1].x, pts[i+1].y
area += x0 * y1 - x1 * y0
return abs(area * 0.5)