求任意多边形面积
按逆时针方向依次给出多边形 \(n\) 个顶点,求多边形的面积。
公式:
\[Area=\frac{1}{2}|\sum\limits_{i=1}^{n}\overrightarrow{OP_i}\times \overrightarrow {OP_{i+1}}|
\]
(其中 \(P_{n+1}=P_1\))
不太会证明可以感性理解。任取一点 \(O\),可以发现多边形内的面积被扫过奇数遍,多边形外的面积被扫过偶数遍(其中一正一负抵消)。然后你直接取 \(O\) 在原点很方便。
Upd7.2:在lxm神仙的点拨下好像会证明了。首先你任选多边形外一点 \(O\),发现如果在多边形内一点 \(Q\),\(PQ\) 这条射线一定经过奇数条多边形的边。当你穿出多边形时,你会被这条边的两个端点和点 \(O\) 围成的三角形加上(一定是加因为矢量是逆时针定义的),同样,穿进多边形的时候这个点会被减上一次。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=100009;
const double eps=1e-10;
int n;
struct Point
{
double x,y;
Point() {}
Point(double X,double Y) : x(X),y(Y) {}
Point operator - (const Point a)const { return Point(x-a.x,y-a.y); }
double operator * (const Point a)const { return x*a.y-y*a.x; }
void read() { scanf("%lf %lf",&x,&y); }
void print() { printf("%.2lf %.2lf\n",x,y); }
}a[N],Q;
int nxt(int x) { return x==n?1:x+1; }
void init()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
a[i].read();
}
void work()
{
double area=0;
for (int i=1;i<=n;i++)
area+=(a[i]*a[nxt(i)])/2;
printf("%.2lf\n",area);
}
int main()
{
init();
work();
return 0;
}
由于博主比较菜,所以有很多东西待学习,大部分文章会持续更新,另外如果有出错或者不周之处,欢迎大家在评论中指出!