题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5733
【题意】给定4个空间点,求构成的四面体的内切圆和内切圆半径,如果不存在内切圆,输出“O O O O”
【分析】QAQ公式题。。比赛没有公式表示很忧伤。。先用向量的混合积求出体积V。体积V为0表示4点共面没有内切圆。继续求出四个面的面积s1,s2,s3,s4,内切圆心半径r=3*V/(s1+s2+s3+s4)。然后内心坐标公式:x=(s1*x1+s2*x2+s3*x3+s4*x4)/(s1+s2+s3+s4).y=(s1*y1+s2*y2+s3*y3+s4*y4)/(s1+s2+s3+s4).z=(s1*z1+s2*z2+s3*z3+s4*z4)/(s1+s2+s3+s4).
【代码】
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define LL long long
LL x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4;
double s1,s2,s3,s4,r;
double c1,c2,c3;
double vol;
void getvol(){
LL x12=x1-x2,y12=y1-y2,z12=z1-z2;
LL x13=x1-x3,y13=y1-y3,z13=z1-z3;
LL x14=x1-x4,y14=y1-y4,z14=z1-z4;
LL tmp=x12*y13*z14+y12*z13*x14+z12*x13*y14-x12*z13*y14-y12*x13*z14-z12*y13*x14;
vol=abs(tmp)*1.0/6;
}
double getarea(LL x11,LL y11,LL z11,LL x22,LL y22,LL z22,LL x33,LL y33,LL z33){
double a=sqrt(((x11-x22)*(x11-x22)+(y11-y22)*(y11-y22)+(z11-z22)*(z11-z22))*1.0);
double b=sqrt(((x11-x33)*(x11-x33)+(y11-y33)*(y11-y33)+(z11-z33)*(z11-z33))*1.0);
double c=sqrt(((x22-x33)*(x22-x33)+(y22-y33)*(y22-y33)+(z22-z33)*(z22-z33))*1.0);
double p=(a+b+c)/2;
return sqrt(p*(p-a)*(p-b)*(p-c));
}
int main(){
while(~scanf("%I64d %I64d %I64d %I64d %I64d %I64d %I64d %I64d %I64d %I64d %I64d %I64d",&x1,&y1,&z1,&x2,&y2,&z2,&x3,&y3,&z3,&x4,&y4,&z4)){
vol=0;
getvol();
if(vol==0){
cout<<"O O O O\n";
continue;
}
s1=getarea(x2,y2,z2,x3,y3,z3,x4,y4,z4);
s2=getarea(x1,y1,z1,x3,y3,z3,x4,y4,z4);
s3=getarea(x1,y1,z1,x2,y2,z2,x4,y4,z4);
s4=getarea(x1,y1,z1,x2,y2,z2,x3,y3,z3);
double tmp=s1+s2+s3+s4;
r=3*vol/tmp;
c1=(s1*x1+s2*x2+s3*x3+s4*x4)*1.0/tmp;
c2=(s1*y1+s2*y2+s3*y3+s4*y4)*1.0/tmp;
c3=(s1*z1+s2*z2+s3*z3+s4*z4)*1.0/tmp;
printf("%.04lf %.04lf %.04lf %.04lf\n",c1,c2,c3,r);
}
}