链接: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 个球形安全区,分别用四元组
<
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>表示,其中
r
1
、
r
2
r1、r2
r1、r2表示球半径,
(
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
)
<
d
<
r
1
+
r
2
fabs(r_1-r_2)<d<r_1+r_2
fabs(r1−r2)<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)(3R−h)∗h2=πh2(R−3h)(R是球的半径,H是球缺的高)。
即
V
=
π
h
2
(
R
−
h
3
)
\large V =\pi h^2(R-\frac{h}{3})
V=πh2(R−3h)
如图所示,上边被切下来的部分就是球缺…我们需要知道它的体积
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;
}