題目鏈接:點擊打開鏈接
題目大意:求一個四面體的內切圓半徑及圓心空間位置
解題思路:
四面體兩條相對的邊處於兩條互相歪斜(在三維空間中既不相交也不平行,等價於異面)的直線上,所以四面體相對邊之間的距離就被定義爲其所在 互相歪斜的直線之間的距離。設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; }