1. 程式人生 > >HDU5733_四面體的內切球

HDU5733_四面體的內切球

1.前言:2018馬上就要過去了,今天的一場模擬賽做到了這個題,一開始沒有人過,我在隊友開其他題的時候偷懶找了個題面最短的題來做,結果還真讓我yy出來了。其實高數基礎紮實還是很有用的哈。

2.題目連結。題意十分的裸,就是給你空間中四個點求球心的座標以及球的半徑。首先我們需要知道一些東西,半徑怎麼求?這個其實大家高中都會,就是等體積法,四面體的體積被表示成表面積與內切球半徑的乘積的3倍。四面體的體積可以有很多種球法,我們可以使用點到平面的距離,我覺得最簡單的還是混合積的六分之一好算。最後最重要的就是球心座標的計算了。其實也很簡單,就是公式,求出每個點對球心座標的貢獻,這其實是一個加權的平均數,權值就是這個點對的面的面積。為什麼時是這樣的?其實微積分中有答案的,不懂得同學可以翻翻書看看。我直接把我的程式碼拉出來:

#include<iomanip>
#include<cmath>
using namespace std;
struct P
{
	double x, y, z;
	P() {};
	P(double x, double y, double z)
	{
		this->x = x;
		this->y = y;
		this->z = z;
	}
	P operator-(const P a)
	{
		return P(a.x - x, a.y - y, a.z - z);
	}
}p[4];
double getA(P a, P b, P c)
{
	double l1 = sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y,2) + pow(a.z - b.z, 2));
	double l2 = sqrt(pow(a.x - c.x, 2) + pow(a.y - c.y, 2) + pow(a.z - c.z,2));
	double l3 = sqrt(pow(b.x - c.x, 2) + pow(b.y - c.y, 2) + pow(b.z - c.z, 2));
	double p = (l1 + l2 + l3) / 2;
	double s = sqrt(p*(p - l1)*(p - l2)*(p - l3));
	return s;
}
double getV(P a, P b, P c)
{
	double s = abs(a.x*(b.y*c.z - b.z*c.y) - a.y*(b.x*c.z - b.z*c.x) + a.z*(b.x*c.y - b.y*c.x));
	return s / 6;
}
#pragma warning(disable:4996)
int main()
{
	
	while (~scanf("%lf%lf%lf",&p[0].x,&p[0].y,&p[0].z))
	{
		for (int i = 1; i < 4; i++)
		{
			cin >> p[i].x >> p[i].y >> p[i].z;
		}
		double v = getV(p[0] - p[1], p[0] - p[2], p[0] - p[3]);
		double s1 = getA(p[0], p[1], p[2]);
		double s2 = getA(p[0], p[1], p[3]);
		double s3 = getA(p[0], p[2], p[3]);
		double s4 = getA(p[1], p[2], p[3]);
		if (v == 0)
		{
			cout << "O O O O" << endl;
		}
		else
		{
			cout << fixed << setprecision(4);
			double S = s1 + s2 + s3 + s4;
			double r = 3 * v / S;
			double x = (p[0].x*s4 + p[1].x*s3 + p[2].x*s2 + p[3].x*s1) / S;
			double y = (p[0].y*s4 + p[1].y*s3 + p[2].y*s2 + p[3].y*s1) / S;
			double z = (p[0].z*s4 + p[1].z*s3 + p[2].z*s2 + p[3].z*s1) / S;
			cout << x << " " << y << " " << z <<" "<<r<<endl;
		}
	}
    
    return 0;
}

當然了,我當時沒有想這麼多就交了,然後A了,其實隊友說這裡需要加一個eps,我當時驚出一身冷汗,覺得要貢獻出1WA了。雖然僥倖過了,但是出於嚴謹還是需要給每一個數據加上eps,設定成1e-8就OK。