首页 > 代码库 > tetrahedron

tetrahedron

题意:

求解一个四面体的内切球。

 

解法:

首先假设内切球球心为$(x0,x1,x2)$,可以用$r = \frac{3V}{S_1+S_2+S_3+S_4}$得出半径,

这样对于四个平面列出三个方程,解得

$x_n = \sum_{i=0}^3{Ai_{x_n} \cdot S_i } / (S_1 + S_2 + S_3 + S_4)$

这样,即可得出内切球。

时间复杂度$O(1)$。

 

技术分享
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 
  6 #define LD double
  7 #define sqr(x) ((x)*(x))
  8 #define eps 1e-13
  9 
 10 using namespace std;
 11 
 12 struct node
 13 {
 14     LD x,y,z;
 15     void scan()
 16     {
 17         scanf("%lf%lf%lf",&x,&y,&z); 
 18     }
 19     void print()
 20     {
 21         printf("%.4lf %.4lf %.4lf\n",x,y,z);
 22     }
 23     LD length()
 24     {
 25         return sqrt(sqr(x)+sqr(y)+sqr(z));
 26     }
 27     node operator+(const node &tmp)
 28     {
 29         return (node){x+tmp.x,y+tmp.y,z+tmp.z};
 30     }    
 31     node operator-(const node &tmp)
 32     {
 33         return (node){x-tmp.x,y-tmp.y,z-tmp.z};
 34     }
 35     node operator/(LD tmp)
 36     {
 37         return (node){x/tmp,y/tmp,z/tmp};
 38     }
 39     node operator*(LD tmp)
 40     {
 41         return (node){x*tmp,y*tmp,z*tmp};
 42     }
 43 };
 44 
 45 node cross(node a,node b)
 46 {
 47     node ans;
 48     ans.x = a.y*b.z - b.y*a.z;
 49     ans.y = b.x*a.z - a.x*b.z;
 50     ans.z = a.x*b.y - b.x*a.y;
 51     return ans;
 52 }
 53 
 54 LD dist(node a,node b)
 55 {
 56     return (b-a).length();
 57 }
 58 
 59 LD dot(node a,node b)
 60 {
 61     return a.x*b.x + a.y*b.y + a.z*b.z;
 62 }
 63 
 64 LD get_angle(node a,node b)
 65 {
 66     LD tmp = dot(a,b)/a.length()/b.length();
 67     return acos(tmp);
 68 }
 69 
 70 node get_node(node A,node B,node C)
 71 {
 72     LD Lth = (B-A).length() + (C-A).length() + (C-B).length();
 73     cout << sqr(Lth-4) << endl;
 74     LD r = fabs(cross(B-A,C-A).length()) / Lth;
 75     cout << r*r << endl;
 76     node v1 = C-A;
 77     node v2 = B-A;
 78     node v = (v1+v2)/(v1+v2).length();
 79     LD d = (C-A).length()/2;
 80     LD L = sqrt(sqr(d)+sqr(r));
 81     v = v*L;
 82     return A+v;
 83 }
 84 
 85 int main()
 86 {
 87     node A,B,C,D;
 88     while(~scanf("%lf%lf%lf",&A.x,&A.y,&A.z))
 89     {
 90         B.scan();
 91         C.scan();
 92         D.scan();
 93         if(fabs(dot(cross(B-A,C-A),D-A)) < eps)
 94         {
 95             puts("O O O O");
 96             continue;
 97         }
 98         LD S1 = fabs(cross(B-D,C-D).length())/2;
 99         LD S2 = fabs(cross(D-A,C-A).length())/2;
100         LD S3 = fabs(cross(B-A,D-A).length())/2;
101         LD S4 = fabs(cross(B-A,C-A).length())/2;
102         LD Ve = fabs(dot(cross(B-A,C-A),D-A))/6;
103         LD R = 3*Ve / ((S1+S2+S3+S4));
104         node ans; 
105         ans.x = (S1*A.x + S2*B.x + S3*C.x + S4*D.x)/(S1+S2+S3+S4);
106         ans.y = (S1*A.y + S2*B.y + S3*C.y + S4*D.y)/(S1+S2+S3+S4);
107         ans.z = (S1*A.z + S2*B.z + S3*C.z + S4*D.z)/(S1+S2+S3+S4);
108         printf("%.4lf %.4lf %.4lf %.4lf\n",ans.x,ans.y,ans.z,R);
109     }
110     return 0;
111 }
112 /*
113 0 0 0 2 0 0 0 0 2 0 2 0
114 0 0 0 2 0 0 3 0 0 4 0 0
115 */
View Code

 

tetrahedron