📅  最后修改于: 2023-12-03 15:11:39.370000             🧑  作者: Mango
在计算机图形学中,给定三个点的坐标,我们可以计算出由这三个点构成的三角形的面积。如果在平面直角坐标系中给出一组点,如何计算由这些点构成的多边形的最小面积呢?接下来,我们将会介绍两种解决方案。
Shoelace 公式(鞋带公式)最初是由古希腊数学家做广义概率论的 Archimedes 提出的。它被称为“鞋带公式”,是因为它只需要知道多边形各个顶点的坐标,及其按逆时针顺序连接时的顺序就可以计算任意多边形面积。
算法总体思路:
标准库中 sample:
def shoelace_formula(points: List[Tuple[float, float]]) -> float:
n = len(points)
twice_area = 0.0
for i in range(n):
j = (i + 1) % n
twice_area += points[i][0] * points[j][1] - points[j][0] * points[i][1]
return abs(twice_area) / 2.0
向量的叉积是计算一个向量和另一个向量之间形成的平行四边形(把向量两个首尾相连形成的图形)的有向面积时产生的。使用叉积计算多边形面积的算法很容易实现。
我们仍然可以从任意点出发,以逆时针顺序遍历所有多边形的点。当遍历每一条边时,将其转换为向量,记录这个向量的起点和终点(当然,我们已经按逆时针顺序进行了遍历)。
用两个向量 u 和 v 来表示平面上的一条线段,可以将这条线段所对应的平行四边形的面积写为:
$$A = |u \times v| = |u| |v| \sin \theta$$
其中 $\theta$ 为 u 和 v 的夹角,向量 $\times$ 表示向量的叉积运算。通过将所有两条相邻边所对应向量的面积进行累加即可得到原多边形的面积。用向量计算多边形面积的算法复杂度为 $O(n)$。
标准库中 sample:
def vector_cross_area(points: List[Tuple[float, float]]) -> float:
# 先计算多边形重心,方便后面计算向量
sx, sy, area = 0.0, 0.0, 0.0
n = len(points)
for i in range(n):
j = (i + 1) % n
t = points[i][0] * points[j][1] - points[j][0] * points[i][1]
area += t
sx += (points[i][0] + points[j][0]) * t
sy += (points[i][1] + points[j][1]) * t
area /= 2.0
sx /= 6.0 * area
sy /= 6.0 * area
# 计算向量和叉积
s = 0.0
for i in range(n):
j = (i + 1) % n
s += (points[i][0] - sx) * (points[j][1] - sy) - (points[j][0] - sx) * (points[i][1] - sy)
return abs(s) / 2.0
以上介绍了两种计算给定三个点的多边形的最小面积的方法。Shoelace 公式更加简单易懂,但它的时间复杂度为 $O(n \log n)$,并且容易出现精度误差。向量计算法复杂度更低,而且数学上更加稳定。可以根据不同的需要选择不同的方法。