CCPC-Wannafly Winter Camp Day2 (Div2, onsite) HCosmic Cleaner

知识点:球

球缺属于几何体,是指用一个平面去截一个球所得的部分,是“体”的概念。而球冠只是个“面”的概念,是指一个球面被一个平面所截得的部分。
因此,球缺可以计算体积;而球冠只能计算面积。

对以c1为球心、半径为r1的球而言:高度为l1的几何体是球缺,高度为x1的几何体也是球缺。
在这里插入图片描述
利用余弦定理,即可求出l1的长度
则x1=r1-l1
百度的计算球缺公式及证明
所以,我们要计算上面那部分高为H的球缺体积时,自己带入即可。

我们要计算两个球体相交的面积时,直接把两个球缺的体积相加即可

题目 Cosmic Cleaner

传送门:求两球相交部分体积

AC代码

#include
#include
#include
#include
using namespace std;
const int inf=0x3f3f3f3f;
const double PI = acos(-1.0);
typedef unsigned long long ll;
const int maxn= 110;
typedef struct point {//三维点double x,y,z;point() {}point(double x, double y,double z):x(x),y(y),z(z){}point operator -(const point &b)const{return point(x - b.x, y - b.y,z-b.z);}point operator +(const point &b)const{return point(x + b.x, y + b.y,z+b.z);}point operator *(const double &k)const{return point(x * k, y * k,z*k);}point operator /(const double &k)const{return point(x / k, y / k,z/k);}double operator *(const point &b)const{return x*b.x + y*b.y+z*b.z;}
}point;double dist(point p1, point p2) {//计算平面上两点距离return sqrt((p1 - p2)*(p1 - p2));
}
typedef struct sphere //球
{double r;point centre;
}sphere;
sphere s,a[maxn];
void SphereInterVS(sphere a, sphere b,double &v,double &s) //求两球相交体积,面积
{double d = dist(a.centre, b.centre);//球心距double l1 = ((a.r*a.r - b.r*b.r) / d + d) / 2;//两个球冠高度double l2 = d - l1;double x1 = a.r - l1;//分别为两个球缺的高度double 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;//剩余部分表面积
}
int t, n;
double x, y, z, r;
int cas = 1;
int main()
{cin >> t;while(t--){cin >> n;for(int i = 1; i <= n; i++){scanf("%lf%lf%lf%lf",&x,&y,&z,&a[i].r);a[i].centre = {x,y,z};}scanf("%lf%lf%lf%lf",&x,&y,&z,&r);s.r = r;s.centre = {x,y,z};double ans = 0, v = 0,ss=0;for(int i = 1; i <= n; i++){double dis = dist(s.centre, a[i].centre);if(dis >= s.r + a[i].r)continue;  //在外部if(dis + min(s.r, a[i].r) <= max(s.r, a[i].r))  //在内部{ans += 4.0 / 3.0 * PI * min(s.r,a[i].r) * min(s.r,a[i].r) * min(s.r,a[i].r);continue;}SphereInterVS(s, a[i], v, ss); //相交部分ans += v;}printf("Case #%d: %.14f\n",cas++,ans);}
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部