两点间距离公式 dis = sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2) + (z1 - z2) * (z1 - z2)); //算球心距离
球体积 4.0 / 3.0 * PI * r * r * r;
球缺体积 PI * h * h *(r - h / 3.0);
typedef long double ld;
const ld pi = acos(-1.0);
int main()
{
//ios::sync_with_stdio(false);
//cin.tie(0); cout.tie(0);
//freopen("D://test.in", "r", stdin);
//freopen("D://test.out", "w", stdout);
ld x1, y1, z1, r1;
ld x2, y2, z2, r2;
scanf("%lf%lf%lf%lf", &x1, &y1, &z1, &r1);
scanf("%lf%lf%lf%lf", &x2, &y2, &z2, &r2);
ld sa = (4.0 / 3.0) * pi * (r1 * r1 * r1);
ld sb = (4.0 / 3.0) * pi * (r2 * r2 * r2);
ld sum = sa + sb;
ld sr = sqrt((x1 - x2)*(x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2));
if(sr + min(r1, r2) <= max(r1, r2))
{
sum = max(sa, sb);
}
else if(sr >= (r1 + r2))
{
sum = sa + sb;
}
else
{
//ld qh = sr - ((sr - r1) + (sr - r2));
ld l1 = ( ((r1 * r1) - (r2 * r2)) / sr + sr) / 2.0;
ld l2 = sr - l1;
ld rx1 = r1 - l1;
ld rx2 = r2 - l2;
sum -= (pi * rx1 * rx1 * (r1 - rx1 / 3.0)); //球R1球缺体积
sum -= (pi * rx2 * rx2 * (r2 - rx2 / 3.0)); //球R2球缺体积
}
printf("%lf\n", sum + 0.0000000001);
return 0;
}
附上过不了题的标准模板, 但是计算方式还是可以借鉴一下的
void SphereInterVS(sphere a, sphere b,double &v,double &s) {
double d = dist(a.centre, b.centre);//球心距
double t = (d*d + a.r*a.r - b.r*b.r) / (2.0 * d);//
double h = sqrt((a.r*a.r) - (t*t)) * 2;//h1=h2,球冠的高
double angle_a = 2 * acos((a.r*a.r + d*d - b.r*b.r) / (2.0 * a.r*d)); //余弦公式计算r1对应圆心角,弧度
double angle_b = 2 * acos((b.r*b.r + d*d - a.r*a.r) / (2.0 * b.r*d)); //余弦公式计算r2对应圆心角,弧度
double l1 = ((a.r*a.r - b.r*b.r) / d + d) / 2;
double l2 = d - l1;
double x1 = a.r - l1, x2 = b.r - l2;//分别为两个球缺的高度
double v1 = PI*x1*x1*(a.r - x1 / 3);//相交部分r1圆所对应的球缺部分体积
double v2 = PI*x2*x2*(b.r - x2 / 3);//相交部分r2圆所对应的球缺部分体积
v = v1 + v2;//相交部分体积
double s1 = PI*a.r*x1; //r1对应球冠表面积
double s2 = PI*a.r*x2; //r2对应球冠表面积
s = 4 * PI*(a.r*a.r + b.r*b.r) - s1 - s2;//剩余部分表面积
}