• 计算几何 专题


    跟着斌神学计算几何

    !!!刷题集

    /*******************************************************/

    平面几何

    点,线,面,形基本关系,点积叉积的理解

    POJ 2318 TOYS(推荐)

    思路:根据差积可知:P x Q>0,P在Q的顺时针方向;P x Q<0,P在Q的逆时针方向;P x Q=0,P与Q共线,同向或反向。。所以如果一个点在一个四边形内,则与两对边的差积小于0.。。。。。。。。
    http://acm.pku.edu.cn/JudgeOnline/problem?id=2318

    /**************************************************************
        Problem:poj 2318
        User: youmi
        Language: C++
        Result: Accepted
        Time:922MS
        Memory:852K
    ****************************************************************/
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    //#include<bits/stdc++.h>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <stack>
    #include <set>
    #include <sstream>
    #include <cmath>
    #include <queue>
    #include <deque>
    #include <string>
    #include <vector>
    #define zeros(a) memset(a,0,sizeof(a))
    #define ones(a) memset(a,-1,sizeof(a))
    #define sc(a) scanf("%d",&a)
    #define sc2(a,b) scanf("%d%d",&a,&b)
    #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
    #define scs(a) scanf("%s",a)
    #define sclld(a) scanf("%I64d",&a)
    #define pt(a) printf("%d
    ",a)
    #define ptlld(a) printf("%I64d
    ",a)
    #define rep0(i,n) for(int i=0;i<n;i++)
    #define rep1(i,n) for(int i=1;i<=n;i++)
    #define rep_1(i,n) for(int i=n;i>=1;i--)
    #define rep_0(i,n) for(int i=n-1;i>=0;i--)
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define lson (step<<1)
    #define rson (lson+1)
    #define eps 1e-8
    #define oo 0x3fffffff
    #define TEST cout<<"*************************"<<endl
    
    using namespace std;
    typedef long long ll;
    const double PI=acos(-1.0);
    int n,m;
    
    const int maxn=5000+10;
    int sgn(double x)
    {
        if(fabs(x)<eps)
            return 0;
        if(x<0)
            return -1;
        else
            return 1;
    }
    struct Point
    {
        double x,y;
        Point(){};
        Point(double _x,double _y)
        {
            x=_x,y=_y;
        }
        Point operator- (const Point &_b)const
        {
            return Point(x-_b.x,y-_b.y);
        }
        double operator*(const Point &_b)const
        {
            return x*_b.x+y*_b.y;
        }
        double operator^(const Point &_b)const
        {
            return x*_b.y-y*_b.x;
        }
        void transXY(double _B)
        {
            double tx=x,ty=y;
            x=tx*cos(_B)-ty*sin(_B);
            y=tx*sin(_B)+ty*cos(_B);
        }
    };
    double cross(struct Point _s,struct Point _e1,struct Point _e2)
    {
        Point s,e;
        s=Point(_e1.x-_s.x,_e1.y-_s.y);
        e=Point(_e2.x-_s.x,_e2.y-_s.y);
        return s^e;
    }
    Point p[maxn],q[maxn];
    int cnt[maxn];
    void sovle(struct Point cur)
    {
        for(int i=1;i<=n;i++)
        {
            if(sgn(cross(p[i],q[i],cur)*cross(p[i-1],q[i-1],cur))==-1)
            {
                cnt[i-1]++;
                return;
            }
        }
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int kase=0;
        while(~sc(n)&&n)
        {
            if(kase++)
                cout<<endl;
            sc(m);
            int x1,y1,x2,y2;
            sc2(x1,y1);
            p[0].x=x1,p[0].y=0;
            q[0].x=x1,q[0].y=y1;
            sc2(x2,y2);
            p[n+1]=Point(x2,y2);
            q[n+1]=Point(x2,y1);
            rep1(i,n)
            {
                sc2(x1,x2);
                p[i]=Point(x2,y2);
                q[i]=Point(x1,y1);
            }
            ++n;
            /**< for(int i=0;i<=n;i++)
            {
                printf("%.0f %.0f	%.0f %.0f
    ",p[i].x,p[i].y,q[i].x,q[i].y);
            } */
            zeros(cnt);
            Point cur;
            rep1(i,m)
            {
                scanf("%lf%lf",&cur.x,&cur.y);
                sovle(cur);
            }
            for(int i=0;i<n;i++)
                printf("%d: %d
    ",i,cnt[i]);
        }
        return 0;
    }

    poj 3304 Segments http://poj.org/problem?id=3304

    思路:http://blog.csdn.net/heartnheart/article/details/5924116 (坑点:n==1的时候)

    /**************************************************************
        Problem:poj 3304
        User: youmi
        Language: C++
        Result: Accepted
        Time:79MS
        Memory:680K
    ****************************************************************/
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    //#include<bits/stdc++.h>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <stack>
    #include <set>
    #include <sstream>
    #include <cmath>
    #include <queue>
    #include <deque>
    #include <string>
    #include <vector>
    #define zeros(a) memset(a,0,sizeof(a))
    #define ones(a) memset(a,-1,sizeof(a))
    #define sc(a) scanf("%d",&a)
    #define sc2(a,b) scanf("%d%d",&a,&b)
    #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
    #define scs(a) scanf("%s",a)
    #define sclld(a) scanf("%I64d",&a)
    #define pt(a) printf("%d
    ",a)
    #define ptlld(a) printf("%I64d
    ",a)
    #define rep0(i,n) for(int i=0;i<n;i++)
    #define rep1(i,n) for(int i=1;i<=n;i++)
    #define rep_1(i,n) for(int i=n;i>=1;i--)
    #define rep_0(i,n) for(int i=n-1;i>=0;i--)
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define lson (step<<1)
    #define rson (lson+1)
    #define esp 1e-8
    #define oo 0x3fffffff
    #define TEST cout<<"*************************"<<endl
    
    using namespace std;
    typedef long long ll;
    const double pi=acos(-1.0);
    int sgn(double x)
    {
        if(fabs(x)<esp)
            return 0;
        if(x<0)
            return -1;
        else
            return 1;
    }
    typedef struct Point
    {
        double x,y;
        Point(){};
        Point(double _x,double _y)
        {
            x=_x,y=_y;
        }
        bool operator==(const Point&_B)const
        {
            return sgn(x-_B.x)==0&&sgn(y-_B.y)==0;
        }
        bool operator!=(const Point&_B)const
        {
            return sgn(x-_B.x)!=0||sgn(y-_B.y)!=0;
        }
        Point   operator-(const Point&_b)const
        {
            return Point(x-_b.x,y-_b.y);
        }
        double   operator*(const Point&_b)const
        {
            return x*_b.x+y*_b.y;
        }
        double   operator^(const Point&_b)const
        {
            return x*_b.y-y*_b.x;
        }
        void transXY(double _B)
        {
            double tx=x,ty=y;
            x=tx*cos(_B)-ty*sin(_B);
            y=tx*sin(_B)+ty*cos(_B);
        }
    }point;
    typedef struct Line
    {
        Point s,e;
        Line(){};
        Line(Point _s,Point _e)
        {
            s=_s,e=_e;
        }
        pair<int,Point>operator&(const Line &_B)const
        {
            Point res=s;
            if(sgn((s-e)^(_B.s-_B.e))==0)
            {
                if(sgn((s-_B.e)^(_B.s-_B.e))==0)
                    return make_pair(0,res);
                else
                    return make_pair(1,res);
            }
            double t=((s-_B.s)^(_B.s-_B.e))/((s-e)^(_B.s-_B.e));
            res.x+=(e.x-s.x)*t;
            res.y+=(e.y-s.y)*t;
            return make_pair(2,res);
        }
    }line;
    double dist(Point a,Point b)
    {
        return sqrt((a-b)*(a-b));
    }
    bool inter(line l1,line l2)
    {
        return
        Max(l1.s.x,l1.e.x)>=Min(l2.s.x,l2.e.x)&&
        Max(l2.s.x,l2.e.x)>=Min(l1.s.x,l1.e.x)&&
        Max(l1.s.y,l1.e.y)>=Min(l2.s.y,l2.e.y)&&
        Max(l2.s.y,l2.e.y)>=Min(l1.s.y,l1.e.y)&&
        sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0&&
        sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e))<=0;
    }
    bool Seg_inter_line(line l1,line l2)
    {
        return sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0;
    }
    int n;
    
    const int maxn=110;
    line seg[maxn];
    bool solve(line cur)
    {
        rep1(k,n)
        {
            if(!Seg_inter_line(cur,seg[k]))
                    return false;
        }
        return true;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int T_T;
        scanf("%d",&T_T);
        for(int kase=1;kase<=T_T;kase++)/**<  */
        {
            sc(n);
            double x1,y1,x2,y2;
            rep1(i,n)
            {
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                seg[i]=Line(Point(x1,y1),Point(x2,y2));
            }
            if(n<=2)
            {
                printf("Yes!
    ");
                continue;
            }
            int flag=0;
            rep1(i,n)
            {
                rep1(j,n)
                {
                    if(i!=j)
                    {
                        line cur;
                        if((seg[i].s!=seg[j].s))
                        {
                            cur=Line(seg[i].s,seg[j].s);
                            if(solve(cur))
                            {
                                 flag=1;
                                break;
                            }
                        }
                        if((seg[i].s!=seg[j].e))
                        {
                            cur=Line(seg[i].s,seg[j].e);
                            if(solve(cur))
                            {
                                 flag=1;
                                break;
                            }
                        }
                        if((seg[i].e!=seg[j].s))
                        {
                            cur=Line(seg[i].e,seg[j].s);
                            if(solve(cur))
                            {
                                 flag=1;
                                break;
                            }
                        }
                        if((seg[i].e!=seg[j].e))
                        {
                            cur=Line(seg[i].e,seg[j].e);
                            if(solve(cur))
                            {
                                 flag=1;
                                break;
                            }
                        }
                    }
                }
                if(flag==1)
                    break;
            }
            puts(flag?"Yes!":"No!");
        }
        return 0;
    }
    (づ ̄ 3 ̄)づ

    poj 1556 The Doors http://poj.org/problem?id=1556

    思路:因为最多18行,所以最多4*18+2个点,在100量级的点求最短路,想怎么求就怎么求,只不多在更新的时候加上交叉判断就好了,不交叉跟新就好啦、、、。。。这题能够1A还得感谢神队友教我调试方法,太好使了。。。。。。。。。。。。。。。。!!!!!!!!!!!!!!!!!!!

    /**************************************************************
        Problem:poj 1556
        User: youmi
        Language: C++
        Result: Accepted
        Time:0MS
        Memory:700K
    ****************************************************************/
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    //#include<bits/stdc++.h>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <stack>
    #include <set>
    #include <sstream>
    #include <cmath>
    #include <queue>
    #include <deque>
    #include <string>
    #include <vector>
    #define zeros(a) memset(a,0,sizeof(a))
    #define ones(a) memset(a,-1,sizeof(a))
    #define sc(a) scanf("%d",&a)
    #define sc2(a,b) scanf("%d%d",&a,&b)
    #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
    #define scs(a) scanf("%s",a)
    #define sclld(a) scanf("%I64d",&a)
    #define pt(a) printf("%d
    ",a)
    #define ptlld(a) printf("%I64d
    ",a)
    #define rep0(i,n) for(int i=0;i<n;i++)
    #define rep1(i,n) for(int i=1;i<=n;i++)
    #define rep_1(i,n) for(int i=n;i>=1;i--)
    #define rep_0(i,n) for(int i=n-1;i>=0;i--)
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define lson (step<<1)
    #define rson (lson+1)
    #define esp 1e-8
    #define oo 0x3fffffff
    #define TEST cout<<"*************************"<<endl
    
    using namespace std;
    typedef long long ll;
    
    int n;
    
    const int maxn=100;
    double dis[maxn];
    const int PI=acos(-1.0);
    int sgn(double x)
    {
        if(fabs(x)<esp)
            return 0;
        if(x<0)
            return -1;
        else
            return 1;
    }
    typedef struct Point
    {
        double x,y;
        Point(){};
        Point(double _x,double _y)
        {
            x=_x,y=_y;
        }
        Point operator-(const Point & _b)const
        {
            return Point(x-_b.x,y-_b.y);
        }
        double operator *(const Point &_b)const
        {
            return x* _b.x+y* _b.y;
        }
        double operator^(const Point &_b)const
        {
            return  x* _b.y- _b.x*y;
        }
        void transXY(double _b)
        {
            double tx=x,ty=y;
            x=tx*cos(_b)-ty*sin(_b);
            y=tx*sin(_b)+ty*cos(_b);
        }
    }point;
    point st=Point(0,5),ed=Point(10,5);
    point mat[25][10];
    typedef struct Line
    {
        point s,e;
        Line(){};
        Line(point  _s,point  _e)
        {
            s=_s,e=_e;
        }
    }line;
    line ln[25][10];
    double dist(point a,point b)
    {
        return sqrt((a-b)*(a-b));
    }
    bool inter(line l1,line l2)
    {
        return
        Max(l1.s.x,l1.e.x)>=Min(l2.s.x,l2.e.x)&&
        Max(l1.s.y,l1.e.y)>=Min(l2.s.y,l2.e.y)&&
        Max(l2.s.x,l2.e.x)>=Min(l1.s.x,l1.e.x)&&
        Max(l2.s.y,l2.e.y)>=Min(l1.s.y,l1.e.y)&&
        sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0&&
        sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e))<=0;
    }
    bool is_inter(line temp,int l,int r)
    {
        for(int i=l;i<=r;i++)
        {
            for(int j=1;j<=3;j++)
            {
                if(inter(temp,ln[i][j]))
                    return true;
            }
        }
        return false;
    }
    bool vis[maxn];
    void solve()
    {
        int tot=n*4;
        line temp;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=4;j++)
            {
                temp=Line(st,mat[i][j]);
                int now=(i-1)*4+j-1;
                if(is_inter(temp,1,i-1))
                    dis[now]=oo;
                else
                    dis[now]=dist(st,mat[i][j]);
            }
        }
        if(is_inter(Line(st,ed),1,n))
            dis[tot]=oo;
        else
            dis[tot]=dist(st,ed);
        zeros(vis);
        int cnt=0,now,u;
        while(cnt<=tot)
        {
            now=oo;
            for(int i=0;i<=tot;i++)
            {
                if(!vis[i]&&now>dis[i])
                {
                    now=dis[i];
                    u=i;
                }
            }
            vis[u]=1;
            for(int i=0;i<=tot;i++)
            {
                temp=Line(mat[u/4+1][u%4+1],mat[i/4+1][i%4+1]);
                int mn=Min(i,u);
                int mx=Max(i,u);
                double len=dist(mat[u/4+1][u%4+1],mat[i/4+1][i%4+1]);
                if(i!=u&&!is_inter(temp,mn/4+2,mx/4)&&dis[i]>dis[u]+len)
                    dis[i]=dis[u]+len;
            }
            cnt++;
        }
        printf("%.2f
    ",dis[tot]);
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~sc(n)&&~n)
        {
            double x0,y0;
            rep1(i,n)
            {
                scanf("%lf",&x0);
                mat[i][0]=Point(x0,0),mat[i][5]=Point(x0,10);
                rep1(j,4)
                {
                    scanf("%lf",&y0);
                    mat[i][j]=Point(x0,y0);
                }
                ln[i][1]=Line(mat[i][0],mat[i][1]),ln[i][2]=Line(mat[i][2],mat[i][3]),ln[i][3]=Line(mat[i][4],mat[i][5]);
            }
            mat[n+1][1]=ed;
            solve();
        }
        return 0;
    }
    (づ ̄ 3 ̄)づ

    poj 1113 Wall http://poj.org/problem?id=1113

    思路:基础的凸包问题,结果就是周长加上2*pi*L。。。。。。。话说自从学会精湛的调试方法后一路1A。。。。。。。。。。

    /**************************************************************
        Problem:poj 1113
        User: youmi
        Language: C++
        Result: Accepted
        Time:63MS
        Memory:692K
    ****************************************************************/
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    //#include<bits/stdc++.h>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <stack>
    #include <set>
    #include <sstream>
    #include <cmath>
    #include <queue>
    #include <deque>
    #include <string>
    #include <vector>
    #define zeros(a) memset(a,0,sizeof(a))
    #define ones(a) memset(a,-1,sizeof(a))
    #define sc(a) scanf("%d",&a)
    #define sc2(a,b) scanf("%d%d",&a,&b)
    #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
    #define scs(a) scanf("%s",a)
    #define sclld(a) scanf("%I64d",&a)
    #define pt(a) printf("%d
    ",a)
    #define ptlld(a) printf("%I64d
    ",a)
    #define rep0(i,n) for(int i=0;i<n;i++)
    #define rep1(i,n) for(int i=1;i<=n;i++)
    #define rep_1(i,n) for(int i=n;i>=1;i--)
    #define rep_0(i,n) for(int i=n-1;i>=0;i--)
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define lson (step<<1)
    #define rson (lson+1)
    #define esp 1e-6
    #define oo 0x3fffffff
    #define TEST cout<<"*************************"<<endl
    
    using namespace std;
    typedef long long ll;
    
    int n,len;
    const double PI=acos(-1.0);
    const int maxn=1000+10;
    int sgn(double x)
    {
        if(fabs(x)<esp)
            return 0;
        if(x<0)
            return -1;
        else
            return 1;
    }
    struct point
    {
        double x,y;
        point(){};
        point(double _x,double _y)
        {
            x=_x,y=_y;
        }
        point operator-(const point &_b)const
        {
            return point(x-_b.x,y-_b.y);
        }
        double operator *(const point &_b)const
        {
            return x*_b.x+y*_b.y;
        }
        double operator^(const point &_b)const
        {
            return x*_b.y-_b.x*y;
        }
    };
    double dist(point a,point b)
    {
        return sqrt((a-b)*(a-b));
    }
    point lst[maxn];
    int stc[maxn],top;
    bool _cmp(point p1,point p2)
    {
        double temp=(p1-lst[0])^(p2-lst[0]);
        if(sgn(temp)>0)
            return true;
        else if(sgn(temp)==0&&sgn(dist(p1,lst[0])-dist(p2,lst[0]))<=0)
            return true;
        else
            return false;
    }
    void graham()
    {
        point p0=lst[0];
        int k=0;
        for(int i=1;i<n;i++)
        {
            if((p0.y>lst[i].y)||(p0.y==lst[i].y&&p0.x>lst[i].x))
            {
                p0=lst[i];
                k=i;
            }
        }
        swap(lst[k],lst[0]);
        sort(lst+1,lst+n,_cmp);
        if(n==1)
        {
            top=1;
            stc[0]=0;
            return ;
        }
        top=2;
        stc[0]=0;
        stc[1]=1;
        if(n==2)
            return ;
        for(int i=2;i<n;i++)
        {
            while(top>1&&sgn((lst[stc[top-1]]-lst[stc[top-2]])^(lst[i]-lst[stc[top-2]]))<=0)
                top--;
            stc[top++]=i;
        }
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~sc2(n,len))
        {
            double x0,y0;
            rep0(i,n)
            {
                scanf("%lf%lf",&x0,&y0);
                lst[i]=point(x0,y0);
            }
            graham();
            if(n<=2)
            {
                printf("0
    ");
                continue;
            }
            double ans=0;
            for(int i=0;i<top;i++)
            {
                point a=lst[stc[(i-1+top)%top]];
                point b=lst[stc[(i-0+top)%top]];
                ans+=dist(a,b);
            }
            ans+=2*PI*len;
            ll temp=(ll)floor(ans);
            if((int)fabs(ans-temp+0.5)==1)
                printf("%lld
    ",temp+1);
            else
                printf("%lld
    ",temp);
        }
        return 0;
    }
    (づ ̄ 3 ̄)づ

     /*******************************************************/

    立体几何

    题目链接:hdu 5733 tetrahedron

    题意:给定一个四面体,求其内切圆半径和内心,如若不存在输出4个‘O’。

    解题: 首先用叉积判断是否四点共面,若四点共面,则不能形成四面体。随后,利用四面体体积公式,海伦公式(求三角形面积),四面体内心公式,求出四面           体的内切圆半径和内心。

    /**************************************************************
        Problem:hdu 5733
        User: youmi
        Language: C++
        Result: Accepted
        Time:0MS
        Memory:1616K
    ****************************************************************/
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    //#include<bits/stdc++.h>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <stack>
    #include <set>
    #include <sstream>
    #include <cmath>
    #include <queue>
    #include <deque>
    #include <string>
    #include <vector>
    #define zeros(a) memset(a,0,sizeof(a))
    #define ones(a) memset(a,-1,sizeof(a))
    #define sc(a) scanf("%d",&a)
    #define sc2(a,b) scanf("%d%d",&a,&b)
    #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
    #define scs(a) scanf("%s",a)
    #define sclld(a) scanf("%I64d",&a)
    #define pt(a) printf("%d
    ",a)
    #define ptlld(a) printf("%I64d
    ",a)
    #define rep(i,from,to) for(int i=from;i<=to;i++)
    #define irep(i,to,from) for(int i=to;i>=from;i--)
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define lson (step<<1)
    #define rson (lson+1)
    #define eps 1e-6
    #define oo 0x3fffffff
    #define TEST cout<<"*************************"<<endl
    const double pi=4*atan(1.0);
    
    using namespace std;
    typedef long long ll;
    template <class T> inline void read(T &n)
    {
        char c; int flag = 1;
        for (c = getchar(); !(c >= '0' && c <= '9' || c == '-'); c = getchar()); if (c == '-') flag = -1, n = 0; else n = c - '0';
        for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0'; n *= flag;
    }
    int Pow(int base, ll n, int mo)
    {
        if (n == 0) return 1;
        if (n == 1) return base % mo;
        int tmp = Pow(base, n >> 1, mo);
        tmp = (ll)tmp * tmp % mo;
        if (n & 1) tmp = (ll)tmp * base % mo;
        return tmp;
    }
    inline int sign(double p)
    {
        if(p>eps)return 1;
        else if(p<-eps)return -1;
        else return 0;
    }
    struct Point
    {
        double x,y,z;
        Point(double xx=0,double yy=0,double zz=0):x(xx),y(yy),z(zz){}
        Point operator +(const Point p1)
        {
            return Point(x+p1.x,y+p1.y,z+p1.z);
        }
        Point operator -(const Point p1)
        {
            return Point(x-p1.x,y-p1.y,z-p1.z);
        }
        Point operator *(const Point p1)
        {
            return Point(y*p1.z-z*p1.y,z*p1.x-x*p1.z,x*p1.y-y*p1.x);
        }
        Point operator *(double d)
        {
            return Point(d*x,d*y,d*z);
        }
        Point operator /(double d)
        {
            return Point(x/d,y/d,z/d);
        }
        double operator ^(const Point p1)
        {
            return x*p1.x+y*p1.y+z*p1.z;
        }
        double getLen()
        {
            return sqrt(x*x+y*y+z*z);
        }
        int read()
        {
            return scanf("%lf%lf%lf",&x,&y,&z);
        }
    };
    
    struct Plane
    {
        Point a,b,c;
        Plane(){}
        Plane(Point _a,Point _b,Point _c):a(_a),b(_b),c(_c){}
    };
    struct CH3D
    {
        double vlen(Point a)
        {
            return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);
        }
        Point normal_vec(Plane s)
        {
            return (s.a-s.b)*(s.b-s.c);
        }
        Point cross(Point a,Point b,Point c)
        {
            return Point(
                    (b.y-a.y)*(c.z-a.z)-(b.z-a.z)*(c.y-a.y),
                    (b.z-a.z)*(c.x-a.x)-(b.x-a.x)*(c.z-a.z),
                    (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x)
                    );
        }
        //三角形面积
        double area(Point a,Point b,Point c)
        {
            return fabs(vlen((b-a)*(c-a))/2.0);
        }
        //四面体面积
        double volume(Point a,Point b,Point c,Point d)
        {
            return fabs(((b-a)*(c-a))^(d-a)/6.0);
        }
    
    };
    //***************************
    CH3D hull;
    
    int n;
    Point a,b,c,d;
    void work()
    {
        double v=hull.volume(a,b,c,d);
        double s1=hull.area(a,b,c);
        double s2=hull.area(a,b,d);
        double s3=hull.area(b,c,d);
        double s4=hull.area(a,c,d);
        double r=3*v/(s1+s2+s3+s4);
        double sum=s1+s2+s3+s4;
        double x1=(s1*d.x+s2*c.x+s3*a.x+s4*b.x)/sum;
        double y1=(s1*d.y+s2*c.y+s3*a.y+s4*b.y)/sum;
        double z1=(s1*d.z+s2*c.z+s3*a.z+s4*b.z)/sum;
        printf("%.4lf %.4lf %.4lf %.4lf
    ",x1,y1,z1,r);
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        while(~a.read())
        {
            b.read();
            c.read();
            d.read();
            Plane s=Plane(a,b,c);
            if(fabs(hull.normal_vec(s)^(d-a))<eps)
            {
                printf("O O O O
    ");
                continue;
            }
            work();
        }
    }
    不为失败找借口,只为成功找方法
  • 相关阅读:
    在android模拟器运行arm 移植的 c程序
    Android实现对c++方式调用
    Hdu 1003 Max Sum
    HDU 1005 Number Sequence
    poj 1222 EXTENDED LIGHTS OUT 高斯消元法
    分治算法
    HDU杭电acm题目分类大全
    HDU 1002 A + B Problem II 大数相加
    HDU 1004 Let the Balloon Rise
    phpcms栏目和专题的区分
  • 原文地址:https://www.cnblogs.com/youmi/p/4937358.html
Copyright © 2020-2023  润新知