zoukankan      html  css  js  c++  java
  • 2017-03-18 HDU 5733 计算几何 codeforces 599E 状压dp(待补)

    HDU 5733

    题意:给出四面体的四个顶点,求出其内切球的球心坐标和半径,如果不存在内切球,输出"O O O O"。

    tags:一堆公式。。可以做模板了

    我们可以将平面上的四点得到由同一个点出发的三个矢量。这样就可以计算这三个矢量的混合积M,则M/6即为四面体体积V。

    题目无解的情况当且仅当四点共面,即混合积为0。

    求得四面体体积后,可以根据公式r = 3V/(S1+S2+S3+S4)得到内切球半径, S1~S4为四面体四个面的面积。

    当前的问题转化为如何求四面体四个面的面积。

    由于我们已经知道四个顶点的坐标,因此可以通过海伦公式来分别求解四个面的面积S1~S4,以此来求得r。

    对于球心坐标,有公式:

    x=(p1.x*s1+p2.x*s2+p3.x*s3+p4.x*s4)/(s1+s2+s3+s4);

    y=(p1.y*s1+p2.y*s2+p3.y*s3+p4.y*s4)/(s1+s2+s3+s4);

    z=(p1.z*s1+p2.z*s2+p3.z*s3+p4.z*s4)/(s1+s2+s3+s4);

    si为pi做顶点时,对应的底面的面积。

    // HDU 5733 
    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a;i<=b;i++)
    #define per(i,b,a) for (int i=b;i>=a;i--)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    typedef long long ll;
    const int N = 200005;
    const double eps=1e-8;
    
    double s[4], sum, x, y, z, v;
    
    struct Point {
        double x, y, z;
        Point operator - (const Point &b) const {    //向量 a 与 b 的点积 
            return Point{x-b.x, y-b.y, z-b.z};
        }
        Point operator ^ (const Point &b) const {    //向量 a 与 b 的叉积 
            return Point{(y*b.z-z*b.y), (z*b.x-x*b.z), (x*b.y-y*b.x)};
        }
    } p[4];
    int dcmp(double x) {        // x为混合积,判正负,x==0表示4点共面 
        if(fabs(x)<eps) return 0;
        return x<0?-1:1;
    }
    double MixMul(Point a, Point b, Point c) {        //求向量a,b,c的混合积 
        return a.x*b.y*c.z+a.y*b.z*c.x+a.z*b.x*c.y-a.x*b.z*c.y-a.y*b.x*c.z-a.z*b.y*c.x;
    }
    double dis(Point a, Point b) {            //两点距离 
        return sqrt(pow(a.x-b.x, 2)+pow(a.y-b.y, 2)+pow(a.z-b.z, 2));
    }
    double Heron(double a, double b, double c) {    //海伦公式求三角形面积 
        double p=(a+b+c)/2;
        return sqrt(p*(p-a)*(p-b)*(p-c));
    }
    double getsqr(Point a, Point b, Point c) {        //通过海伦公式求三个向量构成的面的面积 
        return Heron(dis(a,b), dis(b,c), dis(a,c));
    }
    
    int main()
    {
        while(~scanf("%lf %lf %lf", &p[0].x, &p[0].y, &p[0].z)) 
        {
            rep(i,1,3) scanf("%lf %lf %lf", &p[i].x, &p[i].y, &p[i].z);
            v=fabs(MixMul(p[0]-p[1], p[0]-p[2], p[0]-p[3]));
            if(dcmp(v)==0) {
                puts("O O O O");
                continue;
            }
            
            s[3]=getsqr(p[0], p[1], p[2]);        // 分别求出4个面的面积s[i]
            s[2]=getsqr(p[0], p[1], p[3]);
            s[1]=getsqr(p[0], p[2], p[3]);
            s[0]=getsqr(p[1], p[2], p[3]);
            sum=0;
            rep(i,0,3) s[i]=fabs(s[i]), sum+=s[i];    // sum为四个面的面积和,内切球半径 = v/2/sum 
            x=y=z=0;
            rep(i,0,3) {
                x+=p[i].x*s[i];
                y+=p[i].y*s[i];
                z+=p[i].z*s[i];
            }
            x/=sum, y/=sum, z/=sum;        //内切球球心坐标公式 
            printf("%.4f %.4f %.4f %.4f
    ", x, y, z, v/2/sum);
        }
    
        return 0;
    }
  • 相关阅读:
    读取json中的中文乱码
    Qt新建一个对话框
    Qt窗口全屏
    Qt设置QWidget背景图片
    Qt加载本地图片
    junit5|软断言
    Classpath resource [/data/department/createDepartment.csv] does not exist
    有个用户反馈上传头像失败,分析原因?
    手机扫描二维码的测试用例(转载)
    一次完整的HTTP请求过程是怎么样的呢?【图文详解】(转载)
  • 原文地址:https://www.cnblogs.com/sbfhy/p/6592014.html
Copyright © 2011-2022 走看看