纪念做出来的第一道计算几何题

题意:给出两个球的圆心坐标,半径,求出它们的体积并

分:一.外切,相离  二. 内切,内含  三.相交               三种情况来写。其中相交的时候求出两个球的体积并相加,由于球冠部分被多加了一次,所以要计算出两个球的球冠体,然后减去。直接上代码

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;

const double pi=acos(-1);

struct ball{
    double x,y,z,r;
    ball(double x=0,double y=0,double z=0,double r=0):x(x),y(y),z(z),r(r){}
    double dist(ball a){
        return sqrt((x-a.x)*(x-a.x)+(y-a.y)*(y-a.y)+(z-a.z)*(z-a.z)); 
    }
    
    double v()
    {
        return pi*r*r*r*4/3;
    }
}a,b;

double solve()
{
    double d=a.dist(b);
    if(d-a.r-b.r>=0) return a.v()+b.v();
    double r1=a.r,r2=b.r;
    if(d+r1<=r2||d+r2<=r1) return max(a.v(),b.v());
    double v1=pi/3*(r1-(r1*r1-r2*r2+d*d)/(2*d))*(r1-(r1*r1-r2*r2+d*d)/(2*d));//计算球冠体的公式
    v1 *= 3*r1- (r1-(r1*r1-r2*r2+d*d)/(2*d));
    double v2=pi/3*(r2-(r2*r2-r1*r1+d*d)/(2*d))*(r2-(r2*r2-r1*r1+d*d)/(2*d));
    v2 *= 3*r2- (r2-(r2*r2-r1*r1+d*d)/(2*d));
    return a.v()+b.v()-(v1+v2);
}
int main()
{
    cin>>a.x>>a.y>>a.z>>a.r;
    cin>>b.x>>b.y>>b.z>>b.r;
    printf("%.7f\n",solve());
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/rainyskywx/p/10463026.html
今日推荐