zoukankan      html  css  js  c++  java
  • HDU 5733

    HDU 5733 - tetrahedron

    题意:
        给定四点,求是否能够成四面体,若能则求出其内接圆心和半径

    是否能构成四面体: 三点成面的法线和另一点与三点中任一点相连的向量是否垂直?

    四面体内接球
        球心: 任意三个角平分面的交点
        半径: 交点到任意面的距离

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cmath>
      4 using namespace std;
      5 const double EPS = 1e-8;
      6 struct Point3
      7 {
      8     double x,y,z;
      9     Point3() {}
     10     Point3(double x,double y,double z):x(x),y(y),z(z) {}
     11 };
     12 typedef Point3 Vec3;
     13 Vec3 operator + (Vec3 A,Vec3 B)
     14 { 
     15     return Vec3(A.x + B.x, A.y + B.y, A.z + B.z); 
     16 }
     17 Vec3 operator - (Vec3 A,Vec3 B)
     18 { 
     19     return Vec3(A.x - B.x, A.y - B.y, A.z - B.z); 
     20 }
     21 Vec3 operator * (Vec3 A,double p)
     22 { 
     23     return Vec3(A.x * p, A.y * p, A.z * p);
     24 }
     25 Vec3 operator / (Vec3 A,double p)
     26 { 
     27     return Vec3(A.x / p, A.y / p, A.z / p); 
     28 }
     29 int dcmp(double x)//double cmp
     30 {
     31     return fabs(x) < EPS ? 0 : (x < 0? -1: 1);
     32 }
     33 double Dot3(Vec3 A,Vec3 B)//Dot mult
     34 {
     35     return A.x*B.x + A.y*B.y + A.z*B.z;
     36 }
     37 double Length3(Vec3 A)
     38 {
     39     return sqrt( Dot3(A, A) );
     40 }
     41 double Angle(Vec3 A,Vec3 B)//夹角 
     42 {
     43     return acos(Dot3(A,B) / Length3(A) / Length3(B));
     44 }
     45 Vec3 Cross3(Vec3 A,Vec3 B)//叉积 右手螺旋A->B 
     46 {
     47     return Vec3(A.y * B.z - A.z * B.y,
     48                 A.z * B.x - A.x * B.z,
     49                 A.x * B.y - A.y * B.x);
     50 }
     51 struct Plane
     52 {
     53     Vec3 n; //法线
     54     Point3 p0; 
     55     Plane() {}
     56     Plane(Vec3 nn,Point3 pp0)
     57     {
     58         n = nn / Length3(nn);
     59         p0 = pp0;
     60     }
     61     Plane(Point3 a,Point3 b,Point3 c)
     62     {
     63         Point3 nn = Cross3(b-a,c-a);
     64         n = nn/(Length3(nn));
     65         p0 = a;
     66     }
     67 };
     68 //角平分面 法向量为两平面法向量相加(内角)或相减(外角)
     69 Plane jpfPlane(Point3 a1,Point3 a2,Point3 b,Point3 c) 
     70 {
     71     Plane p1(a1,b,c),p2(a2,c,b);
     72     Vec3 temp = p1.n + p2.n;
     73     return Plane(Cross3(temp, c-b),b);
     74 }
     75 Point3 LinePlaneIntersection(Point3 p1,Point3 p2,Plane a)//线面交点 取线上任意两点 
     76 {
     77     Point3 p0 = a.p0;
     78     Vec3 n = a.n,v = p2-p1;
     79     double t = (Dot3(n,p0-p1) / Dot3(n,p2-p1)); //映射到法向量的比例 
     80     return p1 + v * t;
     81 }
     82 Point3 PlaneInsertion(Plane a,Plane b,Plane c)//三面交点 
     83 {//两面交线与两面法线均垂直,法线叉积为其方向矢量. 
     84     Vec3 nn = Cross3(a.n,b.n),use = Cross3(nn,a.n);
     85     Point3 st = LinePlaneIntersection(a.p0, a.p0+use,b);//得交线上一点 
     86     return LinePlaneIntersection(st, st+nn, c);
     87 }
     88 double DistanceToPlane(Point3 p,Plane a)
     89 {
     90     Point3 p0 = a.p0;
     91     Vec3 n = a.n;
     92     return fabs( Dot3(p-p0,n) / Length3(n) );
     93 } 
     94 bool isOnePlane(Point3 a,Point3 b,Point3 c,Point3 d)
     95 {
     96     double t = Dot3(d-a,Cross3(b-a,c-a) );
     97     return dcmp(t)==0;
     98 }
     99 int main()
    100 {
    101     Point3 p[4];
    102     while(~scanf("%lf%lf%lf",&p[0].x,&p[0].y,&p[0].z))
    103     {
    104         for(int i=1;i<4;i++) scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z);
    105         if(isOnePlane(p[0],p[1],p[2],p[3]))
    106         {
    107             puts("O O O O"); continue;
    108         }
    109         Plane a = jpfPlane(p[3],p[2],p[1],p[0]),//三个角平分面的交点即为圆心 
    110               b = jpfPlane(p[3],p[0],p[1],p[2]),
    111               c = jpfPlane(p[3],p[1],p[0],p[2]);
    112         Plane d(p[0],p[1],p[2]);
    113         Point3 center = PlaneInsertion(a,b,c);
    114         double r = DistanceToPlane(center,d);
    115         printf("%.4f %.4f %.4f %.4f
    ",center.x,center.y,center.z,r);
    116     }
    117 }
    我自倾杯,君且随意
  • 相关阅读:
    随机-byte编码
    dataframe骚操作,待续
    oracle中的rowid
    java提高篇-----理解java的三大特性之继承
    staruml使用教程
    黑马程序员:HTML习题1
    Cocos2d-x-->CCSprite 动画
    地址栏传参中文乱码详解
    Qt学习第二天
    Lync 2010 升级到2013 之部署2013前端服务器!
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/5705802.html
Copyright © 2011-2022 走看看