hdu 5733 tetrahedron(2016 Multi-University Training Contest 1——几何公式题)

来源:互联网 发布:淘宝的企业店铺怎么开 编辑:程序博客网 时间:2024/05/19 01:29

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5733

tetrahedron

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 408    Accepted Submission(s): 157


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.4226O O O O
 

Author
HIT
 

Source
2016 Multi-University Training Contest 1
 
题目大意:给四面体四个顶点的左边,求该四面体的内切球的球心坐标及其半径,如果不存在内切球,则输出O O O O。
解题思路:各种公式的套用,首先要判断是否存在内切球,可以转换成给的四个顶点是否可容易构成四面体。我们先要求出三个点构成的平面方程,然后判断另一点是否在这个平面上。
接着要求每个面的面积,再此之前还要求一下每条边的边长,再根据海伦公式求面积。
海伦公式为:S = sqrt(s1* (s1-a) * (s1-b)*(s1-c)),其中s1表示的是三角形的周长的一半。
最后求内切球的球心,公式为:
ansx=( Sabc*a[4].x+Sabd*a[3].x + Sacd*a[2].x+Sbcd*a[1].x)/S; 
ansy=( Sabc*a[4].y+Sabd*a[3].y + Sacd*a[2].y+Sbcd*a[1].y)/S; 
ansz=( Sabc*a[4].z+Sabd*a[3].z + Sacd*a[2].z+Sbcd*a[1].z)/S; 
其中S为表面积。

详见代码。
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>using namespace std;struct point{    double x,y,z;} s[10];struct node{    point st,ed;};point Cross(point a, point b){    point s;    s.x = a.y*b.z - a.z*b.y;    s.y = a.z*b.x - a.x*b.z;    s.z = a.x*b.y - b.x*a.y;    return s;}double dot(point a, point b){    double s = a.x*b.x+a.y*b.y+a.z*b.z;    return s;}int main(){    double A,B,C,D,line;    while (~scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",&s[1].x,&s[1].y,&s[1].z,&s[2].x,&s[2].y,&s[2].z,&s[3].x,&s[3].y,&s[3].z,&s[4].x,&s[4].y,&s[4].z))    {        //先判断是否四点共面,求平面方程Ax+By+Cz+d=0;        A=((s[2].y-s[1].y)*(s[3].z-s[1].z)-(s[2].z-s[1].z)*(s[3].y-s[1].y));        B=((s[2].z-s[1].z)*(s[3].x-s[1].x)-(s[2].x-s[1].x)*(s[3].z-s[1].z));        C=((s[2].x-s[1].x)*(s[3].y-s[1].y)-(s[2].y-s[1].y)*(s[3].x-s[1].x));        D= -(A * s[1].x + B * s[1].y + C * s[1].z);        line=A*s[4].x+B*s[4].y+C*s[4].z+D;        if (fabs(line)<1e-6)        {            printf ("O O O O\n");            continue;        }        //先计算每个边的边长,再根据海伦公式:S = sqrt(s1*(s1-a)*(s1-b)*(s1-c))计算面积        node AB,AC,BC,AD,BD,CD;        AB.st = s[1], AB.ed = s[2];        AC.st = s[1], AC.ed = s[3];        BC.st = s[2], BC.ed = s[3];        AD.st = s[1], AD.ed = s[4];        BD.st = s[2], BD.ed = s[4];        CD.st = s[3], CD.ed = s[4];        double a=sqrt((AB.st.x-AB.ed.x)*(AB.st.x-AB.ed.x)+(AB.st.y-AB.ed.y)*(AB.st.y-AB.ed.y)+                      (AB.st.z-AB.ed.z)*(AB.st.z-AB.ed.z));        double b=sqrt((AC.st.x-AC.ed.x)*(AC.st.x-AC.ed.x)+(AC.st.y-AC.ed.y)*(AC.st.y-AC.ed.y)+                      (AC.st.z-AC.ed.z)*(AC.st.z-AC.ed.z));        double c=sqrt((BC.st.x-BC.ed.x)*(BC.st.x-BC.ed.x)+(BC.st.y-BC.ed.y)*(BC.st.y-BC.ed.y)+                      (BC.st.z-BC.ed.z)*(BC.st.z-BC.ed.z));        double d=sqrt((AD.st.x-AD.ed.x)*(AD.st.x-AD.ed.x)+(AD.st.y-AD.ed.y)*(AD.st.y-AD.ed.y)+                      (AD.st.z-AD.ed.z)*(AD.st.z-AD.ed.z));        double e=sqrt((BD.st.x-BD.ed.x)*(BD.st.x-BD.ed.x)+(BD.st.y-BD.ed.y)*(BD.st.y-BD.ed.y)+                      (BD.st.z-BD.ed.z)*(BD.st.z-BD.ed.z));        double f=sqrt((CD.st.x-CD.ed.x)*(CD.st.x-CD.ed.x)+(CD.st.y-CD.ed.y)*(CD.st.y-CD.ed.y)+                      (CD.st.z-CD.ed.z)*(CD.st.z-CD.ed.z));        //得到边长之后,一个公式就计算了面积        double s1 = 0.5*(a+b+c);        double Sabc = sqrt(s1*(s1-a)*(s1-b)*(s1-c));        double s2 = 0.5*(a+e+d);        double Sabd = sqrt(s2*(s2-a)*(s2-e)*(s2-d));        double s3 = 0.5*(d+b+f);        double Sacd = sqrt(s3*(s3-d)*(s3-b)*(s3-f));        double s4 = 0.5*(e+f+c);        double Sbcd = sqrt(s4*(s4-c)*(s4-e)*(s4-f));        double S = Sabc + Sabd + Sacd + Sbcd;        //计算内切球的半径        point AD1,BD1,CD1;        AD1.x = AD.ed.x-AD.st.x;        AD1.y = AD.ed.y-AD.st.y;        AD1.z = AD.ed.z-AD.st.z;        BD1.x = BD.ed.x-BD.st.x;        BD1.y = BD.ed.y-BD.st.y;        BD1.z = BD.ed.z-BD.st.z;        CD1.x = CD.ed.x-CD.st.x;        CD1.y = CD.ed.y-CD.st.y;        CD1.z = CD.ed.z-CD.st.z;        double r = fabs(dot(Cross(AD1,BD1),CD1))/2.0/S;        //计算内切球的球心坐标        double ansx, ansy, ansz;        ansx=( Sabc*s[4].x+Sabd*s[3].x + Sacd*s[2].x+Sbcd*s[1].x)/S;        ansy=( Sabc*s[4].y+Sabd*s[3].y + Sacd*s[2].y+Sbcd*s[1].y)/S;        ansz=( Sabc*s[4].z+Sabd*s[3].z + Sacd*s[2].z+Sbcd*s[1].z)/S;        printf("%.4lf %.4lf %.4lf %.4lf\n",ansx, ansy, ansz, r);    }    return 0;}


0 0
原创粉丝点击