HDU #5733 tetrahedron

tetrahedron

传送门


Time Limit: 2000/1000 MS (Java/Others)  
Memory Limit: 65536/65536 K (Java/Others)


Problem Description
Given four points ABCD, if ABCD is a tetrahedron, calculate the inscribed sphere of ABCD.
 
Input
Multiple test cases .
Each test cases contains a line of 12 integers indicating 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
 
 
Solution:
求四面体的内切球的半径和球心坐标。
半径可以通过将体积算两次来求:第一次用向量算,第二次用四个面的面积和乘内切球半径算。
内心的直角坐标可用体积坐标来算。
四面体的体积坐标

A1,A2,A3,A4,P,POP
四面体内P,

P=i=14λiAi,

i=14λi=1

:

P,.:

λ1=VPA2A3A4VA1A2A3A4

λ2=VPA1A3A4VA1A2A3A4

λ3=VPA1A2A4VA1A2A3A4

λ4=VPA1A2A3VA1A2A3A4

A1A2A3A4S1,S2,S3,S4,PA1A2A3A4I,

λi=SiS1+S2+S3+S4,i=1,2,3,4

OI=i=14λiAi=i=14SiAii=14Si

I(x,y,z):

x=i=14Sixii=14Si

y=i=14Siyii=14Si

z=i=14Sizii=14Si

无解的情况对应着四面体四点共面, 即体积为零.

Implementation:

复制代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

struct point{  
    LL x,y,z; 
    int read(){
        return scanf("%lld%lld%lld", &x, &y, &z);
    }

    point operator-(const point &p){
        return {x-p.x, y-p.y, z-p.z};
    }

    point operator^(const point &p){ //cross product
        return {y*p.z-z*p.y, z*p.x-x*p.z, x*p.y-y*p.x};
    }
    double operator*(const point &p){    //dot product
        return x*p.x+y*p.y+z*p.z;
    }
    double len(){
        return sqrt(x*x+y*y+z*z);
    }

}p[4];


int main(){
    for(; ~p[0].read(); ){
        for(int i=1; i<4; i++) p[i].read();

        LL vol=abs(((p[1]-p[0])^(p[2]-p[0]))*(p[3]-p[0]));

        if(!vol){
            puts("O O O O");    //error-prone: O, not 0
            continue;
        }

        double s[4], sum=0;
        point vec[2];

        for(int i=0; i<4; i++){
           for(int j=0; j<4; j++)
                if(j!=i){
                    for(int k=0, l=0; k<4; k++)
                        if(k!=j && k!=i)
                            vec[l++]=p[k]-p[j];
                    break;
                }
            s[i]=abs((vec[0]^vec[1]).len()), sum+=s[i];
        }

        double tot=0, x, y, z;
        for(int i=0; i<4; i++) tot+=s[i]*p[i].x;
        x=tot/sum;
        tot=0;
        for(int i=0; i<4; i++) tot+=s[i]*p[i].y;
        y=tot/sum;
        tot=0;
        for(int i=0; i<4; i++) tot+=s[i]*p[i].z;
        z=tot/sum;
        printf("%.4f %.4f %.4f %.4f\n", x, y, z, vol/sum);
    }
}
复制代码

 

 

 

posted @   Pat  阅读(205)  评论(0编辑  收藏  举报
编辑推荐:
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
阅读排行:
· 开发的设计和重构,为开发效率服务
· 从零开始开发一个 MCP Server!
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· Ai满嘴顺口溜,想考研?浪费我几个小时
点击右上角即可分享
微信分享提示