zoj3500

求两个球的体积交或者并

#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;
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值