题面
给出 N 个点依次构成多边形的顶点,1 <= N <= 1000000
B 为磁感应强度
求区域的磁通量
分析
磁通量=BS,所以问题的关键是用这 N 个点求出多边形。
这里涉及到多边形的面积算法,一般采用向量外积。
因为向量
∣
a
⃗
×
b
⃗
∣
|\vec a ×\vec b|
∣a×b∣=a和b向量构成平行四边形的面积,所以可用这个来计算三角形面积。将原本的多边形用某个点K进行划分,构成一系列三角形即可。其中,这些三角形的一个顶点是 K ,另外两个顶点是相邻的两个多边形顶点。
同时,这个面积是有方向性的,也就是说对于一些凹多边形,这个方式计算出来的结果会抵消不属于多边形的部分,但同时要求计算保证多边形上顶点取的顺序性。
点K可随便取,取一个多边形上的顶点也是可以的
如
K
t
1
⃗
×
K
t
2
⃗
\vec{Kt_{1}}×\vec{Kt_{2}}
Kt1×Kt2 是黄色部分,面积正向。
而之后的
K
t
2
⃗
×
K
t
3
⃗
\vec{Kt_{2}}×\vec{Kt_{3}}
Kt2×Kt3 是负向面积,抵消了一部分黄色,而加入了一部分多边形面积。(多边形内部面积不会被重复抵消)
K
t
3
⃗
×
K
t
4
⃗
\vec{Kt_{3}}×\vec{Kt_{4}}
Kt3×Kt4 使黄色部分完全抵消了,加入了有一部分多边形面积。
计算过程中不区分正负面积,能保证抵消。
所有面积加和完成后进行一次绝对值计算,使有向面积变成绝对值。
代码
#include<iostream>
#include<math.h>
#include<cstdio>
#include<string>
#include<cstring>
#include<iomanip>
using namespace std;
double x[100005], y[100005];//存所有的点x,y坐标
int main()
{
ios::sync_with_stdio(false);
int n;
double B,ans=0.0;
cin >> n >> B;
if (n <= 2) { cout << "0.0000";return 0; }
for (int i = 0; i < n; i++)
{
cin >> x[i] >> y[i];
}
double a1, b1, a2, b2;//vector
for (int i = 1; i < n-1; i++)
{
a1 = x[i] - x[0];//取x[0],y[0]为上面的K点
b1 = y[i] - y[0];
a2 = x[i + 1] - x[0];
b2 = y[i + 1] - y[0];//计算出向量
ans += a1 * b2 - b1 * a2;
}
if (ans < 0)ans = -ans;
ans *= B*0.5;
cout <<fixed<< setprecision(4) << ans;
return 0;
}