题意
空间里有6个点,满足 ∣ P 1 A ∣ ⩾ k 1 ∣ P 1 B ∣ \left | P_1A \right | \geqslant k_1\left | P_1B \right | ∣P1A∣⩾k1∣P1B∣, ∣ P 2 C ∣ ⩾ k 2 ∣ P 2 D ∣ \left | P_2C \right | \geqslant k_2\left | P_2D \right | ∣P2C∣⩾k2∣P2D∣,求P1,P2各自的轨迹相交部分的体积;
思路
对于固定的k,P1,P2的轨迹构成标准的阿波罗尼斯球壳
;
同时,题意的k > 1,可以得知为轨迹为实心的球体,于是问题转化为求两球相交部分的体积;
将条件 ∣ P 1 A ∣ ⩾ k 1 ∣ P 1 B ∣ \left | P_1A \right | \geqslant k_1\left | P_1B \right | ∣P1A∣⩾k1∣P1B∣, ∣ P 2 C ∣ ⩾ k 2 ∣ P 2 D ∣ \left | P_2C \right | \geqslant k_2\left | P_2D \right | ∣P2C∣⩾k2∣P2D∣化简得:
( 1 − k 2 ) ( x p + y p 2 + z p 2 ) + x p ( 2 k 2 x 2 − 2 x 1 ) + y p ( 2 k 2 y 2 − 2 y 1 ) + z p ( 2 k 2 z 2 − 2 z 1 ) + x 1 2 + y 1 2 + z 1 2 − k 2 ( x 2 2 + y 2 2 + z 2 2 ) = 0 \left ( 1 - k^2 \right )\left ( x_p + y_p^2 + z_p^2 \right ) + x_p\left ( 2k^2x_2 - 2x_1 \right ) + y_p\left ( 2k^2y_2 - 2y_1 \right ) + z_p\left ( 2k^2z_2 - 2z_1 \right ) + x_1^2 + y_1^2 + z_1^2 - k^2\left ( x_2^2 + y_2^2 + z_2^2\right )= 0 (1−k2)(xp+yp2+zp2)+xp(2k2x2−2x1)+yp(2k2y2−2y1)+zp(2k2z2−2z1)+x12+y12+z12−k2(x22+y22+z22)=0
又知球的方程: x 2 + y 2 + z 2 + 2 a x + 2 b y + 2 c z + d = 0 x^2 + y^2 + z^2 + 2ax + 2by + 2cz + d = 0 x2+y2+z2+2ax+2by+2cz+d=0
可得球心坐标 ( − a , − b , − c ) \left ( -a,-b,-c \right ) (−a,−b,−c),半径 r = a 2 + b 2 + c 2 − d r = \sqrt{a^2 + b^2 + c^2 - d} r=a2+b2+c2−d
然后判断两个球是否相交即可;
如果相交
把立体具化成平面,黄色是相交部分在球1中的体积,利用三重积分或者二重积分算体积;
∫
∫
∫
d
x
d
y
d
z
=
∫
r
−
h
r
π
∗
(
r
2
−
z
2
)
d
z
\int \int \int dxdydz = \int_{r - h}^{r} \pi * (r^2 - z^2)dz
∫∫∫dxdydz=∫r−hrπ∗(r2−z2)dz
或者
∫ ∫ [ r 2 − x 2 − y 2 − ( r − h ) ] d x d y = ∫ 0 2 π d Θ ∫ 0 2 r h − h 2 ( r 2 − ρ 2 − ( r − h ) ) ρ d ρ \int \int \left [ \sqrt{r^2 - x^2 - y^2} - (r - h) \right ]dxdy = \int_{0}^{2\pi }d\Theta \int_{0}^{\sqrt{2rh - h^2}}\left ( \sqrt{r^2 - \rho^2 } - \left ( r - h \right ) \right )\rho d\rho ∫∫[r2−x2−y2−(r−h)]dxdy=∫02πdΘ∫02rh−h2(r2−ρ2−(r−h))ρdρ
化简可得到
V
=
π
h
2
(
r
−
1
3
h
)
V = \pi h^2\left ( r - \frac{1}{3}h \right )
V=πh2(r−31h)
最后同理得到球2部分加起来即可;
AC代码
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <string>
#include <algorithm>
#include <queue>
#include <utility>
#include <stack>
#include <map>
#include <vector>
#include <set>
#include <iomanip>
#include <unordered_map>
#define hz020 return
#define mes memset
#define mec memcpy
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll,ll> PII;
const double pi = acos(-1);
const int N = 25;
const int null = 0x3f3f3f3f,INF = 1e9;
const ll mod = 998244353;
int T;
double x[4], y[4], z[4];
int k1, k2;
void solve(double x1, double y1, double z1, double x2, double y2, double z2, double r1, double r2)
{
double dist = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2));
if (dist >= r1 + r2) printf("0.000\n");
else if (dist + r2 <= r1) printf("%.3lf\n", pi * r2 * r2 * r2 * 4 / 3);
else if (dist + r1 <= r2) printf("%.3lf\n", pi * r1 * r1 * r1 * 4 / 3);
else
{
double cos1 = (dist * dist + r1 * r1 - r2 * r2) / (2 * r1 * dist), cos2 = (dist * dist + r2 * r2 - r1 * r1) / (2 * r2 * dist);
double h1 = r1 - r1 * cos1, h2 = r2 - r2 * cos2;
printf("%.3lf\n", pi * h1 * h1 * (r1 - h1 / 3) + pi * h2 * h2 * (r2 - h2 / 3));
}
}
int main()
{
cin >> T;
while (T --)
{
for (int i = 0; i <= 3;i ++ ) cin >> x[i] >> y[i] >> z[i];
cin >> k1 >> k2;
double sq1 = k1 * k1, idx1 = 1 - sq1;
//圆心
double xp1 = (sq1 * x[1] - x[0]) / idx1, yp1 = (sq1 * y[1] - y[0]) / idx1, zp1 = (sq1 * z[1] - z[0]) / idx1;
double dp1 = (x[0] * x[0] + y[0] * y[0] + z[0] * z[0] - sq1 * (x[1] * x[1] + y[1] * y[1] + z[1] * z[1])) / idx1;
//半径
double rp1 = sqrt(xp1 * xp1 + yp1 * yp1 + zp1 * zp1 - dp1);
double sq2 = k2 * k2, idx2 = 1 - sq2;
//圆心
double xp2 = (sq2 * x[3] - x[2]) / idx2, yp2 = (sq2 * y[3] - y[2]) / idx2, zp2 = (sq2 * z[3] - z[2]) / idx2;
double dp2 = (x[2] * x[2] + y[2] * y[2] + z[2] * z[2] - sq2 * (x[3] * x[3] + y[3] * y[3] + z[3] * z[3])) / idx2;
//半径
double rp2 = sqrt(xp2 * xp2 + yp2 * yp2 + zp2 * zp2 - dp2);
solve (xp1, yp1, zp1, xp2, yp2, zp2, rp1, rp2);
}
hz020 0;
}