windows10安装mysql8,只需要四步

PyTorch设置随机数种子使结果可复现

  返回  

2021多校第二场F 简单计算几何模板(球体相交体积)

2021/7/20 15:43:59 浏览:

简单板子题

  • 题意
  • 代码

题意

[原题链接](https://ac.nowcoder.com/acm/contest/11253/F) 大致题意: 有A,B,C,D四个点(三维坐标)和k1,k2两个常数

在空间上取一点P1使 |AP1|/|BP1|=k1 (所有的P1集合会是一个球体)
取一点P2使 |CP2|/|DP2|=k2 (所有的P2集合会是一个球体)
然后求两个球体的相交的体积大小


提示:以下是本篇文章正文内容,下面案例可供参考

代码

#include <bits/stdc++.h>
#include<math.h>
#define endl "\n"	
const double PI = acos(-1.0);
const double EI = exp(1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 1000050;
using namespace std;
//Spherical_Cap 球缺 
struct point //三维
{
	double x, y, z;
	point() {}   // 构造函数
	point(double a, double b, double c) :x(a), y(b), z(c) {}
	void in() { cin >> x >> y >> z; }
};
inline point operator+(point a, point b) { return point(a.x + b.x, a.y + b.y, a.z + b.z); }
inline point operator-(point a, point b) { return point(a.x - b.x, a.y - b.y, a.z - b.z); }
inline point operator*(double k, point a){ return point(a.x * k, a.y * k, a.z * k); }   // 常数 k 乘以一个向量or点
inline double distance(point a) { return sqrt(a.x * a.x + a.y * a.y + a.z * a.z); }   // 点到原点的距离  distance(A-B)即是AB的距离
void getsphere(point A, point B,double k, point& O, double& R)  //用阿圆 得出球体的球心 和半径  AP/BP=k  传出O球心坐标 和R半径
{
	O = B + 1/ (k * k - 1)*(B-A);
	R = k / (k * k - 1) * distance(A-B);
}
double Spherical_Cap(double R, double H)  // R是球的半径  H是球缺的高度
{
	return PI * H * H * (R - H / 3.0);
}
// curved surface of spherical cap 球冠
double Cureer_Surface_Of_Spherical_Cap(double R, double H)
{
	return 2 * PI * R * H;
}
double Overlapping_volume_sphere(point A, double R1, point B, double R2) // 计算重叠球体体积大小
{
	double d = distance(A - B);
	if (d > R1 + R2)
		return 0;
	else if (d < fabs(R1 - R2))
	{
		if (R1 < R2)
			swap(R1, R2);
		return R2*4.0/3 * PI * R2 * R2;
	}
	else
	{
		double h1 = R1 - (R1 * R1 + d * d - R2 * R2) / (2 * R1 * d) * R1; // 用余弦定理来算
		double h2 = R2 - (R2 * R2 + d * d - R1 * R1) / (2 * R2 * d) * R2;
		return Spherical_Cap(R1, h1) + Spherical_Cap(R2, h2);
	}
}
int main()
{
	std::ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	int t;
	cin >> t;
	while (t--)
	{
		point A, B, C, D;
		A.in(), B.in(), C.in(), D.in();
		double k1, k2;
		cin >> k1 >> k2;
		point O1, O2;
		double R1, R2;
		getsphere(A, B, k1, O1, R1);
		getsphere(C, D, k2, O2, R2);
		double p = Overlapping_volume_sphere(O1, R1, O2, R2);
		cout << fixed << setprecision(3) << p << endl;
	}
	return 0;
}

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号