求凸多边形的面积
碰到这个问题的时候,我第一个想到的是固定凸多边形的一个点,然后枚举所有边与它组成三角形,最后计算三角形的面积和。知道如如何用鞋带公式求三角形的面积后,我写出了以下代码:
// 鞋带公式求三角形面积
double area(std::array<i64, 2> &u, std::array<i64, 2> &v, std::array<i64, 2> &w) {
return std::abs((u[0] * (v[1] - w[1]) + v[0] * (w[1] - u[1]) + w[0] * (u[1] - v[1])));
}
double get() {
double S = 0;
for (int i = 2; i < n; i++) {
S += area(a[0], a[i - 1], a[i]);
}
return S / 2.0;
}
只能说这个实现可以,但不是那么简洁。
看题解的时候又看到了一个可以认为是 三角形鞋带公式 向 求任意多边形面积的公式 的推广:
double get() {
double S = 0;
for (int i = 0; i < n; i++) {
int j = (i + 1) % n;
S += (a[i].x * a[j].y - a[j].x * a[i].y);
}
return S / 2.0
}
从代码表现上来看,\(S\) 每次的增量似乎是两个点之间的叉积。但两个点怎么有叉积?其实并非两个点,而是从原点 \((0, 0)\) 到两个点的向量,改成这样就好看一些:
double get() {
double S = 0;
for (int i = 0; i < n; i++) {
int j = (i + 1) % n;
S += ((a[i].x - 0) * (a[j].y - 0) - (a[j].x - 0) * (a[i].y - 0));
}
return S / 2.0
}
但是实际实现时没必要。
需要注意的是,下面两端代码需要保证多变形上的点是以逆时针的顺序给出的,如果是以顺时针顺序给出,则最后的结果要取相反数
浙公网安备 33010602011771号