hdu 5726 tetrahedron 立体几何

tetrahedron/center>

题目连接:

http://acm.hdu.edu.cn/showproblem.php?pid=5726

Description

Given four points ABCD, if ABCD is a tetrahedron, calculate the inscribed sphere of ABCD.

Input

Multiple test cases (test cases ≤100).

Each test cases contains a line of 12 integers [−1e6,1e6] indicate the coordinates of four vertices of ABCD.

Input ends by EOF.

Output

Print the coordinate of the center of the sphere and the radius, rounded to 4 decimal places.

If there is no such sphere, output "O O O O"

Sample Input

0 0 0 2 0 0 0 0 2 0 2 0
0 0 0 2 0 0 3 0 0 4 0 0

Sample Output

0.4226 0.4226 0.4226 0.4226
O O O O

Hint

题意

给你一个四面体,求内切球的坐标和半径。

题解:

网上去搜了一堆公式,随便抄了抄就过去了。

直接百度就好了,什么体积坐标什么的。。。

wa了半天,队友才发现是他自己叉积写错了,尴尬。

代码

#include <bits/stdc++.h>

using namespace std;

struct point
{
    double x,y,z;
}P[5];
struct pingmian
{
    double a,b,c,d;
}pm[5];
double area[5];

double P2planeDist(double x, double y, double z, double a, double b, double c, double d)
{
    return fabs(a*x+b*y+c*z+d)/sqrt(a*a+b*b+c*c);
}
double dist(point p0,point p1)
{
    return sqrt((p0.x-p1.x)*(p0.x-p1.x)+(p0.y-p1.y)*(p0.y-p1.y)+(p0.z-p1.z)*(p0.z-p1.z));
}
int check(point p0,point p1,point p2)
{
    p1.x-=p0.x,p1.y-=p0.y,p1.z-=p0.z;
    p2.x-=p0.x,p2.y-=p0.y,p2.z-=p0.z;
    if((p1.x*p2.y==p1.y*p2.x)&&(p1.x*p2.z==p1.z*p2.x)&&(p1.y*p2.z==p1.z*p2.y)) return 0;
    return 1;
}
point mul(point p0,point p1)
{
    point p2;
    p2.x=p0.y*p1.z-p0.z*p1.y;
    p2.y=-p0.x*p1.z+p0.z*p1.x;
    p2.z=p0.x*p1.y-p0.y*p1.x;
    return p2;
}
void cal(int p,point p0,point p1,point p2)
{
    double a=dist(p0,p1),b=dist(p1,p2),c=dist(p0,p2);
    double d=(a+b+c)/2.0;
    area[p]=sqrt(d*(d-a)*(d-b)*(d-c));
    p1.x-=p0.x,p1.y-=p0.y,p1.z-=p0.z;
    p2.x-=p0.x,p2.y-=p0.y,p2.z-=p0.z;
    point p3=mul(p1,p2);
    pm[p].a=p3.x,pm[p].b=p3.y,pm[p].c=p3.z;
    pm[p].d=-(pm[p].a*p0.x+pm[p].b*p0.y+pm[p].c*p0.z);
    return ;
}

int main()
{
    while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",&P[0].x,&P[0].y,&P[0].z,&P[1].x,&P[1].y,&P[1].z,&P[2].x,&P[2].y,&P[2].z,&P[3].x,&P[3].y,&P[3].z)!=EOF)
    {
        if(!(check(P[0],P[1],P[2])&&check(P[0],P[1],P[3])&&check(P[0],P[2],P[3])&&check(P[1],P[2],P[3])))
        {
            printf("O O O O\n");
            continue;
        }
        cal(3,P[0],P[1],P[2]);
        cal(2,P[0],P[1],P[3]);
        cal(1,P[0],P[2],P[3]);
        cal(0,P[1],P[2],P[3]);
        double r=area[3]*P2planeDist(P[3].x,P[3].y,P[3].z,pm[3].a,pm[3].b,pm[3].c,pm[3].d)/(area[0]+area[1]+area[2]+area[3]);
   //     cout<<pm[3].a<<" "<<pm[3].b<<" "<<pm[3].c<<" "<<pm[3].d<<endl;
   //     cout<<P2planeDist(P[3].x,P[3].y,P[3].z,pm[3].a,pm[3].b,pm[3].c,pm[3].d)<<endl;
        point ans;
        if(r<1e-9)
        {
            printf("O O O O\n");
            continue;
        }
      //  cout<<area[0]<<" "<<area[1]<<" "<<area[2]<<" "<<area[3]<<endl;
        ans.x=(area[0]*P[0].x+area[1]*P[1].x+area[2]*P[2].x+area[3]*P[3].x)/(area[0]+area[1]+area[2]+area[3]);
        ans.y=(area[0]*P[0].y+area[1]*P[1].y+area[2]*P[2].y+area[3]*P[3].y)/(area[0]+area[1]+area[2]+area[3]);
        ans.z=(area[0]*P[0].z+area[1]*P[1].z+area[2]*P[2].z+area[3]*P[3].z)/(area[0]+area[1]+area[2]+area[3]);
        printf("%.4f %.4f %.4f %.4f\n",ans.x,ans.y,ans.z,r);
    }
    return 0;
}
posted @ 2016-07-20 09:46  qscqesze  阅读(377)  评论(4编辑  收藏  举报