题目链接:点击打开链接
题目大意:求一个四面体的内切圆半径及圆心空间位置
解题思路:
四面体两条相对的边处于两条互相歪斜(在三维空间中既不相交也不平行,等价于异面)的直线上,所以四面体相对边之间的距离就被定义为其所在 互相歪斜的直线之间的距离。设d是四面体相对的边a 和 b − c之间的距离,则四面体的另一个体积公式是:
-
如果OABC四点能够构成一个四面体,并且O点位于我们所定的空间直角坐标系的原点,而向量a、b、c代表着顶点A、B、C相对于O的位置,则四面体内切圆半径可表示为:(在以下的公式中,像a2这样的向量的平方代表着数量积a·a,b2和c2也是这样)
内心:
- 代码:
-
#include <bits/stdc++.h> using namespace std; const double eps = 1e-8; struct V { V(){x = y = z = 0.0;} V(double a, double b, double c) { x = a, y = b, z = c; } double x, y, z; friend V operator + (V &a, V &b) { return V(a.x+b.x, a.y+b.y, a.z+b.z); } friend V operator - (V &a, V &b) { return V(a.x-b.x, a.y-b.y, a.z-b.z); } friend double operator * (V &a, V &b) { return a.x*b.x + a.y*b.y + a.z*b.z; } friend V operator * (V &a, double &b) { return V(a.x*b, a.y*b, a.z*b); } friend V operator * (double &b, V &a) { return V(a.x*b, a.y*b, a.z*b); } friend V operator ^ (V &a, V &b) { return V(a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x); } friend V operator / (V &a, double &b) { return V(a.x/b, a.y/b, a.z/b); } }; double Abs(V a) { return sqrt(a.x*a.x + a.y*a.y + a.z*a.z); } double calR(V a, V b, V c) { V tmp = b^c, tmp2 = c^a, tmp3 = a^b; double v = fabs(tmp*a); tmp = tmp+tmp2; tmp = tmp+tmp3; double fm = Abs(b^c) + Abs(c^a) + Abs(a^b) + Abs(tmp); return v/fm; } V calP(V a, V b, V c) { V tmp = b^c, tmp2 = c^a, tmp3 = a^b; double v = fabs(tmp*a); tmp = tmp+tmp2; tmp = tmp+tmp3; double fm = Abs(b^c) + Abs(c^a) + Abs(a^b) + Abs(tmp); double xx = Abs(b^c), yy = Abs(c^a), zz = Abs(a^b); tmp = a*xx, tmp2 = b*yy, tmp3 = c*zz; tmp = tmp+tmp2; tmp = tmp+tmp3; return tmp/fm; } int main() { V p[4]; double a, b, c; while (~scanf("%lf%lf%lf", &a, &b, &c)) { p[0] = V(a, b, c); for (int i = 1; i < 4; i++) { scanf("%lf%lf%lf", &a, &b, &c); p[i] = V(a, b, c); } V A = p[1] - p[0]; V B = p[2] - p[0]; V C = p[3] - p[0]; V CV = A^B; double isOK = CV*C; if (fabs(isOK) < eps) { puts("O O O O"); continue; } double r = calR(A, B, C); V po = calP(A, B, C); po = po+p[0]; printf("%.4f %.4f %.4f %.4f\n", po.x, po.y, po.z, r); } return 0; }