纯纯的模拟微积分求面积:
首先,我们建立一下坐标系,以两个焦点的中心为原点,焦点连成的直线为x轴建立直角坐标系。(答案里边是这么说的,但是代码里边我感觉x轴只是平行这条直线。。。)不过呢,转平行了,我们可以把它们当成x轴和焦点的直线是重合的,因为吧,最后我们微积分求那个小长方形是要用上边界减下边界的,这样就抵消了。。。
我们这样来做,用一条垂直的线从-1000扫到1000,步长是多少呢,取0.001是可以的,假设分割的小长方形,缺失的那一块是正方形的话,一个就是10^-6,最大是2000/0.001*10^-6=2,虽然是2,但是这题确实可以过。
长方形这样来取,能算进面积的必定是有四个焦点的,椭圆两个,三角形里边两个,上顶点,是分别取y的最大值的较小的一个,下顶点,是分别取y的最小值的较大的那个,然后一直加上来就好了。。。。。。
还有一些数学上的知识(这里焦点只是转平行了应该):
这样去理解就好了。
代码如下所示:
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
double xa, ya, xb, yb, L, A, ans;
double x[6], y[6], Y[6];
double dist(double a, double b, double c, double d){
return sqrt((c - a) * (c - a) + (d - b) * (d - b));
}
double get(double now, int pos1, int pos2){
if(fabs(x[pos1] - x[pos2]) <= eps && fabs(x[pos1] - now) <= eps) return inf;
if(now <= min(x[pos1], x[pos2]) || now >= max(x[pos1], x[pos2])) return inf;
return (y[pos2] - y[pos1]) / (x[pos2] - x[pos1]) * (now - x[pos2]) + y[pos2];
}
bool ok1(double now){
double xx = (xa + xb) / 2, yy = (ya + yb) / 2;
double a = L / 2 , c = dist(xa, ya, xb, yb) / 2;
double b = sqrt(a * a - c * c);
double mid = 1.0 - (now - xx) * (now - xx) / (a * a);
if(mid <= 0) return false;
mid = sqrt(mid) * b;
Y[1] = yy - mid, Y[2] = yy + mid;
return true;
}
bool ok2(double now){
int cnt = 2;
for(int i = 1; i <= 3; i++){
int nex = i + 1 == 4 ? 1 : i + 1;
double mid = get(now, i, nex);
if(mid - 1000 > eps) continue;
if(cnt == 3 && fabs(mid - Y[cnt]) <= eps) continue;
Y[++cnt] = mid;
}
if(cnt != 4) return false;
return true;
}
double get_angle(double a, double b, double c, double d){
double now = acos((c - a) / dist(a, b, c, d));
if(d - b < 0) return 2 * acos(-1) - now;
return now;
}
void init(){
A = get_angle(xa , ya , xb , yb);
double dis1 = dist(0, 0, xa, ya), dis2 = dist(0, 0, xb, yb);
double S1 = get_angle(0, 0, xa, ya) - A, S2 = get_angle(0, 0, xb, yb) - A;
xa = dis1 * cos(S1) , ya = dis1 * sin(S1);
xb = dis2 * cos(S2) , yb = dis2 * sin(S2);
}
void change(int pos){
double dis = dist(0, 0, x[pos], y[pos]);
double S = get_angle(0, 0, x[pos], y[pos]) - A;
x[pos] = dis * cos(S) , y[pos] = dis * sin(S);
}
double calc(double now){
if(!ok1(now)) return 0;
if(!ok2(now)) return 0;
double ma = max(min(Y[1], Y[2]), min(Y[3], Y[4]));
double mi = min(max(Y[1], Y[2]), max(Y[3], Y[4]));
if(mi - ma <= eps) return 0;
return mi - ma;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0) , cout.tie(0);
cin >> xa >> ya >> xb >> yb >> L;
init();
for (int i = 1 ; i <= 3 ; i ++) cin >> x[i] >> y[i] , change(i);
if(L <= eps || dist(xa, ya, xb, yb) >= L) return cout << "0.00\n" , 0;
for(double i = -1000 ; i <= 1000 ; i += 0.001) ans += calc(i) * 0.001;
cout << setprecision(2) << fixed << ans << '\n';
return 0;
}