hdu5733 tetrahedron (求四面体内切球球心+点面距)

tetrahedron
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 569 Accepted Submission(s): 219

Problem 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

Author
HIT

Source
2016 Multi-University Training Contest 1

题意:给你四个点,让你判断是否能形成四面体,如果能形成,求出内切球球心和半径。
思路:因为四个点有可能会形不成四面体,当发生这种情况的时候,肯定会有至少3个点在同一平面,所以说我们要先确定一个平面,然后判断四点共面
1.任取三个点,判断是否共线,如果存在3个点共线,则必不可能形成四面体。
2.当满足1后,判断第四个顶点距离底面的距离,如果小于eps,说明四点共面,则必不可能形成四面体,点面距离公式为:

d=|PQn||n|

其中 P 为所求点, Q 为平面上任意一点, n 为平面法向量,法向量可以通过叉积求得。
3.当1、2都满足的时候,说明可以形成四面体,就要求它的内切球球心了,根据公式得:球心坐标(X,Y,Z),求法为:
X=4i=1sixi6

Y=4i=1siyi6

Z=4i=1sizi6

其中 si 为以第 i 个点为顶点对应的底面面积, xi,yi,zi 分别为第 i 个点的坐标。
4.球心求出之后,直接求球心到任意一个面的距离即为半径,如果想要在不求球心快速求出半径的情况下,记同一顶点引出的三条棱棱长的平方分别为a,b,c,它们的对棱棱长的平方分别为d,e,f,则四面体的体积V满足:
V=ad(b+c+e+fad)+be(a+c+d+fbe)+cf(a+b+d+ecf)abfbcdcaedef)12

,因为一个四面体可以分割为四个小的四面体,所以说:
(s1+s2+s3+s4)r=3V

所以可得: r=3Vs1+s2+s3+s4 .

ac代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAXN 1010000
#define LL long long
#define ll __int64
#define INF 0x7fffffff
#define mem(x) memset(x,0,sizeof(x))
#define PI acos(-1)
#define eps 1e-8
using namespace std;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
double dpow(double a,ll b){double ans=1.0;while(b){if(b%2)ans=ans*a;a=a*a;b/=2;}return ans;}
//head
struct s
{
    double x,y,z;
};
s a,b,c,d;
//距离
double dis(s A,s B)
{
    return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)+(A.z-B.z)*(A.z-B.z));
}
//叉积AxB
s cross(s A,s B)
{
    s n;
    n.x=A.y*B.z-A.z*B.y;
    n.y=A.z*B.x-A.x*B.z;
    n.z=A.x*B.y-A.y*B.x;
    return n;
}
//点积
double point_m(s A,s B)
{
    double ans=A.x*B.x+A.y*B.y+A.z*B.z;
    return ans;
}
//判断三点共线
bool check(s A,s B,s C)
{
    double distarr[5];
    distarr[0]=dis(A,B);
    distarr[1]=dis(A,C);
    distarr[2]=dis(B,C);
    sort(distarr,distarr+3);
    return fabs(distarr[0]+distarr[1]-distarr[2])s A,s B,s C,s D)
{
    s a1;a1.x=A.x-B.x,a1.y=A.y-B.y,a1.z=A.z-B.z;
    s a2;a2.x=B.x-C.x,a2.y=B.y-C.y,a2.z=B.z-C.z;
    s n=cross(a1,a2);//法向量
    s up;up.x=D.x-A.x;up.y=D.y-A.y;up.z=D.z-A.z;
    double aa=point_m(up,n);
    double bb=point_m(n,n);
    return fabs(aa/sqrt(bb));
}
//三角形面积
double area(s A,s B,s C)
{
    double ba=dis(B,C);
    double bb=dis(A,C);
    double bc=dis(B,A);
    double p=(ba+bb+bc)/2.0;
    return sqrt(p*(p-ba)*(p-bb)*(p-bc));
}
int main()
{
    while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&a.z,&b.x,&b.y,&b.z,&c.x,&c.y,&c.z,&d.x,&d.y,&d.z)!=EOF)
    {
        if(check(a,b,c)||check(a,b,d)||check(a,c,d)||check(b,c,d))
        {
            printf("O O O O\n");
            continue;
        }
        else if(dis_D(a,b,c,d)printf("O O O O\n");
            continue;
        }
        double sa=area(b,c,d);
        double sb=area(a,c,d);
        double sc=area(a,b,d);
        double sd=area(a,b,c);
        double sum=sa+sb+sc+sd;
        s ans;double l=dis_D(a,b,c,d);
        ans.x=(sa*a.x+sb*b.x+sc*c.x+sd*d.x)/sum;
        ans.y=(sa*a.y+sb*b.y+sc*c.y+sd*d.y)/sum;
        ans.z=(sa*a.z+sb*b.z+sc*c.z+sd*d.z)/sum;
        double la=dis(a,b)*dis(a,b),lb=dis(a,d)*dis(a,d),lc=dis(a,c)*dis(a,c),ld=dis(c,d)*dis(c,d),le=dis(b,c)*dis(b,c),lf=dis(b,d)*dis(b,d);
        double V=sqrt(la*ld*(lb+lc+le+lf-la-ld)+lb*le*(la+lc+ld+lf-lb-le)+lc*lf*(la+lb+ld+le-lc-lf)-la*lb*lf-lb*lc*ld-lc*la*le-ld*le*lf)/4.0;
        double R=V/sum;
        printf("%.4lf %.4lf %.4lf %.4lf\n",ans.x,ans.y,ans.z,R);
    }
    return 0;
}

你可能感兴趣的:(计算几何)