2021牛客暑期多校训练营2 Girlfriend(阿波罗尼斯圆 + 计算几何)

题意

空间里有6个点,满足 ∣ P 1 A ∣ ⩾ k 1 ∣ P 1 B ∣ \left | P_1A \right | \geqslant k_1\left | P_1B \right | P1Ak1P1B ∣ P 2 C ∣ ⩾ k 2 ∣ P 2 D ∣ \left | P_2C \right | \geqslant k_2\left | P_2D \right | P2Ck2P2D,求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 | P1Ak1P1B ∣ P 2 C ∣ ⩾ k 2 ∣ P 2 D ∣ \left | P_2C \right | \geqslant k_2\left | P_2D \right | P2Ck2P2D化简得:

( 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 (1k2)(xp+yp2+zp2)+xp(2k2x22x1)+yp(2k2y22y1)+zp(2k2z22z1)+x12+y12+z12k2(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+c2d

然后判断两个球是否相交即可;

如果相交

在这里插入图片描述

把立体具化成平面,黄色是相交部分在球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=rhrπ(r2z2)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 [r2x2y2 (rh)]dxdy=02πdΘ02rhh2 (r2ρ2 (rh))ρdρ

化简可得到
V = π h 2 ( r − 1 3 h ) V = \pi h^2\left ( r - \frac{1}{3}h \right ) V=πh2(r31h)

最后同理得到球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;
}  

END

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半碗无糖蓝莓冻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值