牛客练习赛41 E-球的体积并——————几何

链接:https://ac.nowcoder.com/acm/contest/373/E
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
Special Judge, 64bit IO Format: %lld
题目描述
某天lililalala正在玩一种奇妙的吃鸡游戏–因为在这个游戏里会同时有两个圆形安全区(他们可能相交)。
lililalala觉得求圆的面积并太简单了,所以想把这个问题升级一下。
现在在三维空间里有 2 个球形安全区,分别用四元组 &lt; x 1 , y 1 , z 1 , r 1 &gt; &lt;x1,y1,z1,r1&gt; <x1,y1,z1,r1> &lt; x 2 , y 2 , z 2 , r 2 &gt; &lt;x2,y2,z2,r2&gt; <x2,y2,z2,r2>表示,其中 r 1 、 r 2 r1、r2 r1r2表示球半径, ( x 1 , y 1 , z 1 ) (x1,y1,z1) (x1,y1,z1) ( x 2 , y 2 , z 2 ) (x2,y2,z2) (x2,y2,z2)表示球心
lililalala想知道安全区的总体积是多少?即求这两个球的体积并。

输入描述:
输入有两行。
第一行四个实数 x 1 , y 1 , z 1 , r 1 x1,y1,z1,r1 x1,y1,z1,r1–第一个球的球心坐标和半径。
第二行四个实数 x 2 , y 2 , z 2 , r 2 x2,y2,z2,r2 x2,y2,z2,r2–第二个球的球心坐标和半径。
保证所有输入的坐标和半径的范围都在 [ − 100 , 100 ] [−100,100] [100,100] 内。

输出描述:
输出一行一个实数–表示两个球的体积并,你的答案被认为正确,当且仅当绝对误差不超过10−6。
示例1
输入
0 0 0 1
2 0 0 1
输出
8.3775804
示例2
输入
0 0 0 1
0 0 0 0.5
输出
4.1887902


两个球不相交或者小球在大球内部的情况非常简单,结果就是球的体积
两球相交的时候,即 f a b s ( r 1 − r 2 ) &lt; d &lt; r 1 + r 2 fabs(r_1-r_2)&lt;d&lt;r_1+r_2 fabs(r1r2)<d<r1+r2的情况
结果是两个球的体积减去它们球缺的体积就好了

球缺

  • 一个球被平面截下的一部分叫做球缺。
  • 截面叫做球缺的底面
  • 垂直于截面的直径被截后被截下的线段长叫做球缺的高。
  • 球缺曲面部分的面积(球冠面积) S = 2 π R h S=2πRh S=2πRh
  • 球缺体积公式 V = ( π / 3 ) ( 3 R − h ) ∗ h 2 = π h 2 ( R − h 3 ) V=(π/3)(3R-h)*h^2=\pi h^2(R-\frac{h}{3}) V=(π/3)(3Rh)h2=πh2(R3h)(R是球的半径,H是球缺的高)。


V = π h 2 ( R − h 3 ) \large V =\pi h^2(R-\frac{h}{3}) V=πh2(R3h)
如图所示,上边被切下来的部分就是球缺…我们需要知道它的体积
在这里插入图片描述

code

#include<bits/stdc++.h>
using namespace std;
const double PI = acos(-1.0);

struct Point{
        double x,y,z,r;
}a,b;

double dis(Point a,Point b)
{
        return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) + (a.z-b.z)*(a.z-b.z));
}
int main()
{
        // freopen("../in.txt","r",stdin);
        // freopen("../out.txt","w",stdout);
        cin>>a.x>>a.y>>a.z>>a.r;
        cin>>b.x>>b.y>>b.z>>b.r;
        double d = dis(a,b);
        double ans = 4.0*PI*(a.r*a.r*a.r+b.r*b.r*b.r)/3.0;
        if(d<=fabs(a.r-b.r))    ans = 4.0*PI*pow(a.r>b.r?a.r:b.r,3)/3.0;//小球在大球内
        else if(d<a.r+b.r){//两球相交,减去两个球缺的体积
                double cosq1 = (a.r*a.r + d*d - b.r*b.r)/(2.0*a.r*d); //对应的余弦角
                double cosq2 = (b.r*b.r + d*d - a.r*a.r)/(2.0*b.r*d);
                double h1 = a.r*(1-cosq1);//a球 球缺的高
                double h2 = b.r*(1-cosq2);//b球 球缺的高
                ans -= PI*h1*h1*(a.r-h1/3.0);//球缺体积公式
                ans -= PI*h2*h2*(b.r-h2/3.0);//减去b球的球缺部分
        }
        printf("%.7f\n",ans);
        return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值