求两个球的体积交或者并
#include <cstdio> #include <cmath> #include <algorithm> using namespace std; const double pi=acos(-1.); struct point3{ double x, y, z; }; struct sph{ point3 c; double r; void read(){ scanf("%lf%lf%lf%lf", &c.x, &c.y, &c.z, &r); } }; double dist(point3 a, point3 b){ return sqrt(pow(a.x-b.x, 2.)+pow(a.y-b.y, 2.)+pow(a.z-b.z, 2.)); } //计算球的体积 double sphArea(sph s){ return 4*pi*s.r*s.r*s.r/3; } //计算到s的球心的距离为d的平面横截求s得到的小球冠的体积 double crownArea(sph s, double d){ return pi*(s.r*s.r*(s.r-d)-(s.r*s.r*s.r-d*d*d)/3); } //计算三角形面积的平方,输入三边长 double trianArea(double a,double b,double c){ double s=(a+b+c)/2; return s*(s-a)*(s-b)*(s-c); } //求两个求相交部分的体积 double interArea(sph a, sph b){ if(a.r>b.r) swap(a, b); double d=dist(a.c, b.c); if(d+a.r<=b.r) return sphArea(a); if(d>=a.r+b.r) return 0.; double ans=0., s, h, tmp; s=trianArea(a.r, b.r, d); h=4*s/(d*d); tmp=crownArea(a, sqrt(a.r*a.r-h)); if(a.r*a.r+d*d-b.r*b.r<0.) tmp=sphArea(a)-tmp; ans+=tmp; tmp=crownArea(b, sqrt(b.r*b.r-h)); if(b.r*b.r+d*d-a.r*a.r<0.) tmp=sphArea(b)-tmp; ans+=tmp; return ans; } int main(){ //freopen("in.txt", "r", stdin); int t; scanf("%d", &t); sph a, b; while(t--){ a.read(); b.read(); double ans=sphArea(a)+sphArea(b)-interArea(a, b); printf("%.2lf\n", ans); } return 0; }