HDU 5733 tetrahedron(计算几何)

Description
给出A,B,C,D四个点坐标,如果ABCD构成一个四面体,则输出这个四面体的内切球球心坐标及其半径,否则输出O O O O
Input
多组用例,每组用例输入12个整数分别表示这四个点的坐标,以文件尾结束输入
Output
对于每组用例,如果ABCD是一个四面体,则输出这个四面体的内切球球心坐标及其半径(保留到小数点后四位),否则输出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
Solution
首先可以用向量叉乘求出四个面的面积s1,s2,s3,s4和四面体的体积V,如果V=0说明这四个点共面不能形成四面体,否则由r*(s1+s2+s3+s4)/3=V得到内切球半径r=3*v/(s1+s2+s3+s4),之后根据
x=(x1*s1+x2*s2+x3*s3+x4*s4)/(s1+s2+s3+s4)
y=(y1*s1+y2*s2+y3*s3+y4*s4)/(s1+s2+s3+s4)
z=(z1*s1+z2*s2+z3*s3+z4*s4)/(s1+s2+s3+s4)
求出内切球球心坐标即可
Code

#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
#define eps 1e-8
struct node
{
    double x,y,z;
}a,b,c,d,ans;
double get(node a,node b,node c)
{
    double x1=b.x-a.x,y1=b.y-a.y,z1=b.z-a.z;
    double x2=c.x-a.x,y2=c.y-a.y,z2=c.z-a.z;
    double d1=y1*z2-y2*z1;
    double d2=x1*z2-x2*z1;
    double d3=x1*y2-x2*y1;
    return sqrt(d1*d1+d2*d2+d3*d3)*0.5;
}
double Get(node a,node b,node c,node d)
{
    double x1=b.x-a.x,y1=b.y-a.y,z1=b.z-a.z;
    double x2=c.x-a.x,y2=c.y-a.y,z2=c.z-a.z;
    double x3=d.x-a.x,y3=d.y-a.y,z3=d.z-a.z;
    double ans=x1*(y2*z3-y3*z2)-y1*(x2*z3-x3*z2)+z1*(x2*y3-x3*y2);
    return abs(ans)/6.0;
}
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))
    {
        double s1,s2,s3,s4,V;
        V=Get(a,b,c,d);
        s1=get(b,c,d);
        s2=get(a,c,d);
        s3=get(a,b,d);
        s4=get(a,b,c);
        double t=s1+s2+s3+s4;
        if(V<eps)
        {
            printf("O O O O\n");
            continue;
        }
        ans.x=(s1*a.x+s2*b.x+s3*c.x+s4*d.x)/t;
        ans.y=(s1*a.y+s2*b.y+s3*c.y+s4*d.y)/t;
        ans.z=(s1*a.z+s2*b.z+s3*c.z+s4*d.z)/t;
        double r=V*3.0/t;
        printf("%.4lf %.4lf %.4lf %.4lf\n",ans.x,ans.y,ans.z,r);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值