E.球的体积并
链接:https://ac.nowcoder.com/acm/contest/373/E
题解:先判断一下两个球不相交以及包含的关系,比较好考虑,然后就是两个球有交集的时候,
主要就是求两个弧面对应的高,可以设夹角,然后利用cos角的关系就是余玄定理表示对应的高,最后就是求相交的体积,得出结果。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<string>
using namespace std;
#define PI acos(-1)//不能用acos
typedef double db;
db dis(db x1, db y1, db z1, db r1, db x2, db y2, db z2, db r2){
db len = sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1) + (z2 - z1)*(z2 - z1));
return len;
}
db x1, x2, y, y2, z1, z2, r1, r2;//用了y1会报错?
int main(){
cin >> x1 >> y >> z1 >> r1;
cin >> x2 >> y2 >> z2 >> r2;
db len = dis(x1, y, z1, r1, x2, y2, z2, r2);
if (len + r1 <= r2)//r1在r2内
printf("%.7lf\n", 4.0*PI*(r2*r2*r2) / 3);
else if (len + r2 <= r1)//r2在r1内
printf("%.7lf\n", 4.0*PI*(r1*r1*r1) / 3);
else if (len >= r1 + r2)
printf("%.7lf\n", 4.0*PI*(r1*r1*r1 + r2*r2*r2) / 3);
else{
//设r1与圆心连线的夹角为t,cost=(r1*r1+len*len-r2*r2)/(2*r1*len);
//r1圆对应半球的高为h1=r1*(1-cost);
//h1=r1-(r1*r1+len*len-r2*r2)/(2*len);
//此时可求h2;
db h1 = r1 - (r1*r1 + len*len - r2*r2) / (2 * len);
db h2 = r1 + r2 - len - h1;
db sum1 = 4.0*PI*(r1*r1*r1 + r2*r2*r2) / 3;
db sum2 = (PI / 3)*((3 * r1 - h1)*h1*h1 + (3 * r2 - h2)*h2*h2);//减去的体积
printf("%.7lf\n", sum1 - sum2);
}
return 0;
}