任意多边形的面积公式

前置芝士$:$向量及其的基本运算,如叉积(叉积运算下面用符号^表示)。

对于一个已知三点坐标的三角形,其面积是可以算出来的。

设点$c$为原点$(0,0)$

$S_{\Delta}=\frac{|\vec{a}|\times |\vec{b}|\times\sin (\theta)}{2}=\frac{\vec{a}~\hat{}~\vec{b}}{2}=\frac{\left|x_{1}\times y_{2}-x_{2}\times y_{1}\right|}{2}$

对于任意多边形

$S=\frac{\left| \sum_{1}^{n-1}(x[i]\times y[i+1]-x[i+1]\times y[i])+x[n]\times y[1]-x[1]\times y[n]\right|}{2}$

$ps:$注意绝对值不要忘。

来张图

在网上并没有找到什么严格的证明,但是如果自己手玩过就会发现这样做是对的。

其中标出的$a$部分(不包括多边形本身)被重复算了两次,一次加,一次减,而多边形本身只被算了一次,符合题意。

如果点的坐标不是按顺序依次给出的又该怎么办呢?

$1.$所给多边形为凹包(或者不给说明,凸包和凹包都有可能):

如果点不是按照顺序依次给出的,那么所构成的多边形一定不唯一(画画就明了),所以点一定是按顺序给出的

$2.$所给多边形为凸包:

我们可以先将点按极角排序,就可套用公式了,(凸包的点极角排序后多边形的顶点是依次有序的,且多边形一定是唯一的)

例题P2785 物理1(phsic1)- 磁通量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <bits/stdc++.h>
#define int long long
#define re register
#define inf 0x3f3f3f3f
#define N 2000900
#define sqr(x) ((x)*(x))
#define eps 1e-6
using namespace std;
struct point{
double x,y;
friend point operator -(point a,point b){
return (point){b.x-a.x,b.y-a.y};
}
friend double operator ^(point a,point b){
return a.x*b.y-a.y*b.x;
}
}p[N],s;
inline int read(){
int x=0,w=0;char ch=getchar();
while (!isdigit(ch))w|=ch=='-',ch=getchar();
while (isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return w?-x:x;
}
inline bool cmp(point a,point b){
return ((a-s)^(b-s))>0;
}
double ans,b;
signed main(){
int n=read();scanf("%lf",&b);
scanf("%lf%lf",&p[0].x,&p[0].y);
for (int i=1;i<n;++i)scanf("%lf%lf",&p[i].x,&p[i].y);
for (int i=0;i<n-1;++i)ans+=(p[i]^p[i+1]);
ans+=p[n-1]^p[0];
printf("%.4lf\n",ans*b*0.5);
return 0;
}