天天看點

HDU5733_四面體的内切球

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

#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;
}