题意:题意很简单就是给你四个点,判断这四个点能不能组成四面体,如果能求出内切圆半径,和内切圆坐标。
思路:公式题
ans.x=(sa*A.x+sb*B.x+sc*C.x+sd*D.x)/ssum;
ans.y=(sa*A.y+sb*B.y+sc*C.y+sd*D.y)/ssum;
ans.z=(sa*A.z+sb*B.z+sc*C.z+sd*D.z)/ssum;
r可以通过v/ssum*3求得
v可以通过公式或者面和高来求得
#include<bits/stdc++.h>
using namespace std;
#define maxn 9999999
#define eps 1e-8
struct point3{
double x,y,z;
};
///A,B两点作差
point3 cha(point3 A,point3 B) {
point3 tt;
tt.x=A.x-B.x;
tt.y=A.y-B.y;
tt.z=A.z-B.z;
return tt;
}
///两点距离
double dis(point3 A,point3 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));
}
///叉积
point3 cross(point3 A,point3 B) {
point3 tt;
tt.x=A.y*B.z-A.z*B.y;
tt.y=A.z*B.x-A.x*B.z;
tt.z=A.x*B.y-A.y*B.x;
return tt;
}
///点积
double dot_product(point3 A,point3 B) {
return A.x*B.x+A.y*B.y+A.z*B.z;
}
///三点共线
bool check(point3 A,point3 B,point3 C) {
double disp[5];
disp[0]=dis(A,B);
disp[1]=dis(A,C);
disp[2]=dis(B,C);
sort(disp,disp+3);
return fabs(disp[0]+disp[1]-disp[2])<eps;
}
///点面距离 D到A,B,C的面积
double disDM(point3 A,point3 B,point3 C,point3 D) {
point3 a1=cha(A,B);
point3 a2=cha(B,C);
point3 n=cross(a1,a2);///求法向量
point3 up=cha(D,A);
double aa=dot_product(up,n);
double bb=dot_product(n,n);
return fabs(aa/sqrt(bb));
}
///三角形面积
double area3(point3 A,point3 B,point3 C) {
double la=dis(B,C);
double lb=dis(A,C);
double lc=dis(A,B);
double p=(la+lb+lc)/2.0;
return sqrt(p*(p-la)*(p-lb)*(p-lc));///海伦公式
}
int main()
{
point3 A,B,C,D;
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)) {
// cout << "2***********" << endl;
printf("O O O O\n");
continue;
}
if(disDM(A,B,C,D)<eps) {
//cout << "1***********" << endl;
printf("O O O O\n");
continue;
}
double sa=area3(B,C,D);
double sb=area3(A,C,D);
double sc=area3(A,B,D);
double sd=area3(A,B,C);
double ssum=sa+sb+sc+sd;
point3 ans;
ans.x=(sa*A.x+sb*B.x+sc*C.x+sd*D.x)/ssum;
ans.y=(sa*A.y+sb*B.y+sc*C.y+sd*D.y)/ssum;
ans.z=(sa*A.z+sb*B.z+sc*C.z+sd*D.z)/ssum;
/*
double aa=dis(A,B)*dis(A,B);
double bb=dis(A,C)*dis(A,C);
double cc=dis(A,D)*dis(A,D);
double dd=dis(C,D)*dis(C,D);
double ee=dis(B,D)*dis(B,D);
double ff=dis(B,C)*dis(B,C);
double v=sqrt((aa*dd*(bb+cc+ee+ff-aa-dd)+bb*ee*(aa+cc+dd+ff-bb-ee)+cc*ff*(aa+bb+dd+ee-cc-ff)-aa*bb*ff-bb*cc*dd-cc*aa*ee-dd*ee*ff)/16);
*/
///此公式也挺方便
double ld=disDM(A,B,C,D);
double v=sd*ld/3.0;
double r=v/ssum*3.0;
printf("%.4f %.4f %.4f %.4f\n",ans.x,ans.y,ans.z,r);
}
return 0;
}