【题目大意】:给出两个球心坐标及半径,求球交
【解题思路】:圆缺公式~~模版测试
【代码】:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
const double pi = 3.14159265358979323846;
const double eps = 1e-10;
struct Point
{
double x,y,z;
}d[2];
double get_v(double R, double h)
{
return pi*R*h*h - 1/3.0*pi*h*h*h;
}
double ball(double r)
{
return 4.0/3.0 * pi * r*r*r;
}
double cal(double r1, double r2, double dis) {
return (r1 * r1 - r2 * r2 + dis * dis) / (2 * dis);
}
int main()
{
int n;
double r1, r2;
scanf("%d", &n);
while (n--)
{
scanf("%lf%lf%lf%lf", &d[0].x, &d[0].y, &d[0].z, &r1);
scanf("%lf%lf%lf%lf", &d[1].x, &d[1].y, &d[1].z, &r2);
double dis = sqrt((d[0].x-d[1].x)*(d[0].x-d[1].x) + (d[0].y-d[1].y)*(d[0].y-d[1].y)
+(d[0].z-d[1].z)*(d[0].z-d[1].z));
if (dis >= r1 + r2) printf("%.2f\n", ball(r1) + ball(r2));
else
{
if (dis - (max(r1,r2)-min(r1,r2)) <= eps) printf("%.2f\n", ball(max(r1,r2)));
else
{
double ans = ball(r1) + ball(r2);
double x1 = cal(r1, r2, dis);
double v1 = get_v(r1, r1-x1);
double v2 = get_v(r2, r2-dis+x1);
ans -= (v1 + v2);
printf("%.2f\n", ans);
}
}
}
return 0;
}